Lingotek Translation - Version 1.5.4

Version Description

(2022-04-12) = - WordPress: Translations are auto uploaded after edit. - WordPress: Change when translations are auto requested - WordPress - Custom content types have no Bulk Actions menu - WordPress enhancement: Completed Target Lock Feature - WordPress: Remove the payment method link in account settings

Download this release

Release Info

Developer sowmiya2021
Plugin Icon 128x128 Lingotek Translation
Version 1.5.4
Comparing to
See all releases

Code changes from version 1.5.3 to 1.5.4

CHANGELOG.md CHANGED
@@ -1,7 +1,3 @@
1
  # Changelog
2
-
3
- ## [1.5.4] - 2022-04-12
4
- - Merging release 1.5.4 branch
5
-
6
  ## [1.4.16] - 2021-07-22
7
  - Merging hotfix 1.4.16 branch
1
  # Changelog
 
 
 
 
2
  ## [1.4.16] - 2021-07-22
3
  - Merging hotfix 1.4.16 branch
admin/actions.php CHANGED
@@ -141,6 +141,13 @@ abstract class Lingotek_Actions {
141
  'description' => __( 'Delete this translation from Lingotek TMS', 'lingotek-translation' ),
142
  'per_locale' => false,
143
  ),
 
 
 
 
 
 
 
144
  );
145
 
146
  // action icons
@@ -225,6 +232,11 @@ abstract class Lingotek_Actions {
225
  'title' => __( 'Document has been archived', 'lingotek-translation' ),
226
  'icon' => 'remove',
227
  ),
 
 
 
 
 
228
  );
229
 
230
  $this->type = $type;
@@ -829,6 +841,18 @@ abstract class Lingotek_Actions {
829
  );
830
  null !== filter_input( INPUT_GET, 'locale' ) ? $document->create_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->create_translations();
831
  break;
 
 
 
 
 
 
 
 
 
 
 
 
832
 
833
  case 'lingotek-delete':
834
  check_admin_referer( 'lingotek-delete' );
@@ -1232,6 +1256,22 @@ abstract class Lingotek_Actions {
1232
  return $link;
1233
  }
1234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1235
  /**
1236
  * Gets the workbench access url.
1237
  *
141
  'description' => __( 'Delete this translation from Lingotek TMS', 'lingotek-translation' ),
142
  'per_locale' => false,
143
  ),
144
+
145
+ 'lock-target' => array(
146
+ 'action' => __( 'Lock/Unlock target', 'lingotek-translation' ),
147
+ 'progress' => __( 'Locking/Unlocking translation', 'lingotek-translation' ),
148
+ 'description' => __( 'Lock/Unlock this target', 'lingotek-translation' ),
149
+ 'per_locale' => true,
150
+ ),
151
  );
152
 
153
  // action icons
232
  'title' => __( 'Document has been archived', 'lingotek-translation' ),
233
  'icon' => 'remove',
234
  ),
235
+
236
+ 'locked' => array(
237
+ 'title' => __( 'The target has been locked', 'lingotek-translation' ),
238
+ 'icon' => 'lock',
239
+ ),
240
  );
241
 
242
  $this->type = $type;
841
  );
842
  null !== filter_input( INPUT_GET, 'locale' ) ? $document->create_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->create_translations();
843
  break;
844
+
845
+ case 'lock-target':
846
+ check_admin_referer( 'lock-target' );
847
+ $locale = filter_input( INPUT_GET, 'locale');
848
+ $ltk_locale = Lingotek::map_to_wp_locale( $locale );
849
+ $status = $document->translations[ $ltk_locale];
850
+ if ( $status === 'current') {
851
+ $document->update_translation_status( $ltk_locale, 'locked' );
852
+ } else {
853
+ $document->update_translation_status( $ltk_locale, 'current' );
854
+ }
855
+ break;
856
 
857
  case 'lingotek-delete':
858
  check_admin_referer( 'lingotek-delete' );
1256
  return $link;
1257
  }
1258
 
1259
+ public function toggle_lock ( $object_id, $document, $ltk_locale ) {
1260
+ $link = wp_nonce_url(
1261
+ add_query_arg(
1262
+ array(
1263
+ 'document_id' => $document->document_id,
1264
+ 'locale' => $ltk_locale,
1265
+ 'action' => 'lock-target',
1266
+ 'noheader' => true,
1267
+ ),
1268
+ defined( 'DOING_AJAX' ) && DOING_AJAX ? wp_get_referer() : wp_get_referer()
1269
+ ),
1270
+ 'lock-target'
1271
+ );
1272
+ return $link;
1273
+ }
1274
+
1275
  /**
1276
  * Gets the workbench access url.
1277
  *
admin/admin.php CHANGED
@@ -392,9 +392,9 @@ class Lingotek_Admin {
392
 
393
  return array(
394
  'upload' => array(
395
- 'label' => __( 'Upload content', 'lingotek-translation' ),
396
  'options' => $options,
397
- 'description' => __( 'How should new and modified content be uploaded to Lingotek?', 'lingotek-translation' ),
398
  ),
399
  'download' => array(
400
  'label' => __( 'Download translations', 'lingotek-translation' ),
392
 
393
  return array(
394
  'upload' => array(
395
+ 'label' => __( 'Upload source', 'lingotek-translation' ),
396
  'options' => $options,
397
+ 'description' => __( 'How should new and modified source content be uploaded to Lingotek?', 'lingotek-translation' ),
398
  ),
399
  'download' => array(
400
  'label' => __( 'Download translations', 'lingotek-translation' ),
admin/chip-target.php CHANGED
@@ -57,7 +57,7 @@ class Lingotek_Chip_Target extends Lingotek_Chip_Base {
57
  /* translators: %s: The lingotek locale. */
58
  $title = sprintf( __( 'Download translation for %s', 'lingotek-translation' ), $language->lingotek_locale );
59
  }
60
- if ( in_array( $status, array( 'current', 'interim', 'intermediate', 'edited' ), true ) ) {
61
  $uri = $post_actions->workbench_url( $this->id, $this->document, $language->lingotek_locale );
62
  $title = __( 'Open in Lingotek workbench', 'lingotek-translation' );
63
  }
