Automatic Translate Addon For Loco Translate - Version 1.7.4

Version Description

Download this release

Release Info

Developer Narinder singh
Plugin Icon 128x128 Automatic Translate Addon For Loco Translate
Version 1.7.4
Comparing to
See all releases

Code changes from version 1.5 to 1.7.4

assets/css/atlt-admin-feedback-notice.css CHANGED
@@ -1,7 +1,5 @@
1
  .cool-feedback-notice-wrapper.notice.notice-info.is-dismissible {
2
  padding: 5px;
3
- display: inline-block;
4
- width: 100%;
5
  }
6
  .cool-feedback-notice-wrapper .logo_container {
7
  width:80px;
@@ -23,6 +21,21 @@
23
  float: left;
24
  margin: 0px 5px;
25
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  .clrfix{
27
  clear:both;
28
  }
@@ -48,3 +61,25 @@
48
  margin: 0 auto;
49
  display: block;
50
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  .cool-feedback-notice-wrapper.notice.notice-info.is-dismissible {
2
  padding: 5px;
 
 
3
  }
4
  .cool-feedback-notice-wrapper .logo_container {
5
  width:80px;
21
  float: left;
22
  margin: 0px 5px;
23
  }
24
+ .cool-feedback-notice-wrapper ul li.already_rated a:before {
25
+ color: #cc0000;
26
+ content: "\f153";
27
+ font: normal 16px/20px dashicons;
28
+ display: inline-block;
29
+ vertical-align: middle;
30
+ margin-right: 4px;
31
+ height: 22px;
32
+ }
33
+ .cool-feedback-notice-wrapper ul li.already_rated a[title="Not Interested"] {
34
+ position: absolute;
35
+ right: 5px;
36
+ top: 5px;
37
+ z-index: 9;
38
+ }
39
  .clrfix{
40
  clear:both;
41
  }
61
  margin: 0 auto;
62
  display: block;
63
  }