@@ -134,6 +134,20 @@ class Lingotek_Chip_Target extends Lingotek_Chip_Base {
134
  __( 'Open in Lingotek workbench', 'lingotek-translation' )
135
  );
136
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  if ( 'disabled' === $status ) {
138
  $url = null;
139
  }
57
  /* translators: %s: The lingotek locale. */
58
  $title = sprintf( __( 'Download translation for %s', 'lingotek-translation' ), $language->lingotek_locale );
59
  }
60
+ if ( in_array( $status, array( 'current', 'interim', 'intermediate', 'edited', 'locked' ), true ) ) {
61
  $uri = $post_actions->workbench_url( $this->id, $this->document, $language->lingotek_locale );
62
  $title = __( 'Open in Lingotek workbench', 'lingotek-translation' );
63
  }
134
  __( 'Open in Lingotek workbench', 'lingotek-translation' )
135
  );
136
  }
137
+
138
+ if ( in_array( $status, array( 'current'), true ) ) {
139
+ $urls[] = new Lingotek_Action_Url(
140
+ $post_actions->toggle_lock( $this->id, $this->document, $language->locale ),
141
+ sprintf( __( 'Lock target', 'lingotek-translation' ), $language->locale )
142
+ );
143
+ }
144
+
145
+ if ( in_array( $status, array( 'locked'), true ) ) {
146
+ $urls[] = new Lingotek_Action_Url(
147
+ $post_actions->toggle_lock( $this->id, $this->document, $language->locale ),
148
+ sprintf( __( 'Unlock target', 'lingotek-translation' ), $language->locale )
149
+ );
150
+ }
151
  if ( 'disabled' === $status ) {
152
  $url = null;
153
  }
admin/manage/view-edit-profile.php CHANGED
@@ -21,7 +21,8 @@ $target_settings = array(
21
 
22
  $profiles = $this->get_profiles_usage( get_option( 'lingotek_profiles' ) );
23
 
24
- $profile = isset( $_GET['profile'] ) && array_key_exists( sanitize_key( wp_unslash( $_GET['profile'] ) ), $profiles ) ? $profiles[ sanitize_key( wp_unslash( $_GET['profile'] ) ) ] : array();
 
25
  $disabled = isset( $profile['profile'] ) && in_array( $profile['profile'], array( 'automatic', 'manual' ), true ) ? 'disabled="disabled"' : '';
26
  // Code to determine which filter scenario will be displayed. (Not configured, defaults, custom filters)
27
  $primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options'], true );
@@ -68,7 +69,7 @@ unset( $settings['secondary_filter_id']['options'][ $primary_filter_id ] );
68
  <?php
69
  if ( ! empty( $profile ) ) {
70
  // localize canned profile names
71
- $profile_name = $disabled ? __( 'Disabled', 'lingotek-translation' ) : $profile['name'];
72
  }
73
  printf(
74
  '<input name="name" id="name" type="text" value="%s" %s>',
21
 
22
  $profiles = $this->get_profiles_usage( get_option( 'lingotek_profiles' ) );
23
 
24
+ $profile = isset( $_GET['profile'] ) && array_key_exists( sanitize_key( wp_unslash( $_GET['profile'] ) ), $profiles ) ? $profiles[ sanitize_key( wp_unslash( $_GET['profile'] ) ) ] : array();
25
+ // Disable certain fields if the profile is a default translation profile
26
  $disabled = isset( $profile['profile'] ) && in_array( $profile['profile'], array( 'automatic', 'manual' ), true ) ? 'disabled="disabled"' : '';
27
  // Code to determine which filter scenario will be displayed. (Not configured, defaults, custom filters)
28
  $primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options'], true );
69
  <?php
70
  if ( ! empty( $profile ) ) {
71
  // localize canned profile names
72
+ $profile_name = isset( $profile['name'] ) ? $profile['name'] : __( 'Disabled', 'lingotek-translation' );
73
  }
74
  printf(
75
  '<input name="name" id="name" type="text" value="%s" %s>',
admin/post-actions.php CHANGED
@@ -30,14 +30,14 @@ class Lingotek_Post_Actions extends Lingotek_Actions {
30
  add_filter( "bulk_actions-edit-$taxonomy", array( &$this, 'add_bulk_actions' ) );
31
  }
32
 
33
- $polylang_enabled = PLL()->model->get_translated_post_types();
 
34
  // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
35
  $polylang_enabled = apply_filters( 'pll_get_post_types', $polylang_enabled, false );
36
 
37
  foreach ( $polylang_enabled as $type ) {
38
  add_filter( "bulk_actions-edit-$type", array( &$this, 'add_bulk_actions' ) );
39
  }
40
-
41
  // manage bulk actions, row actions and icon actions.
42
  add_action( 'load-edit.php', array( &$this, 'manage_actions' ) );
43
  add_action( 'load-upload.php', array( &$this, 'manage_actions' ) );
@@ -161,6 +161,25 @@ class Lingotek_Post_Actions extends Lingotek_Actions {
161
  list( $action, $locale ) = explode( ':', $action, 2 );
162
  }
163
  switch ( $action ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  case 'bulk-lingotek-upload':
165
  $type = empty( $typenow ) ? 'media' : 'post';
166
  $filtered_get = filter_input_array( INPUT_GET );
@@ -195,7 +214,6 @@ class Lingotek_Post_Actions extends Lingotek_Actions {
195
  }
196
  }
197
  }
198
-
199
  case 'bulk-lingotek-request':
200
  case 'bulk-lingotek-download':
201
  case 'bulk-lingotek-status':
@@ -218,7 +236,7 @@ class Lingotek_Post_Actions extends Lingotek_Actions {
218
  }
219
  $redirect = add_query_arg( $action, 1, $redirect );
220
  $redirect = add_query_arg( 'ids', implode( ',', $post_ids ), $redirect );
221
- if ( $locale ) {
222
  $redirect = add_query_arg( 'target_locale', $locale, $redirect );
223
  }
224
  break;
30
  add_filter( "bulk_actions-edit-$taxonomy", array( &$this, 'add_bulk_actions' ) );
31
  }
32
 
33
+ // We want to enable the bulk actions in all the translated post types enabled in Polylang
34
+ $polylang_enabled = PLL()->model->get_translated_post_types( false );
35
  // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
36
  $polylang_enabled = apply_filters( 'pll_get_post_types', $polylang_enabled, false );
37
 
38
  foreach ( $polylang_enabled as $type ) {
39
  add_filter( "bulk_actions-edit-$type", array( &$this, 'add_bulk_actions' ) );
40
  }
 
41
  // manage bulk actions, row actions and icon actions.
42
  add_action( 'load-edit.php', array( &$this, 'manage_actions' ) );
43
  add_action( 'load-upload.php', array( &$this, 'manage_actions' ) );
161
  list( $action, $locale ) = explode( ':', $action, 2 );
162
  }
163
  switch ( $action ) {
164
+ case 'bulk-lingotek-lock-target':
165
+ if ( empty( $post_ids ) ) {
166
+ $type = empty( $typenow ) ? 'media' : 'post';
167
+ $filtered_get = filter_input_array( INPUT_GET );
168
+ if ( ! isset( $filtered_get[ $type ] ) ) {
169
+ return;
170
+ }
171
+
172
+ $post_ids = array_map( 'intval', $filtered_get[ $type ] );
173
+ }
174
+ foreach( $post_ids as $post_id ) {
175
+ $document = $this->lgtm->get_group( 'post', $post_id );
176
+ if( isset( $document->translations[$locale] ) && $document->translations[$locale] === 'current' ) {
177
+ $document->update_translation_status( $locale, 'locked' );
178
+ } elseif( isset( $document->translations[$locale] ) && $document->translations[$locale] === 'locked' ) {
179
+ $document->update_translation_status( $locale, 'current' );
180
+ }
181
+ }
182
+ break;
183
  case 'bulk-lingotek-upload':
184
  $type = empty( $typenow ) ? 'media' : 'post';
185
  $filtered_get = filter_input_array( INPUT_GET );
214
  }
215
  }
216
  }
 
217
  case 'bulk-lingotek-request':
218
  case 'bulk-lingotek-download':
219
  case 'bulk-lingotek-status':
236
  }
237
  $redirect = add_query_arg( $action, 1, $redirect );
238
  $redirect = add_query_arg( 'ids', implode( ',', $post_ids ), $redirect );
239
+ if ( isset( $locale ) && $locale ) {
240
  $redirect = add_query_arg( 'target_locale', $locale, $redirect );
241
  }
242
  break;