64
+
65
+ /*Custom Sidebar*/
66
+ .loco-settings-custom-sidebar {
67
+ border: 4px solid #b9b9b9;
68
+ max-width: 320px;
69
+ width:18%;
70
+ float: right;
71
+ margin-right: 15px;
72
+ padding: 10px;
73
+ box-sizing: border-box;
74
+ }
75
+ .loco-settings-custom-sidebar h2 {
76
+ background: #d6d6d6;
77
+ padding: 5px;
78
+ font-size: 1em;
79
+ font-weight: bold;
80
+ }
81
+ .loco-settings-custom-sidebar ul li {
82
+ list-style: square;
83
+ padding-left: 0;
84
+ margin-left: 16px;
85
+ }
assets/images/atlt-logo.png CHANGED
Binary file
assets/images/google-api.png CHANGED
Binary file
assets/images/microsoft-api.png ADDED
Binary file
assets/images/screenshot-1.gif CHANGED
Binary file
assets/js/api-testing.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+ $('.atlt_test_api').on('click', function (event) {
3
+ event.preventDefault();
4
+ var $this = $(this);
5
+ var endpoint=info["info"]["endpoint"];
6
+ $this.parent().find(".atlt-preloader").show();
7
+ var ajaxURL=$this.data('ajaxurl');
8
+ var source=$this.data('source');
9
+ var target=$this.data('target');
10
+ var text=$this.data('text');
11
+ var apikey=$this.data('apikey');
12
+ var apiprovider=$this.data('api-provider');
13
+ var nonce=$this.data('nonce');
14
+ var defaultString='"Hello World" Translation in French:-';
15
+ var data = {
16
+ 'action':endpoint,
17
+ 'nonce':nonce,
18
+ 'source':source,
19
+ 'target':target,
20
+ 'text':text,
21
+ 'apikey':apikey,
22
+ 'apiprovider':apiprovider,
23
+ };
24
+ var request = $.ajax({
25
+ url:ajaxURL,
26
+ method: "POST",
27
+ data:data,
28
+ });
29
+ request.done(function (response, textStatus, jqXHR ){
30
+ // console.log(response);
31
+
32
+ $this.parent().find(".atlt-preloader").hide();
33
+ let output='';
34
+ if(response && jqXHR.status==200){
35
+ let json_resp = JSON.parse(response);
36
+ if(json_resp.translatedString!=null && json_resp.translatedString.length
37
+ && json_resp['code']==200){
38
+ traString=json_resp.translatedString;
39
+ output=defaultString+'"'+traString+'"';
40
+ swal({
41
+ icon: "success",
42
+ text:output
43
+ });
44
+ }else{
45
+ let errorCode=json_resp['code'];
46
+ let message=json_resp['error'];
47
+ swal({
48
+ icon: "error",
49
+ text:errorCode+ " " +message
50
+ });
51
+ }
52
+ }else{
53
+ swal({
54
+ icon: "error",
55
+ text:response
56
+ });
57
+ }
58
+
59
+ });
60
+ request.fail(function( jqXHR, textStatus ) {
61
+ swal({
62
+ icon: "warning",
63
+ text:"Request failed: " + textStatus
64
+ });
65
+ $this.parent().find(".atlt-preloader").hide();
66
+ });
67
+ });
68
+ });
assets/js/atlt-custom.js DELETED
@@ -1,601 +0,0 @@
1
- var TotalCharacters=0;
2
- var HtmlStrings = 0;
3
- var requestChars=0;
4
-
5
- let event = document.createEvent('event');
6
- event.initEvent('atlt_translated');
7
- createSettingsPopup();
8
-
9
- $('#atlt-dialog .atlt-ok.button').on('click',function(){
10
- // hide dialog container by finding main parent DOM
11
- localStorage.removeItem('unSavedString');
12
- $("#atlt-dialog").parent('.ui-dialog').hide();
13
- });
14
-
15
-
16
-
17
- /*
18
- |--------------------------------------------------------------------------
19
- | Auto Translator Custom Code
20
- |--------------------------------------------------------------------------
21
- */
22
- //encode URL query string
23
- function createEncodedString(allStringText){
24
- const queryString=allStringText.map((item)=>{
25
- return "&text="+ encodeURIComponent(item.source);
26
- }).join(",");
27
-
28
- return queryString;
29
- }
30
-
31
- function validLicenseKey(licenseKey){
32
- return licenseKey;
33
- }
34
-
35
- $(document).ready(function(){
36
- const locoRawData=conf.podata;
37
- if(locoRawData!=undefined && locoRawData.length>0 ){
38
- // called auto traslate button
39
- addAutoTranslationBtn();
40
- }
41
-
42
- $(document).on("click", "#cool-auto-translate-btn", function() {
43
- $('#atlt-dialog').dialog({width:320,height:300});
44
- });
45
- /* $("#atlt-settings-form").submit(function( event ) {
46
- event.preventDefault();
47
- let type = $("input[name='translationtype']:checked").val();
48
- console.log(type);
49
- }); */
50
- // main translate handler
51
-
52
- $("#atlt-settings-form").submit(function( event ) {
53
- event.preventDefault();
54
- let strType = $("input[name='translationtype']:checked").val();
55
- let apiType = $("input[name='api_type']:checked").val();
56
- let mainBtn=$("#cool-auto-translate-btn");
57
- var thisBtn=$("#cool-auto-translate-start");
58
-
59
- var todayLimit= mainBtn.data('today-limit');
60
- var totalLimit= mainBtn.data('total-limit');
61
- // const targetLang=conf.locale.lang;
62
- const apiKey = ATLT["api_key"]["atlt_api-key"];
63
-
64
- if(locoRawData!=undefined && locoRawData.length>0 && apiKey!='' ){
65
- let plainStrArr=[];
66
- let htmlStrArr=[];
67
- let orgStrArr=[];
68
- orgStrArr=locoRawData.filter((item,index)=>{
69
- if((item.target===undefined || item.target=="")){
70
- return true;
71
- }
72
- });
73
-
74
- htmlStrArr=locoRawData.filter((item,index)=>{
75
- if( (item.target===undefined || item.target=="" && item.source!="" && item.source!==undefined)){
76
- if( ValidURL(item.source)){
77
- return false;
78
- }else if(isContainChars(item.source)){
79
- return false;
80
- } else if(isHTML(item.source)){
81
- return true;
82
- }else if(isAllowedChars(item.source)){
83
- return true;
84
- }else{
85
- return false;
86
- }
87
- }
88
- });
89
-
90
- plainStrArr=locoRawData.filter((item,index)=>{
91
- if( (item.target===undefined || item.target=="") && item.source!=""){
92
- if(isHTML(item.source) || ValidURL(item.source)){
93
- return false;
94
- }else if(isSpecialChars(item.source)){
95
- return false;
96
- }
97
- else if( item.source.includes('#') == true)
98
- {
99
- return false;
100
- }else{
101
- return true;
102
- }
103
- }
104
- });
105
-
106
- var countChars=0;
107
- if(strType=="plain"){
108
- if (plainStrArr !== null) {
109
- plainStrArr.map(function(index){
110
- countChars +=index.source.length;
111
- });
112
- }
113
- }else{
114
- if (htmlStrArr !== null) {
115
- plainStrArr.map(function(index){
116
- countChars +=index.length;
117
- });
118
- }
119
- }
120
-
121
- if (htmlStrArr !== null || plainStrArr !== null ) {
122
- if(countChars>parseInt(todayLimit)){
123
- alert('Your translation string are larger then available free limit.In order to extend limit Buy Pro license key');
124
- }else{
125
-
126
- if(strType=="plain"){
127
- if(plainStrArr.length==0){
128
- $("#atlt-dialog").parent('.ui-dialog').hide();
129
- mainBtn.attr('disabled','disabled');
130
- alert("You have no untransalted strings");
131
- window.location.reload();
132
- return;
133
- }
134
- dataObj = {
135
- textToTranslateArr:plainStrArr,
136
- thisBtn:$(this),
137
- strType:"plain",
138
- apiType:apiType
139
- };
140
- }else{
141
- if(htmlStrArr.length==0){
142
- $("#atlt-dialog").parent('.ui-dialog').hide();
143
- mainBtn.attr('disabled','disabled');
144
- alert("You have no untransalted HTML strings");
145
- window.location.reload();
146
- return;
147
- }
148
- dataObj = {
149
- textToTranslateArr:htmlStrArr,
150
- thisBtn:$(this),
151
- strType:"html",
152
- apiType:apiType
153
- };
154
- }
155
- dataObj.orgStrArr= orgStrArr;
156
- thisBtn.val('Translating...');
157
- mainBtn.text("Translating..");
158
- $("#atlt_preloader").show();
159
-
160
- window.locoEditorStats.dataObj = dataObj;
161
- jQuery(document).trigger('atlt_translated');
162
-
163
- // load raw message data
164
-
165
- } //
166
-
167
- } // else close
168
- }
169
-
170
- });
171
-
172
- });
173
-
174
- jQuery(document).on('atlt_translated',function(){
175
- let textToTranslate = window.locoEditorStats.dataObj.textToTranslateArr
176
- let totalTranslated = window.locoEditorStats.totalTranslated
177
- const apiKey = ATLT["api_key"]["atlt_api-key"];
178
- const nonce=ATLT["nonce"];
179
- const saveBtn=$('[data-loco="save"]');
180
- const orignalstringArr=window.locoEditorStats.dataObj.orgStrArr;
181
- const targetLang=conf['locale']["lang"];
182
- let indexRequest = 50;
183
- if( ATLT.api_key['atlt_index-per-request'] != "" && typeof ATLT.api_key['atlt_index-per-request'] != "undefined" ){
184
- indexRequest = ATLT.api_key['atlt_index-per-request'];
185
- }
186
-
187
- if( typeof textToTranslate == "object" && textToTranslate.length >= 1 ){
188
- let translationO = {
189
- textToTranslateArr:textToTranslate.slice(indexRequest),
190
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
191
- strType:window.locoEditorStats.dataObj.strType,
192
- orgStrArr:window.locoEditorStats.dataObj.orgStrArr,
193
- apiType:window.locoEditorStats.dataObj.apiType
194
- };
195
- window.locoEditorStats.dataObj = translationO;
196
-
197
- // partial data request
198
- let data = {
199
- sourceLang:'en',
200
- targetLang:targetLang,
201
- textToTranslateArr:textToTranslate.slice(0,indexRequest),
202
- orginalArr:orignalstringArr,
203
- apiKey:apiKey,
204
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
205
- strType:window.locoEditorStats.dataObj.strType,
206
- apiType:window.locoEditorStats.dataObj.apiType,
207
- saveBtn:saveBtn,
208
- nonce:nonce
209
- };
210
-
211
- textToTranslate.slice(0,indexRequest).map(function(value,index){
212
- TotalCharacters += (value.source).length;
213
- requestChars+=(value.source).length;
214
- })
215
- atlt_translate(data);
216
- }
217
- })
218
-
219
- // Translate
220
- function atlt_translate(data) {
221
-
222
- atlt_ajax_translation_request(data, "POST").success(function(
223
- resp
224
- ) {
225
- const json_resp = JSON.parse(resp);
226
- if( json_resp == false ){
227
- data.thisBtn.hide('slow');
228
- $("#cool-auto-translate-btn").attr('disabled','disabled');
229
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
230
- alert('Unable to make request to the server at the moment. Try again later.');
231
- }else if( typeof json_resp['code'] === undefined || json_resp['code'] != 200 ){
232
- let error = '';
233
- switch(json_resp['code']){
234
- case 401:
235
- error = 'Yendex API Key is invalid!';
236
- break;
237
- case 402:
238
- error = 'Provided Yendex API Key has been blocked!';
239
- break;
240
- case 404:
241
- error = 'Exceeded the daily limit for Yendex API on the amount of translated text.';
242
- break;
243
- case 422:
244
- error = 'The text cannot be translated by Yendex API.';
245
- break;
246
- case 501:
247
- error = 'Yendex API does not support the specified translation direction.';
248
- break;
249
- default:
250
- error = json_resp['message'];
251
- }
252
- if( error != '' && (data.textToTranslateArr).length != 0 ){
253
- $('#atlt-dialog .atlt-final-message').html("<strong>"+error+"</strong>");
254
- $('#atlt-dialog .atlt-ok.button').show();
255
-
256
- $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
257
- //data.thisBtn.attr('disabled','disabled');
258
- $("#atlt_preloader").hide();
259
- }
260
- return;
261
- }
262
-
263
- let totalTranslated = window.locoEditorStats.totalTranslated;
264
-
265
- var response = json_resp['translatedString'];
266
- let unSavedStr=[];
267
- if(response!==undefined){
268
- for(i=0;i< response.length;i++){
269
- var text = response[i];
270
- if( data.textToTranslateArr[i] === undefined ){
271
- break;
272
- }
273
- data.textToTranslateArr[i].target = text ;
274
- }
275
- }
276
-
277
- let translatedStrArr=data['textToTranslateArr'];
278
- var mergeTranslatedText = atlt_arrayUnique(translatedStrArr.concat(data['orginalArr']) );
279
-
280
- let Emptytargets = [];
281
- for(var x=0; x<translatedStrArr.length;++x){
282
- if(translatedStrArr[x].target !='' ){
283
- Emptytargets[x]=translatedStrArr[x].source;
284
- }
285
- }
286
-
287
- let items;
288
- if (localStorage.getItem('unSavedString')) {
289
- items = JSON.parse(localStorage.getItem('unSavedString'))
290
- } else {
291
- items = []
292
- }
293
- var unSavedStrArr = items.concat(Emptytargets);
294
- localStorage.setItem('unSavedString', JSON.stringify(unSavedStrArr));
295
-
296
-
297
- messages = loco.po.init( locale ).wrap( conf.powrap );
298
- // ready to render editor
299
- messages.load(mergeTranslatedText);
300
-
301
- // editor event behaviours
302
- editor
303
- .on('poUnsaved', function(){
304
- window.onbeforeunload = onUnloadWarning;
305
- } )
306
- .on('poSave', function(){
307
- updateStatus();
308
- window.onbeforeunload = null;
309
- } )
310
- .on( 'poUpdate', updateStatus );
311
-
312
- // ready to render editor
313
- editor.load(messages);
314
- data.saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
315
- updateStatus();
316
- // run through DOM and mark *(STAR) for newly translated
317
- markUnsavedString();
318
-
319
- requestChars=0;
320
- // update progress bar
321
- $('#atlt-dialog .translated-label').text('Translated');
322
- $('#atlt-dialog .translated-text').text(window.locoEditorStats.totalTranslated);
323
-
324
- $('#atlt-dialog .atlt-progress-bar-value').width(window.locoEditorStats.totalTranslated);
325
- if(json_resp!==undefined){
326
- if(json_resp['stats']['time_saved']!==undefined){
327
- var saved_time_msg = '<br/><br/><span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">Wahooo! You have saved your <strong>'+json_resp['stats']['time_saved']+'</strong> via auto translating '+parseInt(json_resp['stats']['totalChars'])+ ' characters using <strong><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">Loco Automatic Translate Addon</a></strong>.</span><br/><br/>';
328
- }
329
- }
330
- switch( window.locoEditorStats.totalTranslated ){
331
- case "0%":
332
- $('#atlt-dialog .translated-label').text('Translating...');
333
- $('#atlt-dialog .translated-text').text('');
334
- break;
335
- case "100%":
336
- data.thisBtn.text('Translated');
337
-
338
- data.thisBtn.attr('disabled','disabled').hide('slow');
339
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
340
- // change cursor to 'default' state
341
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)"+saved_time_msg);
342
- $('#atlt-dialog .atlt-ok.button').show();
343
- return;
344
- break;
345
- }
346
- $("#cool-auto-translate-btn").text("Translated");
347
- // run through DOM and mark *(STAR) for newly translated
348
- for(var x=0;x<=Emptytargets.length;x++){
349
- var source = Emptytargets[x];
350
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
351
- return jQuery(this).text() == source
352
- }).addClass('po-unsaved');
353
- }
354
-
355
- if( (window.locoEditorStats.dataObj.textToTranslateArr).length == 0){
356
- data.thisBtn.text('Translated');
357
- $("#atlt_preloader").hide();
358
- data.thisBtn.attr('disabled','disabled').hide('slow');
359
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
360
- // change cursor to 'default' state
361
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)."+saved_time_msg);
362
- $('#atlt-dialog .atlt-ok.button').show();
363
- return;
364
- }
365
-
366
- jQuery(document).trigger('atlt_translated');
367
-
368
- });
369
-
370
- }
371
-
372
- // find unique index in array
373
- function atlt_arrayUnique(array) {
374
- var a = array.concat();
375
- for(var i=0; i<a.length; ++i) {
376
- for(var j=i+1; j<a.length; ++j) {
377
- if(a[i] === a[j])
378
- a.splice(j--, 1);
379
- }
380
- }
381
-
382
- return a;
383
- }
384
-
385
-
386
- // auto traslator button in editor
387
- function addAutoTranslationBtn(){
388
- if($("#loco-toolbar").find("#cool-auto-translate-btn").length>0){
389
- $("#loco-toolbar").find("#cool-auto-translate-btn").remove();
390
- }
391
-
392
- const inActiveBtn='<fieldset><button title="Add API key to enable this feature." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button> <a style="font-size:9px;display:block;margin-left:8px;" target="_blank" href="https://tech.yandex.com/translate/">Get Free API Key</a></fieldset>';
393
- const otherBtn='<fieldset><button class="button" id="atlt_reload" title="Reload">Reload</button><button class="button" id="atlt_reset_all">Reset All String</button></fieldset>'
394
- const disabledBtn='<fieldset><button title="Buy PRO." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button><div style="max-width:320px; display:inline-block;margin-top: 4px;"><span style="font-size:12px;display:inline-block;margin-left:8px;">You have exceeded free translation limit. In order to extend the limit - <a target="_blank" style="font-size:14px;display:inline-block;margin-left:8px;" target="_blank" href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/">Buy Premium License</a></span></div></fieldset>';
395
- const apiKey=ATLT["api_key"]["atlt_api-key"];
396
- const userType=ATLT["info"].type;
397
- const allowed=ATLT["info"].allowed;
398
- const today=ATLT["info"].today;
399
- const total=ATLT["info"].total;
400
- const aTodayChars=300000;
401
- const aTodayChar=1000000;
402
- if( ATLT == '' || ATLT["api_key"] == '' || apiKey=='' ){
403
- $("#loco-toolbar").find("#loco-actions")
404
- .append(inActiveBtn);
405
- return;
406
- }else if( allowed=="no" && userType=='free'){
407
- $("#loco-toolbar").find("#loco-actions")
408
- .append(disabledBtn);
409
- return;
410
- }else if(today!==undefined && parseInt(today)>aTodayChars && userType=='free'){
411
- $("#loco-toolbar").find("#loco-actions")
412
- .append(disabledBtn);
413
- return;
414
- }else if(total!==undefined && parseInt(total)>aTodayChar
415
- && userType=='free'){
416
- $("#loco-toolbar").find("#loco-actions")
417
- .append(disabledBtn);
418
- return;
419
- }else if( window.locoEditorStats.totalTranslated != "100%" && window.locoEditorStats.totalWords > 0 ){
420
- if(userType=='pro' && validLicenseKey(ATLT["info"]["licenseKey"])){
421
- $("#loco-toolbar").find("#loco-actions")
422
- .append('<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>');
423
- }else{
424
- if(today==undefined){
425
- var todayChars=aTodayChars;
426
- }else{
427
- var todayChars=aTodayChars-parseInt(today);
428
- }
429
- var totalChars=aTodayChar-parseInt(total);
430
- var freeBtn='<fieldset><button data-today-limit="'+todayChars+'" data-total-limit="'+totalChars+'" id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
431
- $("#loco-toolbar").find("#loco-actions").append(freeBtn);
432
- }
433
- } else if( window.locoEditorStats.totalWords == 0){
434
- return;
435
- } else {
436
- $("#loco-toolbar").find("#loco-actions")
437
- .append('<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>');
438
- }
439
- }
440
-
441
-
442
- // mark unsaved after ajax translation process
443
- function markUnsavedString(){
444
- const unSavedString = JSON.parse(localStorage.getItem('unSavedString'));
445
- console.log(unSavedString);
446
- for(var x=0;x<=unSavedString.length;x++){
447
- var source = unSavedString[x];
448
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
449
- return jQuery(this).text() == source
450
- }).addClass('po-unsaved');
451
- }
452
- }
453
-
454
- // detect String contain URL
455
- function ValidURL(str) {
456
- var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
457
- if(!pattern.test(str)) {
458
- return false;
459
- } else {
460
- return true;
461
- }
462
- }
463
- // detect Valid HTML in string
464
- function isHTML(str){
465
- var rgex=/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i;
466
- if(str!==undefined){
467
- return rgex.test(str);
468
- }else {
469
- return false;
470
- }
471
- }
472
- // check special chars in string
473
- function isSpecialChars(str){
474
- var rgex=/[@#^&*{}|<>]/g;
475
- if(str!==undefined){
476
- return rgex.test(str);
477
- }else {
478
- return false;
479
- }
480
- }
481
- // allowed special chars in HTML string
482
- function isAllowedChars(str){
483
- var rgex=/[!@#$%^&*(),?":|<>]/g;
484
- if(str!==undefined){
485
- return rgex.test(str);
486
- }else {
487
- return false;
488
- }
489
- }
490
- // check string contain curly brackets
491
- function isContainChars(str){
492
- var rgex=/[{}[]/g;
493
- if(str!==undefined){
494
- return rgex.test(str);
495
- }else {
496
- return false;
497
- }
498
- }
499
-
500
- function atltFormatNumber(num) {
501
- return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
502
- }
503
-
504
- // create popup model for translation settings
505
- function createSettingsPopup(){
506
- let preloaderImg=extradata['preloader_path'];
507
- const userInfo=ATLT["info"].type;
508
- const yAC=ATLT["info"].yAvailableChars;
509
- let yACH='';
510
- let fieldStatus="";
511
- let contCls="";
512
- let proLbl="";
513
- let gContCls='';
514
- let gAvailableCharsHtml='';
515
- if(userInfo=="free"){
516
- let gAC=0;
517
- fieldStatus="disabled";
518
- contCls="html-disabled";
519
- gContCls='g-disabled';
520
- proLbl='<span class="atlt-pro-feature"><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/" target="_blank" style="color:red;font-weight:bold;" title="Only For Pro Users">PRO Only</a></span>';
521
- }else{
522
- let gAC=ATLT["info"].gAvailableChars;
523
- if(gAC!==undefined && gAC>10000){
524
- gAvailableCharsHtml='<span class="available-chars"> ('+ atltFormatNumber(gAC)+' Available This Month)</span>';
525
- }
526
- if(gAC<10000){
527
- gAvailableCharsHtml='<span class="used-chars">You have consumed All Free Characters</span>';
528
- }
529
- }
530
- if(yAC!==undefined){
531
- yACH='<span class="available-chars"> ('+atltFormatNumber(yAC)+' Available Today)</span>';
532
- }
533
- let settingsHTML=`<div class="atlt-settings">
534
- <form id="atlt-settings-form" method="post" action="#">
535
- <strong class="atlt-heading">Select Translation API</strong>
536
- <div class="inputGroup">
537
- <input class="inputEle" type="radio" id="yendex_api"
538
- checked="true" name="api_type" value="yendex">
539
- <label for="yendex_api">Yendex ${yACH}</label>
540
- </div>
541
- <div class="inputGroup ${gContCls}">
542
- <input class="inputEle" type="radio" id="google_api"
543
- name="api_type" value="google" ${fieldStatus}>
544
- <label for="google_api">Google</label> ${proLbl} ${gAvailableCharsHtml}
545
- </div>
546
- <strong class="atlt-heading">Select Content Type</strong>
547
- <div class="inputGroup">
548
- <input class="inputEle" type="radio" id="typeplain" checked="true" name="translationtype" value="plain">
549
- <label for="typeplain">Translate Plain Text Strings</label>
550
- </div><div class="inputGroup ${contCls}">
551
- <input class="inputEle" type="radio" id="typehtml" name="translationtype" value="html" ${fieldStatus}>
552
- <label for="typehtml">Translate HTML Strings (Beta) ${proLbl}<br/><small style="display:inline-block;margin-left:24px;margin-top:8px;">(<a href="https://locotranslate.com/html-translation-languages-list/" target="_blank">List of languages with HTML support</a>)</small></label>
553
- </div>
554
- <br/>
555
- <fieldset><input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">
556
- <img style="display:none;margin-left:10px;margin-top:-3px;" id="atlt_preloader" src="${preloaderImg}">
557
- </fieldset>
558
- </form>
559
- </div>`;
560
- // custom popup message box
561
- let popup_html = `<div id="atlt-dialog-container">
562
- <div style="display:none;" id="atlt-dialog" title="Automatic Translation Progress">
563
- ${settingsHTML}
564
- <p><span class="translated-label">Translated</span>
565
- <span class="translated-text">0%</span></p>
566
- <div class="atlt-progress-bar-track">
567
- <div class="atlt-progress-bar-value">
568
- </div></div>
569
- <div class="atlt-final-message"></div>
570
- <button style="display:none;" class="atlt-ok button button-primary">OK</button>
571
- </div></div>`;
572
- $("body").append( popup_html );
573
- }
574
-
575
- function atlt_ajax_translation_request(data,type){
576
- let filteredArr=[];
577
- filteredArr=data.textToTranslateArr.map((item)=>{
578
- if( typeof item.source!= 'undefined'){
579
- return item.source;
580
- } });
581
- const jsonData=JSON.stringify(filteredArr);
582
-
583
- return jQuery.ajax({
584
- url: ajaxurl,
585
- type:'POST',
586
- data: {'action':'atlt_translation',
587
- 'sourceLan':data.sourceLang,
588
- 'targetLan':data.targetLang,
589
- 'totalCharacters': TotalCharacters,
590
- 'requestChars':requestChars,
591
- 'nonce':data.nonce,
592
- 'strType':data.strType,
593
- 'apiType':data.apiType,
594
- 'data':jsonData
595
- },
596
- done:function(res){
597
- console.log(res)
598
- }
599
-
600
- });
601
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/loco-js-editor.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * Script for PO file editor pages
3
  */
@@ -5,6 +6,7 @@
5
  var TotalCharacters=0;
6
  var HtmlStrings = 0;
7
  var requestChars=0;
 
8
  // ES6 Modules or TypeScript
9
  let event = document.createEvent('event');
10
  event.initEvent('atlt_run_translation');
@@ -44,6 +46,7 @@
44
  saveButton,
45
  innerDiv = document.getElementById('loco-editor-inner');
46
 
 
47
  /**
48
  *
49
  */
@@ -168,7 +171,7 @@
168
  doSaveAction( unthink );
169
  setTimeout(function() {
170
  location.reload();
171
- },1500);
172
  return false;
173
  } );
174
  return true;
@@ -543,7 +546,7 @@ function registerFuzzyButton( button ){
543
 
544
  return queryString;
545
  }
546
-
547
  function validLicenseKey(licenseKey){
548
  if(licenseKey!=undefined && licenseKey.length>1){
549
  let validKey= validate_pattern(licenseKey);
@@ -555,6 +558,26 @@ function registerFuzzyButton( button ){
555
  }
556
 
557
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  function validate_pattern(str){
559
  let m;
560
  const regex = /^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;
@@ -586,17 +609,12 @@ $(document).ready(function(){
586
  }
587
 
588
  $(document).on("click", "#cool-auto-translate-btn", function() {
589
- $('#atlt-dialog').dialog({width:400,height:450});
590
  });
591
- /* $("#atlt-settings-form").submit(function( event ) {
592
- event.preventDefault();
593
- let type = $("input[name='translationtype']:checked").val();
594
- console.log(type);
595
- }); */
596
  // main translate handler
597
 
598
  $("input[name=api_type]").on( "click",function(){
599
- if($(this).val()=="google"){
600
  $("#typehtmlWrapper").hide();
601
  $("#typeplain").attr("checked","checked");
602
  }else{
@@ -662,12 +680,17 @@ $(document).ready(function(){
662
  return resetStrs=tranArr.map(function(item){
663
  if(item.source!==undefined && item.target!==undefined ){
664
  if(type=="html"){
665
- if((isHTML(item.source)|| isAllowedChars(item.source))){
666
  item.target="";
 
 
667
  }
668
  }
669
  if(type=="plain"){
670
- if(isHTML(item.source) || isAllowedChars(item.source)){
 
 
 
671
  }else{
672
  item.target="";
673
  }
@@ -731,12 +754,16 @@ $(document).ready(function(){
731
  alert("Google Translation Only Available in the PRO version");
732
  return false;
733
  }
 
 
 
 
734
  if((user_type==undefined || user_type=="pro") && ATLT["info"]["licenseKey"]==undefined){
735
  alert("Please enter Your License Key");
736
  return false;
737
  }
738
 
739
- if(conf['locale']["lang"]=!undefined){
740
  targetLang=conf['locale']["lang"];
741
  }else{
742
  targetLang=getTargetLang();
@@ -745,8 +772,26 @@ $(document).ready(function(){
745
  alert("Google Translate Only Support Plain Text Translation");
746
  return false;
747
  }
 
 
 
 
748
  if(apiType=="google"){
 
 
 
749
  sourceApiKey = ATLT["api_key"]["gApiKey"];
 
 
 
 
 
 
 
 
 
 
 
750
  }else{
751
  sourceApiKey = ATLT["api_key"]["yApiKey"];
752
  }
@@ -782,7 +827,7 @@ $(document).ready(function(){
782
  if(plainStrArr.length==0){
783
  $("#atlt-dialog").parent('.ui-dialog').hide();
784
  mainBtn.attr('disabled','disabled');
785
- alert("You have no untransalted plain strings");
786
  window.location.reload();
787
  return;
788
  }
@@ -794,7 +839,7 @@ $(document).ready(function(){
794
  if(htmlStrArr.length==0){
795
  $("#atlt-dialog").parent('.ui-dialog').hide();
796
  mainBtn.attr('disabled','disabled');
797
- alert("You have no untransalted HTML strings");
798
  window.location.reload();
799
  return;
800
  }
@@ -808,6 +853,8 @@ $(document).ready(function(){
808
  dataObj.thisBtn=thisBtn;
809
  dataObj.apiType=apiType;
810
  dataObj.targetLang=targetLang;
 
 
811
  // save data object globaly for later use
812
  window.locoEditorStats.dataObj = dataObj;
813
  jQuery(document).trigger('atlt_run_translation');
@@ -816,7 +863,7 @@ $(document).ready(function(){
816
  $("#atlt_preloader").show();
817
  // load raw message data
818
 
819
- } //
820
 
821
  } // else close
822
  }
@@ -837,7 +884,7 @@ jQuery(document).on('atlt_run_translation',function(){
837
  if( ATLT.api_key['atlt_index-per-request'] != "" && typeof ATLT.api_key['atlt_index-per-request'] != "undefined" ){
838
  indexRequest = ATLT.api_key['atlt_index-per-request'];
839
  }
840
-
841
  //save pending array in window object for later use
842
  if( typeof textToTranslate == "object" && textToTranslate.length >= 1 ){
843
  // update object for later us
@@ -848,6 +895,7 @@ jQuery(document).on('atlt_run_translation',function(){
848
  orgStrArr:window.locoEditorStats.dataObj.orgStrArr,
849
  apiType:window.locoEditorStats.dataObj.apiType,
850
  targetLang:targetLang,
 
851
  };
852
  window.locoEditorStats.dataObj = translationO;
853
 
@@ -862,6 +910,7 @@ jQuery(document).on('atlt_run_translation',function(){
862
  strType:window.locoEditorStats.dataObj.strType,
863
  apiType:window.locoEditorStats.dataObj.apiType,
864
  saveBtn:saveBtn,
 
865
  nonce:nonce
866
  };
867
  // slice data
@@ -878,91 +927,78 @@ function atlt_translate(data) {
878
 
879
  atlt_ajax_translation_request(data, "POST").success(function(
880
  resp,status,xhr) {
881
- if(xhr.status==200){
882
-
 
 
883
  const json_resp = JSON.parse(resp);
884
- if( json_resp === false && JSON.parse(resp)!=undefined){
885
- data.thisBtn.hide('slow');
886
- $("#atlt_preloader").hide();
887
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
888
- $('#atlt-dialog .atlt-ok.button').show();
889
-
890
- alert('Unable to make request to the server at the moment. Try again later.');
891
- }else if(json_resp['code']==500){
892
- alert('Unable to make request to the server at the moment. Try again later.');
893
- window.location.reload();
894
- return;
895
- }
896
- else if( typeof json_resp['code'] === undefined ||
897
- json_resp['code'] != 200 ){
898
- let error = '';
899
- switch(json_resp['code']){
900
- case 401:
901
- error = 'Yandex API Key is invalid!';
902
- break;
903
- case 402:
904
- error = 'Provided Yandex API Key has been blocked!';
905
- break;
906
- case 404:
907
- error = 'Exceeded the daily limit for Yandex API on the amount of translated text.';
908
- break;
909
- case 422:
910
- error = 'The text cannot be translated by Yandex API.';
911
- break;
912
- case 501:
913
- error = 'Yandex API does not support the specified translation direction.';
914
- break;
915
- default:
916
- error = json_resp['message'];
917
- }
918
- if( error != '' && (data.textToTranslateArr).length != 0 ){
919
- $('#atlt-dialog .atlt-final-message').html("<strong>"+error+"</strong>");
920
- $('#atlt-dialog .atlt-ok.button').show();
921
- $("#atlt_preloader").hide();
922
- $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
923
- //data.thisBtn.attr('disabled','disabled');
924
- }
925
- return;
926
  }
927
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
928
  let totalTranslated = window.locoEditorStats.totalTranslated;
929
-
930
- var response = json_resp['translatedString'];
931
  let unSavedStr=[];
932
- if(response!==undefined){
933
- for(i=0;i< response.length;i++){
934
- var text = response[i];
935
  if( data.textToTranslateArr[i] === undefined ){
936
  break;
937
  }
938
- data.textToTranslateArr[i].target = text ;
939
  }
940
  }
941
 
942
- let translatedStrArr=data['textToTranslateArr'];
943
- // var mergeTranslatedText = atlt_arrayUnique(translatedStrArr.concat(data['orginalArr']) );
944
-
945
  let Emptytargets = [];
946
  for(var x=0; x<translatedStrArr.length;++x){
947
  if(translatedStrArr[x].target !='' ){
948
  Emptytargets[x]=translatedStrArr[x].source;
949
  }
950
  }
951
-
952
  let items;
953
  if (localStorage.getItem('unSavedString')) {
954
  items = JSON.parse(localStorage.getItem('unSavedString'))
955
  } else {
956
  items = []
957
  }
 
958
  var unSavedStrArr = items.concat(Emptytargets);
959
  localStorage.setItem('unSavedString', JSON.stringify(unSavedStrArr));
960
-
961
-
962
  messages = loco.po.init( locale ).wrap( conf.powrap );
963
  // ready to render editor
964
- messages.load(data['orginalArr']);
965
-
966
  // editor event behaviours
967
  editor
968
  .on('poUnsaved', function(){
@@ -979,7 +1015,7 @@ if(xhr.status==200){
979
  data.saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
980
  updateStatus();
981
  // run through DOM and mark *(STAR) for newly translated
982
- markUnsavedString();
983
 
984
  requestChars=0;
985
  // update progress bar
@@ -987,11 +1023,10 @@ if(xhr.status==200){
987
  $('#atlt-dialog .translated-text').text(window.locoEditorStats.totalTranslated);
988
 
989
  $('#atlt-dialog .atlt-progress-bar-value').width(window.locoEditorStats.totalTranslated);
990
- if(json_resp!=undefined){
991
- if(json_resp['stats']['time_saved']!=undefined){
992
- var saved_time_msg = '<br/><br/><span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">Wahooo! You have saved your <strong>'+json_resp['stats']['time_saved']+'</strong> via auto translating '+parseInt(json_resp['stats']['totalChars'])+ ' characters using <strong><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">Loco Automatic Translate Addon</a></strong>.</span><br/><br/>';
993
- }
994
- }
995
  switch( window.locoEditorStats.totalTranslated ){
996
  case "0%":
997
  $('#atlt-dialog .translated-label').text('Translating...');
@@ -1003,7 +1038,7 @@ if(xhr.status==200){
1003
  data.thisBtn.attr('disabled','disabled');
1004
  $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1005
  // change cursor to 'default' state
1006
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)"+saved_time_msg);
1007
  $('#atlt-dialog .atlt-ok.button').show();
1008
  return;
1009
  break;
@@ -1017,20 +1052,22 @@ if(xhr.status==200){
1017
  }).addClass('po-unsaved');
1018
  }
1019
 
 
 
1020
  if( (window.locoEditorStats.dataObj.textToTranslateArr).length == 0){
1021
  data.thisBtn.val('Translated').attr("disabled","true");
1022
  $("#atlt_preloader").hide();
1023
  // data.thisBtn.attr('disabled','disabled').hide('slow');
1024
  $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1025
  // change cursor to 'default' state
1026
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)."+saved_time_msg);
1027
  $('#atlt-dialog .atlt-ok.button').show();
1028
  return;
1029
  }
1030
 
1031
  jQuery(document).trigger('atlt_run_translation');
1032
 
1033
- }else{
1034
  data.thisBtn.hide('slow');
1035
  $("#atlt_preloader").hide();
1036
  $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
@@ -1038,6 +1075,7 @@ if(xhr.status==200){
1038
  alert('Unable to make request to the server at the moment. Try again later.');
1039
  }
1040
  }).fail(function(jqXHR){
 
1041
  if(jqXHR.status==500 || jqXHR.status==0){
1042
  // internal server error or internet connection broke
1043
  data.thisBtn.hide('slow');
@@ -1061,16 +1099,14 @@ function filterSavedStrings(rawArray){
1061
  function filterRawObject(rawArray,filterType){
1062
  filterdArr=[];
1063
  return filterdArr=rawArray.filter((item,index)=>{
1064
- if( (item.target===undefined || item.target=="" && item.source!="" && item.source!==undefined)){
1065
  if( ValidURL(item.source)){
1066
  return false;
1067
  }
1068
  if(filterType=="html"){
1069
- if(isContainChars(item.source)){
1070
- return false;
1071
- } else if(isHTML(item.source)){
1072
  return true;
1073
- }else if(isAllowedChars(item.source)){
1074
  return true;
1075
  }else{
1076
  return false;
@@ -1078,7 +1114,11 @@ function filterRawObject(rawArray,filterType){
1078
  }else{
1079
  if(isHTML(item.source)){
1080
  return false;
1081
- }else if(isSpecialChars(item.source)){
 
 
 
 
1082
  return false;
1083
  }else if( item.source.includes('#') ) {
1084
  return false;
@@ -1090,18 +1130,6 @@ function filterRawObject(rawArray,filterType){
1090
  });
1091
  }
1092
 
1093
- // find unique index in array
1094
- function atlt_arrayUnique(array) {
1095
- var a = array.concat();
1096
- for(var i=0; i<a.length; ++i) {
1097
- for(var j=i+1; j<a.length; ++j) {
1098
- if(a[i] === a[j])
1099
- a.splice(j--, 1);
1100
- }
1101
- }
1102
- return a;
1103
- }
1104
-
1105
 
1106
  // auto traslator button in editor
1107
  function addAutoTranslationBtn(){
@@ -1177,7 +1205,10 @@ function atlt_arrayUnique(array) {
1177
 
1178
  if((Array.isArray(savedStrings) && savedStrings.length)){
1179
  if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1180
- locoActions.append(otherBtn);
 
 
 
1181
  }
1182
  }
1183
 
@@ -1232,6 +1263,16 @@ function isAllowedChars(str){
1232
  return false;
1233
  }
1234
  }
 
 
 
 
 
 
 
 
 
 
1235
  // check string contain curly brackets
1236
  function isContainChars(str){
1237
  var rgex=/[{}[]/g;
@@ -1252,57 +1293,90 @@ function createSettingsPopup(){
1252
  const userInfo=ATLT["info"].type;
1253
  const yAC=ATLT["info"].yAvailableChars;
1254
  const licenseKey=ATLT["info"]["licenseKey"];
1255
-
1256
  let yfieldStatus="";
1257
  let gfieldStatus="";
 
1258
  let hfieldStatus="";
1259
  let htmlSupported="";
1260
  let contCls="";
1261
  let proLbl="";
1262
  let gContCls='';
1263
  let gHtml='';
 
 
1264
  let submitBtn='';
1265
  let yHtml='';
1266
  let yChecked='checked="true"';
1267
  if(userInfo=="free"){
1268
  let gAC=0;
1269
  gfieldStatus="disabled";
 
1270
  hfieldStatus="disabled";
1271
  contCls="html-disabled";
1272
  gContCls='g-disabled';
1273
- proLbl='<span class="atlt-pro-feature"><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;" title="Only For Pro Users">PRO Only</a></span>';
1274
- gHtml=proLbl+' (70% better than Yendex Translate)';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1275
  }else{
1276
 
1277
- if( ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])
1278
- && ATLT["api_key"]["gApiKey"]!=""){
1279
- let gAC=ATLT["info"].gAvailableChars;
1280
- if(gAC!==undefined && gAC>10000){
1281
- gHtml='<span class="available-chars"> ('+ atltFormatNumber(gAC)+' Available This Month)</span>';
 
 
 
 
 
 
 
 
1282
  }
1283
- if(gAC<10000){
1284
- gHtml='<span class="used-chars">You have consumed All Free Characters</span>';
 
 
 
 
 
 
 
 
 
 
1285
  }
1286
- }else{
1287
- gfieldStatus="disabled";
1288
- gContCls='g-disabled';
1289
-
1290
- gHtml='<span class="error">Please Enter Google Translate API key in the Settings Panel</span>';
1291
- }
1292
 
1293
  if(ATLT["api_key"]["yApiKey"]!="")
1294
  {
1295
  if(yAC!==undefined){
1296
- yHtml='<span class="available-chars"> ('+atltFormatNumber(yAC)+' Available Today)</span>';
1297
  }
1298
  }else{
1299
  yfieldStatus="disabled";
1300
  yContCls='g-disabled';
1301
  yChecked='';
1302
- yHtml='<span class="error">Please Enter Yandex API key in the Settings Panel</span>';
1303
  }
 
1304
  }
1305
- if( ATLT["api_key"]["yApiKey"]!="" || ATLT["api_key"]["gApiKey"]!="" )
 
1306
  {
1307
  submitBtn='<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">';
1308
  }else{
@@ -1315,12 +1389,19 @@ function createSettingsPopup(){
1315
  <div class="inputGroup">
1316
  <input class="inputEle" type="radio" id="yandex_api"
1317
  ${yChecked} ${yfieldStatus} name="api_type" value="yandex">
1318
- <label for="yandex_api">Yandex ${yHtml}</label>
1319
  </div>
1320
  <div class="inputGroup ${gContCls}">
1321
  <input class="inputEle" type="radio" id="google_api"
1322
  name="api_type" value="google" ${gfieldStatus}>
1323
- <label for="google_api">Google</label> ${gHtml}
 
 
 
 
 
 
 
1324
  </div>
1325
  <br/>
1326
  <strong class="atlt-heading">Select Content Type</strong>
@@ -1333,7 +1414,7 @@ function createSettingsPopup(){
1333
  <label for="typehtml">Translate HTML Strings (Beta) ${proLbl}
1334
  </label>
1335
  </br>
1336
- <small style="display:inline-block;margin-left:24px;margin-top:8px;">(<a href="https://locotranslate.com/html-translation-languages-list/" target="_blank">List of languages with HTML support</a>)</small>
1337
  </div>
1338
 
1339
  <br/>
@@ -1370,7 +1451,7 @@ function atlt_ajax_translation_request(data,type){
1370
  return jQuery.ajax({
1371
  url: ajaxurl,
1372
  type:'POST',
1373
- data: {'action':'atlt_translation',
1374
  'sourceLan':data.sourceLang,
1375
  'targetLan':data.targetLang,
1376
  'totalCharacters': TotalCharacters,
@@ -1378,7 +1459,7 @@ function atlt_ajax_translation_request(data,type){
1378
  'nonce':data.nonce,
1379
  'strType':data.strType,
1380
  'apiType':data.apiType,
1381
- 'data':jsonData
1382
  },
1383
  done:function(res){
1384
  // console.log(res)
1
+
2
  /**
3
  * Script for PO file editor pages
4
  */
6
  var TotalCharacters=0;
7
  var HtmlStrings = 0;
8
  var requestChars=0;
9
+
10
  // ES6 Modules or TypeScript
11
  let event = document.createEvent('event');
12
  event.initEvent('atlt_run_translation');
46
  saveButton,
47
  innerDiv = document.getElementById('loco-editor-inner');
48
 
49
+
50
  /**
51
  *
52
  */
171
  doSaveAction( unthink );
172
  setTimeout(function() {
173
  location.reload();
174
+ },3500);
175
  return false;
176
  } );
177
  return true;
546
 
547
  return queryString;
548
  }
549
+ // validate key
550
  function validLicenseKey(licenseKey){
551
  if(licenseKey!=undefined && licenseKey.length>1){
552
  let validKey= validate_pattern(licenseKey);
558
  }
559
 
560
  }
561
+
562
+ // create Saved Time Message HTML
563
+ function savedTimeInfo(statsObj){
564
+ var info='';
565
+ if(statsObj!=undefined && statsObj['time_saved']!==undefined){
566
+ let timeSaved=statsObj['time_saved'];
567
+ let totalChars=statsObj['totalChars'];
568
+ var info =`<div class="saved_time_wrapper" style="margin:10px 0px">
569
+ <span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">
570
+ Wahooo! You have saved your
571
+ <strong>${timeSaved}</strong>
572
+ via auto translating <strong>${totalChars}</strong>
573
+ characters using <strong> <br />
574
+ <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">
575
+ Loco Automatic Translate Addon</a></strong>
576
+ </span></div>`;
577
+ }
578
+ return info;
579
+ }
580
+ // validate pattern
581
  function validate_pattern(str){
582
  let m;
583
  const regex = /^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;
609
  }
610
 
611
  $(document).on("click", "#cool-auto-translate-btn", function() {
612
+ $('#atlt-dialog').dialog({width:440,height:500});
613
  });
 
 
 
 
 
614
  // main translate handler
615
 
616
  $("input[name=api_type]").on( "click",function(){
617
+ if($(this).val()=="google" || $(this).val()=="microsoft"){
618
  $("#typehtmlWrapper").hide();
619
  $("#typeplain").attr("checked","checked");
620
  }else{
680
  return resetStrs=tranArr.map(function(item){
681
  if(item.source!==undefined && item.target!==undefined ){
682
  if(type=="html"){
683
+ if((isHTML(item.source))){
684
  item.target="";
685
+ }else if(isAllowedChars(item.source) && isPlacehodersChars(item.source)==false){
686
+ item.target="";
687
  }
688
  }
689
  if(type=="plain"){
690
+ if( isPlacehodersChars(item.source)==true){
691
+ item.target="";
692
+ }
693
+ else if(isHTML(item.source) || isAllowedChars(item.source)){
694
  }else{
695
  item.target="";
696
  }
754
  alert("Google Translation Only Available in the PRO version");
755
  return false;
756
  }
757
+ if(user_type=="free" && apiType=="microsoft"){
758
+ alert("Microsoft Translator Only Available in the PRO version");
759
+ return false;
760
+ }
761
  if((user_type==undefined || user_type=="pro") && ATLT["info"]["licenseKey"]==undefined){
762
  alert("Please enter Your License Key");
763
  return false;
764
  }
765
 
766
+ if(conf['locale']["lang"]==!undefined){
767
  targetLang=conf['locale']["lang"];
768
  }else{
769
  targetLang=getTargetLang();
772
  alert("Google Translate Only Support Plain Text Translation");
773
  return false;
774
  }
775
+ if(apiType=="microsoft" && strType=="html"){
776
+ alert("Microsoft Translator Only Support Plain Text Translation");
777
+ return false;
778
+ }
779
  if(apiType=="google"){
780
+ if(targetLang=="zh"){
781
+ targetLang= targetLang+"-"+conf['locale']["region"];
782
+ }
783
  sourceApiKey = ATLT["api_key"]["gApiKey"];
784
+ }else if(apiType=="microsoft"){
785
+ if(targetLang=="zh"){
786
+ if(conf['locale']["region"]=="CN"){
787
+ targetLang= targetLang+"-Hans";
788
+ }else if(conf['locale']["region"]=="TW"){
789
+ targetLang= targetLang+"-Hant";
790
+ }else{
791
+ targetLang= targetLang+"-"+conf['locale']["region"];
792
+ }
793
+ }
794
+ sourceApiKey = ATLT["api_key"]["mApiKey"];
795
  }else{
796
  sourceApiKey = ATLT["api_key"]["yApiKey"];
797
  }
827
  if(plainStrArr.length==0){
828
  $("#atlt-dialog").parent('.ui-dialog').hide();
829
  mainBtn.attr('disabled','disabled');
830
+ alert("You have no untranslated plain strings");
831
  window.location.reload();
832
  return;
833
  }
839
  if(htmlStrArr.length==0){
840
  $("#atlt-dialog").parent('.ui-dialog').hide();
841
  mainBtn.attr('disabled','disabled');
842
+ alert("You have no untranslated HTML strings");
843
  window.location.reload();
844
  return;
845
  }
853
  dataObj.thisBtn=thisBtn;
854
  dataObj.apiType=apiType;
855
  dataObj.targetLang=targetLang;
856
+ dataObj.endpoint=ATLT["endpoint"];
857
+
858
  // save data object globaly for later use
859
  window.locoEditorStats.dataObj = dataObj;
860
  jQuery(document).trigger('atlt_run_translation');
863
  $("#atlt_preloader").show();
864
  // load raw message data
865
 
866
+ } //
867
 
868
  } // else close
869
  }
884
  if( ATLT.api_key['atlt_index-per-request'] != "" && typeof ATLT.api_key['atlt_index-per-request'] != "undefined" ){
885
  indexRequest = ATLT.api_key['atlt_index-per-request'];
886
  }
887
+
888
  //save pending array in window object for later use
889
  if( typeof textToTranslate == "object" && textToTranslate.length >= 1 ){
890
  // update object for later us
895
  orgStrArr:window.locoEditorStats.dataObj.orgStrArr,
896
  apiType:window.locoEditorStats.dataObj.apiType,
897
  targetLang:targetLang,
898
+ endpoint:window.locoEditorStats.dataObj.endpoint
899
  };
900
  window.locoEditorStats.dataObj = translationO;
901
 
910
  strType:window.locoEditorStats.dataObj.strType,
911
  apiType:window.locoEditorStats.dataObj.apiType,
912
  saveBtn:saveBtn,
913
+ endpoint:window.locoEditorStats.dataObj.endpoint,
914
  nonce:nonce
915
  };
916
  // slice data
927
 
928
  atlt_ajax_translation_request(data, "POST").success(function(
929
  resp,status,xhr) {
930
+ // console.log(resp);
931
+
932
+ if(xhr.status==200 && resp!=null){
933
+
934
  const json_resp = JSON.parse(resp);
935
+ let responseObj;
936
+ let apiProvider=window.locoEditorStats.dataObj.apiType;
937
+ // console.log(window.locoEditorStats.dataObj);
938
+
939
+ if(json_resp['error'] && json_resp['error']['code']==800)
940
+ {
941
+ let errorMsz= json_resp['error']['message'];
942
+ $('#atlt-dialog .atlt-final-message').html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>");
943
+ $('#atlt-dialog .atlt-ok.button').show();
944
+ $("#atlt_preloader").hide();
945
+ $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
946
+ setTimeout(function() {
947
+ location.reload();
948
+ },4000);
949
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
950
  }
951
+
952
+ if(json_resp.translatedString!=null && json_resp.translatedString.length
953
+ && json_resp['code']==200){
954
+ responseObj=json_resp.translatedString;
955
+ }else{
956
+ let errorCode=json_resp['code'];
957
+ let errorMsz=json_resp['error'];
958
+ $('#atlt-dialog .atlt-final-message').html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>");
959
+ $('#atlt-dialog .atlt-ok.button').show();
960
+ $("#atlt_preloader").hide();
961
+ $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
962
+ setTimeout(function() {
963
+ location.reload();
964
+ },4000);
965
+ return false;
966
+
967
+ }
968
+
969
  let totalTranslated = window.locoEditorStats.totalTranslated;
970
+
 
971
  let unSavedStr=[];
972
+ if(responseObj!==undefined && responseObj.length){
973
+ for(i=0;i< responseObj.length;i++){
974
+ var text = responseObj[i];
975
  if( data.textToTranslateArr[i] === undefined ){
976
  break;
977
  }
978
+ data.textToTranslateArr[i].target = text ;
979
  }
980
  }
981
 
982
+ let translatedStrArr=data.textToTranslateArr;
983
+
 
984
  let Emptytargets = [];
985
  for(var x=0; x<translatedStrArr.length;++x){
986
  if(translatedStrArr[x].target !='' ){
987
  Emptytargets[x]=translatedStrArr[x].source;
988
  }
989
  }
 
990
  let items;
991
  if (localStorage.getItem('unSavedString')) {
992
  items = JSON.parse(localStorage.getItem('unSavedString'))
993
  } else {
994
  items = []
995
  }
996
+
997
  var unSavedStrArr = items.concat(Emptytargets);
998
  localStorage.setItem('unSavedString', JSON.stringify(unSavedStrArr));
 
 
999
  messages = loco.po.init( locale ).wrap( conf.powrap );
1000
  // ready to render editor
1001
+ messages.load(conf.podata);
 
1002
  // editor event behaviours
1003
  editor
1004
  .on('poUnsaved', function(){
1015
  data.saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
1016
  updateStatus();
1017
  // run through DOM and mark *(STAR) for newly translated
1018
+ markUnsavedString();
1019
 
1020
  requestChars=0;
1021
  // update progress bar
1023
  $('#atlt-dialog .translated-text').text(window.locoEditorStats.totalTranslated);
1024
 
1025
  $('#atlt-dialog .atlt-progress-bar-value').width(window.locoEditorStats.totalTranslated);
1026
+
1027
+ let saved_time_html= savedTimeInfo(json_resp['stats']);
1028
+ let finalHTML="<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>).";
1029
+
 
1030
  switch( window.locoEditorStats.totalTranslated ){
1031
  case "0%":
1032
  $('#atlt-dialog .translated-label').text('Translating...');
1038
  data.thisBtn.attr('disabled','disabled');
1039
  $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1040
  // change cursor to 'default' state
1041
+ $('#atlt-dialog .atlt-final-message').html(finalHTML+saved_time_html);
1042
  $('#atlt-dialog .atlt-ok.button').show();
1043
  return;
1044
  break;
1052
  }).addClass('po-unsaved');
1053
  }
1054
 
1055
+
1056
+
1057
  if( (window.locoEditorStats.dataObj.textToTranslateArr).length == 0){
1058
  data.thisBtn.val('Translated').attr("disabled","true");
1059
  $("#atlt_preloader").hide();
1060
  // data.thisBtn.attr('disabled','disabled').hide('slow');
1061
  $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1062
  // change cursor to 'default' state
1063
+ $('#atlt-dialog .atlt-final-message').html(finalHTML+saved_time_html);
1064
  $('#atlt-dialog .atlt-ok.button').show();
1065
  return;
1066
  }
1067
 
1068
  jQuery(document).trigger('atlt_run_translation');
1069
 
1070
+ } else{
1071
  data.thisBtn.hide('slow');
1072
  $("#atlt_preloader").hide();
1073
  $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
1075
  alert('Unable to make request to the server at the moment. Try again later.');
1076
  }
1077
  }).fail(function(jqXHR){
1078
+ console.log(jqXHR);
1079
  if(jqXHR.status==500 || jqXHR.status==0){
1080
  // internal server error or internet connection broke
1081
  data.thisBtn.hide('slow');
1099
  function filterRawObject(rawArray,filterType){
1100
  filterdArr=[];
1101
  return filterdArr=rawArray.filter((item,index)=>{
1102
+ if((item.source!=="" && item.source!==undefined) && (item.target===undefined || item.target=="")){
1103
  if( ValidURL(item.source)){
1104
  return false;
1105
  }
1106
  if(filterType=="html"){
1107
+ if(isHTML(item.source)){
 
 
1108
  return true;
1109
+ }else if(isAllowedChars(item.source) && isPlacehodersChars(item.source)==false){
1110
  return true;
1111
  }else{
1112
  return false;
1114
  }else{
1115
  if(isHTML(item.source)){
1116
  return false;
1117
+ }
1118
+ else if(isPlacehodersChars(item.source)){
1119
+ return true;
1120
+ }
1121
+ else if(isSpecialChars(item.source)){
1122
  return false;
1123
  }else if( item.source.includes('#') ) {
1124
  return false;
1130
  });
1131
  }
1132
 
 
 
 
 
 
 
 
 
 
 
 
 
1133
 
1134
  // auto traslator button in editor
1135
  function addAutoTranslationBtn(){
1205
 
1206
  if((Array.isArray(savedStrings) && savedStrings.length)){
1207
  if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1208
+ if(ATLT["info"]["proInstalled"]=="yes"){
1209
+ locoActions.append(otherBtn);
1210
+ }
1211
+
1212
  }
1213
  }
1214
 
1263
  return false;
1264
  }
1265
  }
1266
+
1267
+ // allowed special chars in plain text
1268
+ function isPlacehodersChars(str){
1269
+ var rgex=/%s|%d/g;
1270
+ if(str!==undefined){
1271
+ return rgex.test(str);
1272
+ }else {
1273
+ return false;
1274
+ }
1275
+ }
1276
  // check string contain curly brackets
1277
  function isContainChars(str){
1278
  var rgex=/[{}[]/g;
1293
  const userInfo=ATLT["info"].type;
1294
  const yAC=ATLT["info"].yAvailableChars;
1295
  const licenseKey=ATLT["info"]["licenseKey"];
1296
+ const proInstalled=ATLT["info"]["proInstalled"];
1297
  let yfieldStatus="";
1298
  let gfieldStatus="";
1299
+ let mfieldStatus="";
1300
  let hfieldStatus="";
1301
  let htmlSupported="";
1302
  let contCls="";
1303
  let proLbl="";
1304
  let gContCls='';
1305
  let gHtml='';
1306
+ let mContCls='';
1307
+ let mHtml='';
1308
  let submitBtn='';
1309
  let yHtml='';
1310
  let yChecked='checked="true"';
1311
  if(userInfo=="free"){
1312
  let gAC=0;
1313
  gfieldStatus="disabled";
1314
+ mfieldStatus="disabled";
1315
  hfieldStatus="disabled";
1316
  contCls="html-disabled";
1317
  gContCls='g-disabled';
1318
+ mContCls='m-disabled';
1319
+ proLbl='<span class="atlt-pro-feature"><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;font-size:0.9em;" title="Only For Pro Users">PRO Only</a></span>';
1320
+
1321
+ gHtml=proLbl+' ';
1322
+ mHtml=proLbl+' ';
1323
+ }else if(proInstalled=="no"){
1324
+ gfieldStatus="disabled";
1325
+ mfieldStatus="disabled";
1326
+ hfieldStatus="disabled";
1327
+ contCls="html-disabled";
1328
+ gContCls='g-disabled';
1329
+ mContCls='m-disabled';
1330
+ proLbl='<span style="color:red;font-weight:bold;font-size:0.9em;" class="atlt-pro-feature">Please Install PRO version</span>';
1331
+
1332
+ gHtml=proLbl+' ';
1333
+ mHtml=proLbl+' ';
1334
  }else{
1335
 
1336
+ if(ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"]))
1337
+ {
1338
+ if(ATLT["api_key"]["gApiKey"]!="" ){
1339
+ let gAC=ATLT["info"].gAvailableChars;
1340
+ if(gAC!==undefined && gAC>10000){
1341
+ gHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+ atltFormatNumber(gAC)+' Free Char. Available This Month)</span>';
1342
+ }else if(gAC<10000){
1343
+ gHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>';
1344
+ }
1345
+ }else{
1346
+ gfieldStatus="disabled";
1347
+ gContCls='g-disabled';
1348
+ gHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Google Translate API key)</span>';
1349
  }
1350
+ if(ATLT["api_key"]["mApiKey"]!=undefined &&
1351
+ ATLT["api_key"]["mApiKey"]!="" ){
1352
+ mAC=ATLT["info"].mAvailableChars;
1353
+ if(mAC!==undefined && mAC>10000){
1354
+ mHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+ atltFormatNumber(mAC)+' Free Char. Available This Month)</span>';
1355
+ }else if(mAC<10000){
1356
+ mHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>';
1357
+ }
1358
+ }else{
1359
+ mfieldStatus="disabled";
1360
+ mContCls='m-disabled';
1361
+ mHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Microsoft Translator API key)</span>';
1362
  }
1363
+
 
 
 
 
 
1364
 
1365
  if(ATLT["api_key"]["yApiKey"]!="")
1366
  {
1367
  if(yAC!==undefined){
1368
+ yHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(yAC)+' Free Char. Available Today)</span>';
1369
  }
1370
  }else{
1371
  yfieldStatus="disabled";
1372
  yContCls='g-disabled';
1373
  yChecked='';
1374
+ yHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Yandex Translate API key)</span>';
1375
  }
1376
+ }
1377
  }
1378
+
1379
+ if( ATLT["api_key"]["yApiKey"]!="" || ATLT["api_key"]["gApiKey"]!="" || ATLT["api_key"]["mApiKey"]!="" )
1380
  {
1381
  submitBtn='<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">';
1382
  }else{
1389
  <div class="inputGroup">
1390
  <input class="inputEle" type="radio" id="yandex_api"
1391
  ${yChecked} ${yfieldStatus} name="api_type" value="yandex">
1392
+ <label for="yandex_api">Yandex Translate ${yHtml}</label>
1393
  </div>
1394
  <div class="inputGroup ${gContCls}">
1395
  <input class="inputEle" type="radio" id="google_api"
1396
  name="api_type" value="google" ${gfieldStatus}>
1397
+ <label for="google_api">Google Translate ${gHtml}</label>
1398
+ </div>
1399
+ <div class="inputGroup ${mContCls}">
1400
+ <input class="inputEle" type="radio" id="microsoft_api"
1401
+ name="api_type" value="microsoft" ${mfieldStatus}>
1402
+ <label for="microsoft_api">Microsoft Translator ${mHtml}</label>
1403
+ <br/>
1404
+ <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locotranslate.com/supported-languages/" target="_blank">View all supported languages list</a>)</small>
1405
  </div>
1406
  <br/>
1407
  <strong class="atlt-heading">Select Content Type</strong>
1414
  <label for="typehtml">Translate HTML Strings (Beta) ${proLbl}
1415
  </label>
1416
  </br>
1417
+ <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locotranslate.com/html-translation-languages-list/" target="_blank">List of languages with HTML support</a>)</small>
1418
  </div>
1419
 
1420
  <br/>
1451
  return jQuery.ajax({
1452
  url: ajaxurl,
1453
  type:'POST',
1454
+ data: {'action':data.endpoint,
1455
  'sourceLan':data.sourceLang,
1456
  'targetLan':data.targetLang,
1457
  'totalCharacters': TotalCharacters,
1459
  'nonce':data.nonce,
1460
  'strType':data.strType,
1461
  'apiType':data.apiType,
1462
+ 'data':jsonData
1463
  },
1464
  done:function(res){
1465
  // console.log(res)
assets/js/loco-js-editor.min.js CHANGED
@@ -1,1398 +1 @@
1
- /**
2
- * Script for PO file editor pages
3
- */
4
- !function( window, $ ){
5
- var TotalCharacters=0;
6
- var HtmlStrings = 0;
7
- var requestChars=0;
8
- // ES6 Modules or TypeScript
9
- let event = document.createEvent('event');
10
- event.initEvent('atlt_run_translation');
11
- createSettingsPopup();
12
-
13
- $('#atlt-dialog .atlt-ok.button').on('click',function(){
14
- // hide dialog container by finding main parent DOM
15
- localStorage.removeItem('unSavedString');
16
- $("#atlt-dialog").parent('.ui-dialog').hide();
17
- });
18
-
19
- var loco = window.locoScope,
20
- conf = window.locoConf,
21
- syncParams = null,
22
- saveParams = null,
23
- // UI translation
24
- translator = loco.l10n,
25
- sprintf = loco.string.sprintf,
26
- // PO file data
27
- locale = conf.locale,
28
- messages = loco.po.init( locale ).wrap( conf.powrap ),
29
- template = ! locale,
30
- // form containing action buttons
31
- elForm = document.getElementById('loco-actions'),
32
- filePath = conf.popath,
33
- syncPath = conf.potpath,
34
-
35
- // file system connect when file is locked
36
- elFilesys = document.getElementById('loco-fs'),
37
- fsConnect = elFilesys && loco.fs.init( elFilesys ),
38
-
39
- // prevent all write operations if readonly mode
40
- readonly = conf.readonly,
41
- editable = ! readonly,
42
- // Editor components
43
- editor,
44
- saveButton,
45
- innerDiv = document.getElementById('loco-editor-inner');
46
-
47
- /**
48
- *
49
- */
50
- function doSyncAction( callback ){
51
- function onSuccess( result ){
52
- var info = [],
53
- doc = messages,
54
- exp = result.po,
55
- src = result.pot,
56
- pot = loco.po.init().load( exp ),
57
- done = doc.merge( pot ),
58
- nadd = done.add.length,
59
- ndel = done.del.length,
60
- t = translator;
61
- // reload even if unchanged, cos indexes could be off
62
- editor.load( doc );
63
- // Show summary
64
- if( nadd || ndel ){
65
- if( src ){
66
- // Translators: Where %s is the name of the POT template file. Message appears after sync
67
- info.push( sprintf( t._('Merged from %s'), src ) );
68
- }
69
- else {
70
- // Translators: Message appears after sync operation
71
- info.push( t._('Merged from source code') );
72
- }
73
- // Translators: Summary of new strings after running in-editor Sync
74
- nadd && info.push( sprintf( t._n('1 new string added','%s new strings added', nadd ), nadd ) );
75
- // Translators: Summary of existing strings that no longer exist after running in-editor Sync
76
- ndel && info.push( sprintf( t._n('1 obsolete string removed','%s obsolete strings removed', ndel ), ndel ) );
77
- // editor thinks it's saved, but we want the UI to appear otherwise
78
- $(innerDiv).trigger('poUnsaved',[]);
79
- updateStatus();
80
- // debug info in lieu of proper merge confirmation:
81
- window.console && debugMerge( console, done );
82
- }
83
- else if( src ){
84
- // Translators: Message appears after sync operation when nothing has changed. %s refers to a POT file.
85
- info.push( sprintf( t._('Already up to date with %s'), src ) );
86
- }
87
- else {
88
- // Translators: Message appears after sync operation when nothing has changed
89
- info.push( t._('Already up to date with source code') );
90
- }
91
- loco.notices.success( info.join('. ') );
92
- $(innerDiv).trigger('poMerge',[result]);
93
- // done sync
94
- callback && callback();
95
- }
96
- loco.ajax.post( 'sync', syncParams, onSuccess, callback );
97
- }
98
-
99
- function debugMerge( console, result ){
100
- var i = -1, t = result.add.length;
101
- while( ++i < t ){
102
- console.log(' + '+result.add[i].source() );
103
- }
104
- i = -1, t = result.del.length;
105
- while( ++i < t ){
106
- console.log(' - '+result.del[i].source() );
107
- }
108
- }
109
-
110
- /**
111
- * Post full editor contents to "posave" endpoint
112
- */
113
- function doSaveAction( callback ){
114
- function onSuccess( result ){
115
- callback && callback();
116
- editor.save( true );
117
- // Update saved time update
118
- $('#loco-po-modified').text( result.datetime||'[datetime error]' );
119
- }
120
- saveParams.locale = String( messages.locale() || '' );
121
- if( fsConnect ){
122
- fsConnect.applyCreds( saveParams );
123
- }
124
- // adding PO source last for easier debugging in network inspector
125
- saveParams.data = String( messages );
126
- loco.ajax.post( 'save', saveParams, onSuccess, callback );
127
- }
128
- function saveIfDirty(){
129
- editor.dirty && doSaveAction();
130
- }
131
- function onUnloadWarning(){
132
- // Translators: Warning appears when user tries to refresh or navigate away when editor work is unsaved
133
- return translator._("Your changes will be lost if you continue without saving");
134
- }
135
-
136
- function registerSaveButton( button ){
137
- saveButton = button;
138
- // enables and disable according to save/unsave events
139
- editor
140
- .on('poUnsaved', function(){
141
- enable();
142
- $(button).addClass( 'button-primary loco-flagged' );
143
- } )
144
- .on('poSave', function(){
145
- disable();
146
- $(button).removeClass( 'button-primary loco-flagged' );
147
- } )
148
- ;
149
- function disable(){
150
- button.disabled = true;
151
- }
152
- function enable(){
153
- button.disabled = false;
154
- }
155
- function think(){
156
- disable();
157
- $(button).addClass('loco-loading');
158
- }
159
- function unthink(){
160
- enable();
161
- $(button).removeClass('loco-loading');
162
- }
163
- saveParams = $.extend( { path: filePath }, conf.project||{} );
164
-
165
- $(button).click( function(event){
166
- event.preventDefault();
167
- think();
168
- doSaveAction( unthink );
169
- setTimeout(function() {
170
- location.reload();
171
- },1500);
172
- return false;
173
- } );
174
- return true;
175
- };
176
-
177
- function registerSyncButton( button ){
178
- var project = conf.project;
179
- if( project ){
180
- function disable(){
181
- button.disabled = true;
182
- }
183
- function enable(){
184
- button.disabled = false;
185
- }
186
- function think(){
187
- disable();
188
- $(button).addClass('loco-loading');
189
- }
190
- function unthink(){
191
- enable();
192
- $(button).removeClass('loco-loading');
193
- }
194
- // Only permit sync when document is saved
195
- editor
196
- .on('poUnsaved', function(){
197
- disable();
198
- } )
199
- .on('poSave', function(){
200
- enable();
201
- } )
202
- ;
203
- // params for sync end point
204
- syncParams = {
205
- bundle: project.bundle,
206
- domain: project.domain,
207
- type: template ? 'pot' : 'po',
208
- sync: syncPath||''
209
- };
210
- // enable syncing on button click
211
- $(button)
212
- .click( function(event){
213
- event.preventDefault();
214
- think();
215
- doSyncAction( unthink );
216
- return false;
217
- } )
218
- //.attr('title', syncPath ? sprintf( translator._('Update from %s'), syncPath ) : translator._('Update from source code') )
219
- ;
220
- enable();
221
- }
222
- return true;
223
- }
224
-
225
- function registerFuzzyButton( button ){
226
- var toggled = false,
227
- enabled = false
228
- ;
229
- function redraw( message, state ){
230
- // fuzziness only makes sense when top-level string is translated
231
- var allowed = message && message.translated(0) || false;
232
- if( enabled !== allowed ){
233
- button.disabled = ! allowed;
234
- enabled = allowed;
235
- }
236
- // toggle on/off according to new fuzziness
237
- if( state !== toggled ){
238
- $(button)[ state ? 'addClass' : 'removeClass' ]('inverted');
239
- toggled = state;
240
- }
241
- }
242
- // state changes depending on whether an asset is selected and is fuzzy
243
- editor
244
- .on('poSelected', function( event, message ){
245
- redraw( message, message && message.fuzzy() || false );
246
- } )
247
- .on( 'poEmpty', function( event, blank, message, pluralIndex ){
248
- if( 0 === pluralIndex && blank === enabled ){
249
- redraw( message, toggled );
250
- }
251
- } )
252
- .on( 'poFuzzy', function( event, message, newState ){
253
- redraw( message, newState );
254
- } )
255
- ;
256
- // click toggles current state
257
- $(button).click( function( event ){
258
- event.preventDefault();
259
- editor.fuzzy( ! editor.fuzzy() );
260
- return false;
261
- } );
262
- return true;
263
- };
264
-
265
- function registerRevertButton( button ){
266
- // No need for revert when document is saved
267
- editor
268
- .on('poUnsaved', function(){
269
- button.disabled = false;
270
- } )
271
- .on('poSave', function(){
272
- button.disabled = true;
273
- } )
274
- ;
275
- // handling unsaved state prompt with onbeforeunload, see below
276
- $(button).click( function( event ){
277
- event.preventDefault();
278
- location.reload();
279
- return false;
280
- } );
281
- return true;
282
- };
283
-
284
- function registerInvisiblesButton( button ){
285
- var $button = $(button);
286
- button.disabled = false;
287
- editor.on('poInvs', function( event, state ){
288
- $button[ state ? 'addClass' : 'removeClass' ]('inverted');
289
- });
290
- $button.click( function( event ){
291
- event.preventDefault();
292
- editor.setInvs( ! editor.getInvs() );
293
- return false;
294
- } );
295
- locoScope.tooltip.init($button);
296
- return true;
297
- }
298
-
299
- function registerCodeviewButton( button ){
300
- var $button = $(button);
301
- button.disabled = false;
302
- $button.click( function(event){
303
- event.preventDefault();
304
- var state = ! editor.getMono();
305
- editor.setMono( state );
306
- $button[ state ? 'addClass' : 'removeClass' ]('inverted');
307
- return false;
308
- } );
309
- locoScope.tooltip.init($button);
310
- return true;
311
- };
312
-
313
- function registerAddButton( button ){
314
- button.disabled = false;
315
- $(button).click( function( event ){
316
- event.preventDefault();
317
- // Need a placeholder guaranteed to be unique for new items
318
- var i = 1, baseid, msgid, regex = /(\d+)$/;
319
- msgid = baseid = 'New message';
320
- while( messages.get( msgid ) ){
321
- i = regex.exec(msgid) ? Math.max(i,RegExp.$1) : i;
322
- msgid = baseid+' '+( ++i );
323
- }
324
- editor.add( msgid );
325
- return false;
326
- } );
327
- return true;
328
- };
329
-
330
- function registerDelButton( button ){
331
- button.disabled = false;
332
- $(button).click( function(event){
333
- event.preventDefault();
334
- editor.del();
335
- return false;
336
- } );
337
- return true;
338
- };
339
-
340
- function registerDownloadButton( button, id ){
341
- button.disabled = false;
342
- $(button).click( function( event ){
343
- var form = button.form,
344
- path = filePath;
345
- // swap out path
346
- if( 'binary' === id ){
347
- path = path.replace(/\.po$/,'.mo');
348
- }
349
- form.path.value = path;
350
- form.source.value = messages.toString();
351
- // allow form to submit
352
- return true;
353
- } );
354
- return true;
355
- }
356
-
357
-
358
- // event handler that stops dead
359
- function noop( event ){
360
- event.preventDefault();
361
- return false;
362
- }
363
-
364
- /*/ dummy function for enabling buttons that do nothing (or do something inherently)
365
- function registerNoopButton( button ){
366
- return true;
367
- }*/
368
-
369
- /**
370
- * Update status message above editor.
371
- * This is dynamic version of PHP Loco_gettext_Metadata::getProgressSummary
372
- * TODO implement progress bar, not just text.
373
- */
374
- function updateStatus(){
375
- var t = translator,
376
- stats = editor.stats(),
377
- total = stats.t,
378
- fuzzy = stats.f,
379
- empty = stats.u,
380
- // Translators: Shows total string count at top of editor
381
- stext = sprintf( t._n('1 string','%s strings',total ), total.format(0) ),
382
- extra = [];
383
- if( locale ){
384
- // Translators: Shows percentage translated at top of editor
385
- stext = sprintf( t._('%s%% translated'), stats.p.replace('%','') ) +', '+ stext;
386
- // Translators: Shows number of fuzzy strings at top of editor
387
- fuzzy && extra.push( sprintf( t._('%s fuzzy'), fuzzy.format(0) ) );
388
- // Translators: Shows number of untranslated strings at top of editor
389
- empty && extra.push( sprintf( t._('%s untranslated'), empty.format(0) ) );
390
- if( extra.length ){
391
- stext += ' ('+extra.join(', ')+')';
392
- }
393
- }
394
- $('#loco-po-status').text( stext );
395
- if( typeof window.locoEditorStats == 'undefined'){
396
- window.locoEditorStats = {totalWords:stats.t, totalTranslated:stats.p} ;
397
- }else{
398
- window.locoEditorStats.totalWords = stats.t;
399
- window.locoEditorStats.totalTranslated = stats.p;
400
- }
401
-
402
- }
403
-
404
- /**
405
- * Enable text filtering
406
- */
407
- function initSearchFilter( elSearch ){
408
- editor.searchable( loco.fulltext.init() );
409
- // prep search text field
410
- elSearch.disabled = false;
411
- elSearch.value = '';
412
- function showValidFilter( numFound ){
413
- $(elSearch.parentNode)[ numFound || null == numFound ? 'removeClass' : 'addClass' ]('invalid');
414
- }
415
- var listener = loco.watchtext( elSearch, function( value ){
416
- var numFound = editor.filter( value, true );
417
- showValidFilter( numFound );
418
- } );
419
- editor
420
- .on( 'poFilter', function( event, value, numFound ){
421
- listener.val( value||'' );
422
- showValidFilter( numFound );
423
- } )
424
- .on( 'poMerge', function( event, result ){
425
- var value = listener.val();
426
- value && editor.filter( value );
427
- } )
428
- ;
429
- }
430
-
431
- // resize function fits editor to screen, accounting for headroom and touching bottom of screen.
432
- var resize = function(){
433
- function top( el, ancestor ){
434
- var y = el.offsetTop||0;
435
- while( ( el = el.offsetParent ) && el !== ancestor ){
436
- y += el.offsetTop||0;
437
- }
438
- return y;
439
- }
440
- var fixHeight,
441
- minHeight = parseInt($(innerDiv).css('min-height')||0)
442
- ;
443
- return function(){
444
- var padBottom = 20,
445
- topBanner = top( innerDiv, document.body ),
446
- winHeight = window.innerHeight,
447
- setHeight = Math.max( minHeight, winHeight - topBanner - padBottom )
448
- ;
449
- if( fixHeight !== setHeight ){
450
- innerDiv.style.height = String(setHeight)+'px';
451
- fixHeight = setHeight;
452
- }
453
- };
454
- }();
455
-
456
- // ensure outer resize is handled before editor's internal resize
457
- resize();
458
- $(window).resize( resize );
459
-
460
- // initialize editor
461
- innerDiv.innerHTML = '';
462
- editor = loco.po.ed
463
- .init( innerDiv )
464
- .localise( translator )
465
- ;
466
- loco.po.kbd
467
- .init( editor )
468
- .add( 'save', saveIfDirty )
469
- .enable('copy','clear','enter','next','prev','fuzzy','save','invis')
470
- ;
471
-
472
- // initialize toolbar button actions
473
- var buttons = {
474
- // help: registerNoopButton,
475
- save: editable && registerSaveButton,
476
- sync: editable && registerSyncButton,
477
- revert: registerRevertButton,
478
- // editor mode togglers
479
- invs: registerInvisiblesButton,
480
- code: registerCodeviewButton,
481
- // downloads / post-throughs
482
- source: registerDownloadButton,
483
- binary: template ? null : registerDownloadButton
484
- };
485
- // POT only
486
- if( template ){
487
- buttons.add = editable && registerAddButton;
488
- buttons.del = editable && registerDelButton;
489
- }
490
- // PO only
491
- else {
492
- buttons.fuzzy = registerFuzzyButton;
493
- };
494
- $('#loco-toolbar').find('button').each( function(i,el){
495
- var id = el.getAttribute('data-loco'), register = buttons[id];
496
- register && register(el,id) || $(el).hide();
497
- } );
498
-
499
- // disable submit on dummy form
500
- $(elForm).submit( noop );
501
-
502
- // enable text filtering
503
- initSearchFilter( document.getElementById('loco-search') );
504
-
505
- // editor event behaviours
506
- editor
507
- .on('poUnsaved', function(){
508
- window.onbeforeunload = onUnloadWarning;
509
- } )
510
- .on('poSave', function(){
511
- updateStatus();
512
- window.onbeforeunload = null;
513
- } )
514
- .on( 'poUpdate', updateStatus );
515
-
516
-
517
- // load raw message data
518
- messages.load( conf.podata );
519
-
520
- // ready to render editor
521
- editor.load( messages );
522
-
523
- // locale should be cast to full object once set in editor
524
- if( locale = editor.targetLocale ){
525
- locale.isRTL() && $(innerDiv).addClass('trg-rtl');
526
- }
527
- // enable template mode when no target locale
528
- else {
529
- editor.unlock();
530
- }
531
-
532
-
533
- /*
534
- |--------------------------------------------------------------------------
535
- | Auto Translator Custom Code
536
- |--------------------------------------------------------------------------
537
- */
538
- //encode URL query string
539
- function createEncodedString(allStringText){
540
- const queryString=allStringText.map((item)=>{
541
- return "&text="+ encodeURIComponent(item.source);
542
- }).join(",");
543
-
544
- return queryString;
545
- }
546
-
547
- function validLicenseKey(licenseKey){
548
- if(licenseKey!=undefined && licenseKey.length>1){
549
- let validKey= validate_pattern(licenseKey);
550
- if(validKey.length>1){
551
- return licenseKey;
552
- }
553
- }else{
554
- return false;
555
- }
556
-
557
- }
558
- function validate_pattern(str){
559
- let m;
560
- const regex = /^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;
561
- let saveMatch=[];
562
- while ((m = regex.exec(str)) !== null) {
563
- // This is necessary to avoid infinite loops with zero-width matches
564
- if (m.index === regex.lastIndex) {
565
- regex.lastIndex++;
566
- }
567
- // The result can be accessed through the `m`-variable.
568
- m.forEach((match, groupIndex) => {
569
- saveMatch.push(match);
570
- // console.log(`Found match, group ${groupIndex}: ${match}`);
571
- });
572
- }
573
- return saveMatch;
574
- }
575
- function getTargetLang(){
576
- return window.locoConf.locale.lang?window.locoConf.locale.lang:null;
577
- }
578
- $(document).ready(function(){
579
- if( template ){
580
- return ;
581
- }
582
- const locoRawData=conf.podata;
583
- if(locoRawData!=undefined && locoRawData.length>0 ){
584
- // called auto traslate button
585
- addAutoTranslationBtn();
586
- }
587
-
588
- $(document).on("click", "#cool-auto-translate-btn", function() {
589
- $('#atlt-dialog').dialog({width:400,height:450});
590
- });
591
- /* $("#atlt-settings-form").submit(function( event ) {
592
- event.preventDefault();
593
- let type = $("input[name='translationtype']:checked").val();
594
- console.log(type);
595
- }); */
596
- // main translate handler
597
-
598
- $("input[name=api_type]").on( "click",function(){
599
- if($(this).val()=="google"){
600
- $("#typehtmlWrapper").hide();
601
- $("#typeplain").attr("checked","checked");
602
- }else{
603
- $("#typehtmlWrapper").show();
604
- }
605
- });
606
-
607
- // integrate reset string traslation button
608
- $("#atlt_reset_all").on("click",function(){
609
- swal("What type of strings do you want to reset?",
610
- {
611
- dangerMode: true,
612
- icon: "warning",
613
- confirmButtonColor: '#8CD4F5',
614
-
615
- buttons: {
616
- plain: {
617
- text: "Plain Text Strings",
618
- value: "plain",
619
- class:"danger"
620
- },
621
- html: {
622
- text: "HTML Strings",
623
- value: "html",
624
- },
625
- all: {
626
- text: "All Strings",
627
- value: "all",
628
- },
629
- cancel: {
630
- text: "Cancel",
631
- value: null,
632
- visible: true,
633
- className: "",
634
- closeModal: false,
635
- },
636
- },
637
- })
638
- .then((value) => {
639
- switch (value) {
640
- case "all":
641
- resetTranslations(value);
642
- swal("Done!", "You have successfully reset all strings translations. Just close this popup & SAVE!","success");;
643
- break;
644
- case "plain":
645
- resetTranslations(value);
646
- swal("Done!", "You have successfully reset all plain text strings translations. Just close this popup & SAVE!", "success");
647
- break;
648
- case "html":
649
- resetTranslations(value);
650
- swal("Done!", "You have successfully reset all strings with HTML translations. Just close this popup & SAVE!", "success");
651
- break;
652
- default:
653
- swal("Cancelled, Just close this popup!");
654
- }
655
- });
656
-
657
- });
658
-
659
- // reset string array
660
- function resetTransArr(tranArr,type){
661
- var resetStrs=[];
662
- return resetStrs=tranArr.map(function(item){
663
- if(item.source!==undefined && item.target!==undefined ){
664
- if(type=="html"){
665
- if((isHTML(item.source)|| isAllowedChars(item.source))){
666
- item.target="";
667
- }
668
- }
669
- if(type=="plain"){
670
- if(isHTML(item.source) || isAllowedChars(item.source)){
671
- }else{
672
- item.target="";
673
- }
674
- }
675
- if(type=="all"){
676
- item.target="";
677
- }
678
- return item;
679
- }
680
- });
681
- }
682
-
683
- // integrate reset translation button
684
- function resetTranslations(type){
685
- var resetArr=[];
686
- const saveBtn=$('[data-loco="save"]');
687
- if(conf.podata!==undefined){
688
- if(type=="plain"){
689
- resetArr=resetTransArr(conf.podata,"plain");
690
- }else if(type=="html"){
691
- resetArr=resetTransArr(conf.podata,"html");
692
- }else{
693
- resetArr=resetTransArr(conf.podata,"all");
694
- }
695
- messages = loco.po.init( locale ).wrap( conf.powrap );
696
- messages.load(resetArr);
697
- // editor event behaviours
698
- editor
699
- .on('poUnsaved', function(){
700
- window.onbeforeunload = onUnloadWarning;
701
- } )
702
- .on('poSave', function(){
703
- updateStatus();
704
- window.onbeforeunload = null;
705
- } )
706
- .on( 'poUpdate', updateStatus );
707
-
708
- // ready to render editor
709
- editor.load(messages);
710
- saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
711
- updateStatus();
712
- }
713
- }
714
- // handle form settings
715
- $("#atlt-settings-form").submit(function( event ) {
716
- event.preventDefault();
717
- const user_type=ATLT["info"].type;
718
- let strType = $("input[name='translationtype']:checked").val();
719
- let apiType = $("input[name='api_type']:checked").val();
720
- let mainBtn=$("#cool-auto-translate-btn");
721
- var thisBtn=$("#cool-auto-translate-start");
722
- let sourceApiKey ='';
723
- var todayLimit= mainBtn.data('today-limit');
724
- var totalLimit= mainBtn.data('total-limit');
725
- let targetLang='';
726
- if(user_type=="free" && strType=="html"){
727
- alert("HTML Translation Only Available in the PRO version");
728
- return false;
729
- }
730
- if(user_type=="free" && apiType=="google"){
731
- alert("Google Translation Only Available in the PRO version");
732
- return false;
733
- }
734
- if((user_type==undefined || user_type=="pro") && ATLT["info"]["licenseKey"]==undefined){
735
- alert("Please enter Your License Key");
736
- return false;
737
- }
738
-
739
- if(conf['locale']["lang"]=!undefined){
740
- targetLang=conf['locale']["lang"];
741
- }else{
742
- targetLang=getTargetLang();
743
- }
744
- if(apiType=="google" && strType=="html"){
745
- alert("Google Translate Only Support Plain Text Translation");
746
- return false;
747
- }
748
- if(apiType=="google"){
749
- sourceApiKey = ATLT["api_key"]["gApiKey"];
750
- }else{
751
- sourceApiKey = ATLT["api_key"]["yApiKey"];
752
- }
753
- // filter transable strings
754
- if(locoRawData!=undefined && locoRawData.length>0 && sourceApiKey!='' ){
755
- let plainStrArr=[];
756
- let htmlStrArr=[];
757
- let orgStrArr=[];
758
- orgStrArr=locoRawData;
759
- var countChars=0;
760
- if(strType=="plain"){
761
- plainStrArr= filterRawObject(locoRawData,"plain");
762
- if (plainStrArr !== null) {
763
- plainStrArr.map(function(index){
764
- countChars +=index.source.length;
765
- });
766
- }
767
- }else{
768
- htmlStrArr= filterRawObject(locoRawData,"html");
769
- if (htmlStrArr !== null) {
770
- plainStrArr.map(function(index){
771
- countChars +=index.length;
772
- });
773
- }
774
- }
775
-
776
- if (htmlStrArr !== null || plainStrArr !== null ) {
777
- if(countChars>parseInt(todayLimit)){
778
- alert('Your translation string are larger then available free limit.In order to extend limit Buy Pro license key');
779
- }else{
780
-
781
- if(strType=="plain"){
782
- if(plainStrArr.length==0){
783
- $("#atlt-dialog").parent('.ui-dialog').hide();
784
- mainBtn.attr('disabled','disabled');
785
- alert("You have no untransalted plain strings");
786
- window.location.reload();
787
- return;
788
- }
789
- dataObj = {
790
- textToTranslateArr:plainStrArr,
791
- strType:"plain",
792
- };
793
- }else{
794
- if(htmlStrArr.length==0){
795
- $("#atlt-dialog").parent('.ui-dialog').hide();
796
- mainBtn.attr('disabled','disabled');
797
- alert("You have no untransalted HTML strings");
798
- window.location.reload();
799
- return;
800
- }
801
- dataObj = {
802
- textToTranslateArr:htmlStrArr,
803
- strType:"html",
804
- };
805
- }
806
- // create data object for later use
807
- dataObj.orgStrArr=orgStrArr;
808
- dataObj.thisBtn=thisBtn;
809
- dataObj.apiType=apiType;
810
- dataObj.targetLang=targetLang;
811
- // save data object globaly for later use
812
- window.locoEditorStats.dataObj = dataObj;
813
- jQuery(document).trigger('atlt_run_translation');
814
- thisBtn.val('Translating...');
815
- mainBtn.text("Translating..");
816
- $("#atlt_preloader").show();
817
- // load raw message data
818
-
819
- } //
820
-
821
- } // else close
822
- }
823
-
824
- });
825
-
826
- });
827
- // create translation events
828
- jQuery(document).on('atlt_run_translation',function(){
829
- let textToTranslate = window.locoEditorStats.dataObj.textToTranslateArr
830
- let totalTranslated = window.locoEditorStats.totalTranslated
831
- const apiKey = ATLT["api_key"]["yApiKey"];
832
- const nonce=ATLT["nonce"];
833
- const saveBtn=$('[data-loco="save"]');
834
- const orignalstringArr=window.locoEditorStats.dataObj.orgStrArr;
835
- const targetLang= window.locoEditorStats.dataObj.targetLang;
836
- let indexRequest = 50;
837
- if( ATLT.api_key['atlt_index-per-request'] != "" && typeof ATLT.api_key['atlt_index-per-request'] != "undefined" ){
838
- indexRequest = ATLT.api_key['atlt_index-per-request'];
839
- }
840
-
841
- //save pending array in window object for later use
842
- if( typeof textToTranslate == "object" && textToTranslate.length >= 1 ){
843
- // update object for later us
844
- let translationO = {
845
- textToTranslateArr:textToTranslate.slice(indexRequest), //save pending index for later us
846
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
847
- strType:window.locoEditorStats.dataObj.strType,
848
- orgStrArr:window.locoEditorStats.dataObj.orgStrArr,
849
- apiType:window.locoEditorStats.dataObj.apiType,
850
- targetLang:targetLang,
851
- };
852
- window.locoEditorStats.dataObj = translationO;
853
-
854
- // send partial data request
855
- let data = {
856
- sourceLang:'en',
857
- targetLang:targetLang,
858
- textToTranslateArr:textToTranslate.slice(0,indexRequest),
859
- orginalArr:orignalstringArr,
860
- apiKey:apiKey,
861
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
862
- strType:window.locoEditorStats.dataObj.strType,
863
- apiType:window.locoEditorStats.dataObj.apiType,
864
- saveBtn:saveBtn,
865
- nonce:nonce
866
- };
867
- // slice data
868
- textToTranslate.slice(0,indexRequest).map(function(value,index){
869
- TotalCharacters += (value.source).length;
870
- requestChars+=(value.source).length;
871
- })
872
- atlt_translate(data);
873
- }
874
- })
875
-
876
- // Translate
877
- function atlt_translate(data) {
878
-
879
- atlt_ajax_translation_request(data, "POST").success(function(
880
- resp,status,xhr) {
881
- if(xhr.status==200){
882
-
883
- const json_resp = JSON.parse(resp);
884
- if( json_resp === false && JSON.parse(resp)!=undefined){
885
- data.thisBtn.hide('slow');
886
- $("#atlt_preloader").hide();
887
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
888
- $('#atlt-dialog .atlt-ok.button').show();
889
-
890
- alert('Unable to make request to the server at the moment. Try again later.');
891
- }else if(json_resp['code']==500){
892
- alert('Unable to make request to the server at the moment. Try again later.');
893
- window.location.reload();
894
- return;
895
- }
896
- else if( typeof json_resp['code'] === undefined ||
897
- json_resp['code'] != 200 ){
898
- let error = '';
899
- switch(json_resp['code']){
900
- case 401:
901
- error = 'Yandex API Key is invalid!';
902
- break;
903
- case 402:
904
- error = 'Provided Yandex API Key has been blocked!';
905
- break;
906
- case 404:
907
- error = 'Exceeded the daily limit for Yandex API on the amount of translated text.';
908
- break;
909
- case 422:
910
- error = 'The text cannot be translated by Yandex API.';
911
- break;
912
- case 501:
913
- error = 'Yandex API does not support the specified translation direction.';
914
- break;
915
- default:
916
- error = json_resp['message'];
917
- }
918
- if( error != '' && (data.textToTranslateArr).length != 0 ){
919
- $('#atlt-dialog .atlt-final-message').html("<strong>"+error+"</strong>");
920
- $('#atlt-dialog .atlt-ok.button').show();
921
- $("#atlt_preloader").hide();
922
- $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
923
- //data.thisBtn.attr('disabled','disabled');
924
- }
925
- return;
926
- }
927
-
928
- let totalTranslated = window.locoEditorStats.totalTranslated;
929
-
930
- var response = json_resp['translatedString'];
931
- let unSavedStr=[];
932
- if(response!==undefined){
933
- for(i=0;i< response.length;i++){
934
- var text = response[i];
935
- if( data.textToTranslateArr[i] === undefined ){
936
- break;
937
- }
938
- data.textToTranslateArr[i].target = text ;
939
- }
940
- }
941
-
942
- let translatedStrArr=data['textToTranslateArr'];
943
- // var mergeTranslatedText = atlt_arrayUnique(translatedStrArr.concat(data['orginalArr']) );
944
-
945
- let Emptytargets = [];
946
- for(var x=0; x<translatedStrArr.length;++x){
947
- if(translatedStrArr[x].target !='' ){
948
- Emptytargets[x]=translatedStrArr[x].source;
949
- }
950
- }
951
-
952
- let items;
953
- if (localStorage.getItem('unSavedString')) {
954
- items = JSON.parse(localStorage.getItem('unSavedString'))
955
- } else {
956
- items = []
957
- }
958
- var unSavedStrArr = items.concat(Emptytargets);
959
- localStorage.setItem('unSavedString', JSON.stringify(unSavedStrArr));
960
-
961
-
962
- messages = loco.po.init( locale ).wrap( conf.powrap );
963
- // ready to render editor
964
- messages.load(data['orginalArr']);
965
-
966
- // editor event behaviours
967
- editor
968
- .on('poUnsaved', function(){
969
- window.onbeforeunload = onUnloadWarning;
970
- } )
971
- .on('poSave', function(){
972
- updateStatus();
973
- window.onbeforeunload = null;
974
- } )
975
- .on( 'poUpdate', updateStatus );
976
-
977
- // ready to render editor
978
- editor.load(messages);
979
- data.saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
980
- updateStatus();
981
- // run through DOM and mark *(STAR) for newly translated
982
- markUnsavedString();
983
-
984
- requestChars=0;
985
- // update progress bar
986
- $('#atlt-dialog .translated-label').text('Translated');
987
- $('#atlt-dialog .translated-text').text(window.locoEditorStats.totalTranslated);
988
-
989
- $('#atlt-dialog .atlt-progress-bar-value').width(window.locoEditorStats.totalTranslated);
990
- if(json_resp!=undefined){
991
- if(json_resp['stats']['time_saved']!=undefined){
992
- var saved_time_msg = '<br/><br/><span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">Wahooo! You have saved your <strong>'+json_resp['stats']['time_saved']+'</strong> via auto translating '+parseInt(json_resp['stats']['totalChars'])+ ' characters using <strong><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">Loco Automatic Translate Addon</a></strong>.</span><br/><br/>';
993
- }
994
- }
995
- switch( window.locoEditorStats.totalTranslated ){
996
- case "0%":
997
- $('#atlt-dialog .translated-label').text('Translating...');
998
- $('#atlt-dialog .translated-text').text('');
999
- break;
1000
- case "100%":
1001
- data.thisBtn.hide();
1002
- $("#atlt_preloader").hide();
1003
- data.thisBtn.attr('disabled','disabled');
1004
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1005
- // change cursor to 'default' state
1006
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)"+saved_time_msg);
1007
- $('#atlt-dialog .atlt-ok.button').show();
1008
- return;
1009
- break;
1010
- }
1011
-
1012
- // run through DOM and mark *(STAR) for newly translated
1013
- for(var x=0;x<=Emptytargets.length;x++){
1014
- var source = Emptytargets[x];
1015
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
1016
- return jQuery(this).text() == source
1017
- }).addClass('po-unsaved');
1018
- }
1019
-
1020
- if( (window.locoEditorStats.dataObj.textToTranslateArr).length == 0){
1021
- data.thisBtn.val('Translated').attr("disabled","true");
1022
- $("#atlt_preloader").hide();
1023
- // data.thisBtn.attr('disabled','disabled').hide('slow');
1024
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1025
- // change cursor to 'default' state
1026
- $('#atlt-dialog .atlt-final-message').html("<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>)."+saved_time_msg);
1027
- $('#atlt-dialog .atlt-ok.button').show();
1028
- return;
1029
- }
1030
-
1031
- jQuery(document).trigger('atlt_run_translation');
1032
-
1033
- }else{
1034
- data.thisBtn.hide('slow');
1035
- $("#atlt_preloader").hide();
1036
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
1037
- $('#atlt-dialog .atlt-ok.button').show();
1038
- alert('Unable to make request to the server at the moment. Try again later.');
1039
- }
1040
- }).fail(function(jqXHR){
1041
- if(jqXHR.status==500 || jqXHR.status==0){
1042
- // internal server error or internet connection broke
1043
- data.thisBtn.hide('slow');
1044
- $("#atlt_preloader").hide();
1045
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
1046
- $('#atlt-dialog .atlt-ok.button').show();
1047
- alert('Unable to make request to the server at the moment. Try again later.');
1048
- }
1049
- });
1050
- }
1051
- // filter all saved strings
1052
- function filterSavedStrings(rawArray){
1053
- return filterdArr=rawArray.filter((item,index)=>{
1054
- if(item.target!="" &&(item.source!==undefined && item.source!="")){
1055
- return true;
1056
- }
1057
- });
1058
- }
1059
-
1060
- // filter string based upon type
1061
- function filterRawObject(rawArray,filterType){
1062
- filterdArr=[];
1063
- return filterdArr=rawArray.filter((item,index)=>{
1064
- if( (item.target===undefined || item.target=="" && item.source!="" && item.source!==undefined)){
1065
- if( ValidURL(item.source)){
1066
- return false;
1067
- }
1068
- if(filterType=="html"){
1069
- if(isContainChars(item.source)){
1070
- return false;
1071
- } else if(isHTML(item.source)){
1072
- return true;
1073
- }else if(isAllowedChars(item.source)){
1074
- return true;
1075
- }else{
1076
- return false;
1077
- }
1078
- }else{
1079
- if(isHTML(item.source)){
1080
- return false;
1081
- }else if(isSpecialChars(item.source)){
1082
- return false;
1083
- }else if( item.source.includes('#') ) {
1084
- return false;
1085
- }else{
1086
- return true;
1087
- }
1088
- }
1089
- }
1090
- });
1091
- }
1092
-
1093
- // find unique index in array
1094
- function atlt_arrayUnique(array) {
1095
- var a = array.concat();
1096
- for(var i=0; i<a.length; ++i) {
1097
- for(var j=i+1; j<a.length; ++j) {
1098
- if(a[i] === a[j])
1099
- a.splice(j--, 1);
1100
- }
1101
- }
1102
- return a;
1103
- }
1104
-
1105
-
1106
- // auto traslator button in editor
1107
- function addAutoTranslationBtn(){
1108
- if($("#loco-toolbar").find("#cool-auto-translate-btn").length>0){
1109
- $("#loco-toolbar").find("#cool-auto-translate-btn").remove();
1110
- }
1111
- const locoActions= $("#loco-toolbar").find("#loco-actions");
1112
- const otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>';
1113
- const allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>';
1114
- let savedStrings=filterSavedStrings(conf.podata);
1115
-
1116
- let plainStrings= filterRawObject(conf.podata,"plain");
1117
- let htmlStrings = filterRawObject(conf.podata,"html");
1118
- const userType=ATLT["info"].type;
1119
- if((Array.isArray(plainStrings) && plainStrings.length) ||
1120
- (Array.isArray(htmlStrings)&& htmlStrings.length)
1121
- ){
1122
- const inActiveBtn='<fieldset><button title="Add API key to enable this feature." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button> <a style="font-size:9px;display:block;margin-left:8px;" target="_blank" href="https://tech.yandex.com/translate/">Get Free API Key</a></fieldset>';
1123
- const disabledBtn='<fieldset><button title="Buy PRO." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button><div style="max-width:320px; display:inline-block;margin-top: 4px;"><span style="font-size:12px;display:inline-block;margin-left:8px;">You have exceeded free translation limit. In order to extend the limit - <a target="_blank" style="font-size:14px;display:inline-block;margin-left:8px;" target="_blank" href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing">Buy Premium License</a></span></div></fieldset>';
1124
- const apiKey=ATLT["api_key"]["yApiKey"];
1125
- const proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
1126
- const allowed=ATLT["info"].allowed;
1127
- const today=ATLT["info"].today;
1128
- const total=ATLT["info"].total;
1129
- const aTodayChars=300000;
1130
- const aTodayChar=1000000;
1131
-
1132
- // not added API key
1133
- if( ATLT == '' || ATLT["api_key"] == '' || apiKey=='' ){
1134
- if( userType=='free'){
1135
- locoActions.append(inActiveBtn);
1136
- return;
1137
- }else{
1138
- locoActions.append(proActiveBtn);
1139
- }
1140
- }else if( allowed=="no" && userType=='free'){
1141
- // free not allowed
1142
- locoActions.append(disabledBtn);
1143
- return;
1144
- }else if(today!==undefined && parseInt(today)>aTodayChars
1145
- && userType=='free'){
1146
- // today free limit exceeded
1147
- locoActions.append(disabledBtn);
1148
- return;
1149
- }else if(total!==undefined && parseInt(total)>aTodayChar
1150
- && userType=='free'){
1151
- // monthly limit exceeded
1152
- locoActions.append(disabledBtn);
1153
- return;
1154
- }else if( window.locoEditorStats.totalTranslated != "100%"
1155
- && window.locoEditorStats.totalWords > 0 ){
1156
- //Pro user and added key then show button
1157
- if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1158
- locoActions.append(proActiveBtn);
1159
- }else{
1160
- //if user is free and allowed the show button
1161
- if(today==undefined){
1162
- var todayChars=aTodayChars;
1163
- }else{
1164
- var todayChars=aTodayChars-parseInt(today);
1165
- }
1166
- var totalChars=aTodayChar-parseInt(total);
1167
- // append button for free
1168
- var freeBtn='<fieldset><button data-today-limit="'+todayChars+'" data-total-limit="'+totalChars+'" id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
1169
- locoActions.append(freeBtn);
1170
- }
1171
- } else if( window.locoEditorStats.totalWords == 0){
1172
- return;
1173
- }
1174
- } else{
1175
- locoActions.append(allTranslated);
1176
- }
1177
-
1178
- if((Array.isArray(savedStrings) && savedStrings.length)){
1179
- if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1180
- locoActions.append(otherBtn);
1181
- }
1182
- }
1183
-
1184
- }
1185
-
1186
-
1187
- // mark unsaved after ajax translation process
1188
- function markUnsavedString(){
1189
- const unSavedString = JSON.parse(localStorage.getItem('unSavedString'));
1190
-
1191
- for(var x=0;x<=unSavedString.length;x++){
1192
- var source = unSavedString[x];
1193
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
1194
- return jQuery(this).text() == source
1195
- }).addClass('po-unsaved');
1196
- }
1197
- }
1198
-
1199
- // detect String contain URL
1200
- function ValidURL(str) {
1201
- var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
1202
- if(!pattern.test(str)) {
1203
- return false;
1204
- } else {
1205
- return true;
1206
- }
1207
- }
1208
- // detect Valid HTML in string
1209
- function isHTML(str){
1210
- var rgex=/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i;
1211
- if(str!==undefined){
1212
- return rgex.test(str);
1213
- }else {
1214
- return false;
1215
- }
1216
- }
1217
- // check special chars in string
1218
- function isSpecialChars(str){
1219
- var rgex=/[@#^$%&*{}|<>]/g;
1220
- if(str!==undefined){
1221
- return rgex.test(str);
1222
- }else {
1223
- return false;
1224
- }
1225
- }
1226
- // allowed special chars in HTML string
1227
- function isAllowedChars(str){
1228
- var rgex=/[!@#$%^&*(),?":|<>]/g;
1229
- if(str!==undefined){
1230
- return rgex.test(str);
1231
- }else {
1232
- return false;
1233
- }
1234
- }
1235
- // check string contain curly brackets
1236
- function isContainChars(str){
1237
- var rgex=/[{}[]/g;
1238
- if(str!==undefined){
1239
- return rgex.test(str);
1240
- }else {
1241
- return false;
1242
- }
1243
- }
1244
- // format numbers
1245
- function atltFormatNumber(num) {
1246
- return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
1247
- }
1248
-
1249
- // create popup model for translation settings
1250
- function createSettingsPopup(){
1251
- let preloaderImg=extradata['preloader_path'];
1252
- const userInfo=ATLT["info"].type;
1253
- const yAC=ATLT["info"].yAvailableChars;
1254
- const licenseKey=ATLT["info"]["licenseKey"];
1255
-
1256
- let yfieldStatus="";
1257
- let gfieldStatus="";
1258
- let hfieldStatus="";
1259
- let htmlSupported="";
1260
- let contCls="";
1261
- let proLbl="";
1262
- let gContCls='';
1263
- let gHtml='';
1264
- let submitBtn='';
1265
- let yHtml='';
1266
- let yChecked='checked="true"';
1267
- if(userInfo=="free"){
1268
- let gAC=0;
1269
- gfieldStatus="disabled";
1270
- hfieldStatus="disabled";
1271
- contCls="html-disabled";
1272
- gContCls='g-disabled';
1273
- proLbl='<span class="atlt-pro-feature"><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;" title="Only For Pro Users">PRO Only</a></span>';
1274
- gHtml=proLbl+' (70% better than Yendex Translate)';
1275
- }else{
1276
-
1277
- if( ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])
1278
- && ATLT["api_key"]["gApiKey"]!=""){
1279
- let gAC=ATLT["info"].gAvailableChars;
1280
- if(gAC!==undefined && gAC>10000){
1281
- gHtml='<span class="available-chars"> ('+ atltFormatNumber(gAC)+' Available This Month)</span>';
1282
- }
1283
- if(gAC<10000){
1284
- gHtml='<span class="used-chars">You have consumed All Free Characters</span>';
1285
- }
1286
- }else{
1287
- gfieldStatus="disabled";
1288
- gContCls='g-disabled';
1289
-
1290
- gHtml='<span class="error">Please Enter Google Translate API key in the Settings Panel</span>';
1291
- }
1292
-
1293
- if(ATLT["api_key"]["yApiKey"]!="")
1294
- {
1295
- if(yAC!==undefined){
1296
- yHtml='<span class="available-chars"> ('+atltFormatNumber(yAC)+' Available Today)</span>';
1297
- }
1298
- }else{
1299
- yfieldStatus="disabled";
1300
- yContCls='g-disabled';
1301
- yChecked='';
1302
- yHtml='<span class="error">Please Enter Yandex API key in the Settings Panel</span>';
1303
- }
1304
- }
1305
- if( ATLT["api_key"]["yApiKey"]!="" || ATLT["api_key"]["gApiKey"]!="" )
1306
- {
1307
- submitBtn='<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">';
1308
- }else{
1309
- submitBtn='<button class="atlt-ok button button-primary">OK</button>';
1310
-
1311
- }
1312
- let settingsHTML=`<div class="atlt-settings">
1313
- <form id="atlt-settings-form" method="post" action="#">
1314
- <strong class="atlt-heading">Select Translation API</strong>
1315
- <div class="inputGroup">
1316
- <input class="inputEle" type="radio" id="yandex_api"
1317
- ${yChecked} ${yfieldStatus} name="api_type" value="yandex">
1318
- <label for="yandex_api">Yandex ${yHtml}</label>
1319
- </div>
1320
- <div class="inputGroup ${gContCls}">
1321
- <input class="inputEle" type="radio" id="google_api"
1322
- name="api_type" value="google" ${gfieldStatus}>
1323
- <label for="google_api">Google</label> ${gHtml}
1324
- </div>
1325
- <br/>
1326
- <strong class="atlt-heading">Select Content Type</strong>
1327
- <div class="inputGroup">
1328
- <input class="inputEle" type="radio" id="typeplain" checked="true" name="translationtype" value="plain">
1329
- <label for="typeplain">Translate Plain Text Strings</label>
1330
- </div>
1331
- <div id="typehtmlWrapper" class="inputGroup ${contCls}">
1332
- <input class="inputEle" type="radio" id="typehtml" name="translationtype" value="html" ${hfieldStatus}>
1333
- <label for="typehtml">Translate HTML Strings (Beta) ${proLbl}
1334
- </label>
1335
- </br>
1336
- <small style="display:inline-block;margin-left:24px;margin-top:8px;">(<a href="https://locotranslate.com/html-translation-languages-list/" target="_blank">List of languages with HTML support</a>)</small>
1337
- </div>
1338
-
1339
- <br/>
1340
- <fieldset>
1341
- ${submitBtn}
1342
- <img style="display:none;margin-left:10px;margin-top:-3px;" id="atlt_preloader" src="${preloaderImg}">
1343
- </fieldset>
1344
- </form>
1345
- </div>`;
1346
- // custom popup message box
1347
- let popup_html = `<div id="atlt-dialog-container">
1348
- <div style="display:none;" id="atlt-dialog" title="Automatic Translation Progress">
1349
- ${settingsHTML}
1350
- <p><span class="translated-label">Translated</span>
1351
- <span class="translated-text">0%</span></p>
1352
- <div class="atlt-progress-bar-track">
1353
- <div class="atlt-progress-bar-value">
1354
- </div></div>
1355
- <div class="atlt-final-message"></div>
1356
- <button style="display:none;" class="atlt-ok button button-primary">OK</button>
1357
- </div></div>`;
1358
- $("body").append( popup_html );
1359
- }
1360
-
1361
- // send ajax request
1362
- function atlt_ajax_translation_request(data,type){
1363
- let filteredArr=[];
1364
- filteredArr=data.textToTranslateArr.map((item)=>{
1365
- if( typeof item.source!= 'undefined'){
1366
- return item.source;
1367
- } });
1368
- const jsonData=JSON.stringify(filteredArr);
1369
-
1370
- return jQuery.ajax({
1371
- url: ajaxurl,
1372
- type:'POST',
1373
- data: {'action':'atlt_translation',
1374
- 'sourceLan':data.sourceLang,
1375
- 'targetLan':data.targetLang,
1376
- 'totalCharacters': TotalCharacters,
1377
- 'requestChars':requestChars,
1378
- 'nonce':data.nonce,
1379
- 'strType':data.strType,
1380
- 'apiType':data.apiType,
1381
- 'data':jsonData
1382
- },
1383
- done:function(res){
1384
- // console.log(res)
1385
- }
1386
-
1387
-
1388
- });
1389
- }
1390
-
1391
- // ok, editor ready
1392
- updateStatus();
1393
-
1394
- // clean up
1395
- //delete window.locoConf;
1396
- //conf = buttons = null;
1397
-
1398
- }( window, jQuery );
1
+ !function(window,$){var TotalCharacters=0,HtmlStrings=0,requestChars=0;let event;document.createEvent("event").initEvent("atlt_run_translation"),createSettingsPopup(),$("#atlt-dialog .atlt-ok.button").on("click",(function(){localStorage.removeItem("unSavedString"),$("#atlt-dialog").parent(".ui-dialog").hide()}));var loco=window.locoScope,conf=window.locoConf,syncParams=null,saveParams=null,translator=loco.l10n,sprintf=loco.string.sprintf,locale=conf.locale,messages=loco.po.init(locale).wrap(conf.powrap),template=!locale,elForm=document.getElementById("loco-actions"),filePath=conf.popath,syncPath=conf.potpath,elFilesys=document.getElementById("loco-fs"),fsConnect=elFilesys&&loco.fs.init(elFilesys),readonly,editable=!conf.readonly,editor,saveButton,innerDiv=document.getElementById("loco-editor-inner");function doSyncAction(callback){function onSuccess(result){var info=[],doc=messages,exp=result.po,src=result.pot,pot=loco.po.init().load(exp),done=doc.merge(pot),nadd=done.add.length,ndel=done.del.length,t=translator;editor.load(doc),nadd||ndel?(src?info.push(sprintf(t._("Merged from %s"),src)):info.push(t._("Merged from source code")),nadd&&info.push(sprintf(t._n("1 new string added","%s new strings added",nadd),nadd)),ndel&&info.push(sprintf(t._n("1 obsolete string removed","%s obsolete strings removed",ndel),ndel)),$(innerDiv).trigger("poUnsaved",[]),updateStatus(),window.console&&debugMerge(console,done)):src?info.push(sprintf(t._("Already up to date with %s"),src)):info.push(t._("Already up to date with source code")),loco.notices.success(info.join(". ")),$(innerDiv).trigger("poMerge",[result]),callback&&callback()}loco.ajax.post("sync",syncParams,onSuccess,callback)}function debugMerge(console,result){for(var i=-1,t=result.add.length;++i<t;)console.log(" + "+result.add[i].source());for(i=-1,t=result.del.length;++i<t;)console.log(" - "+result.del[i].source())}function doSaveAction(callback){function onSuccess(result){callback&&callback(),editor.save(!0),$("#loco-po-modified").text(result.datetime||"[datetime error]")}saveParams.locale=String(messages.locale()||""),fsConnect&&fsConnect.applyCreds(saveParams),saveParams.data=String(messages),loco.ajax.post("save",saveParams,onSuccess,callback)}function saveIfDirty(){editor.dirty&&doSaveAction()}function onUnloadWarning(){return translator._("Your changes will be lost if you continue without saving")}function registerSaveButton(button){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}return saveButton=button,editor.on("poUnsaved",(function(){enable(),$(button).addClass("button-primary loco-flagged")})).on("poSave",(function(){disable(),$(button).removeClass("button-primary loco-flagged")})),saveParams=$.extend({path:filePath},conf.project||{}),$(button).click((function(event){return event.preventDefault(),think(),doSaveAction(unthink),setTimeout((function(){location.reload()}),3500),!1})),!0}function registerSyncButton(button){var project=conf.project;if(project){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}editor.on("poUnsaved",(function(){disable()})).on("poSave",(function(){enable()})),syncParams={bundle:project.bundle,domain:project.domain,type:template?"pot":"po",sync:syncPath||""},$(button).click((function(event){return event.preventDefault(),think(),doSyncAction(unthink),!1})),enable()}return!0}function registerFuzzyButton(button){var toggled=!1,enabled=!1;function redraw(message,state){var allowed=message&&message.translated(0)||!1;enabled!==allowed&&(button.disabled=!allowed,enabled=allowed),state!==toggled&&($(button)[state?"addClass":"removeClass"]("inverted"),toggled=state)}return editor.on("poSelected",(function(event,message){redraw(message,message&&message.fuzzy()||!1)})).on("poEmpty",(function(event,blank,message,pluralIndex){0===pluralIndex&&blank===enabled&&redraw(message,toggled)})).on("poFuzzy",(function(event,message,newState){redraw(message,newState)})),$(button).click((function(event){return event.preventDefault(),editor.fuzzy(!editor.fuzzy()),!1})),!0}function registerRevertButton(button){return editor.on("poUnsaved",(function(){button.disabled=!1})).on("poSave",(function(){button.disabled=!0})),$(button).click((function(event){return event.preventDefault(),location.reload(),!1})),!0}function registerInvisiblesButton(button){var $button=$(button);return button.disabled=!1,editor.on("poInvs",(function(event,state){$button[state?"addClass":"removeClass"]("inverted")})),$button.click((function(event){return event.preventDefault(),editor.setInvs(!editor.getInvs()),!1})),locoScope.tooltip.init($button),!0}function registerCodeviewButton(button){var $button=$(button);return button.disabled=!1,$button.click((function(event){event.preventDefault();var state=!editor.getMono();return editor.setMono(state),$button[state?"addClass":"removeClass"]("inverted"),!1})),locoScope.tooltip.init($button),!0}function registerAddButton(button){return button.disabled=!1,$(button).click((function(event){event.preventDefault();var i=1,baseid,msgid,regex=/(\d+)$/;for(msgid=baseid="New message";messages.get(msgid);)i=regex.exec(msgid)?Math.max(i,RegExp.$1):i,msgid=baseid+" "+ ++i;return editor.add(msgid),!1})),!0}function registerDelButton(button){return button.disabled=!1,$(button).click((function(event){return event.preventDefault(),editor.del(),!1})),!0}function registerDownloadButton(button,id){return button.disabled=!1,$(button).click((function(event){var form=button.form,path=filePath;return"binary"===id&&(path=path.replace(/\.po$/,".mo")),form.path.value=path,form.source.value=messages.toString(),!0})),!0}function noop(event){return event.preventDefault(),!1}function updateStatus(){var t=translator,stats=editor.stats(),total=stats.t,fuzzy=stats.f,empty=stats.u,stext=sprintf(t._n("1 string","%s strings",total),total.format(0)),extra=[];locale&&(stext=sprintf(t._("%s%% translated"),stats.p.replace("%",""))+", "+stext,fuzzy&&extra.push(sprintf(t._("%s fuzzy"),fuzzy.format(0))),empty&&extra.push(sprintf(t._("%s untranslated"),empty.format(0))),extra.length&&(stext+=" ("+extra.join(", ")+")")),$("#loco-po-status").text(stext),void 0===window.locoEditorStats?window.locoEditorStats={totalWords:stats.t,totalTranslated:stats.p}:(window.locoEditorStats.totalWords=stats.t,window.locoEditorStats.totalTranslated=stats.p)}function initSearchFilter(elSearch){function showValidFilter(numFound){$(elSearch.parentNode)[numFound||null==numFound?"removeClass":"addClass"]("invalid")}editor.searchable(loco.fulltext.init()),elSearch.disabled=!1,elSearch.value="";var listener=loco.watchtext(elSearch,(function(value){var numFound;showValidFilter(editor.filter(value,!0))}));editor.on("poFilter",(function(event,value,numFound){listener.val(value||""),showValidFilter(numFound)})).on("poMerge",(function(event,result){var value=listener.val();value&&editor.filter(value)}))}var resize=function(){function top(el,ancestor){for(var y=el.offsetTop||0;(el=el.offsetParent)&&el!==ancestor;)y+=el.offsetTop||0;return y}var fixHeight,minHeight=parseInt($(innerDiv).css("min-height")||0);return function(){var padBottom=20,topBanner=top(innerDiv,document.body),winHeight=window.innerHeight,setHeight=Math.max(minHeight,winHeight-topBanner-20);fixHeight!==setHeight&&(innerDiv.style.height=String(setHeight)+"px",fixHeight=setHeight)}}();resize(),$(window).resize(resize),innerDiv.innerHTML="",editor=loco.po.ed.init(innerDiv).localise(translator),loco.po.kbd.init(editor).add("save",saveIfDirty).enable("copy","clear","enter","next","prev","fuzzy","save","invis");var buttons={save:editable&&registerSaveButton,sync:editable&&registerSyncButton,revert:registerRevertButton,invs:registerInvisiblesButton,code:registerCodeviewButton,source:registerDownloadButton,binary:template?null:registerDownloadButton};function createEncodedString(allStringText){const queryString=allStringText.map(item=>"&text="+encodeURIComponent(item.source)).join(",");return queryString}function validLicenseKey(licenseKey){if(!(null!=licenseKey&&licenseKey.length>1))return!1;{let validKey;if(validate_pattern(licenseKey).length>1)return licenseKey}}function savedTimeInfo(statsObj){var info="";if(null!=statsObj&&void 0!==statsObj.time_saved){let timeSaved,totalChars;var info=`<div class="saved_time_wrapper" style="margin:10px 0px">\n <span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">\n Wahooo! You have saved your \n <strong>${statsObj.time_saved}</strong> \n via auto translating <strong>${statsObj.totalChars}</strong> \n characters using <strong> <br />\n <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">\n Loco Automatic Translate Addon</a></strong>\n </span></div>`}return info}function validate_pattern(str){let m;const regex=/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;let saveMatch=[];for(;null!==(m=regex.exec(str));)m.index===regex.lastIndex&&regex.lastIndex++,m.forEach((match,groupIndex)=>{saveMatch.push(match)});return saveMatch}function getTargetLang(){return window.locoConf.locale.lang?window.locoConf.locale.lang:null}function atlt_translate(data){atlt_ajax_translation_request(data,"POST").success((function(resp,status,xhr){if(200==xhr.status&&null!=resp){const json_resp=JSON.parse(resp);let responseObj,apiProvider=window.locoEditorStats.dataObj.apiType;if(json_resp.error&&800==json_resp.error.code){let errorMsz=json_resp.error.message;return $("#atlt-dialog .atlt-final-message").html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>"),$("#atlt-dialog .atlt-ok.button").show(),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Error").attr("disabled","disabled"),setTimeout((function(){location.reload()}),4e3),!1}if(null==json_resp.translatedString||!json_resp.translatedString.length||200!=json_resp.code){let errorCode=json_resp.code,errorMsz=json_resp.error;return $("#atlt-dialog .atlt-final-message").html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>"),$("#atlt-dialog .atlt-ok.button").show(),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Error").attr("disabled","disabled"),setTimeout((function(){location.reload()}),4e3),!1}responseObj=json_resp.translatedString;let totalTranslated=window.locoEditorStats.totalTranslated,unSavedStr=[];if(void 0!==responseObj&&responseObj.length)for(i=0;i<responseObj.length;i++){var text=responseObj[i];if(void 0===data.textToTranslateArr[i])break;data.textToTranslateArr[i].target=text}let translatedStrArr=data.textToTranslateArr,Emptytargets=[],items;for(var x=0;x<translatedStrArr.length;++x)""!=translatedStrArr[x].target&&(Emptytargets[x]=translatedStrArr[x].source);items=localStorage.getItem("unSavedString")?JSON.parse(localStorage.getItem("unSavedString")):[];var unSavedStrArr=items.concat(Emptytargets);localStorage.setItem("unSavedString",JSON.stringify(unSavedStrArr)),(messages=loco.po.init(locale).wrap(conf.powrap)).load(conf.podata),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),editor.load(messages),data.saveBtn.addClass("button-primary loco-flagged").removeAttr("disabled"),updateStatus(),markUnsavedString(),requestChars=0,$("#atlt-dialog .translated-label").text("Translated"),$("#atlt-dialog .translated-text").text(window.locoEditorStats.totalTranslated),$("#atlt-dialog .atlt-progress-bar-value").width(window.locoEditorStats.totalTranslated);let saved_time_html=savedTimeInfo(json_resp.stats),finalHTML="<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>).";switch(window.locoEditorStats.totalTranslated){case"0%":$("#atlt-dialog .translated-label").text("Translating..."),$("#atlt-dialog .translated-text").text("");break;case"100%":return data.thisBtn.hide(),$("#atlt_preloader").hide(),data.thisBtn.attr("disabled","disabled"),$("#cool-auto-translate-btn").text("Translated - SAVE NOW").attr("disabled","disabled"),$("#atlt-dialog .atlt-final-message").html(finalHTML+saved_time_html),void $("#atlt-dialog .atlt-ok.button").show()}for(var x=0;x<=Emptytargets.length;x++){var source=Emptytargets[x];jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter((function(index){return jQuery(this).text()==source})).addClass("po-unsaved")}if(0==window.locoEditorStats.dataObj.textToTranslateArr.length)return data.thisBtn.val("Translated").attr("disabled","true"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translated - SAVE NOW").attr("disabled","disabled"),$("#atlt-dialog .atlt-final-message").html(finalHTML+saved_time_html),void $("#atlt-dialog .atlt-ok.button").show();jQuery(document).trigger("atlt_run_translation")}else data.thisBtn.hide("slow"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translation").attr("disabled","disabled"),$("#atlt-dialog .atlt-ok.button").show(),alert("Unable to make request to the server at the moment. Try again later.")})).fail((function(jqXHR){console.log(jqXHR),500!=jqXHR.status&&0!=jqXHR.status||(data.thisBtn.hide("slow"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translation").attr("disabled","disabled"),$("#atlt-dialog .atlt-ok.button").show(),alert("Unable to make request to the server at the moment. Try again later."))}))}function filterSavedStrings(rawArray){return filterdArr=rawArray.filter((item,index)=>{if(""!=item.target&&void 0!==item.source&&""!=item.source)return!0})}function filterRawObject(rawArray,filterType){return filterdArr=[],filterdArr=rawArray.filter((item,index)=>{if(""!==item.source&&void 0!==item.source&&(void 0===item.target||""==item.target))return!ValidURL(item.source)&&("html"==filterType?!!isHTML(item.source)||!(!isAllowedChars(item.source)||0!=isPlacehodersChars(item.source)):!isHTML(item.source)&&(!!isPlacehodersChars(item.source)||!isSpecialChars(item.source)&&!item.source.includes("#")))})}function addAutoTranslationBtn(){$("#loco-toolbar").find("#cool-auto-translate-btn").length>0&&$("#loco-toolbar").find("#cool-auto-translate-btn").remove();const locoActions=$("#loco-toolbar").find("#loco-actions"),otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>',allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>';let savedStrings=filterSavedStrings(conf.podata),plainStrings=filterRawObject(conf.podata,"plain"),htmlStrings=filterRawObject(conf.podata,"html");const userType=ATLT.info.type;if(Array.isArray(plainStrings)&&plainStrings.length||Array.isArray(htmlStrings)&&htmlStrings.length){const inActiveBtn='<fieldset><button title="Add API key to enable this feature." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button> <a style="font-size:9px;display:block;margin-left:8px;" target="_blank" href="https://tech.yandex.com/translate/">Get Free API Key</a></fieldset>',disabledBtn='<fieldset><button title="Buy PRO." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button><div style="max-width:320px; display:inline-block;margin-top: 4px;"><span style="font-size:12px;display:inline-block;margin-left:8px;">You have exceeded free translation limit. In order to extend the limit - <a target="_blank" style="font-size:14px;display:inline-block;margin-left:8px;" target="_blank" href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing">Buy Premium License</a></span></div></fieldset>',apiKey=ATLT.api_key.yApiKey,proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>',allowed=ATLT.info.allowed,today=ATLT.info.today,total=ATLT.info.total,aTodayChars=3e5,aTodayChar=1e6;if(""==ATLT||""==ATLT.api_key||""==apiKey){if("free"==userType)return void locoActions.append(inActiveBtn);locoActions.append(proActiveBtn)}else{if("no"==allowed&&"free"==userType)return void locoActions.append(disabledBtn);if(void 0!==today&&parseInt(today)>aTodayChars&&"free"==userType)return void locoActions.append(disabledBtn);if(void 0!==total&&parseInt(total)>aTodayChar&&"free"==userType)return void locoActions.append(disabledBtn);if("100%"!=window.locoEditorStats.totalTranslated&&window.locoEditorStats.totalWords>0)if("pro"==userType&&null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey))locoActions.append(proActiveBtn);else{if(null==today)var todayChars=aTodayChars;else var todayChars=aTodayChars-parseInt(today);var totalChars,freeBtn='<fieldset><button data-today-limit="'+todayChars+'" data-total-limit="'+(aTodayChar-parseInt(total))+'" id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';locoActions.append(freeBtn)}else if(0==window.locoEditorStats.totalWords)return}}else locoActions.append(allTranslated);Array.isArray(savedStrings)&&savedStrings.length&&"pro"==userType&&null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey)&&"yes"==ATLT.info.proInstalled&&locoActions.append(otherBtn)}function markUnsavedString(){const unSavedString=JSON.parse(localStorage.getItem("unSavedString"));for(var x=0;x<=unSavedString.length;x++){var source=unSavedString[x];jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter((function(index){return jQuery(this).text()==source})).addClass("po-unsaved")}}function ValidURL(str){var pattern;return!!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(str)}function isHTML(str){var rgex;return void 0!==str&&/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(str)}function isSpecialChars(str){var rgex;return void 0!==str&&/[@#^$%&*{}|<>]/g.test(str)}function isAllowedChars(str){var rgex;return void 0!==str&&/[!@#$%^&*(),?":|<>]/g.test(str)}function isPlacehodersChars(str){var rgex;return void 0!==str&&/%s|%d/g.test(str)}function isContainChars(str){var rgex;return void 0!==str&&/[{}[]/g.test(str)}function atltFormatNumber(num){return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")}function createSettingsPopup(){let preloaderImg=extradata.preloader_path;const userInfo=ATLT.info.type,yAC=ATLT.info.yAvailableChars,licenseKey=ATLT.info.licenseKey,proInstalled=ATLT.info.proInstalled;let yfieldStatus="",gfieldStatus="",mfieldStatus="",hfieldStatus="",htmlSupported="",contCls="",proLbl="",gContCls="",gHtml="",mContCls="",mHtml="",submitBtn="",yHtml="",yChecked='checked="true"';if("free"==userInfo){let gAC=0;gfieldStatus="disabled",mfieldStatus="disabled",hfieldStatus="disabled",contCls="html-disabled",gContCls="g-disabled",mContCls="m-disabled",proLbl='<span class="atlt-pro-feature"><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;font-size:0.9em;" title="Only For Pro Users">PRO Only</a></span>',gHtml=proLbl+" ",mHtml=proLbl+" "}else if("no"==proInstalled)gfieldStatus="disabled",mfieldStatus="disabled",hfieldStatus="disabled",contCls="html-disabled",gContCls="g-disabled",mContCls="m-disabled",proLbl='<span style="color:red;font-weight:bold;font-size:0.9em;" class="atlt-pro-feature">Please Install PRO version</span>',gHtml=proLbl+" ",mHtml=proLbl+" ";else if(null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey)){if(""!=ATLT.api_key.gApiKey){let gAC=ATLT.info.gAvailableChars;void 0!==gAC&&gAC>1e4?gHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(gAC)+" Free Char. Available This Month)</span>":gAC<1e4&&(gHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>')}else gfieldStatus="disabled",gContCls="g-disabled",gHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Google Translate API key)</span>';null!=ATLT.api_key.mApiKey&&""!=ATLT.api_key.mApiKey?(mAC=ATLT.info.mAvailableChars,void 0!==mAC&&mAC>1e4?mHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(mAC)+" Free Char. Available This Month)</span>":mAC<1e4&&(mHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>')):(mfieldStatus="disabled",mContCls="m-disabled",mHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Microsoft Translator API key)</span>'),""!=ATLT.api_key.yApiKey?void 0!==yAC&&(yHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(yAC)+" Free Char. Available Today)</span>"):(yfieldStatus="disabled",yContCls="g-disabled",yChecked="",yHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Yandex Translate API key)</span>')}submitBtn=""!=ATLT.api_key.yApiKey||""!=ATLT.api_key.gApiKey||""!=ATLT.api_key.mApiKey?'<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">':'<button class="atlt-ok button button-primary">OK</button>';let settingsHTML,popup_html=`<div id="atlt-dialog-container">\n <div style="display:none;" id="atlt-dialog" title="Automatic Translation Progress">\n ${`<div class="atlt-settings">\n <form id="atlt-settings-form" method="post" action="#">\n <strong class="atlt-heading">Select Translation API</strong>\n <div class="inputGroup">\n <input class="inputEle" type="radio" id="yandex_api" \n ${yChecked} ${yfieldStatus} name="api_type" value="yandex">\n <label for="yandex_api">Yandex Translate ${yHtml}</label>\n </div>\n <div class="inputGroup ${gContCls}">\n <input class="inputEle" type="radio" id="google_api" \n name="api_type" value="google" ${gfieldStatus}>\n <label for="google_api">Google Translate ${gHtml}</label>\n </div>\n <div class="inputGroup ${mContCls}">\n <input class="inputEle" type="radio" id="microsoft_api" \n name="api_type" value="microsoft" ${mfieldStatus}>\n <label for="microsoft_api">Microsoft Translator ${mHtml}</label>\n <br/>\n <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locotranslate.com/supported-languages/" target="_blank">View all supported languages list</a>)</small>\n </div>\n <br/>\n <strong class="atlt-heading">Select Content Type</strong>\n <div class="inputGroup">\n <input class="inputEle" type="radio" id="typeplain" checked="true" name="translationtype" value="plain">\n <label for="typeplain">Translate Plain Text Strings</label>\n </div>\n <div id="typehtmlWrapper" class="inputGroup ${contCls}">\n <input class="inputEle" type="radio" id="typehtml" name="translationtype" value="html" ${hfieldStatus}>\n <label for="typehtml">Translate HTML Strings (Beta) ${proLbl}\n </label>\n </br>\n <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locotranslate.com/html-translation-languages-list/" target="_blank">List of languages with HTML support</a>)</small>\n </div>\n \n <br/>\n <fieldset>\n ${submitBtn}\n <img style="display:none;margin-left:10px;margin-top:-3px;" id="atlt_preloader" src="${preloaderImg}">\n </fieldset>\n </form>\n </div>`}\n <p><span class="translated-label">Translated</span>\n <span class="translated-text">0%</span></p>\n <div class="atlt-progress-bar-track">\n <div class="atlt-progress-bar-value">\n </div></div>\n <div class="atlt-final-message"></div>\n <button style="display:none;" class="atlt-ok button button-primary">OK</button>\n </div></div>`;$("body").append(popup_html)}function atlt_ajax_translation_request(data,type){let filteredArr=[];filteredArr=data.textToTranslateArr.map(item=>{if(void 0!==item.source)return item.source});const jsonData=JSON.stringify(filteredArr);return jQuery.ajax({url:ajaxurl,type:"POST",data:{action:data.endpoint,sourceLan:data.sourceLang,targetLan:data.targetLang,totalCharacters:TotalCharacters,requestChars:requestChars,nonce:data.nonce,strType:data.strType,apiType:data.apiType,data:jsonData},done:function(res){}})}template?(buttons.add=editable&&registerAddButton,buttons.del=editable&&registerDelButton):buttons.fuzzy=registerFuzzyButton,$("#loco-toolbar").find("button").each((function(i,el){var id=el.getAttribute("data-loco"),register=buttons[id];register&&register(el,id)||$(el).hide()})),$(elForm).submit(noop),initSearchFilter(document.getElementById("loco-search")),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),messages.load(conf.podata),editor.load(messages),(locale=editor.targetLocale)?locale.isRTL()&&$(innerDiv).addClass("trg-rtl"):editor.unlock(),$(document).ready((function(){if(template)return;const locoRawData=conf.podata;function resetTransArr(tranArr,type){var resetStrs=[];return tranArr.map((function(item){if(void 0!==item.source&&void 0!==item.target)return"html"==type&&(isHTML(item.source)?item.target="":isAllowedChars(item.source)&&0==isPlacehodersChars(item.source)&&(item.target="")),"plain"==type&&(1==isPlacehodersChars(item.source)?item.target="":isHTML(item.source)||isAllowedChars(item.source)||(item.target="")),"all"==type&&(item.target=""),item}))}function resetTranslations(type){var resetArr=[];const saveBtn=$('[data-loco="save"]');void 0!==conf.podata&&(resetArr=resetTransArr(conf.podata,"plain"==type?"plain":"html"==type?"html":"all"),(messages=loco.po.init(locale).wrap(conf.powrap)).load(resetArr),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),editor.load(messages),saveBtn.addClass("button-primary loco-flagged").removeAttr("disabled"),updateStatus())}null!=locoRawData&&locoRawData.length>0&&addAutoTranslationBtn(),$(document).on("click","#cool-auto-translate-btn",(function(){$("#atlt-dialog").dialog({width:440,height:500})})),$("input[name=api_type]").on("click",(function(){"google"==$(this).val()||"microsoft"==$(this).val()?($("#typehtmlWrapper").hide(),$("#typeplain").attr("checked","checked")):$("#typehtmlWrapper").show()})),$("#atlt_reset_all").on("click",(function(){swal("What type of strings do you want to reset?",{dangerMode:!0,icon:"warning",confirmButtonColor:"#8CD4F5",buttons:{plain:{text:"Plain Text Strings",value:"plain",class:"danger"},html:{text:"HTML Strings",value:"html"},all:{text:"All Strings",value:"all"},cancel:{text:"Cancel",value:null,visible:!0,className:"",closeModal:!1}}}).then(value=>{switch(value){case"all":resetTranslations(value),swal("Done!","You have successfully reset all strings translations. Just close this popup & SAVE!","success");break;case"plain":resetTranslations(value),swal("Done!","You have successfully reset all plain text strings translations. Just close this popup & SAVE!","success");break;case"html":resetTranslations(value),swal("Done!","You have successfully reset all strings with HTML translations. Just close this popup & SAVE!","success");break;default:swal("Cancelled, Just close this popup!")}})})),$("#atlt-settings-form").submit((function(event){event.preventDefault();const user_type=ATLT.info.type;let strType=$("input[name='translationtype']:checked").val(),apiType=$("input[name='api_type']:checked").val(),mainBtn=$("#cool-auto-translate-btn");var thisBtn=$("#cool-auto-translate-start");let sourceApiKey="";var todayLimit=mainBtn.data("today-limit"),totalLimit=mainBtn.data("total-limit");let targetLang="";if("free"==user_type&&"html"==strType)return alert("HTML Translation Only Available in the PRO version"),!1;if("free"==user_type&&"google"==apiType)return alert("Google Translation Only Available in the PRO version"),!1;if("free"==user_type&&"microsoft"==apiType)return alert("Microsoft Translator Only Available in the PRO version"),!1;if((null==user_type||"pro"==user_type)&&null==ATLT.info.licenseKey)return alert("Please enter Your License Key"),!1;if(targetLang=1==conf.locale.lang?conf.locale.lang:getTargetLang(),"google"==apiType&&"html"==strType)return alert("Google Translate Only Support Plain Text Translation"),!1;if("microsoft"==apiType&&"html"==strType)return alert("Microsoft Translator Only Support Plain Text Translation"),!1;if("google"==apiType?("zh"==targetLang&&(targetLang=targetLang+"-"+conf.locale.region),sourceApiKey=ATLT.api_key.gApiKey):"microsoft"==apiType?("zh"==targetLang&&("CN"==conf.locale.region?targetLang+="-Hans":"TW"==conf.locale.region?targetLang+="-Hant":targetLang=targetLang+"-"+conf.locale.region),sourceApiKey=ATLT.api_key.mApiKey):sourceApiKey=ATLT.api_key.yApiKey,null!=locoRawData&&locoRawData.length>0&&""!=sourceApiKey){let plainStrArr=[],htmlStrArr=[],orgStrArr=[];orgStrArr=locoRawData;var countChars=0;if("plain"==strType?(plainStrArr=filterRawObject(locoRawData,"plain"),null!==plainStrArr&&plainStrArr.map((function(index){countChars+=index.source.length}))):(htmlStrArr=filterRawObject(locoRawData,"html"),null!==htmlStrArr&&plainStrArr.map((function(index){countChars+=index.length}))),null!==htmlStrArr||null!==plainStrArr)if(countChars>parseInt(todayLimit))alert("Your translation string are larger then available free limit.In order to extend limit Buy Pro license key");else{if("plain"==strType){if(0==plainStrArr.length)return $("#atlt-dialog").parent(".ui-dialog").hide(),mainBtn.attr("disabled","disabled"),alert("You have no untranslated plain strings"),void window.location.reload();dataObj={textToTranslateArr:plainStrArr,strType:"plain"}}else{if(0==htmlStrArr.length)return $("#atlt-dialog").parent(".ui-dialog").hide(),mainBtn.attr("disabled","disabled"),alert("You have no untranslated HTML strings"),void window.location.reload();dataObj={textToTranslateArr:htmlStrArr,strType:"html"}}dataObj.orgStrArr=orgStrArr,dataObj.thisBtn=thisBtn,dataObj.apiType=apiType,dataObj.targetLang=targetLang,dataObj.endpoint=ATLT.endpoint,window.locoEditorStats.dataObj=dataObj,jQuery(document).trigger("atlt_run_translation"),thisBtn.val("Translating..."),mainBtn.text("Translating.."),$("#atlt_preloader").show()}}}))})),jQuery(document).on("atlt_run_translation",(function(){let textToTranslate=window.locoEditorStats.dataObj.textToTranslateArr,totalTranslated=window.locoEditorStats.totalTranslated;const apiKey=ATLT.api_key.yApiKey,nonce=ATLT.nonce,saveBtn=$('[data-loco="save"]'),orignalstringArr=window.locoEditorStats.dataObj.orgStrArr,targetLang=window.locoEditorStats.dataObj.targetLang;let indexRequest=50;if(""!=ATLT.api_key["atlt_index-per-request"]&&void 0!==ATLT.api_key["atlt_index-per-request"]&&(indexRequest=ATLT.api_key["atlt_index-per-request"]),"object"==typeof textToTranslate&&textToTranslate.length>=1){let translationO={textToTranslateArr:textToTranslate.slice(indexRequest),thisBtn:window.locoEditorStats.dataObj.thisBtn,strType:window.locoEditorStats.dataObj.strType,orgStrArr:window.locoEditorStats.dataObj.orgStrArr,apiType:window.locoEditorStats.dataObj.apiType,targetLang:targetLang,endpoint:window.locoEditorStats.dataObj.endpoint};window.locoEditorStats.dataObj=translationO;let data={sourceLang:"en",targetLang:targetLang,textToTranslateArr:textToTranslate.slice(0,indexRequest),orginalArr:orignalstringArr,apiKey:apiKey,thisBtn:window.locoEditorStats.dataObj.thisBtn,strType:window.locoEditorStats.dataObj.strType,apiType:window.locoEditorStats.dataObj.apiType,saveBtn:saveBtn,endpoint:window.locoEditorStats.dataObj.endpoint,nonce:nonce};textToTranslate.slice(0,indexRequest).map((function(value,index){TotalCharacters+=value.source.length,requestChars+=value.source.length})),atlt_translate(data)}})),updateStatus()}(window,jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
automatic-translator-addon-for-loco-translate.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /*
3
- Plugin Name:Loco Automatic Translate Addon
4
  Description:Auto language translator add-on for Loco Translate plugin to translate plugins and themes translation files into any language via fully automatic machine translations via yandex Translate API.
5
- Version:1.5
6
  License:GPL2
7
- Text Domain:atlt
8
  Domain Path:languages
9
  Author:Cool Plugins
10
  Author URI:https://coolplugins.net/
11
  */
12
  namespace LocoAutoTranslateAddon;
13
- use LocoAutoTranslateAddon\Helpers\Helpers;
14
  /**
15
  * @package Loco Automatic Translate Addon
16
- * @version 1.5
17
  */
18
  if (!defined('ABSPATH')) {
19
  die('WordPress Environment Not Found!');
@@ -22,29 +22,63 @@ if (!defined('ABSPATH')) {
22
  define('ATLT_FILE', __FILE__);
23
  define('ATLT_URL', plugin_dir_url(ATLT_FILE));
24
  define('ATLT_PATH', plugin_dir_path(ATLT_FILE));
25
- define('ATLT_VERSION', '1.5');
26
 
27
  class LocoAutoTranslate
28
  {
29
  public function __construct()
30
- {
31
  register_activation_hook( ATLT_FILE, array( $this, 'atlt_activate' ) );
32
  register_deactivation_hook( ATLT_FILE, array( $this, 'atlt_deactivate' ) );
 
33
  add_action('plugins_loaded', array($this, 'atlt_check_required_loco_plugin'));
34
- /*** Template Setting Page Link inside Plugins List */
35
  add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this,'atlt_settings_page_link'));
36
- add_action( 'admin_enqueue_scripts', array( $this, 'atlt_enqueue_scripts') );
37
- add_action('wp_ajax_atlt_translation', array($this, 'atlt_translate_string_callback'), 100);
 
38
  add_action('init',array($this,'checkStatus'));
39
- add_action('plugins_loaded', array($this,'include_files'));
 
 
40
 
 
41
  }
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  /**
44
  * create 'settings' link in plugins page
45
  */
46
  public function atlt_settings_page_link($links){
47
  $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt') ) .'">Settings</a>';
 
48
  return $links;
49
  }
50
 
@@ -55,198 +89,220 @@ class LocoAutoTranslate
55
  */
56
  public function include_files()
57
  {
58
- include_once ATLT_PATH . 'includes/Helpers/Helpers.php';
59
- include_once ATLT_PATH . 'includes/Core/class.settings-api.php';
60
- include_once ATLT_PATH . 'includes/Core/class.settings-panel.php';
61
- new Core\Settings_Panel();
62
- if ( is_admin() ) {
 
63
  include_once ATLT_PATH . "includes/ReviewNotice/class.review-notice.php";
64
  new ALTLReviewNotice\ALTLReviewNotice();
65
  include_once ATLT_PATH . 'includes/Feedback/class.feedback-form.php';
66
  new FeedbackForm\FeedbackForm();
67
- //require_once ATLT_PATH . "includes/init-api.php";
68
  include_once ATLT_PATH . 'includes/Register/LocoAutomaticTranslateAddonPro.php';
69
- }
70
 
71
  }
72
- public function checkStatus(){
73
- Helpers::checkPeriod();
74
- }
75
-
76
- /*
77
- |----------------------------------------------------------------------
78
- | check if required "Loco Translate" plugin is active
79
- | also register the plugin text domain
80
- |----------------------------------------------------------------------
81
- */
82
- public function atlt_check_required_loco_plugin()
83
- {
84
-
85
- if (!function_exists('loco_plugin_self')) {
86
- add_action('admin_notices', array($this, 'atlt_plugin_required_admin_notice'));
87
- }
88
- load_plugin_textdomain('atlt', false, basename(dirname(__FILE__)) . '/languages/');
89
-
90
- }
91
-
92
- /*
93
- |----------------------------------------------------------------------
94
- | Notice to 'Admin' if "Loco Translate" is not active
95
- |----------------------------------------------------------------------
96
- */
97
- public function atlt_plugin_required_admin_notice()
98
- {
99
- if (current_user_can('activate_plugins')) {
100
- $url = 'plugin-install.php?tab=plugin-information&plugin=loco-translate&TB_iframe=true';
101
- $title = "Loco Translate";
102
- $plugin_info = get_plugin_data(__FILE__, true, true);
103
- echo '<div class="error"><p>' . sprintf(__('In order to use <strong>%s</strong> plugin, please install and activate the latest version of <a href="%s" class="thickbox" title="%s">%s</a>', 'atlt'), $plugin_info['Name'], esc_url($url), esc_attr($title), esc_attr($title)) . '.</p></div>';
104
- deactivate_plugins(__FILE__);
105
- }
106
- }
107
-
108
  /*
109
- |------------------------------------------------------
110
- | Send Request to yandex API
111
- |------------------------------------------------------
112
- */
113
- public function yandex_api_call($stringArr,$target_language,$source_language,$requestType,$apiKey){
114
- // create query string
115
- $queryString='';
116
- $langParam = $source_language.'-'.$target_language;
117
-
118
- if(is_array($stringArr)){
119
- foreach($stringArr as $str){
120
- $queryString.='&text='.urlencode($str);
121
- }
122
- }
123
- // build query
124
- $buildReqURL='';
125
- $buildReqURL.='https://translate.yandex.net/api/v1.5/tr.json/translate';
126
- $buildReqURL.='?key=' . $apiKey . '&lang=' . $langParam.'&format='.$requestType;
127
- $buildReqURL.=$queryString;
128
- // get API response
129
- $response = wp_remote_get($buildReqURL, array('timeout'=>'180'));
130
-
131
- if (is_wp_error($response)) {
132
- return $response; // Bail early
133
- }
134
- $body = wp_remote_retrieve_body($response);
135
- // convert string into assoc array
136
- $data = json_decode( $body, true);
137
- return $data;
138
- }
139
-
140
-
141
- /*
142
  |----------------------------------------------------------------------
143
- | AJAX called to this function for translation
144
  |----------------------------------------------------------------------
145
  */
146
- public function atlt_translate_string_callback()
147
  {
148
  // verify request
149
  if ( ! wp_verify_nonce($_REQUEST['nonce'], 'atlt_nonce' ) ) {
150
- die(json_encode(array('code' => 850, 'message' => 'Request Time Out. Please refresh your browser window.')));
151
- } else {
152
- // user status
 
153
  $status=Helpers::atltVerification();
154
  if($status['type']=="free" && $status['allowed']=="no"){
155
- die(json_encode(array('code' => 800, 'message' => 'You have cons med daily limit')));
156
- }
 
157
  // get request vars
158
  if (empty($_REQUEST['data'])) {
159
- die(json_encode(array('code' => 900, 'message' => 'Empty request')));
 
160
  }
161
  if(isset($_REQUEST['data'])){
162
  $responseArr=array();
163
  $response=array();
164
-
165
  $requestData = $_REQUEST['data'];
166
  $targetLang=$_REQUEST['targetLan'];
167
  $sourceLang=$_REQUEST['sourceLan'];
168
  if($targetLang=="nb" || $targetLang=="nn"){
169
  $targetLang="no";
170
  }
171
-
172
  $request_chars = $_REQUEST['requestChars'];
173
  $totalChars = $_REQUEST['totalCharacters'];
174
  $requestType=$_REQUEST['strType'];
175
  $apiType=$_REQUEST['apiType'];
176
  $stringArr= json_decode(stripslashes($requestData),true);
177
-
178
- if($apiType=="google"){
179
- $g_api_key= Helpers::getAPIkey("google");
180
- if(empty($g_api_key)||$g_api_key==""){
181
- die(json_encode(array('code' => 902, 'message' => 'You have not Entered Google Translate API Key')));
182
- }
183
- $apiKey = $g_api_key;
184
-
185
- if(is_array( $stringArr)&& !empty($stringArr))
186
- {
187
- $response=$this->translate_array($stringArr,$targetLang,$sourceLang, $apiKey);
188
- if(is_array($response)&& count($response)>=1)
189
- {
190
- $responseArr['translatedString']=$response;
191
- $responseArr['code']=200;
192
- // grab translation count data
193
- $responseArr['stats']= $this->saveStringsCount($request_chars,$totalChars,$apiType);
194
- }else{
195
-
196
- $responseArr['code']=500;
197
- $responseArr['message']=$response;
198
-
199
- }
200
- }
201
- }else{
202
- // grab API keys
203
- $api_key = Helpers::getAPIkey("yandex");
204
-
205
  if(empty($api_key)|| $api_key==""){
206
- die(json_encode(array('code' => 902, 'message' => 'You have not Entered yandex API Key')));
207
- }
208
- $apiKey = $api_key;
 
 
 
 
 
209
  if(is_array( $stringArr)&& !empty($stringArr))
210
  {
211
  $response=$this->yandex_api_call($stringArr,$targetLang,$sourceLang,$requestType,$apiKey);
212
-
213
  if(is_array($response) && $response['code']==200)
214
  {
215
  // grab translation count data
216
- $responseArr['code']=200;
217
- $responseArr['translatedString']= $response['text'];
218
- $responseArr['stats']= $this->saveStringsCount($request_chars,$totalChars,$apiType);
 
 
 
219
  }else{
220
- $responseArr['code']=500;
221
- $responseArr['message']=$response['errors']['http_request_failed'];
222
  }
223
- }
224
- }
225
-
226
  die(json_encode($responseArr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
227
-
228
  }
229
-
230
  }
231
-
232
  }
233
-
234
 
235
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  public function saveStringsCount($request_chars,$totalChars,$apiType)
237
  {
238
- if($apiType=="google"){
239
- $today_translated = Helpers::gTodayTranslated( $request_chars);
240
- $monthly_translated = Helpers::gMonthlyTranslated( $request_chars);
241
- }else{
242
- $today_translated = Helpers::todayTranslated( $request_chars);
243
- $monthly_translated = Helpers::monthlyTranslated( $request_chars);
244
- }
245
  /** Calculate the total time save on translation */
246
  $session_time_saved = Helpers::atlt_time_saved_on_translation( $totalChars);
247
  $total_time_saved = Helpers::atlt_time_saved_on_translation($totalChars);
248
  // create response array
249
-
250
  $stats=array(
251
  'todays_translation'=>$today_translated,
252
  'total_translation'=>$monthly_translated,
@@ -256,94 +312,41 @@ class LocoAutoTranslate
256
  );
257
  return $stats;
258
  }
259
- /*
 
260
  |------------------------------------------------------
261
- | Send Request to API
262
  |------------------------------------------------------
263
  */
264
- /**
265
- * @param array $strings_array Array of string to translate
266
- * @return array|WP_Error Response
267
- */
268
- public function send_request( $source_language, $target_language, $strings_array,$apiKey ){
269
- // $apiKey='AIzaSyAA575IhTNuMrgS-ISe23WlGmjs4LGZu58';
270
-
271
- /* build our translation request */
272
- $translation_request = 'key='.$apiKey;
273
-
274
- $translation_request .= '&source='.$source_language;
275
- $translation_request .= '&target='.$target_language;
276
- foreach( $strings_array as $new_string ){
277
- $translation_request .= '&q='.rawurlencode($new_string);
278
  }
279
- // $referer =
280
-
281
- /* Due to url length restrictions we need so send a POST request faked as a GET request and send the strings in the body of the request and not in the URL */
282
- $response = wp_remote_post( "https://www.googleapis.com/language/translate/v2", array(
283
- 'headers' => array(
284
- 'X-HTTP-Method-Override' => 'GET', //this fakes a GET request
285
- // 'Referer' => $referer
286
- ),
287
- 'body' => $translation_request,
288
- )
289
- );
290
- return $response;
291
  }
292
-
293
-
294
-
295
- /*
296
- |------------------------------------------------------
297
- | Translate Array
298
- |------------------------------------------------------
299
- */
300
-
301
- /**
302
- * Returns an array with the API provided translations of the $new_strings array.
303
- */
304
- public function translate_array($new_strings, $target_language_code, $source_language_code,$api_key ){
305
-
306
- if( empty( $new_strings ) )
307
- return array();
308
-
309
- $source_language =$source_language_code;
310
- $target_language = $target_language_code;
311
-
312
- $translated_strings = array();
313
-
314
- /* split our strings that need translation in chunks of maximum 128 strings because Google Translate has a limit of 128 strings */
315
- $new_strings_chunks = array_chunk( $new_strings, 128, true );
316
- /* if there are more than 128 strings we make multiple requests */
317
- foreach( $new_strings_chunks as $new_strings_chunk ){
318
- $response = $this->send_request( $source_language, $target_language, $new_strings_chunk,$api_key );
319
- /* analyze the response */
320
- if ( is_array( $response ) && ! is_wp_error( $response ) ) {
321
-
322
- /* decode it */
323
- $translation_response = json_decode( $response['body'] );
324
- if( !empty( $translation_response->error ) ){
325
- return array(); // return an empty array if we encountered an error. This means we don't store any translation in the DB
326
- }
327
- else{
328
- /* if we have strings build the translation strings array and make sure we keep the original keys from $new_string */
329
- $translations = $translation_response->data->translations;
330
- $i = 0;
331
- foreach( $new_strings_chunk as $key => $old_string ){
332
- if( !empty( $translations[$i]->translatedText ) ) {
333
- $translated_strings[$key] = $translations[$i]->translatedText;
334
- }
335
- $i++;
336
- }
337
- }
338
- }
339
-
340
- }
341
-
342
- // will have the same indexes as $new_string or it will be an empty array if something went wrong
343
- return $translated_strings;
344
  }
 
 
 
 
 
345
 
346
- /*
 
347
  |------------------------------------------------------------------------
348
  | Enqueue required JS file
349
  |------------------------------------------------------------------------
@@ -351,36 +354,70 @@ class LocoAutoTranslate
351
  function atlt_enqueue_scripts(){
352
  wp_deregister_script('loco-js-editor');
353
  wp_register_script( 'sweet-alert', ATLT_URL.'assets/sweetalert/sweetalert.min.js', array('loco-js-min-admin'),false, true);
354
- wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),false, true);
355
-
 
 
 
 
356
  if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit')
357
  {
358
  $data=array();
359
  wp_enqueue_script('sweet-alert');
 
360
  wp_enqueue_script('loco-js-editor');
 
361
  $status=Helpers::atltVerification();
362
-
363
  $data['api_key']['yApiKey']=Helpers::getAPIkey("yandex");
364
  $data['info']['yAvailableChars']=Helpers::getAvailableChars("yandex");
365
  $data['nonce']= wp_create_nonce('atlt_nonce');
366
-
 
 
 
 
 
367
  if($status['type']=="free"){
368
  $data['info']=Helpers::atltVerification();
369
  }else{
370
  $data['api_key']['gApiKey']=Helpers::getAPIkey("google");
 
371
  $key=Helpers::getLicenseKey();
372
  if(Helpers::validKey( $key)){
373
  $data['info']['type']="pro";
374
  $data['info']['allowed']="yes";
375
  $data['info']['licenseKey']=$key;
376
  $data['info']['gAvailableChars']=Helpers::getAvailableChars("google");
377
- }
 
 
 
 
 
 
 
378
  }
379
-
380
  $extraData['preloader_path']=ATLT_URL.'/assets/images/preloader.gif';
381
  wp_localize_script('loco-js-editor', 'ATLT', $data);
382
  wp_localize_script('loco-js-editor', 'extradata', $extraData);
383
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  }
385
 
386
  }
@@ -394,21 +431,16 @@ class LocoAutoTranslate
394
  $plugin_info = get_plugin_data(__FILE__, true, true);
395
  update_option('atlt_version', $plugin_info['Version'] );
396
  update_option("atlt-installDate",date('Y-m-d h:i:s') );
397
- update_option("atlt-ratingDiv","no");
398
  update_option("atlt-type","free");
399
  }
400
-
401
-
402
-
403
  /*
404
  |-------------------------------------------------------
405
  | Plugin deactivation
406
  |-------------------------------------------------------
407
  */
408
  public function atlt_deactivate(){
409
-
410
  }
411
-
412
  }
413
 
414
  $atlt=new LocoAutoTranslate();
1
  <?php
2
  /*
3
+ Plugin Name:Automatic Translate Addon For Loco Translate
4
  Description:Auto language translator add-on for Loco Translate plugin to translate plugins and themes translation files into any language via fully automatic machine translations via yandex Translate API.
5
+ Version:1.7.4
6
  License:GPL2
7
+ Text Domain:loco-translate-addon
8
  Domain Path:languages
9
  Author:Cool Plugins
10
  Author URI:https://coolplugins.net/
11
  */
12
  namespace LocoAutoTranslateAddon;
13
+ use LocoAutoTranslateAddon\Helpers\Helpers;
14
  /**
15
  * @package Loco Automatic Translate Addon
16
+ * @version 1.7.4
17
  */
18
  if (!defined('ABSPATH')) {
19
  die('WordPress Environment Not Found!');
22
  define('ATLT_FILE', __FILE__);
23
  define('ATLT_URL', plugin_dir_url(ATLT_FILE));
24
  define('ATLT_PATH', plugin_dir_path(ATLT_FILE));
25
+ define('ATLT_VERSION', '1.7.3');
26
 
27
  class LocoAutoTranslate
28
  {
29
  public function __construct()
30
+ {
31
  register_activation_hook( ATLT_FILE, array( $this, 'atlt_activate' ) );
32
  register_deactivation_hook( ATLT_FILE, array( $this, 'atlt_deactivate' ) );
33
+ if(is_admin()){
34
  add_action('plugins_loaded', array($this, 'atlt_check_required_loco_plugin'));
35
+ /*** Template Setting Page Link inside Plugins List */
36
  add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this,'atlt_settings_page_link'));
37
+ add_action( 'admin_enqueue_scripts', array( $this,'atlt_enqueue_scripts') );
38
+ add_action('wp_ajax_free_autotranslate_handler',array($this,'atlt_free_autotranslate_handler'), 100);
39
+ add_action('wp_ajax_free_test_api_provider',array($this,'atlt_free_test_api_provider'));
40
  add_action('init',array($this,'checkStatus'));
41
+ add_action('init',array($this,'updateSettings'));
42
+ add_action('plugins_loaded', array($this,'include_files'));
43
+
44
 
45
+ }
46
  }
47
 
48
+ public function use_loco_autotranslate_notice(){
49
+ //get the current screen
50
+ $screen = get_current_screen();
51
+ //return if not plugin settings page
52
+ //To get the exact your screen ID just do ver_dump($screen)
53
+ if (in_array($screen->id, array('loco-translate_page_loco-atlt','loco-translate_page_loco-atlt-register')))
54
+ {
55
+ $loco_vesion=loco_plugin_version();
56
+ if (version_compare( $loco_vesion, '2.4', '>=')) {
57
+ if (current_user_can('activate_plugins')) {
58
+ $url= admin_url( 'admin.php?page=loco-config&action=apis');
59
+ echo '<div class="error"><p style="font-size:16px;">' .
60
+ sprintf(__(
61
+ '<strong style="color:red">Notice from <a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/" target="_blank">Loco Addon</a> Owner:</strong> All premium features of <a href="https://wordpress.org/plugins/automatic-translator-addon-for-loco-translate/" target="_blank"><strong>Automatic Translate Addon For Loco Translate</strong></a> has been integrated inside new version of <a href="https://wordpress.org/plugins/loco-translate/" target="_blank"><strong>Loco Translate</strong></a> (2.4.0+) free official plugin. So add translate API keys inside its <a href="%s"><strong>Settings</strong></a> and enjoy automatic translations using Google, Microsoft or Yandex APIs. You can now deactivate <strong>Automatic Translate Addon For Loco Translate</strong>',
62
+ 'loco-translate-addon'),
63
+ esc_url($url)
64
+ ) . '.</p></div>';
65
+ }
66
+ }
67
+ }
68
+ }
69
+ // update settings
70
+ public function updateSettings(){
71
+ if(get_option( 'atlt-ratingDiv')){
72
+ update_option('atlt-already-rated',get_option( 'atlt-ratingDiv'));
73
+ delete_option( 'atlt-ratingDiv');
74
+ }
75
+ }
76
  /**
77
  * create 'settings' link in plugins page
78
  */
79
  public function atlt_settings_page_link($links){
80
  $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt') ) .'">Settings</a>';
81
+ $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt-register') ) .'">License</a>';
82
  return $links;
83
  }
84
 
89
  */
90
  public function include_files()
91
  {
92
+
93
+ if ( is_admin() ) {
94
+ include_once ATLT_PATH .'includes/Helpers/Helpers.php';
95
+ include_once ATLT_PATH . 'includes/Core/class.settings-api.php';
96
+ include_once ATLT_PATH . 'includes/Core/class.settings-panel.php';
97
+ new Core\Settings_Panel();
98
  include_once ATLT_PATH . "includes/ReviewNotice/class.review-notice.php";
99
  new ALTLReviewNotice\ALTLReviewNotice();
100
  include_once ATLT_PATH . 'includes/Feedback/class.feedback-form.php';
101
  new FeedbackForm\FeedbackForm();
 
102
  include_once ATLT_PATH . 'includes/Register/LocoAutomaticTranslateAddonPro.php';
103
+ }
104
 
105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  |----------------------------------------------------------------------
108
+ | Ajax callback handler
109
  |----------------------------------------------------------------------
110
  */
111
+ public function atlt_free_autotranslate_handler()
112
  {
113
  // verify request
114
  if ( ! wp_verify_nonce($_REQUEST['nonce'], 'atlt_nonce' ) ) {
115
+ echo $this->errorResponse('Request Time Out. Please refresh your browser window.');
116
+ die();
117
+ } else {
118
+ // user status
119
  $status=Helpers::atltVerification();
120
  if($status['type']=="free" && $status['allowed']=="no"){
121
+ echo $this->errorResponse('You have consumed API daily limit');
122
+ die();
123
+ }
124
  // get request vars
125
  if (empty($_REQUEST['data'])) {
126
+ echo $this->errorResponse('No String Found');
127
+ die();
128
  }
129
  if(isset($_REQUEST['data'])){
130
  $responseArr=array();
131
  $response=array();
 
132
  $requestData = $_REQUEST['data'];
133
  $targetLang=$_REQUEST['targetLan'];
134
  $sourceLang=$_REQUEST['sourceLan'];
135
  if($targetLang=="nb" || $targetLang=="nn"){
136
  $targetLang="no";
137
  }
 
138
  $request_chars = $_REQUEST['requestChars'];
139
  $totalChars = $_REQUEST['totalCharacters'];
140
  $requestType=$_REQUEST['strType'];
141
  $apiType=$_REQUEST['apiType'];
142
  $stringArr= json_decode(stripslashes($requestData),true);
143
+ // grab API keys
144
+ $api_key = Helpers::getAPIkey("yandex");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  if(empty($api_key)|| $api_key==""){
146
+ echo $this->errorResponse('You have not Entered yandex API Key');
147
+ die();
148
+ }
149
+ $apiKey = $api_key;
150
+ if(Helpers::yandexSLangList($targetLang)==false){
151
+ echo $this->errorResponse('Yandex Translator Does not support this language');
152
+ die();
153
+ }
154
  if(is_array( $stringArr)&& !empty($stringArr))
155
  {
156
  $response=$this->yandex_api_call($stringArr,$targetLang,$sourceLang,$requestType,$apiKey);
 
157
  if(is_array($response) && $response['code']==200)
158
  {
159
  // grab translation count data
160
+ $responseArr['code']=200;
161
+ $responseArr['translatedString']= $response['text'];
162
+ $responseArr['stats']= $this->saveStringsCount($request_chars,$totalChars,$apiType);
163
+ }else if(isset($response['code'])){
164
+ $responseArr['code']=$response['code'];
165
+ $responseArr['error']=$response['message'];
166
  }else{
167
+ $responseArr['error']=$response;
168
+ $responseArr['code']=500;
169
  }
170
+ }
 
 
171
  die(json_encode($responseArr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
 
172
  }
 
173
  }
 
174
  }
 
175
 
176
+
177
+ /*
178
+ |----------------------------------------------------------------------
179
+ | check User Status
180
+ |----------------------------------------------------------------------
181
+ */
182
+ public function checkStatus(){
183
+ Helpers::checkPeriod();
184
+ $key=Helpers::getLicenseKey();
185
+ if(Helpers::validKey( $key) && Helpers::proInstalled()==false){
186
+ add_action('admin_notices', array($this, 'atlt_pro_install_notice'));
187
+ }
188
+ }
189
+ /*
190
+ |----------------------------------------------------------------------
191
+ | check if required "Loco Translate" plugin is active
192
+ | also register the plugin text domain
193
+ |----------------------------------------------------------------------
194
+ */
195
+ public function atlt_check_required_loco_plugin()
196
+ {
197
+ if (!function_exists('loco_plugin_self')) {
198
+ add_action('admin_notices', array($this, 'atlt_plugin_required_admin_notice'));
199
+ }
200
+
201
+ if (function_exists('loco_plugin_self')) {
202
+ add_action('admin_notices',array($this,'use_loco_autotranslate_notice'));
203
+ }
204
+ load_plugin_textdomain('loco-translate-addon', false, basename(dirname(__FILE__)) . '/languages/');
205
+ }
206
+
207
+ /*
208
+ |----------------------------------------------------------------------
209
+ | Install Loco Automatic Translate Addon Pro notice
210
+ |----------------------------------------------------------------------
211
+ */
212
+ public function atlt_pro_install_notice()
213
+ {
214
+
215
+ if (current_user_can('activate_plugins')) {
216
+ $key=Helpers::getLicenseKey();
217
+ $url =esc_url( add_query_arg( 'license-key',$key , 'https://locotranslate.com/data/download-plugin.php' ) );
218
+ $title = "Loco Automatic Translate Addon Pro";
219
+ echo '<div class="error loco-pro-missing" style="border:2px solid;border-color:#dc3232;"><p>' .
220
+ sprintf('You are using <strong>%s</strong> license. Please also install and activate <strong>%s</strong> plugin files to enjoy all premium featues and automatic premium updates.</p>
221
+ <p><a href="%s" target="_blank" title="%s" class="button button-primary"><strong>Download %s plugin</strong></a> and install it, you can also download it from <a href="https://locotranslate.com/my-account/downloads/" target="_blank">https://locotranslate.com/my-account/downloads/</a>',
222
+ esc_attr($title),esc_attr($title),esc_url($url),esc_attr($title),esc_attr($title)) . '.</p></div>';
223
+ }
224
+ }
225
+
226
+ /*
227
+ |----------------------------------------------------------------------
228
+ | Notice to 'Admin' if "Loco Translate" is not active
229
+ |----------------------------------------------------------------------
230
+ */
231
+ public function atlt_plugin_required_admin_notice()
232
+ {
233
+ if (current_user_can('activate_plugins')) {
234
+ echo '<div class="error"><p>' .
235
+ sprintf(__('In order to use <strong>%s</strong> plugin, please install and activate the latest version of <a href="%s" class="thickbox" title="%s">%s</a>',
236
+ 'loco-translate-addon'),
237
+ $plugin_info['Name'], esc_url($url),
238
+ esc_attr($title), esc_attr($title)) . '.</p></div>';
239
+
240
+ deactivate_plugins(__FILE__);
241
+ }
242
+ }
243
+
244
+ /*
245
+ |----------------------------------------------------------------------
246
+ | Verify API's working or not
247
+ |----------------------------------------------------------------------
248
+ */
249
+ public function atlt_free_test_api_provider(){
250
+ if ( ! wp_verify_nonce($_REQUEST['nonce'], 'atlt_nonce' ) ) {
251
+ die(json_encode(array('code' =>500, 'message' => 'Request Time Out. Please refresh your browser window.')));
252
+ } else {
253
+ $text = $_REQUEST['text'];
254
+ $targetLang=$_REQUEST['target'];
255
+ $sourceLang=$_REQUEST['source'];
256
+ $apikey=$_REQUEST['apikey'];
257
+ $apiType=$_REQUEST['apiprovider'];
258
+ $strArr[]=$text;
259
+ $requestType="plain";
260
+ $response=$this->yandex_api_call(
261
+ $strArr,$targetLang,$sourceLang,$requestType,$apikey);
262
+ $responseArr['response']=$response;
263
+ if(is_array($response) && $response['code']==200)
264
+ {
265
+ // grab translation count data
266
+ $responseArr['code']=200;
267
+ $responseArr['translatedString']= $response['text'];
268
+ }else if(isset($response['code']) && isset($response['message'])){
269
+ $responseArr['code']= $response['code'];
270
+ $responseArr['error']= $response['message'];
271
+ }else{
272
+ $responseArr['code']=500;
273
+ $responseArr['error']= $response;
274
+ }
275
+ die(json_encode($responseArr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
276
+ }
277
+ }
278
+
279
+ /*
280
+ |----------------------------------------------------------------------
281
+ | error response creator
282
+ |----------------------------------------------------------------------
283
+ */
284
+ public function errorResponse($message){
285
+ $error=[];
286
+ if($message){
287
+ $error['error']['code']=800;
288
+ $error['error']['message']=$message;
289
+ }
290
+ return json_encode($error);
291
+ }
292
+
293
+ /*
294
+ |----------------------------------------------------------------------
295
+ | Save string usage
296
+ |----------------------------------------------------------------------
297
+ */
298
  public function saveStringsCount($request_chars,$totalChars,$apiType)
299
  {
300
+ $today_translated = Helpers::ytodayTranslated( $request_chars);
301
+ $monthly_translated = Helpers::ymonthlyTranslated( $request_chars);
 
 
 
 
 
302
  /** Calculate the total time save on translation */
303
  $session_time_saved = Helpers::atlt_time_saved_on_translation( $totalChars);
304
  $total_time_saved = Helpers::atlt_time_saved_on_translation($totalChars);
305
  // create response array
 
306
  $stats=array(
307
  'todays_translation'=>$today_translated,
308
  'total_translation'=>$monthly_translated,
312
  );
313
  return $stats;
314
  }
315
+
316
+ /*
317
  |------------------------------------------------------
318
+ | Send Request to yandex API
319
  |------------------------------------------------------
320
  */
321
+ public function yandex_api_call($stringArr,$target_language,$source_language,$requestType,$apiKey){
322
+ // create query string
323
+ $queryString='';
324
+ $langParam = $source_language.'-'.$target_language;
325
+
326
+ if(is_array($stringArr)){
327
+ foreach($stringArr as $str){
328
+ $queryString.='&text='.urlencode($str);
 
 
 
 
 
 
329
  }
 
 
 
 
 
 
 
 
 
 
 
 
330
  }
331
+ // build query
332
+ $buildReqURL='';
333
+ $buildReqURL.='https://translate.yandex.net/api/v1.5/tr.json/translate';
334
+ $buildReqURL.='?key=' . $apiKey . '&lang=' . $langParam.'&format='.$requestType;
335
+ $buildReqURL.=$queryString;
336
+ // get API response
337
+ $response = wp_remote_get($buildReqURL, array('timeout'=>'180'));
338
+
339
+ if (is_wp_error($response)) {
340
+ return $response->get_error_message();; // Bail early
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  }
342
+ $body = wp_remote_retrieve_body($response);
343
+ // convert string into assoc array
344
+ $data = json_decode( $body, true);
345
+ return $data;
346
+ }
347
 
348
+
349
+ /*
350
  |------------------------------------------------------------------------
351
  | Enqueue required JS file
352
  |------------------------------------------------------------------------
354
  function atlt_enqueue_scripts(){
355
  wp_deregister_script('loco-js-editor');
356
  wp_register_script( 'sweet-alert', ATLT_URL.'assets/sweetalert/sweetalert.min.js', array('loco-js-min-admin'),false, true);
357
+ //sweet alert for settings panel
358
+ wp_register_script( 'settings-sweet-alert', ATLT_URL.'assets/sweetalert/sweetalert.min.js',array('jquery'),false, true);
359
+ wp_register_script( 'test-api', ATLT_URL.'assets/js/api-testing.js', array('jquery','settings-sweet-alert'));
360
+ wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.min.js', array('loco-js-min-admin'),false, true);
361
+ wp_register_script( 'loco-js-test', ATLT_URL.'assets/js/loco-autotranslate-handler.js', array('loco-js-min-admin'),false, true);
362
+
363
  if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit')
364
  {
365
  $data=array();
366
  wp_enqueue_script('sweet-alert');
367
+ // wp_enqueue_script('loco-js-test');
368
  wp_enqueue_script('loco-js-editor');
369
+
370
  $status=Helpers::atltVerification();
 
371
  $data['api_key']['yApiKey']=Helpers::getAPIkey("yandex");
372
  $data['info']['yAvailableChars']=Helpers::getAvailableChars("yandex");
373
  $data['nonce']= wp_create_nonce('atlt_nonce');
374
+ $data['endpoint']='free_autotranslate_handler';
375
+ // @since version 1.7.1
376
+ $settings=get_option('atlt_register');
377
+ $index_per_request=isset($settings['atlt_index-per-request'])?$settings['atlt_index-per-request']:50;
378
+ $data['api_key']['atlt_index-per-request']=$index_per_request;
379
+
380
  if($status['type']=="free"){
381
  $data['info']=Helpers::atltVerification();
382
  }else{
383
  $data['api_key']['gApiKey']=Helpers::getAPIkey("google");
384
+ $data['api_key']['mApiKey']=Helpers::getAPIkey("microsoft");
385
  $key=Helpers::getLicenseKey();
386
  if(Helpers::validKey( $key)){
387
  $data['info']['type']="pro";
388
  $data['info']['allowed']="yes";
389
  $data['info']['licenseKey']=$key;
390
  $data['info']['gAvailableChars']=Helpers::getAvailableChars("google");
391
+ $data['info']['mAvailableChars']=Helpers::getAvailableChars("microsoft");
392
+ if(Helpers::proInstalled()==false){
393
+ $data['info']['proInstalled']="no";
394
+ }else{
395
+ $data['info']['proInstalled']="yes";
396
+ $data['endpoint']='pro_autotranslate_handler';
397
+ }
398
+ }
399
  }
 
400
  $extraData['preloader_path']=ATLT_URL.'/assets/images/preloader.gif';
401
  wp_localize_script('loco-js-editor', 'ATLT', $data);
402
  wp_localize_script('loco-js-editor', 'extradata', $extraData);
403
+ }
404
+
405
+ if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'loco-atlt')
406
+ {
407
+ wp_enqueue_script('settings-sweet-alert');
408
+ wp_enqueue_script('test-api');
409
+ $status=Helpers::atltVerification();
410
+ if($status['type']=="free"){
411
+ $testdata['info']['endpoint']='free_test_api_provider';
412
+ }else{
413
+ $key=Helpers::getLicenseKey();
414
+ if(Helpers::validKey( $key) && Helpers::proInstalled()==true){
415
+ $testdata['info']['endpoint']='pro_test_api_provider';
416
+ }else{
417
+ $testdata['info']['endpoint']='free_test_api_provider';
418
+ }
419
+ }
420
+ wp_localize_script('test-api', 'info', $testdata);
421
  }
422
 
423
  }
431
  $plugin_info = get_plugin_data(__FILE__, true, true);
432
  update_option('atlt_version', $plugin_info['Version'] );
433
  update_option("atlt-installDate",date('Y-m-d h:i:s') );
434
+ update_option("atlt-already-rated","no");
435
  update_option("atlt-type","free");
436
  }
 
 
 
437
  /*
438
  |-------------------------------------------------------
439
  | Plugin deactivation
440
  |-------------------------------------------------------
441
  */
442
  public function atlt_deactivate(){
 
443
  }
 
444
  }
445
 
446
  $atlt=new LocoAutoTranslate();
includes/Core/class.settings-api.php CHANGED
@@ -523,7 +523,7 @@ class Settings_API {
523
  ?>
524
  <div class="metabox-holder">
525
  <?php foreach ( $this->settings_sections as $form ) { ?>
526
- <div id="<?php echo $form['id']; ?>" class="group" style="display: none;">
527
  <form method="post" action="options.php">
528
  <?php
529
  do_action( 'wsa_form_top_' . $form['id'], $form );
@@ -540,6 +540,65 @@ class Settings_API {
540
  </div>
541
  <?php } ?>
542
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  <?php
544
  $this->script();
545
  }
523
  ?>
524
  <div class="metabox-holder">
525
  <?php foreach ( $this->settings_sections as $form ) { ?>
526
+ <div style="width:80%;float:left;" id="<?php echo $form['id']; ?>" class="group" style="display: none;">
527
  <form method="post" action="options.php">
528
  <?php
529
  do_action( 'wsa_form_top_' . $form['id'], $form );
540
  </div>
541
  <?php } ?>
542
  </div>
543
+ <div style="max-width:320px;float:right;" class="loco-settings-custom-sidebar">
544
+
545
+ <?php
546
+ $license_key=get_option("LocoAutomaticTranslateAddonPro_lic_Key","");
547
+ $is_pro_active=is_plugin_active('loco-automatic-translate-addon-pro/loco-automatic-translate-addon-pro.php');
548
+ $license_type=get_option('atlt-type');
549
+ $download_url =esc_url( add_query_arg( 'license-key',$license_key , 'https://locotranslate.com/data/download-plugin.php' ) );
550
+
551
+ if($license_type=='pro' && $license_key!= '' && $is_pro_active) {
552
+ ?>
553
+ <h2>Welcome! Loco Automatic Translate Addon</h2>
554
+ <p>Dear Premium User,<br/><br/>We know that machine translation is not perfect as compare to human translation but you can save a lot of your valuable time using automated translations. If you face any issue while using this plugin, you can contact our premium support staff below.</p>
555
+ <p><a href="mailto:contact@coolplugins.net" class="button button-secondary">Contact@CoolPlugins.net</a></p>
556
+ <p>We hope our plugin helped you a little by automating your plugins and themes strings translation process. If you like it, please share some feedback for our team below.</p>
557
+ <p><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" class="button button-primary">Submit Review! ★★★★★</a></p>
558
+ <h2>Important Notice & Links</h2>
559
+ <p>Plugin do not provide any free translation limit, it only provides setting panel to use third party translate APIs. All free characters translation limit provided by third party translate API providers - <strong>Google, Microsoft, Yandex etc.</strong> You can grab translate API keys from these providers by following below instructions.</p>
560
+ <p><a style="font-size:12px" href="https://locotranslate.com/howto-generate-google-translate-api-key/" target="_blank" class="button button-secondary">Generate Google Translate API Key</a></p>
561
+ <p><a style="font-size:12px" href="https://locotranslate.com/how-to-generate-microsoft-translator-api-key/" target="_blank" class="button button-secondary">Generate Microsoft Translate API Key</a></p>
562
+ <p><a style="font-size:12px" href="https://tech.yandex.com/translate/" target="_blank" class="button button-secondary">Generate Yandex Translate API Key</a></p>
563
+ <?php
564
+ }
565
+ else if($is_pro_active && $license_key== ''){
566
+ ?>
567
+ <h2>Enter License Key</h2>
568
+ <p>Dear User,<br/><br/>You have installed and activated <strong>Loco Automatic Translate Addon Pro</strong> plugin but didn't enter pro license key. Please add pro license key to enjoy all premium features.</p>
569
+ <p><a href="?page=loco-atlt-register" class="button button-primary">Enter License Key</a></p>
570
+ <?php
571
+ }
572
+ else if($is_pro_active==false && $license_key!= ''){
573
+ ?>
574
+ <h2>Install Loco Automatic Translate Addon Pro</h2>
575
+ <p>Dear User,<br/><br/>You have activated pro license but didn't install <strong>Loco Automatic Translate Addon Pro</strong> plugin files. Please install and activate Loco Automatic Translate Addon Pro to enjoy all premium features.</p>
576
+ <p><a href="<?php echo $download_url ?>" target="_blank" class="button button-primary">Download Pro Plugin</a></p>
577
+ <p>or visit<br/><a href="https://locotranslate.com/my-account/downloads/" target="_blank">https://locotranslate.com/my-account/downloads/</a></p>
578
+ <?php
579
+ }
580
+ else {
581
+ ?>
582
+ <h2>Welcome! Loco Automatic Translate Addon</h2>
583
+ <p>Dear User,<br/><br/>You are currently using Loco Automatic Translate Addon free license. If you face any issue, please submit a support ticket below.</p>
584
+ <p><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/" target="_blank" class="button button-secondary">Submit Support Ticket</a><br/>(Response time - 4 to 7 days for free users)</p>
585
+ <h2>Upgrade Pro! Use Awesome Features</h2>
586
+ <ul>
587
+ <li>Google Translate API.</li>
588
+ <li>Microsoft Translate API.</li>
589
+ <li>Google & Microsoft automated translations are 70% better than Yandex.</li>
590
+ <li>Google Translate provides 500,000 Char / Month free for automated translations while Microsoft Translate provides free 2,000,000 Char / Month</li>
591
+ <li>Reset translations with one click.</li>
592
+ <li>HTML translations support via Yandex API.</li>
593
+ <li>Regular updates with new features</li>
594
+ <li>Premium support via email.</li>
595
+ </ul>
596
+ <p><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/" target="_blank" class="button button-primary">Buy Pro ($18 - $88)</a></p>
597
+ <?php
598
+ }
599
+ ?>
600
+ </div>
601
+
602
  <?php
603
  $this->script();
604
  }
includes/Core/class.settings-panel.php CHANGED
@@ -30,6 +30,7 @@ if( !class_exists( 'Settings_Panel' ) ){
30
  $this->settings_api->set_sections( $this->get_settings_sections() );
31
  $this->settings_api->set_fields( $this->get_settings_fields() );
32
  $this->settings_api->admin_init();
 
33
  }
34
 
35
  /*
@@ -40,7 +41,6 @@ if( !class_exists( 'Settings_Panel' ) ){
40
  public function get_settings_sections()
41
  {
42
  $sections = array(
43
-
44
  array(
45
  'id' => $this->PREFIX.'register',
46
  'title' => __('Loco Automatic Translate Addon Settings', 'cmb2'),
@@ -66,7 +66,7 @@ if( !class_exists( 'Settings_Panel' ) ){
66
  <tr>
67
  <td><strong>Used Characters</strong></td>
68
  <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
69
- <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit. All free characters translation limit provided by translate API providers - Google, Yendex, Microsoft etc.</td>
70
  </tr>
71
  <tr>
72
  <td><strong>Available Characters</strong></td>
@@ -78,6 +78,70 @@ if( !class_exists( 'Settings_Panel' ) ){
78
  }
79
 
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /*
82
  |--------------------------------------------------------------------
83
  | return all settings fields to be initialized in settings page
@@ -85,7 +149,6 @@ if( !class_exists( 'Settings_Panel' ) ){
85
  */
86
  public function get_settings_fields()
87
  {
88
-
89
  $month = get_option('atlt_translation_month');
90
  $today = ('atlt_translation_day');
91
  $total_translation = get_option('atlt_month_translated_chars', 0);
@@ -149,9 +212,17 @@ if( !class_exists( 'Settings_Panel' ) ){
149
  $pro_per_mon=10000000;
150
  $pro_info='<table>
151
  <tr>
152
- <th><a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank">Buy Pro License Key</a></th>
153
- <th>'.number_format($pro_per_day).' / Day</th>
154
- <th>'.number_format($pro_per_mon).' / Month</th>
 
 
 
 
 
 
 
 
155
  </tr>
156
  </table>';
157
 
@@ -159,13 +230,53 @@ if( !class_exists( 'Settings_Panel' ) ){
159
  'name' => $this->PREFIX.'api-key',
160
  'id' => $this->PREFIX.'api-key',
161
  'class' => $this->PREFIX.'settings-field',
162
- 'label' => 'Enter Yendex Translate<br/>API Key:',
163
- 'desc' => '<a target="_blank" href="https://tech.yandex.com/translate/">Click here to get free Yendex API key.</a><br/>',
164
  'type' => 'text',
165
- 'placeholder'=>__('Yendex API Key','cmb2'),
166
  'default' => ''
167
  );
168
- if(Helpers::userType()=="pro") {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  $key=Helpers::getLicenseKey();
170
  if(Helpers::validKey( $key)){
171
  $settingArr[]=array(
@@ -173,11 +284,21 @@ if( !class_exists( 'Settings_Panel' ) ){
173
  'id' => $this->PREFIX.'google-api-key',
174
  'class' => $this->PREFIX.'settings-field',
175
  'label' => 'Enter Google Translate<br>API Key:',
176
- 'desc' => '<a href="https://locotranslate.com/howto-generate-google-translate-api-key/">Please check API key generation guide</a>',
177
  'type' => 'text',
178
  'placeholder'=>__('Google Translate API Key','cmb2'),
179
  'default' => ''
180
  );
 
 
 
 
 
 
 
 
 
 
181
  }
182
  }else{
183
  $settingArr[]=
@@ -189,13 +310,22 @@ if( !class_exists( 'Settings_Panel' ) ){
189
  'desc' =>'<a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/google-api.png" alt="Add Google Translate API Key"></a>',
190
  'type' => 'html'
191
  );
 
 
 
 
 
 
 
 
 
192
  }
193
  $settingArr[]= array(
194
  'name' => $this->PREFIX.'index-per-request',
195
  'id' => $this->PREFIX.'index-per-request',
196
  'class' => $this->PREFIX.'settings-field',
197
  'label' => 'Index Per Request:',
198
- 'desc' => 'Number of strings index to send to Yendex in every request. Decrease it if you have long strings inside your loco translate table fields.'.$this->welcome_tab(),
199
  'type' => 'number',
200
  'placeholder'=>__('50','cmb2'),
201
  'default' => '50'
@@ -205,12 +335,22 @@ if( !class_exists( 'Settings_Panel' ) ){
205
  // if(Helpers::userType()=="pro") {
206
 
207
  // }
 
 
 
 
 
 
 
 
 
 
208
  $settingArr[]=
209
  array(
210
  'name' => $this->PREFIX.'traslation-limit',
211
  'id' => $this->PREFIX.'traslation-limit',
212
  'class' => $this->PREFIX.'settings-field',
213
- 'label' => 'Yendex Translate<br>Free Translation Limit:',
214
  'desc' => $info_tbl,
215
  'type' => 'html'
216
  );
@@ -219,12 +359,14 @@ if( !class_exists( 'Settings_Panel' ) ){
219
  'name' => $this->PREFIX.'upgrade-to-pro',
220
  'id' => $this->PREFIX.'upgrade-to-pro',
221
  'class' => $this->PREFIX.'settings-field',
222
- 'label' => 'Increase Translation Limit:',
223
  'desc' => $pro_info,
224
  'type' => 'html'
225
  );
226
  }else{
227
 
 
 
228
  $settingArr[]= array(
229
  'name' => $this->PREFIX.'google-traslation-limit',
230
  'id' => $this->PREFIX.'google-traslation-limit',
@@ -232,7 +374,16 @@ if( !class_exists( 'Settings_Panel' ) ){
232
  'label' => 'Google Translate<br>Free Translation Limit:',
233
  'desc' =>$this->create_google_stats_tbl(),
234
  'type' => 'html'
235
- );
 
 
 
 
 
 
 
 
 
236
  }
237
  $settingArr[]= array(
238
  'name' => $this->PREFIX.'license-status',
@@ -242,13 +393,7 @@ if( !class_exists( 'Settings_Panel' ) ){
242
  'desc' => $LS_html,
243
  'type' => 'html'
244
  );
245
- $settingArr[]= array(
246
- 'name' => $this->PREFIX.'rating',
247
- 'id' => $this->PREFIX.'rating',
248
- 'label' => 'Share Your Review:',
249
- 'desc' => $this->rate_now(),
250
- 'type' => 'html'
251
- );
252
  $settingArr[]= array(
253
  'name' => $this->PREFIX.'screenshort',
254
  'id' => $this->PREFIX.'screenshort',
@@ -264,7 +409,7 @@ if( !class_exists( 'Settings_Panel' ) ){
264
 
265
  public function welcome_tab(){
266
  //$this->ce_get_option($this->PREFIX.'-api-key');
267
- return get_submit_button('Save');
268
 
269
  }
270
 
@@ -281,7 +426,7 @@ if( !class_exists( 'Settings_Panel' ) ){
281
  public function screenshort(){
282
 
283
  $src = ATLT_URL .'assets/images/screenshot-1.gif';
284
- $html = '<img src="'.$src.'" width="100%">';
285
 
286
  return $html;
287
  }
@@ -336,21 +481,14 @@ if( !class_exists( 'Settings_Panel' ) ){
336
  // Show API message only in translation editor page
337
  if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit' ){
338
  $plugin_info = get_plugin_data( ATLT_FILE , true, true );
339
-
340
  $message = sprintf('You must provide an %s to use the functionality of <strong>%s</strong>','<a href="'.admin_url('admin.php?page=loco-atlt').'">API key</a>',$plugin_info['Name']);
341
-
342
- $translation = __($message,'atlt');
343
-
344
  $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
345
  echo $HTML;
346
  }else if( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'loco-atlt' ){
347
-
348
  $message = sprintf('Get a free API KEY from %s and save it below to enable the Auto Translation feature.','<a href="https://tech.yandex.com/translate/" target="_blank">Yandex.com</a>');
349
-
350
- $translation = __($message,'atlt');
351
-
352
  $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
353
-
354
  echo $HTML;
355
  }
356
  }
30
  $this->settings_api->set_sections( $this->get_settings_sections() );
31
  $this->settings_api->set_fields( $this->get_settings_fields() );
32
  $this->settings_api->admin_init();
33
+
34
  }
35
 
36
  /*
41
  public function get_settings_sections()
42
  {
43
  $sections = array(
 
44
  array(
45
  'id' => $this->PREFIX.'register',
46
  'title' => __('Loco Automatic Translate Addon Settings', 'cmb2'),
66
  <tr>
67
  <td><strong>Used Characters</strong></td>
68
  <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
69
+ <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit. All free characters translation limit provided by translate API provider - <strong>Google</strong></td>
70
  </tr>
71
  <tr>
72
  <td><strong>Available Characters</strong></td>
78
  }
79
 
80
 
81
+ public function create_microsoft_stats_tbl(){
82
+ $month = get_option('m_translation_month');
83
+ $total_translation = get_option('m_month_translated_chars', 0);
84
+ $a_per_mon=0;
85
+ $total_aval=0;
86
+ $a_per_mon=2000000;
87
+ $total_aval=$a_per_mon-$total_translation;
88
+ $info_tbl='<table>
89
+ <tr>
90
+ <th>Total Characters</th>
91
+ <th>'.number_format($a_per_mon).' / Month</th>
92
+ <th>Special Note</th>
93
+ </tr>
94
+ <tr>
95
+ <td><strong>Used Characters</strong></td>
96
+ <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
97
+ <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit. All free characters translation limit provided by translate API provider - <strong>Microsoft</strong></td>
98
+ </tr>
99
+ <tr>
100
+ <td><strong>Available Characters</strong></td>
101
+ <td>'.number_format($total_aval).'<br/><span>(Available This Month)</span></td>
102
+ </tr>
103
+ </table>
104
+ *Check your correct translation limit usage inside API dashboard if you are using same API key on multiple sites.';
105
+ return $info_tbl;
106
+ }
107
+
108
+ public function APIIntegrationTesting($name){
109
+ $output='';
110
+ $desc='';
111
+ $sourceLang='en';
112
+ $targetLang='fr';
113
+ $rawString='Hello World';
114
+ $ajax_url= admin_url( 'admin-ajax.php' );
115
+ $nonce= wp_create_nonce('atlt_nonce');
116
+ if($name=="microsoft"){
117
+ $apiKey= Helpers::getAPIkey("microsoft");
118
+ $lbl='Microsoft Translation';
119
+ $desc='<a target="_blank" href="https://locotranslate.com/how-to-generate-microsoft-translator-api-key/">Check Microsoft Translator API key generation guide.</a>';
120
+ }else if($name=="google"){
121
+ $apiKey= Helpers::getAPIkey("google");
122
+ $lbl='Google Translation';
123
+ $desc= '<a target="_blank" href="https://locotranslate.com/howto-generate-google-translate-api-key/">Check Google Translator API key generation guide.</a>';
124
+ }else{
125
+ $apiKey= Helpers::getAPIkey("yandex");
126
+ $lbl='Yandex Translation';
127
+ $desc='<a target="_blank" href="https://tech.yandex.com/translate/">Click here to get Yandex Translator free API key.</a>';
128
+ }
129
+ if($apiKey){
130
+ $output .='<div><a class="atlt_test_api button button-primary button-small"
131
+ data-source="'.$sourceLang.'"
132
+ data-nonce="'.$nonce.'"
133
+ data-target="'.$targetLang.'"
134
+ data-text="'.$rawString.'"
135
+ data-apikey="'.$apiKey.'"
136
+ data-api-provider="'.$name.'"
137
+ data-ajaxurl="'.$ajax_url.'"
138
+ href="#"><span class="dashicons dashicons-translation"></span> Test '.$lbl.' API </a> <img style="display:none;width:24px;height:24px;" class="atlt-preloader" src="'.ATLT_URL.'/assets/images/preloader.gif"></div>';
139
+ }else{
140
+ $output.=$desc;
141
+ }
142
+
143
+ return $output;
144
+ }
145
  /*
146
  |--------------------------------------------------------------------
147
  | return all settings fields to be initialized in settings page
149
  */
150
  public function get_settings_fields()
151
  {
 
152
  $month = get_option('atlt_translation_month');
153
  $today = ('atlt_translation_day');
154
  $total_translation = get_option('atlt_month_translated_chars', 0);
212
  $pro_per_mon=10000000;
213
  $pro_info='<table>
214
  <tr>
215
+ <th>Yandex Translate API<br/>(Free Char Limit)</th>
216
+ <td style="min-width:200px;">'.number_format($pro_per_day).' / Day<br/>'.number_format($pro_per_mon).' / Month</td>
217
+ <td rowspan="3" style="max-width:200px;"><p>Free characters translation limit only provided by Translate API providers, e.g. - Google, Microsoft, Yandex etc.<br/>Plugin do not provide any free characters limit for automatic translations.</p></td>
218
+ </tr>
219
+ <tr>
220
+ <th>Google Translate API<br/>(Free Char Limit)</th>
221
+ <td style="min-width:200px;">'.number_format(500000).' / Month</td>
222
+ </tr>
223
+ <tr>
224
+ <th>Microsoft Translator API<br/>(Free Char Limit)</th>
225
+ <td style="min-width:200px;">'.number_format(2000000).' / Month</td>
226
  </tr>
227
  </table>';
228
 
230
  'name' => $this->PREFIX.'api-key',
231
  'id' => $this->PREFIX.'api-key',
232
  'class' => $this->PREFIX.'settings-field',
233
+ 'label' => 'Enter Yandex Translate<br/>API Key:',
234
+ 'desc' =>$this->APIIntegrationTesting("yandex"),
235
  'type' => 'text',
236
+ 'placeholder'=>__('Yandex API Key','cmb2'),
237
  'default' => ''
238
  );
239
+ if(Helpers::userType()=="pro" && Helpers::proInstalled()==false) {
240
+ $key=Helpers::getLicenseKey();
241
+ $url =esc_url( add_query_arg( 'license-key',$key , 'https://locotranslate.com/data/download-plugin.php' ) );
242
+
243
+ $settingArr[]=array(
244
+ 'name' => $this->PREFIX.'install-pro',
245
+ 'id' => $this->PREFIX.'install-pro',
246
+ 'class' => $this->PREFIX.'settings-field',
247
+ 'label' => 'Please Activate Or Download and Install PRO version',
248
+ 'desc' =>'<a href="'.$url.'" target="_blank">Loco Automatic Translate Addon Pro</a>',
249
+ 'type' => 'html',
250
+
251
+ 'default' => ''
252
+ );
253
+ }else if(Helpers::proInstalled()==true && Helpers::getLicenseKey()==false) {
254
+ $settings_page_link=esc_url( get_admin_url(null, 'admin.php?page=loco-atlt-register') );
255
+ $notice=__('Please add <strong>Loco Automatic Translate Addon Pro license key</strong> in the settings panel.', 'loco-translate-addon');
256
+ $settingArr[]=
257
+ array(
258
+ 'name' => $this->PREFIX.'google-api-key-demo-2',
259
+ 'id' => $this->PREFIX.'google-api-key-demo-2',
260
+ 'class' => $this->PREFIX.'settings-field',
261
+ 'label' => 'Enter Google Translate<br>API Key:',
262
+ 'desc' =>'<div class=""><p>'.$notice.'</p>
263
+ <p><a class="button button-secondary" href="'.$settings_page_link.'">'.__('Add License Key & Activate Premium Features').'</a>
264
+ </p></div>',
265
+ 'type' => 'html'
266
+ );
267
+ $settingArr[]=
268
+ array(
269
+ 'name' => $this->PREFIX.'microsoft-api-key-demo-2',
270
+ 'id' => $this->PREFIX.'microsoft-api-key-demo-2',
271
+ 'class' => $this->PREFIX.'settings-field',
272
+ 'label' => 'Enter Microsoft Translator<br>API Key:',
273
+ 'desc' =>'<div class=""><p>'.$notice.'</p>
274
+ <p><a class="button button-secondary" href="'.$settings_page_link.'">'.__('Add License Key & Activate Premium Features').'</a>
275
+ </p></div>',
276
+ 'type' => 'html'
277
+ );
278
+
279
+ }else if(Helpers::userType()=="pro") {
280
  $key=Helpers::getLicenseKey();
281
  if(Helpers::validKey( $key)){
282
  $settingArr[]=array(
284
  'id' => $this->PREFIX.'google-api-key',
285
  'class' => $this->PREFIX.'settings-field',
286
  'label' => 'Enter Google Translate<br>API Key:',
287
+ 'desc' =>$this->APIIntegrationTesting("google"),
288
  'type' => 'text',
289
  'placeholder'=>__('Google Translate API Key','cmb2'),
290
  'default' => ''
291
  );
292
+ $settingArr[]=array(
293
+ 'name' => $this->PREFIX.'microsoft-api-key',
294
+ 'id' => $this->PREFIX.'microsoft-api-key',
295
+ 'class' => $this->PREFIX.'settings-field',
296
+ 'label' => 'Enter Microsoft Translator<br>Subscription Key:',
297
+ 'desc' => $this->APIIntegrationTesting("microsoft"),
298
+ 'type' => 'text',
299
+ 'placeholder'=>__('Microsoft Translator Subscription Key','cmb2'),
300
+ 'default' => ''
301
+ );
302
  }
303
  }else{
304
  $settingArr[]=
310
  'desc' =>'<a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/google-api.png" alt="Add Google Translate API Key"></a>',
311
  'type' => 'html'
312
  );
313
+ $settingArr[]=
314
+ array(
315
+ 'name' => $this->PREFIX.'microsoft-api-key-demo',
316
+ 'id' => $this->PREFIX.'microsoft-api-key-demo',
317
+ 'class' => $this->PREFIX.'settings-field',
318
+ 'label' => 'Enter Microsoft Translator<br>API Key:',
319
+ 'desc' =>'<a href="https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/microsoft-api.png" alt="Add Microsoft Translator API Key"></a>',
320
+ 'type' => 'html'
321
+ );
322
  }
323
  $settingArr[]= array(
324
  'name' => $this->PREFIX.'index-per-request',
325
  'id' => $this->PREFIX.'index-per-request',
326
  'class' => $this->PREFIX.'settings-field',
327
  'label' => 'Index Per Request:',
328
+ 'desc' => 'Number of strings index to send to Translate API in every request.<br/>Decrease it if you have long strings inside your loco translate table fields.'.$this->welcome_tab(),
329
  'type' => 'number',
330
  'placeholder'=>__('50','cmb2'),
331
  'default' => '50'
335
  // if(Helpers::userType()=="pro") {
336
 
337
  // }
338
+
339
+ $settingArr[]=
340
+ array(
341
+ 'name' => $this->PREFIX.'supported-lang-list',
342
+ 'id' => $this->PREFIX.'supported-lang-list',
343
+ 'class' => $this->PREFIX.'settings-field',
344
+ 'label' => 'Supported Languages List',
345
+ 'desc' =>'<a target="_blank" href="https://locotranslate.com/supported-languages/">Click here to view All Supported Languages</a>',
346
+ 'type' => 'html'
347
+ );
348
  $settingArr[]=
349
  array(
350
  'name' => $this->PREFIX.'traslation-limit',
351
  'id' => $this->PREFIX.'traslation-limit',
352
  'class' => $this->PREFIX.'settings-field',
353
+ 'label' => 'Yandex Translate<br>Free Translation Limit:',
354
  'desc' => $info_tbl,
355
  'type' => 'html'
356
  );
359
  'name' => $this->PREFIX.'upgrade-to-pro',
360
  'id' => $this->PREFIX.'upgrade-to-pro',
361
  'class' => $this->PREFIX.'settings-field',
362
+ 'label' => 'Increase Translation Limit<br/>Using Pro License:',
363
  'desc' => $pro_info,
364
  'type' => 'html'
365
  );
366
  }else{
367
 
368
+ if(Helpers::proInstalled()==true) {
369
+
370
  $settingArr[]= array(
371
  'name' => $this->PREFIX.'google-traslation-limit',
372
  'id' => $this->PREFIX.'google-traslation-limit',
374
  'label' => 'Google Translate<br>Free Translation Limit:',
375
  'desc' =>$this->create_google_stats_tbl(),
376
  'type' => 'html'
377
+ );
378
+ $settingArr[]= array(
379
+ 'name' => $this->PREFIX.'microsoft-traslation-limit',
380
+ 'id' => $this->PREFIX.'microsoft-traslation-limit',
381
+ 'class' => $this->PREFIX.'settings-field',
382
+ 'label' => 'Microsoft Translator<br>Free Translation Limit:',
383
+ 'desc' =>$this->create_microsoft_stats_tbl(),
384
+ 'type' => 'html'
385
+ );
386
+ }
387
  }
388
  $settingArr[]= array(
389
  'name' => $this->PREFIX.'license-status',
393
  'desc' => $LS_html,
394
  'type' => 'html'
395
  );
396
+
 
 
 
 
 
 
397
  $settingArr[]= array(
398
  'name' => $this->PREFIX.'screenshort',
399
  'id' => $this->PREFIX.'screenshort',
409
 
410
  public function welcome_tab(){
411
  //$this->ce_get_option($this->PREFIX.'-api-key');
412
+ return get_submit_button('Save Settings');
413
 
414
  }
415
 
426
  public function screenshort(){
427
 
428
  $src = ATLT_URL .'assets/images/screenshot-1.gif';
429
+ $html = '<img src="'.$src.'" style="width:auto;max-width:100%;">';
430
 
431
  return $html;
432
  }
481
  // Show API message only in translation editor page
482
  if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit' ){
483
  $plugin_info = get_plugin_data( ATLT_FILE , true, true );
 
484
  $message = sprintf('You must provide an %s to use the functionality of <strong>%s</strong>','<a href="'.admin_url('admin.php?page=loco-atlt').'">API key</a>',$plugin_info['Name']);
485
+ $translation = __($message,'loco-translate-addon');
 
 
486
  $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
487
  echo $HTML;
488
  }else if( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'loco-atlt' ){
 
489
  $message = sprintf('Get a free API KEY from %s and save it below to enable the Auto Translation feature.','<a href="https://tech.yandex.com/translate/" target="_blank">Yandex.com</a>');
490
+ $translation = __($message,'loco-translate-addon');
 
 
491
  $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
 
492
  echo $HTML;
493
  }
494
  }
includes/Feedback/class.feedback-form.php CHANGED
@@ -98,7 +98,7 @@ class FeedbackForm{
98
  <?php endif; ?>
99
  </div>
100
  <?php endforeach; ?>
101
- <input class="cool-plugins-GDPR-data-notice" id="cool-plugins-GDPR-data-notice" type="checkbox"><label for="cool-plugins-GDPR-data-notice"><?php echo __('I consent to having Cool Plugins store my all submitted information via this form, they can also respond to my inquiry.','cool-plugins');?></label>
102
  </div>
103
  <div class="cool-plugin-popup-button-wrapper">
104
  <a class="cool-plugins-button button-deactivate" id="cool-plugin-submitNdeactivate">Submit and Deactivate</a>
98
  <?php endif; ?>
99
  </div>
100
  <?php endforeach; ?>
101
+ <input class="cool-plugins-GDPR-data-notice" id="cool-plugins-GDPR-data-notice" type="checkbox"><label for="cool-plugins-GDPR-data-notice"><?php echo __('I consent to having <a href="https://coolplugins.net" target="_blank">Cool Plugins</a> store my email-id and other information submitted via this form, they can also respond to my inquiry.','cool-plugins');?></label>
102
  </div>
103
  <div class="cool-plugin-popup-button-wrapper">
104
  <a class="cool-plugins-button button-deactivate" id="cool-plugin-submitNdeactivate">Submit and Deactivate</a>
includes/Helpers/Helpers.php CHANGED
@@ -3,17 +3,15 @@ namespace LocoAutoTranslateAddon\Helpers;
3
  /**
4
  * @package Loco Automatic Translate Addon
5
  */
6
-
7
  class Helpers{
8
-
9
- /*
10
  |----------------------------------------------------------------------------|
11
  | Delete or update per day translated charachter stats |
12
  | @param $value int current translated character to update in database |
13
  |----------------------------------------------------------------------------|
14
  */
15
  // count today translated strings
16
- public static function todayTranslated($value = 0)
17
  {
18
  $now_translated = $value;
19
  if (false===($today= get_transient('atlt_translation_day'))) {
@@ -28,8 +26,16 @@ class Helpers{
28
  }
29
  return $today_total_translated;
30
  }
 
 
 
 
 
 
 
 
31
  // count monthly translated strings
32
- public static function monthlyTranslated($value = 0){
33
  $now_translated=$value;
34
  if (false===($month= get_transient('atlt_translation_month'))) {
35
  delete_option('atlt_month_translated_chars');
@@ -43,37 +49,7 @@ class Helpers{
43
  }
44
  return $month_total_translated;
45
  }
46
- /* google chars stats*/
47
- public static function gTodayTranslated($value = 0)
48
- {
49
- $now_translated = $value;
50
- if (false===($today= get_transient('g_translation_day'))) {
51
- delete_option('g_perday_translated_chars');
52
- update_option('g_perday_translated_chars', $now_translated);
53
- set_transient('g_translation_day', 'true', DAY_IN_SECONDS);
54
- $today_total_translated=$now_translated;
55
- } else {
56
- $already_translated = intval(get_option('g_perday_translated_chars'));
57
- $today_total_translated = $already_translated+$now_translated;
58
- update_option('g_perday_translated_chars', $today_total_translated);
59
- }
60
- return $today_total_translated;
61
- }
62
- // count monthly translated strings
63
- public static function gMonthlyTranslated($value = 0){
64
- $now_translated=$value;
65
- if (false===($month= get_transient('g_translation_month'))) {
66
- delete_option('g_month_translated_chars');
67
- update_option('g_month_translated_chars',$now_translated);
68
- set_transient('g_translation_month', 'true', MONTH_IN_SECONDS);
69
- $month_total_translated=$now_translated;
70
- } else {
71
- $already_translated = intval(get_option('g_month_translated_chars'));
72
- $month_total_translated= $already_translated+$now_translated;
73
- update_option('g_month_translated_chars', $month_total_translated);
74
- }
75
- return $month_total_translated;
76
- }
77
  // check timing
78
  public static function checkPeriod(){
79
  $today=get_transient('atlt_translation_day');
@@ -100,7 +76,6 @@ class Helpers{
100
  }else{
101
  $allowed='yes';
102
  }
103
-
104
  }else{
105
  $today_chars=(int)get_option('atlt_perday_translated_chars');
106
  $info['today']= $today_chars;
@@ -112,7 +87,6 @@ class Helpers{
112
  $allowed='yes';
113
  }
114
  }
115
-
116
  $info['allowed']= $allowed;
117
  return $info;
118
  }
@@ -124,7 +98,6 @@ class Helpers{
124
  }else if(get_option('atlt-type')=='pro'){
125
  return $type='pro';
126
  }
127
-
128
  }
129
 
130
  public static function getAvailableChars($source)
@@ -134,6 +107,10 @@ class Helpers{
134
  $a_per_day=1000000;
135
  $today_total_translated = get_option('atlt_perday_translated_chars', 0);
136
  $availableChars=$a_per_day-$today_total_translated;
 
 
 
 
137
  }else{
138
  $a_per_mon=500000;
139
  $total_translation = get_option('g_month_translated_chars', 0);
@@ -141,7 +118,6 @@ class Helpers{
141
  }
142
  return $availableChars;
143
  }
144
-
145
  public static function getAPIkey($source){
146
  $key='';
147
  $keys_arr= get_option('atlt_register');
@@ -149,14 +125,18 @@ class Helpers{
149
  if(isset($keys_arr['atlt_google-api-key'])){
150
  $key=$keys_arr['atlt_google-api-key'];
151
  }
 
 
 
 
152
  }else{
153
  if(isset($keys_arr['atlt_api-key'])){
154
  $key=$keys_arr['atlt_api-key'];
155
  }
156
-
157
  }
158
  return $key;
159
  }
 
160
  // validate key
161
  public static function validKey($key){
162
  if (preg_match("/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/",$key)){
@@ -186,7 +166,6 @@ class Helpers{
186
  elseif ($n > 1000000000) return round(($n/1000000000), 2).' billion';
187
  elseif ($n > 1000000) return round(($n/1000000), 2).' million';
188
  elseif ($n > 1000) return round(($n/1000), 2).' thousand';
189
-
190
  return number_format($n);
191
  }
192
 
@@ -215,5 +194,17 @@ class Helpers{
215
  }
216
  }
217
 
 
 
 
 
 
 
218
 
 
 
 
 
 
 
219
  }
3
  /**
4
  * @package Loco Automatic Translate Addon
5
  */
 
6
  class Helpers{
7
+ /*
 
8
  |----------------------------------------------------------------------------|
9
  | Delete or update per day translated charachter stats |
10
  | @param $value int current translated character to update in database |
11
  |----------------------------------------------------------------------------|
12
  */
13
  // count today translated strings
14
+ public static function ytodayTranslated($value = 0)
15
  {
16
  $now_translated = $value;
17
  if (false===($today= get_transient('atlt_translation_day'))) {
26
  }
27
  return $today_total_translated;
28
  }
29
+
30
+ public static function proInstalled(){
31
+ if (is_plugin_active('loco-automatic-translate-addon-pro/loco-automatic-translate-addon-pro.php')) {
32
+ return true;
33
+ }else{
34
+ return false;
35
+ }
36
+ }
37
  // count monthly translated strings
38
+ public static function ymonthlyTranslated($value = 0){
39
  $now_translated=$value;
40
  if (false===($month= get_transient('atlt_translation_month'))) {
41
  delete_option('atlt_month_translated_chars');
49
  }
50
  return $month_total_translated;
51
  }
52
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  // check timing
54
  public static function checkPeriod(){
55
  $today=get_transient('atlt_translation_day');
76
  }else{
77
  $allowed='yes';
78
  }
 
79
  }else{
80
  $today_chars=(int)get_option('atlt_perday_translated_chars');
81
  $info['today']= $today_chars;
87
  $allowed='yes';
88
  }
89
  }
 
90
  $info['allowed']= $allowed;
91
  return $info;
92
  }
98
  }else if(get_option('atlt-type')=='pro'){
99
  return $type='pro';
100
  }
 
101
  }
102
 
103
  public static function getAvailableChars($source)
107
  $a_per_day=1000000;
108
  $today_total_translated = get_option('atlt_perday_translated_chars', 0);
109
  $availableChars=$a_per_day-$today_total_translated;
110
+ }else if($source=="microsoft"){
111
+ $a_per_mon=2000000;
112
+ $total_translation = get_option('m_month_translated_chars', 0);
113
+ $availableChars=$a_per_mon-$total_translation;
114
  }else{
115
  $a_per_mon=500000;
116
  $total_translation = get_option('g_month_translated_chars', 0);
118
  }
119
  return $availableChars;
120
  }
 
121
  public static function getAPIkey($source){
122
  $key='';
123
  $keys_arr= get_option('atlt_register');
125
  if(isset($keys_arr['atlt_google-api-key'])){
126
  $key=$keys_arr['atlt_google-api-key'];
127
  }
128
+ }else if($source=="microsoft"){
129
+ if(isset($keys_arr['atlt_microsoft-api-key'])){
130
+ $key=$keys_arr['atlt_microsoft-api-key'];
131
+ }
132
  }else{
133
  if(isset($keys_arr['atlt_api-key'])){
134
  $key=$keys_arr['atlt_api-key'];
135
  }
 
136
  }
137
  return $key;
138
  }
139
+
140
  // validate key
141
  public static function validKey($key){
142
  if (preg_match("/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/",$key)){
166
  elseif ($n > 1000000000) return round(($n/1000000000), 2).' billion';
167
  elseif ($n > 1000000) return round(($n/1000000), 2).' million';
168
  elseif ($n > 1000) return round(($n/1000), 2).' thousand';
 
169
  return number_format($n);
170
  }
171
 
194
  }
195
  }
196
 
197
+ public static function yandexSLangList($langCode,$list=false){
198
+ $json_lang_list='{"af":"Afrikaans","am":"Amharic","ar":"Arabic","az":"Azerbaijani","ba":"Bashkir","be":"Belarusian","bg":"Bulgarian","bn":"Bengali","bs":"Bosnian","ca":"Catalan","ceb":"Cebuano","cs":"Czech","cy":"Welsh","da":"Danish","de":"German","el":"Greek","en":"English","eo":"Esperanto","es":"Spanish","et":"Estonian","eu":"Basque","fa":"Persian","fi":"Finnish","fr":"French","ga":"Irish","gd":"Scottish Gaelic","gl":"Galician","gu":"Gujarati","he":"Hebrew","hi":"Hindi","hr":"Croatian","ht":"Haitian","hu":"Hungarian","hy":"Armenian","id":"Indonesian","is":"Icelandic","it":"Italian","ja":"Japanese","jv":"Javanese","ka":"Georgian","kk":"Kazakh","km":"Khmer","kn":"Kannada","ko":"Korean","ky":"Kyrgyz","la":"Latin","lb":"Luxembourgish","lo":"Lao","lt":"Lithuanian","lv":"Latvian","mg":"Malagasy","mhr":"Mari","mi":"Maori","mk":"Macedonian","ml":"Malayalam","mn":"Mongolian","mr":"Marathi","mrj":"Hill Mari","ms":"Malay","mt":"Maltese","my":"Burmese","ne":"Nepali","nl":"Dutch","no":"Norwegian","pa":"Punjabi","pap":"Papiamento","pl":"Polish","pt":"Portuguese","ro":"Romanian","ru":"Russian","si":"Sinhalese","sk":"Slovak","sl":"Slovenian","sq":"Albanian","sr":"Serbian","su":"Sundanese","sv":"Swedish","sw":"Swahili","ta":"Tamil","te":"Telugu","tg":"Tajik","th":"Thai","tl":"Tagalog","tr":"Turkish","tt":"Tatar","udm":"Udmurt","uk":"Ukrainian","ur":"Urdu","uz":"Uzbek","vi":"Vietnamese","xh":"Xhosa","yi":"Yiddish","zh":"Chinese"}';
199
+ $langArr=json_decode($json_lang_list,true);
200
+ if($list){
201
+ return $langArr;
202
+ }
203
 
204
+ if(isset($langArr[$langCode])){
205
+ return true;
206
+ }else{
207
+ return false;
208
+ }
209
+ }
210
  }
includes/Register/LocoAutomaticTranslateAddonPro.php CHANGED
@@ -156,12 +156,12 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
156
  <th>Premium License</th>
157
  </tr>
158
  <tr>
159
- <td>Yendex Translate API</td>
160
  <td>Available</td>
161
  <td>Available</td>
162
  </tr>
163
  <tr>
164
- <td>Yendex API - free translation limit</td>
165
  <td>300,000 char / day<br/>1,000,000 char / month</td>
166
  <td>1,000,000 char / day<br/>10,000,000 char / month</td>
167
  </tr>
@@ -175,9 +175,9 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
175
  <td>Not Available</td>
176
  <td>500,000 char / month</td>
177
  </tr>
178
- <td>Microsoft Translate API</td>
179
  <td>Not Available</td>
180
- <td>Coming Soon...</td>
181
  </tr>
182
  <tr>
183
  <td>Microsoft API - free translation limit</td>
@@ -187,7 +187,7 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
187
  <tr>
188
  <td>HTML Translation Support</td>
189
  <td>Not Available</td>
190
- <td>Available for Yendex API</td>
191
  </tr>
192
  <tr>
193
  <td>Reset Translations</td>
@@ -195,12 +195,13 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
195
  <td>Available</td>
196
  </tr>
197
  <td>Support</td>
198
- <td>Quick Support Via Email<br/><strong>contact@coolplugins.net</strong></td>
199
- <td>WordPress Free Forum Support!<br/><strong>(Support Time: 7 – 10 days)</strong></td>
200
  </tr>
201
  </table>
 
202
  <br/>
203
- <h3><a href='https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing' target='_blank'>Buy Premium License Key - <strong>($12 - $89)</strong></a></h3>
204
  <br/>
205
  <div class="el-license-field">
206
  <label for="el_license_key"><?php _e("Enter License code",$this->slug);?></label>
156
  <th>Premium License</th>
157
  </tr>
158
  <tr>
159
+ <td>Yandex Translate API</td>
160
  <td>Available</td>
161
  <td>Available</td>
162
  </tr>
163
  <tr>
164
+ <td>Yandex API - free translation limit</td>
165
  <td>300,000 char / day<br/>1,000,000 char / month</td>
166
  <td>1,000,000 char / day<br/>10,000,000 char / month</td>
167
  </tr>
175
  <td>Not Available</td>
176
  <td>500,000 char / month</td>
177
  </tr>
178
+ <td>Microsoft Translator API</td>
179
  <td>Not Available</td>
180
+ <td>Available</td>
181
  </tr>
182
  <tr>
183
  <td>Microsoft API - free translation limit</td>
187
  <tr>
188
  <td>HTML Translation Support</td>
189
  <td>Not Available</td>
190
+ <td>Available for Yandex API</td>
191
  </tr>
192
  <tr>
193
  <td>Reset Translations</td>
195
  <td>Available</td>
196
  </tr>
197
  <td>Support</td>
198
+ <td>WordPress Free Forum Support!<br/><strong>(Support Time: 7 – 10 days)</strong></td>
199
+ <td>Quick Support Via Email<br/><strong>contact@coolplugins.net</strong></td>
200
  </tr>
201
  </table>
202
+ <p>Free characters translation limit only provided by Translate API providers, e.g. - Google, Microsoft, Yandex etc.<br/>Plugin don't provide any free characters limit for automatic translations.</p>
203
  <br/>
204
+ <h3><a href='https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing' target='_blank'>Buy Premium License Key - <strong>($18 - $88)</strong></a></h3>
205
  <br/>
206
  <div class="el-license-field">
207
  <label for="el_license_key"><?php _e("Enter License code",$this->slug);?></label>
includes/ReviewNotice/class.review-notice.php CHANGED
@@ -29,7 +29,7 @@ if (!class_exists('ALTLReviewNotice')) {
29
  }
30
  // ajax callback for review notice
31
  public function atlt_dismiss_review_notice(){
32
- $rs=update_option( 'atlt-ratingDiv','yes' );
33
  echo json_encode( array("success"=>"true") );
34
  exit;
35
  }
@@ -41,7 +41,7 @@ if (!class_exists('ALTLReviewNotice')) {
41
  }
42
  // get installation dates and rated settings
43
  $installation_date = get_option( 'atlt-installDate' );
44
- $alreadyRated =get_option( 'atlt-ratingDiv' )!=false?get_option( 'atlt-ratingDiv'):"no";
45
  // check user already rated
46
  if( $alreadyRated=="yes") {
47
  return;
@@ -77,7 +77,7 @@ if (!class_exists('ALTLReviewNotice')) {
77
  $message="Thanks for using <b>$p_name</b> - WordPress plugin. We hope it has saved your valuable time and efforts! <br/>Please give us a quick rating, it works as a boost for us to keep working on more <a href='https://coolplugins.net' target='_blank'><strong>Cool Plugins</strong></a>!<br/>";
78
 
79
  $html='<div data-ajax-url="%8$s" data-ajax-callback="%9$s" class="cool-feedback-notice-wrapper %1$s">
80
- <div class="logo_container"><a href="%5$s"><img src="%2$s" alt="%3$s"></a></div>
81
  <div class="message_container">%4$s
82
  <div class="callto_action">
83
  <ul>
29
  }
30
  // ajax callback for review notice
31
  public function atlt_dismiss_review_notice(){
32
+ $rs=update_option( 'atlt-already-rated','yes' );
33
  echo json_encode( array("success"=>"true") );
34
  exit;
35
  }
41
  }
42
  // get installation dates and rated settings
43
  $installation_date = get_option( 'atlt-installDate' );
44
+ $alreadyRated =get_option( 'atlt-already-rated' )!=false?get_option( 'atlt-already-rated'):"no";
45
  // check user already rated
46
  if( $alreadyRated=="yes") {
47
  return;
77
  $message="Thanks for using <b>$p_name</b> - WordPress plugin. We hope it has saved your valuable time and efforts! <br/>Please give us a quick rating, it works as a boost for us to keep working on more <a href='https://coolplugins.net' target='_blank'><strong>Cool Plugins</strong></a>!<br/>";
78
 
79
  $html='<div data-ajax-url="%8$s" data-ajax-callback="%9$s" class="cool-feedback-notice-wrapper %1$s">
80
+ <div class="logo_container"><a href="%5$s"><img src="%2$s" alt="%3$s" style="max-width:80px;"></a></div>
81
  <div class="message_container">%4$s
82
  <div class="callto_action">
83
  <ul>
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
- === Loco Automatic Translate Addon ===
2
- Contributors:narinder-singh,satindersingh,coolplugins
3
  Donate link: https://paypal.me/CoolPlugins/10USD/
4
  Tags:loco,translate,translation,translator,localization,language,translations,loco translate,loco addon
5
  Requires at least:4.5
6
- Tested up to:5.3
7
  Requires PHP:5.6
8
  Stable tag:trunk
9
  License:GPLv2 or later
@@ -13,27 +13,33 @@ Automatic language translator add-on for Loco Translate plugin to translate Word
13
 
14
  == Description ==
15
 
 
 
 
 
16
  **Automatic Machine Translator Addon For Loco Translate**
17
 
18
- Install this plugin along with the famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** plugin (**1,000,000+ Active Installations**) and automatically machine translate any WordPress plugin or theme translation files into any language.
 
 
19
 
20
  = Loco Addon Features: =
21
  * One-click translate any plugin or theme all translatable strings.
22
- * You can automatic translate upto **300,000 characters** daily free of cost using Yendex API (you can extend this limit via [premium license key](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/)).
23
  * Check auto translations inside Loco build-in editor to manually edit any machine translated string.
24
  * This plugin uses **[Yandex.Translate](http://translate.yandex.com/)** API to auto translate plugin / theme language(po) files. Grab free api key:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
25
- * Pro version also supports Google Translate API.
26
 
27
  > “If you spend too much time thinking about a thing, you'll never get it done. Stop wasting time, complete work smartly & quickly!”
28
 
29
  = FREE v/s Premium License Key Comparison: =
30
  **Free License**
31
 
32
- * ✅ **Yendex Translate Support:** Available
33
- * ✅ **Yendex API Free Translation Limit:** 300,000 char / day<br/>1,000,000 char / month
34
  * ❌ **Google Translate Support:** Not Available
35
  * ❌ **Google API Free Translation Limit:** Not Available
36
- * ❌ **Microsoft Translate Support:** Not Available
37
  * ❌ **Microsoft API Free Translation Limit:** Not Available
38
  * ❌ **Reset Translations:** Not Available
39
  * ❌ **HTML Translations:** Not Available
@@ -41,19 +47,21 @@ Install this plugin along with the famous **[Loco Translate](https://wordpress.o
41
 
42
  **Premium License**
43
 
44
- * ✅ **Yendex Translate Support:** Available
45
- * ✅ **Yendex API Free Translation Limit:** 1,000,000 char / day<br/>10,000,000 char / month
46
  * ✅ **Google Translate Support:** Available
47
  * ✅ **Google API Free Translation Limit:** 500,000 char / month
48
- * ✅ **Microsoft Translate Support:** Coming soon...
49
  * ✅ **Microsoft API Free Translation Limit:** 2,000,000 char / month
50
  * ✅ **Reset Translations:** Available
51
- * ✅ **HTML Translations:** Available for Yendex Translate API
52
  * ✅ **Premium Support:** Quick support via email - contact@coolplugins.net (**Support time:- 24-48 hours**)
53
- * **Buy Premium License:** [$12 - $89](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing)
54
 
55
  > “Many people make the mistake of saving money by wasting time.”
56
 
 
 
57
  = Who's Behind: =
58
 
59
  This plugin is not developed by or affiliated with the "**Loco Translate**". It is a third party addon that provides automatic machine translations to quickly translate your theme or plugin language files.
@@ -63,48 +71,90 @@ We(**CoolPlugins.net**) only manage [LocoTranslate.com](https://locotranslate.co
63
  > We provide cool solutions to remove famous plugins limitations!
64
 
65
  = Special THANKS!: =
66
- Special thanks to famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** plugin authors for creating an awesome plugin for translations and Yendex for providing translate API.
67
 
68
- All automatic translations will machine translations, powered by Yendex Translate API, so we don't guarantee 100% correctness, please check all translated text carefully before making it live on your production site.
69
  [](http://coderisk.com/wp/plugin/automatic-translator-addon-for-loco-translate/RIPS-FN0AdXlllg)
70
  == Installation ==
71
  1. Install **Loco Automatic Translate Addon** from the WordPress.org repository or by uploading plugin-zip unzipped folder to the **/wp-content/plugins** directory. You must also install **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** free plugin if you want to use this addon.
72
 
73
  2. Activate the plugin through **Plugins >> Installed Plugin** menu in WordPress
74
 
75
- 3. After plugin activation you need to insert Yendex API key inside **Loco Translate >> Auto Translator Addon - Settings**. You can grab a free api key at here:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
76
 
77
  4. While editing any plugin or theme language file using Loco build-in editor, you will find an auto translator button at top to quickly translate all translatable strings with one-click.
78
 
79
- 5. If you want to use Google Translate API or Microsoft Translate API(coming soon...) then you need to purchase [premium license key](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/).
80
 
81
  == Frequently Asked Questions ==
82
  = How it works? =
83
- This plugin works as an addon for **Loco Translate** plugin. First you need to install and activate free version of "Loco translate" then install this addon and use one-click machine translations (supported by Yendex API).
84
 
85
  = Are you using any language translation API? =
86
- Free license users can only use - **[Yendex Translate API](https://tech.yandex.com/translate/)**, you can read more about its terms to use at here - https://yandex.com/legal/translate_api/
87
  Also grab a free API key at here:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
88
 
89
- But if you are using a premium license then you can also use Google Translate API and Microsoft Translate API(coming soon...)
 
90
 
91
  = Is there any translation limit? =
92
- **Free license** users:- can only translate 300,000 characters per day but not more than 1,000,000 per month using Yendex API.
93
- No support available for Google or Microsoft Translate API for free users.
94
 
95
- **Premium license** users:- can translate 1,000,000 characters per day but not more than 10,000,000 per month using Yendex API.
96
  Google Translate API provides free 500,000 char / month for translations.
97
- Microsoft Translate API provides free 2,000,000 char / month for translations.
98
 
99
- *This plugin does not provide free characters for translation. It only provides settings to manage translation APIs (Yendex, Google, Microsoft etc.). Free characters transaltion availability only depends on the API providers (Yendex, Google, Microsoft etc.) terms and they can change it anytime.
100
 
101
 
102
  == Screenshots ==
103
- 1. Automatic Loco Translate Addon
104
- 2. Translations Using Yendex API
105
  3. Free License v/s Premium License
 
106
 
107
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  <strong>Version 1.5 | 14 JAN 2020</strong>
109
  <pre>
110
  Added: Integrated Google Translation API Support
@@ -152,7 +202,7 @@ Added: Integrated Premium License key Manager
152
  Added: Added security checks in every request
153
  Added: Integrated nonce in ajax request
154
  Improved: Improved translation issues
155
- Improved: Imporved overall code
156
  Improved: readme.text
157
  Improved: Added new screenshots
158
  Fixed: Minor translation issues.
1
+ === Automatic Translate Addon For Loco Translate ===
2
+ Contributors:narinder-singh
3
  Donate link: https://paypal.me/CoolPlugins/10USD/
4
  Tags:loco,translate,translation,translator,localization,language,translations,loco translate,loco addon
5
  Requires at least:4.5
6
+ Tested up to:5.4
7
  Requires PHP:5.6
8
  Stable tag:trunk
9
  License:GPLv2 or later
13
 
14
  == Description ==
15
 
16
+ > **Important Notice:-** All features of this addon has been integrated inside **Loco Translate** official plugin (version 2.4.0+) so there is no requirement to use this addon along with Loco official plugin(2.4.0+), If you want to use this addon then Loco Translate official plugin version must be less than 2.4.0
17
+
18
+ **This addon is compatible with Loco Translate official plugin version less than 2.4.0**
19
+
20
  **Automatic Machine Translator Addon For Loco Translate**
21
 
22
+ Install this plugin along with the famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)**(< 2.4.0) plugin (**1,000,000+ Active Installations**) and automatically machine translate any WordPress plugin or theme translation files into any language.
23
+
24
+ This addon supports Yandex Translate API for free users and Yandex, Google & Microsoft Translator APIs for premium users.
25
 
26
  = Loco Addon Features: =
27
  * One-click translate any plugin or theme all translatable strings.
28
+ * You can automatic translate upto **300,000 characters** daily free of cost using Yandex API (you can extend this limit via [premium license key](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/)).
29
  * Check auto translations inside Loco build-in editor to manually edit any machine translated string.
30
  * This plugin uses **[Yandex.Translate](http://translate.yandex.com/)** API to auto translate plugin / theme language(po) files. Grab free api key:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
31
+ * Pro version also supports Google & Microsoft Translator APIs.
32
 
33
  > “If you spend too much time thinking about a thing, you'll never get it done. Stop wasting time, complete work smartly & quickly!”
34
 
35
  = FREE v/s Premium License Key Comparison: =
36
  **Free License**
37
 
38
+ * ✅ **Yandex Translate Support:** Available
39
+ * ✅ **Yandex API Free Translation Limit:** 300,000 char / day<br/>1,000,000 char / month
40
  * ❌ **Google Translate Support:** Not Available
41
  * ❌ **Google API Free Translation Limit:** Not Available
42
+ * ❌ **Microsoft Translator Support:** Not Available
43
  * ❌ **Microsoft API Free Translation Limit:** Not Available
44
  * ❌ **Reset Translations:** Not Available
45
  * ❌ **HTML Translations:** Not Available
47
 
48
  **Premium License**
49
 
50
+ * ✅ **Yandex Translate Support:** Available
51
+ * ✅ **Yandex API Free Translation Limit:** 1,000,000 char / day<br/>10,000,000 char / month
52
  * ✅ **Google Translate Support:** Available
53
  * ✅ **Google API Free Translation Limit:** 500,000 char / month
54
+ * ✅ **Microsoft Translator Support:** Available
55
  * ✅ **Microsoft API Free Translation Limit:** 2,000,000 char / month
56
  * ✅ **Reset Translations:** Available
57
+ * ✅ **HTML Translations:** Available for Yandex Translate API
58
  * ✅ **Premium Support:** Quick support via email - contact@coolplugins.net (**Support time:- 24-48 hours**)
59
+ * **Buy Premium License:** [$18 - $88](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/#pricing)
60
 
61
  > “Many people make the mistake of saving money by wasting time.”
62
 
63
+ https://www.youtube.com/watch?v=pjKNbkQNQDU
64
+
65
  = Who's Behind: =
66
 
67
  This plugin is not developed by or affiliated with the "**Loco Translate**". It is a third party addon that provides automatic machine translations to quickly translate your theme or plugin language files.
71
  > We provide cool solutions to remove famous plugins limitations!
72
 
73
  = Special THANKS!: =
74
+ Special thanks to famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** plugin authors **Tim** for creating an awesome plugin for translations, we have forked some js files from main Loco Translate plugin to create this addon and also thanks to Yandex for providing translate API.
75
 
76
+ All automatic translations will machine translations, powered by Yandex Translate API, so we don't guarantee 100% correctness, please check all translated text carefully before making it live on your production site.
77
  [](http://coderisk.com/wp/plugin/automatic-translator-addon-for-loco-translate/RIPS-FN0AdXlllg)
78
  == Installation ==
79
  1. Install **Loco Automatic Translate Addon** from the WordPress.org repository or by uploading plugin-zip unzipped folder to the **/wp-content/plugins** directory. You must also install **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** free plugin if you want to use this addon.
80
 
81
  2. Activate the plugin through **Plugins >> Installed Plugin** menu in WordPress
82
 
83
+ 3. After plugin activation you need to insert Yandex API key inside **Loco Translate >> Auto Translator Addon - Settings**. You can grab a free api key at here:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
84
 
85
  4. While editing any plugin or theme language file using Loco build-in editor, you will find an auto translator button at top to quickly translate all translatable strings with one-click.
86
 
87
+ 5. If you want to use Google Translate API or Microsoft Translator API then you need to purchase [premium license key](https://locotranslate.com/addon/loco-automatic-translate-premium-license-key/).
88
 
89
  == Frequently Asked Questions ==
90
  = How it works? =
91
+ This plugin works as an addon for **Loco Translate** plugin. First you need to install and activate free version of "Loco translate" then install this addon and use one-click machine translations (supported by Yandex API).
92
 
93
  = Are you using any language translation API? =
94
+ Free license users can only use - **[Yandex Translate API](https://tech.yandex.com/translate/)**, you can read more about its terms to use at here - https://yandex.com/legal/translate_api/
95
  Also grab a free API key at here:- [https://translate.yandex.com/developers/keys](https://translate.yandex.com/developers/keys)
96
 
97
+ API Terms Of Service :- [https://translate.yandex.com/developers/offer](https://translate.yandex.com/developers/offer)
98
+ But if you are using a premium license then you can also use Google Translate API and Microsoft Translator API
99
 
100
  = Is there any translation limit? =
101
+ **Free license** users:- can only translate 300,000 characters per day but not more than 1,000,000 per month using Yandex API.
102
+ No support available for Google or Microsoft Translator API for free users.
103
 
104
+ **Premium license** users:- can translate 1,000,000 characters per day but not more than 10,000,000 per month using Yandex API.
105
  Google Translate API provides free 500,000 char / month for translations.
106
+ Microsoft Translator API provides free 2,000,000 char / month for translations.
107
 
108
+ *This plugin does not provide free characters for translation. It only provides settings to manage translation APIs (Yandex, Google, Microsoft etc.). Free characters translation availability only depends on the API providers (Yandex, Google, Microsoft etc.) terms and they can change it anytime.
109
 
110
 
111
  == Screenshots ==
112
+ 1. Translate Using Yandex Translate API
113
+ 2. Loco Automatic Translate Addon Settings
114
  3. Free License v/s Premium License
115
+ 4. Free Translation Limit by API Providers
116
 
117
  == Changelog ==
118
+ <strong>Version 1.7.4 | 27 MAY 2020</strong>
119
+ <pre>
120
+ Fixed:Admin notice bug
121
+ </pre>
122
+
123
+ <strong>Version 1.7.3 | 15 MAY 2020</strong>
124
+ <pre>
125
+ Updates:Minor Textual changes
126
+ </pre>
127
+ <strong>Version 1.7.1 | 28 APR 2020</strong>
128
+ <pre>
129
+ Fixed: Index per request not working issue.
130
+ Updated: Updated new logo and all assets
131
+ </pre>
132
+ <strong>Version 1.7 | 13 FEB 2020</strong>
133
+ <pre>
134
+ Added: Added Chinese languages support
135
+ Added: Supported Singular and plural string translation
136
+ Added: Added admin notices
137
+ Added: Added support for major language
138
+ Added: Added Punjabi, Kannada, Irish, Malayalam language support in Microsoft Translator
139
+ Fixed: % s and s % space after Special charactors problem
140
+ Fixed: Wrong index updates with multiple strings
141
+ Improved:Improved String translation
142
+ Imporved: overall Code Improvements
143
+ Improved:Optimized Settings panel
144
+ Updated:Textual Changes
145
+ </pre>
146
+ <strong>Version 1.6 | 27 JAN 2020</strong>
147
+ <pre>
148
+ Added: Integrated Microsoft Translation API Support
149
+ Added: Plain text translation support %s,%d placeholders
150
+ Added: Integrated API Testing Button in the settings panel.
151
+ Added: Added Error handling messages
152
+ Added: Integrated Sweetalert popup
153
+ Added: Supported %s,%d placeholder strings in Google translate
154
+ Added: Microsoft translation settings
155
+ Imporved: Review Notice and updated wrong Spelling
156
+ </pre>
157
+
158
  <strong>Version 1.5 | 14 JAN 2020</strong>
159
  <pre>
160
  Added: Integrated Google Translation API Support
202
  Added: Added security checks in every request
203
  Added: Integrated nonce in ajax request
204
  Improved: Improved translation issues
205
+ Improved: Improved overall code
206
  Improved: readme.text
207
  Improved: Added new screenshots
208
  Fixed: Minor translation issues.