admin/settings/view-account.php CHANGED
@@ -127,46 +127,6 @@ if ( ! $community_id ) {
127
  </select>
128
  </td>
129
  </tr>
130
- <tr>
131
- <th scope="row"><?php esc_html_e( 'Payment Method', 'lingotek-translation' ); ?></th>
132
- <td>
133
- <?php
134
- add_thickbox();
135
- wp_enqueue_script( 'lingotek_professional_workflow_account', LINGOTEK_URL . '/js/workflow/professional-workflow-account.js', array(), LINGOTEK_VERSION, false );
136
- $vars = array(
137
- 'modal_id' => 'payment-portal-screen',
138
- 'bridge_payment' => BRIDGE_URL . '/#/payment/portal',
139
- );
140
- wp_localize_script( 'lingotek_professional_workflow_account', 'account_vars', $vars );
141
- wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
142
- $ltk_client = new Lingotek_API();
143
- $payment_info = $ltk_client->get_user_payment_information();
144
- $cc = '';
145
- $cc_type = '';
146
- $payment_method_set = isset( $payment_info['payment_info']['payment_profile']['cc'] );
147
- if ( $payment_method_set ) {
148
- $cc = $payment_info['payment_info']['payment_profile']['cc'];
149
- $cc = str_replace( 'X', '', $cc );
150
-
151
- $cc_type = $payment_info['payment_info']['payment_profile']['cc_type'];
152
- }
153
- ?>
154
- <div id='modal-window-id-payment-portal-screen' style='display:none;' >
155
- <div id='payment-portal-wrapper' class='payment-portal-element'>
156
- <img class='payment-portal-element payment-portal-image' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/translation-logo.png"/>
157
- <img class='payment-portal-element payment-portal-loading' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/loading.gif"/>
158
- <span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
159
- </div>
160
- </div>
161
- <div class='payment-method-setup professional-card-border' style="<?php echo ( $payment_method_set ) ? 'display:inline-block;' : 'display:none'; ?>">
162
- <div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/blue-radio-button.svg"/></div>
163
- <div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/credit-dots.svg" /></div>
164
- <div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'><?php echo esc_html( $cc ); ?></span></div>
165
- <div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src="<?php echo esc_html( Lingotek_Credit_Card_To_Path::get_cc_type_asset_url( $cc_type ) ); ?>"/></div>
166
- </div>
167
- <div style="height:37px; display:inline-block;padding-left: 10px;"><a id="professional-payment-info-link" href="<?php echo esc_url_raw( BRIDGE_URL ); ?>/#/payment/portal?redirect_url=<?php echo rawurlencode( home_url( add_query_arg( null, null ) ) ); ?>" style="display: table-cell;padding-top: 7%;"><?php echo ( $payment_method_set ) ? 'Edit Payment Method' : 'Set Up Payment Method'; ?></a></div>
168
- </td>
169
- </tr>
170
  </table>
171
 
172
  <?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
127
  </select>
128
  </td>
129
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  </table>
131
 
132
  <?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
css/statuses.css CHANGED
@@ -149,6 +149,20 @@ a.language-icon {
149
  background-color: #43a047;
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  .language-icon.target-interim,
153
  .language-icon.target-intermediate {
154
  background-color: #ffffff;
149
  background-color: #43a047;
150
  }
151
 
152
+ .language-icon.target-locked {
153
+ background-color:#C4C4C4;
154
+ background-image: url("../img/lock.png");
155
+ border: 1px solid #C4C4C4;
156
+ transform: rotate(0deg);
157
+ color: #ffffff;
158
+ }
159
+ .language-icon.target-locked a {
160
+ color: #ffffff;
161
+ }
162
+ .language-icon.target-locked:hover {
163
+ background-color: #a2a3a2;
164
+ }
165
+
166
  .language-icon.target-interim,
167
  .language-icon.target-intermediate {
168
  background-color: #ffffff;
img/lock.png ADDED
Binary file
include/api.php CHANGED
@@ -133,8 +133,6 @@ class Lingotek_API extends Lingotek_HTTP {
133
  * @returns bool|string document_id, false if something got wrong
134
  */
135
  public function upload_document( $args, $wp_id = null ) {
136
- Lingotek::log( debug_backtrace() );
137
- Lingotek::log( 'uploading document' );
138
  $args = wp_parse_args(
139
  $args,
140
  array(
@@ -164,10 +162,10 @@ class Lingotek_API extends Lingotek_HTTP {
164
  $lingotek_log_errors['patch_document_error'] = __( "Payment required. Message: $error_message", 'lingotek-translation' );
165
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
166
  } elseif ( $code == 429 ) {
167
- $lingotek_log_errors = get_option( 'lingotek_log_errors', [] );
168
- $lingotek_log_errors['word_limit_error'] = true;
169
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
170
- }
171
  return false;
172
  }
173
 
@@ -203,8 +201,8 @@ class Lingotek_API extends Lingotek_HTTP {
203
  return $this->patch_document( $body->next_document_id, $unformatted_args, $wp_id );
204
  }
205
  if ( $status_code == 429 ) {
206
- $lingotek_log_errors = get_option( 'lingotek_log_errors', [] );
207
- $lingotek_log_errors['word_limit_error'] = true;
208
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
209
  return false;
210
  }
@@ -534,9 +532,9 @@ class Lingotek_API extends Lingotek_HTTP {
534
  if ( $e->properties->status != 'CANCELLED' ) {
535
  // cancelled is in a completed state, but it does not mean the translation is 100% complete
536
  $translations[ $e->properties->locale_code ] = array(
537
- 'progress' => $e->properties->status,
538
- 'percent_complete' => $e->properties->percent_complete,
539
- 'ready_to_download' => $e->properties->ready_to_download
540
 
541
  );
542
  }
@@ -748,10 +746,19 @@ class Lingotek_API extends Lingotek_HTTP {
748
  $lgtm = $GLOBALS['wp_lingotek']->model;
749
  $document = isset( $document ) ? $document : $lgtm->get_group_by_id( $document_id );
750
  $lingotek_locale = Lingotek::map_to_lingotek_locale( $locale );
751
- $args = $unformatted_args = wp_parse_args( $args, array( 'workflow_id' => $this->get_workflow_id() ) );
752
  $args = array_merge( array( 'locale_code' => $lingotek_locale ), $args );
753
- $response = $this->post( $this->api_url . '/document/' . $document_id . '/translation', $args );
754
- $title = isset( $args['title'] ) ? $args['title'] : $document_id;
 
 
 
 
 
 
 
 
 
755
  if ( $wp_id ) {
756
  $arr = get_option( 'lingotek_log_errors', array() );
757
  $status_code = wp_remote_retrieve_response_code( $response );
@@ -768,8 +775,8 @@ class Lingotek_API extends Lingotek_HTTP {
768
  return false;
769
  }
770
  if ( 429 === $status_code ) {
771
- $lingotek_log_errors = get_option( 'lingotek_log_errors', [] );
772
- $lingotek_log_errors['word_limit_error'] = true;
773
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
774
  return false;
775
  }
@@ -948,7 +955,7 @@ class Lingotek_API extends Lingotek_HTTP {
948
  $lingotek_log_errors = array();
949
  }
950
  // Use the response message if it's an authorization error
951
- $response_error_message = 403 == wp_remote_retrieve_response_code( $response ) && $this->get_error_message_from_response( $response ) !== false ?
952
  $this->get_error_message_from_response( $response ) : false;
953
  if ( $response_error_message ) {
954
  $error_message = $response_error_message;
133
  * @returns bool|string document_id, false if something got wrong
134
  */
135
  public function upload_document( $args, $wp_id = null ) {
 
 
136
  $args = wp_parse_args(
137
  $args,
138
  array(
162
  $lingotek_log_errors['patch_document_error'] = __( "Payment required. Message: $error_message", 'lingotek-translation' );
163
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
164
  } elseif ( $code == 429 ) {
165
+ $lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
166
+ $lingotek_log_errors['word_limit_error'] = true;
167
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
168
+ }//end if
169
  return false;
170
  }
171
 
201
  return $this->patch_document( $body->next_document_id, $unformatted_args, $wp_id );
202
  }
203
  if ( $status_code == 429 ) {
204
+ $lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
205
+ $lingotek_log_errors['word_limit_error'] = true;
206
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
207
  return false;
208
  }
532
  if ( $e->properties->status != 'CANCELLED' ) {
533
  // cancelled is in a completed state, but it does not mean the translation is 100% complete
534
  $translations[ $e->properties->locale_code ] = array(
535
+ 'progress' => $e->properties->status,
536
+ 'percent_complete' => $e->properties->percent_complete,
537
+ 'ready_to_download' => $e->properties->ready_to_download,
538
 
539
  );
540
  }
746
  $lgtm = $GLOBALS['wp_lingotek']->model;
747
  $document = isset( $document ) ? $document : $lgtm->get_group_by_id( $document_id );
748
  $lingotek_locale = Lingotek::map_to_lingotek_locale( $locale );
749
+ $args = $unformatted_args = wp_parse_args( $args, array() );
750
  $args = array_merge( array( 'locale_code' => $lingotek_locale ), $args );
751
+ Lingotek_Logger::info(
752
+ 'Request Translation',
753
+ array(
754
+ 'document id' => $document_id,
755
+ 'wp_id' => $wp_id,
756
+ 'locale' => $locale,
757
+ 'args' => $args,
758
+ )
759
+ );
760
+ $response = $this->post( $this->api_url . '/document/' . $document_id . '/translation', $args );
761
+ $title = isset( $args['title'] ) ? $args['title'] : $document_id;
762
  if ( $wp_id ) {
763
  $arr = get_option( 'lingotek_log_errors', array() );
764
  $status_code = wp_remote_retrieve_response_code( $response );
775
  return false;
776
  }
777
  if ( 429 === $status_code ) {
778
+ $lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
779
+ $lingotek_log_errors['word_limit_error'] = true;
780
  update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
781
  return false;
782
  }
955
  $lingotek_log_errors = array();
956
  }
957
  // Use the response message if it's an authorization error
958
+ $response_error_message = 403 == wp_remote_retrieve_response_code( $response ) && $this->get_error_message_from_response( $response ) !== false ?
959
  $this->get_error_message_from_response( $response ) : false;
960
  if ( $response_error_message ) {
961
  $error_message = $response_error_message;
include/callback.php CHANGED
@@ -1,14 +1,19 @@
1
  <?php
2
 
3
- /*
4
  * a class to handle Lingotek callbacks
5
  *
6
  * @since 0.1
7
  */
8
  class Lingotek_Callback {
 
 
 
 
 
9
  public $lgtm;
10
 
11
- /*
12
  * Constructor
13
  *
14
  * @since 0.1
@@ -18,20 +23,20 @@ class Lingotek_Callback {
18
  add_filter( 'request', array( &$this, 'request' ) );
19
  }
20
 
21
- /*
22
- * dispatches the Lingotek callback and dies
23
  *
24
  * @since 0.1
25
  *
26
- * @param array $query_vars query vars known to WordPress
27
- * @return array unmodified query vars if the request is not a Lingotek callback
28
  */
29
  public function request( $query_vars ) {
30
  if ( empty( $query_vars['lingotek'] ) ) {
31
  return $query_vars;
32
  }
33
- $type = $_GET['type'];
34
- if ( isset( $type, $_GET['document_id'] ) && $document = $this->lgtm->get_group_by_id( $_GET['document_id'] ) ) {
35
  switch ( $type ) {
36
  case 'get':
37
  $this->handleGet( $document );
@@ -60,7 +65,7 @@ class Lingotek_Callback {
60
  case 'document_deleted':
61
  $this->handleDocumentDeleted( $document );
62
  break;
63
- case 'document_cancelled';
64
  $this->handleDocumentCancelled( $document );
65
  break;
66
  default:
@@ -123,10 +128,9 @@ class Lingotek_Callback {
123
  $polylang->sync = new PLL_Admin_Sync( $polylang );
124
  // Map to WordPress locale.
125
  $locale = Lingotek::map_to_wp_locale( $_GET['locale'] );
126
- if ($type == 'download_interim_translation') {
127
- $document->is_automatic_download( $locale ) ? $document->create_translation( $locale, true, $type ) : $document->translation_ready_interim( $locale );
128
- }
129
- else {
130
  $document->is_automatic_download( $locale ) ? $document->create_translation( $locale, true, $type ) : $document->translation_ready( $locale );
131
  }
132
  }//end if
@@ -144,9 +148,6 @@ class Lingotek_Callback {
144
  'Document Status' => isset( $_GET['doc_status'] ) ? $_GET['doc_status'] : null,
145
  );
146
  Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
147
- if ( $document->is_automatic_upload() ) {
148
- $document->request_translations();
149
- }
150
  }
151
 
152
  public function handleImportFailure( $document ) {
1
  <?php
2
 
3
+ /**
4
  * a class to handle Lingotek callbacks
5
  *
6
  * @since 0.1
7
  */
8
  class Lingotek_Callback {
9
+ /**
10
+ * Model passed in when callback constructor is called.
11
+ *
12
+ * @var object
13
+ */
14
  public $lgtm;
15
 
16
+ /**
17
  * Constructor
18
  *
19
  * @since 0.1
23
  add_filter( 'request', array( &$this, 'request' ) );
24
  }
25
 
26
+ /**
27
+ * Dispatches the Lingotek callback and dies.
28
  *
29
  * @since 0.1
30
  *
31
+ * @param array $query_vars query vars known to WordPress.
32
+ * @return array unmodified query vars if the request is not a Lingotek callback.
33
  */
34
  public function request( $query_vars ) {
35
  if ( empty( $query_vars['lingotek'] ) ) {
36
  return $query_vars;
37
  }
38
+ $type = isset( $_GET['type'] ) ? $_GET['type'] : false;
39
+ if ( ( $document = $this->lgtm->get_group_by_id( $_GET['document_id'] ) ) && isset( $_GET['document_id'] ) && $type ) {
40
  switch ( $type ) {
41
  case 'get':
42
  $this->handleGet( $document );
65
  case 'document_deleted':
66
  $this->handleDocumentDeleted( $document );
67
  break;
68
+ case 'document_cancelled':
69
  $this->handleDocumentCancelled( $document );
70
  break;
71
  default:
128
  $polylang->sync = new PLL_Admin_Sync( $polylang );
129
  // Map to WordPress locale.
130
  $locale = Lingotek::map_to_wp_locale( $_GET['locale'] );
131
+ if ( $type == 'download_interim_translation' ) {
132
+ $document->is_automatic_download( $locale ) ? $document->create_translation( $locale, true, $type ) : $document->translation_ready_interim( $locale );
133
+ } else {
 
134
  $document->is_automatic_download( $locale ) ? $document->create_translation( $locale, true, $type ) : $document->translation_ready( $locale );
135
  }
136
  }//end if
148
  'Document Status' => isset( $_GET['doc_status'] ) ? $_GET['doc_status'] : null,
149
  );
150
  Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
 
 
 
151
  }
152
 
153
  public function handleImportFailure( $document ) {
include/group-post.php CHANGED
@@ -414,9 +414,9 @@ class Lingotek_Group_Post extends Lingotek_Group {
414
  $post = get_post( $this->source );
415
  // status
416
  $tr_post['post_status'] = ( $prefs['download_post_status'] === self::SAME_AS_SOURCE ) ? $post->post_status : $prefs['download_post_status'];
417
-
418
  // update existing translation
419
- if ( $tr_id = PLL()->model->post->get( $this->source, $locale ) ) {
420
  $tr_post['ID'] = $tr_id;
421
 
422
  // translate metas
@@ -431,7 +431,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
431
  if ( ! $ready_to_download ) {
432
  $this->safe_translation_status_update( $locale, 'interim' );
433
  } else {
434
- $this->safe_translation_status_update( $locale, 'current' );
435
  }
436
  }
437
 
@@ -448,7 +448,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
448
  $tr_post['ID'] = null;
449
 
450
  // translate parent
451
- $tr_post['post_parent'] = ( $post->post_parent && $tr_parent = $this->pllm->post->get_translation( $post->post_parent, $locale ) ) ? $tr_parent : 0;
452
 
453
  if ( 'attachment' == $post->post_type ) {
454
  $tr_id = wp_insert_attachment( $tr_post );
414
  $post = get_post( $this->source );
415
  // status
416
  $tr_post['post_status'] = ( $prefs['download_post_status'] === self::SAME_AS_SOURCE ) ? $post->post_status : $prefs['download_post_status'];
417
+ $language = $this->pllm->get_language( $locale );
418
  // update existing translation
419
+ if ( $tr_id = PLL()->model->post->get( $this->source, $language->locale ) ) {
420
  $tr_post['ID'] = $tr_id;
421
 
422
  // translate metas
431
  if ( ! $ready_to_download ) {
432
  $this->safe_translation_status_update( $locale, 'interim' );
433
  } else {
434
+ $this->safe_translation_status_update( $language->locale, 'current' );
435
  }
436
  }
437
 
448
  $tr_post['ID'] = null;
449
 
450
  // translate parent
451
+ $tr_post['post_parent'] = ( $post->post_parent && $tr_parent = $this->pllm->post->get_translation( $post->post_parent, $language->locale ) ) ? $tr_parent : 0;
452
 
453
  if ( 'attachment' == $post->post_type ) {
454
  $tr_id = wp_insert_attachment( $tr_post );
include/group.php CHANGED
@@ -6,7 +6,11 @@
6
  * @since 0.2
7
  */
8
  abstract class Lingotek_Group {
9
- // used to avoid uploading a translation when using automatinc upload
 
 
 
 
10
  public static $creating_translation;
11
 
12
  /**
@@ -59,7 +63,7 @@ abstract class Lingotek_Group {
59
  *
60
  * @param string $locale
61
  * @param string $status
62
- * @param array $arr translations to add
63
  */
64
  protected function safe_translation_status_update( $locale, $status, $arr = array() ) {
65
  global $wpdb;
@@ -208,7 +212,14 @@ abstract class Lingotek_Group {
208
  if ( $res !== false ) {
209
  $this->document_id = $res;
210
  $this->status = 'importing';
211
- $this->translations = isset( $this->translations ) ? array_fill_keys( array_keys( $this->translations ), 'pending' ) : null;
 
 
 
 
 
 
 
212
  $this->save();
213
  }
214
  return $res;
@@ -362,14 +373,14 @@ abstract class Lingotek_Group {
362
  }
363
  $wp_locale = $lingotek_locale_to_pll_locale[ $lingotek_locale ];
364
 
365
- if ( !$locale_status['ready_to_download'] && ! in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) ) {
366
  $this->translations[ $wp_locale ] = 'pending';
367
  } elseif ( in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) && $locale_status['ready_to_download'] ) {
368
- $this->translations[ $wp_locale ] = 'ready';
369
- } elseif ( in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) && !$locale_status['ready_to_download'] ) {
370
  $this->translations[ $wp_locale ] = $this->translations[ $wp_locale ];
371
- } elseif ( ( ! isset( $this->translations[ $wp_locale ] ) ) || ( $this->translations[ $wp_locale ] !== 'current' ) && ! in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) ) {
372
- $this->translations[ $wp_locale ] = 'ready';
373
  }
374
  }
375
  // If there were any cancelled or deleted targets that we didn't update properly,
@@ -377,7 +388,7 @@ abstract class Lingotek_Group {
377
  $pll_locale_to_lingotek_locale = array_flip( $lingotek_locale_to_pll_locale );
378
  foreach ( $this->translations as $target_locale => $target_status ) {
379
  if ( ! isset( $translations[ $pll_locale_to_lingotek_locale[ $target_locale ] ] ) ) {
380
- if ( ! in_array( $this->translations[ $target_locale ], array( 'deleted', 'cancelled' ) ) ) {
381
  // Mark is a deleted.
382
  $this->translations[ $target_locale ] = 'deleted';
383
  }
@@ -406,7 +417,7 @@ abstract class Lingotek_Group {
406
  public function translation_ready_interim( $locale ) {
407
  $this->safe_translation_status_update( $locale, 'ready-interim' );
408
  }
409
-
410
  /**
411
  * attempts to create all translations from an object
412
  *
6
  * @since 0.2
7
  */
8
  abstract class Lingotek_Group {
9
+ /**
10
+ * Used to avoid uploading a translation when using automatinc upload.
11
+ *
12
+ * @var boolean
13
+ */
14
  public static $creating_translation;
15
 
16
  /**
63
  *
64
  * @param string $locale
65
  * @param string $status
66
+ * @param array $arr Translations to add.
67
  */
68
  protected function safe_translation_status_update( $locale, $status, $arr = array() ) {
69
  global $wpdb;
212
  if ( $res !== false ) {
213
  $this->document_id = $res;
214
  $this->status = 'importing';
215
+ foreach( $this->translations as $key => $value) {
216
+ if( !isset ( $this->translations ) ) {
217
+ $this->translations = null;
218
+ }
219
+ if( isset ( $this->translations ) && $value !== 'locked') {
220
+ $this->translations[$key] = 'pending';
221
+ }
222
+ }
223
  $this->save();
224
  }
225
  return $res;
373
  }
374
  $wp_locale = $lingotek_locale_to_pll_locale[ $lingotek_locale ];
375
 
376
+ if ( ! $locale_status['ready_to_download'] && ! in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) ) {
377
  $this->translations[ $wp_locale ] = 'pending';
378
  } elseif ( in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) && $locale_status['ready_to_download'] ) {
379
+ $this->is_automatic_download( $wp_locale ) ? $this->create_translation( $wp_locale, true ) : $this->translation_ready( $wp_locale );
380
+ } elseif ( in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim' ) ) && ! $locale_status['ready_to_download'] ) {
381
  $this->translations[ $wp_locale ] = $this->translations[ $wp_locale ];
382
+ } elseif ( ( ! isset( $this->translations[ $wp_locale ] ) ) || ( $this->translations[ $wp_locale ] !== 'current' ) && ! in_array( $this->translations[ $wp_locale ], array( 'interim', 'ready-interim', 'locked' ) ) ) {
383
+ $this->is_automatic_download( $wp_locale ) ? $this->create_translation( $wp_locale, true ) : $this->translation_ready( $wp_locale );
384
  }
385
  }
386
  // If there were any cancelled or deleted targets that we didn't update properly,
388
  $pll_locale_to_lingotek_locale = array_flip( $lingotek_locale_to_pll_locale );
389
  foreach ( $this->translations as $target_locale => $target_status ) {
390
  if ( ! isset( $translations[ $pll_locale_to_lingotek_locale[ $target_locale ] ] ) ) {
391
+ if ( ! in_array( $this->translations[ $target_locale ], array( 'deleted', 'cancelled' , 'locked' ) ) ) {
392
  // Mark is a deleted.
393
  $this->translations[ $target_locale ] = 'deleted';
394
  }
417
  public function translation_ready_interim( $locale ) {
418
  $this->safe_translation_status_update( $locale, 'ready-interim' );
419
  }
420
+
421
  /**
422
  * attempts to create all translations from an object
423
  *
include/http.php CHANGED
@@ -1,15 +1,20 @@
1
  <?php
2
 
3
- /*
4
  * a simple wrapper to wp http functions
5
  *
6
  * @since 0.1
7
  */
8
  class Lingotek_HTTP {
 
 
 
 
 
9
  protected $headers = array();
10
 
11
  const TIMEOUT = 30;
12
- /*
13
  * formats a request as multipart
14
  * greatly inspired from mailgun WordPress plugin
15
  *
@@ -29,9 +34,12 @@ class Lingotek_HTTP {
29
  $data .= '--' . $boundary . "\r\n";
30
  $data .= 'Content-Disposition: form-data; name="' . $key;
31
  // Request targets cannot be in an array, as they need to have the same key.
32
- if ( $key !== 'translation_locale_code' && $key !== 'translation_workflow_id' ) {
33
  $data .= '[' . $k . ']';
34
  }
 
 
 
35
  $data .= "\"\r\n\r\n";
36
  $data .= $v . "\r\n";
37
  }
@@ -40,12 +48,12 @@ class Lingotek_HTTP {
40
  $data .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
41
  $data .= $value . "\r\n";
42
  }
43
- }
44
 
45
  $body = $data . '--' . $boundary . '--';
46
  }
47
 
48
- /*
49
  * send a POST request
50
  *
51
  * @since 0.1
@@ -65,7 +73,7 @@ class Lingotek_HTTP {
65
  );
66
  }
67
 
68
- /*
69
  * send a GET request
70
  *
71
  * @since 0.1
@@ -85,7 +93,7 @@ class Lingotek_HTTP {
85
  );
86
  }
87
 
88
- /*
89
  * send a DELETE request
90
  *
91
  * @since 0.1
@@ -106,7 +114,7 @@ class Lingotek_HTTP {
106
  );
107
  }
108
 
109
- /*
110
  * send a PATCH request
111
  *
112
  * @since 0.1
1
  <?php
2
 
3
+ /**
4
  * a simple wrapper to wp http functions
5
  *
6
  * @since 0.1
7
  */
8
  class Lingotek_HTTP {
9
+ /**
10
+ * Array to store request headers.
11
+ *
12
+ * @var array
13
+ */
14
  protected $headers = array();
15
 
16
  const TIMEOUT = 30;
17
+ /**
18
  * formats a request as multipart
19
  * greatly inspired from mailgun WordPress plugin
20
  *
34
  $data .= '--' . $boundary . "\r\n";
35
  $data .= 'Content-Disposition: form-data; name="' . $key;
36
  // Request targets cannot be in an array, as they need to have the same key.
37
+ if ( 'translation_locale_code' !== $key && 'translation_workflow_id' !== $key ) {
38
  $data .= '[' . $k . ']';
39
  }
40
+ if ( 'translation_workflow_id' === $key && 'default' === $v ) {
41
+ $v = isset( $body['workflow_id'] ) ? $body['workflow_id'] : '';
42
+ }
43
  $data .= "\"\r\n\r\n";
44
  $data .= $v . "\r\n";
45
  }
48
  $data .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
49
  $data .= $value . "\r\n";
50
  }
51
+ }//end foreach
52
 
53
  $body = $data . '--' . $boundary . '--';
54
  }
55
 
56
+ /**
57
  * send a POST request
58
  *
59
  * @since 0.1
73
  );
74
  }
75
 
76
+ /**
77
  * send a GET request
78
  *
79
  * @since 0.1
93
  );
94
  }
95
 
96
+ /**
97
  * send a DELETE request
98
  *
99
  * @since 0.1
114
  );
115
  }
116
 
117
+ /**
118
  * send a PATCH request
119
  *
120
  * @since 0.1
include/model.php CHANGED
@@ -350,12 +350,15 @@ class Lingotek_Model {
350
  self::$copying_term = false;
351
  }
352
 
353
- private function format_patch_params( $params, $profile, $source_lang ) {
354
  $params['translation_locale_code'] = array();
355
  $params['translation_workflow_id'] = array();
 
356
 
357
  foreach ( $this->pllm->get_languages_list() as $lang ) {
358
  if ( $lang->lingotek_locale == $source_lang->lingotek_locale
 
 
359
  || ( isset( $profile['targets'][ $lang->slug ] ) && 'disabled' === $profile['targets'][ $lang->slug ] ) ) {
360
  continue;
361
  }
@@ -425,7 +428,7 @@ class Lingotek_Model {
425
  $filter_ids = $this->get_filter_ids( $post->post_type, $language, $post_id );
426
  $params = array_merge( $params, $filter_ids );
427
  if ( $document && in_array( $document->status, array( 'edited', 'importing', 'current' ) ) && $document_id ) {
428
- $response = $document->patch( $this->format_patch_params( $params, $profile, $language ) );
429
  if ( $response ) {
430
  // Only save the hash if the patch function is successful
431
  // Re-establish hash relation if needed
@@ -445,7 +448,8 @@ class Lingotek_Model {
445
  $document = $this->get_group_by_id( $document_id );
446
  if ( isset( $wp_target_locales ) ) {
447
  foreach ( $wp_target_locales as $locale ) {
448
- $document->translations[ $locale ] = 'pending';
 
449
  }
450
  }
451
  $document->save();
@@ -498,7 +502,7 @@ class Lingotek_Model {
498
  $params = array_merge( $params, $filter_ids );
499
 
500
  if ( ( $document = $this->get_group( 'term', $term_id ) ) && 'edited' === $document->status ) {
501
- $document->patch( $this->format_patch_params( $params, $profile, $language ), $term->name, $term );
502
  } elseif ( ! Lingotek_Group::$creating_translation && ! self::$copying_term ) {
503
  $document_id = $client->upload_document( $params, $term_id );
504
 
@@ -554,7 +558,7 @@ class Lingotek_Model {
554
  $params = array_merge( $params, $filter_ids );
555
 
556
  if ( ( $document = $this->get_group( $type, $group ) ) && 'edited' === $document->status ) {
557
- $document->patch( $this->format_patch_params( $params, $profile, $language ) );
558
  } else {
559
  $document_id = $client->upload_document( $params, $group );
560
 
350
  self::$copying_term = false;
351
  }
352
 
353
+ private function format_patch_params( $params, $profile, $source_lang, $translations ) {
354
  $params['translation_locale_code'] = array();
355
  $params['translation_workflow_id'] = array();
356
+ $requested_locales = isset($translations) && is_array($translations) ? array_keys($translations) : array();
357
 
358
  foreach ( $this->pllm->get_languages_list() as $lang ) {
359
  if ( $lang->lingotek_locale == $source_lang->lingotek_locale
360
+ || ( isset($translations[$lang->locale]) && $translations[$lang->locale] === 'locked' )
361
+ || !in_array($lang->locale, $requested_locales) //This ensures that only previously requested locales get included in the patch request
362
  || ( isset( $profile['targets'][ $lang->slug ] ) && 'disabled' === $profile['targets'][ $lang->slug ] ) ) {
363
  continue;
364
  }
428
  $filter_ids = $this->get_filter_ids( $post->post_type, $language, $post_id );
429
  $params = array_merge( $params, $filter_ids );
430
  if ( $document && in_array( $document->status, array( 'edited', 'importing', 'current' ) ) && $document_id ) {
431
+ $response = $document->patch( $this->format_patch_params( $params, $profile, $language, $document->translations ) );
432
  if ( $response ) {
433
  // Only save the hash if the patch function is successful
434
  // Re-establish hash relation if needed
448
  $document = $this->get_group_by_id( $document_id );
449
  if ( isset( $wp_target_locales ) ) {
450
  foreach ( $wp_target_locales as $locale ) {
451
+ $language = PLL()->model->get_language( $locale );
452
+ $document->translations[ $language->locale ] = 'pending';
453
  }
454
  }
455
  $document->save();
502
  $params = array_merge( $params, $filter_ids );
503
 
504
  if ( ( $document = $this->get_group( 'term', $term_id ) ) && 'edited' === $document->status ) {
505
+ $document->patch( $this->format_patch_params( $params, $profile, $language, $document->translations ), $term->name, $term );
506
  } elseif ( ! Lingotek_Group::$creating_translation && ! self::$copying_term ) {
507
  $document_id = $client->upload_document( $params, $term_id );
508
 
558
  $params = array_merge( $params, $filter_ids );
559
 
560
  if ( ( $document = $this->get_group( $type, $group ) ) && 'edited' === $document->status ) {
561
+ $document->patch( $this->format_patch_params( $params, $profile, $language, $document->translations ) );
562
  } else {
563
  $document_id = $client->upload_document( $params, $group );
564
 
lingotek.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  Plugin name: Lingotek Translation
4
  Plugin URI: http://lingotek.com/wordpress#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wplingotektranslationplugin
5
- Version: 1.5.3
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
@@ -19,7 +19,7 @@ if ( ! function_exists( 'add_action' ) ) {
19
  }
20
 
21
  // Plugin version (should match above meta).
22
- define( 'LINGOTEK_VERSION', '1.5.3' );
23
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
24
  // Plugin name as known by WordPress.
25
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) );
2
  /**
3
  Plugin name: Lingotek Translation
4
  Plugin URI: http://lingotek.com/wordpress#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wplingotektranslationplugin
5
+ Version: 1.5.4
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
19
  }
20
 
21
  // Plugin version (should match above meta).
22
+ define( 'LINGOTEK_VERSION', '1.5.4' );
23
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
24
  // Plugin name as known by WordPress.
25
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) );
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://lingotek.com/
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
  Tested up to: 5.8
7
- Stable tag: 1.5.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -123,6 +123,13 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
123
  5. The Lingotek Translation plugin provides the ability to Copy, Translate, and Ignore each specific custom field. Our plugin supports Wordpress custom fields and advanced custom fields.
124
 
125
  == Changelog ==
 
 
 
 
 
 
 
126
 
127
  = 1.5.3 (2022-03-01) =
128
  - ELEMENTOR: Uploading Metadata content
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
  Tested up to: 5.8
7
+ Stable tag: 1.5.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
123
  5. The Lingotek Translation plugin provides the ability to Copy, Translate, and Ignore each specific custom field. Our plugin supports Wordpress custom fields and advanced custom fields.
124
 
125
  == Changelog ==
126
+ = 1.5.4 (2022-04-12) =
127
+ - WordPress: Translations are auto uploaded after edit.
128
+ - WordPress: Change when translations are auto requested
129
+ - WordPress - Custom content types have no Bulk Actions menu
130
+ - WordPress enhancement: Completed Target Lock Feature
131
+ - WordPress: Remove the payment method link in account settings
132
+
133
 
134
  = 1.5.3 (2022-03-01) =
135
  - ELEMENTOR: Uploading Metadata content