Lingotek Translation - Version 1.3.8

Version Description

(2018-7-11) =

  • Added document metadata fields to translation profiles
  • Added manual copying of categories and tags
  • Fixed other minor bugs
Download this release

Release Info

Developer ipoulsen
Plugin Icon 128x128 Lingotek Translation
Version 1.3.8
Comparing to
See all releases

Code changes from version 1.3.7 to 1.3.8

admin/actions.php CHANGED
@@ -252,7 +252,7 @@ abstract class Lingotek_Actions {
252
  return sprintf('<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
253
  self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'] . "\n" . $api_error, $additional);
254
  }
255
-
256
  /**
257
  * Outputs an upload icon
258
  *
252
  return sprintf('<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
253
  self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'] . "\n" . $api_error, $additional);
254
  }
255
+
256
  /**
257
  * Outputs an upload icon
258
  *
admin/filters-columns.php CHANGED
@@ -118,40 +118,42 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
118
  // error_log('bool: ' . print_r($disabled, true) . PHP_EOL, 3, '/var/www/html/wp-content/plugins/lingotek-translation/error.log');
119
  // post ready for upload.
120
  if ( $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
 
121
  return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
122
  : ($document && (count( $document->desc_array ) >= 3) ? $actions->upload_icon( $object_id, true ) : $actions->upload_icon( $object_id ));
123
  } // if language is set to copy and profile is manual.
124
- elseif ( ('post' === $type) && ((isset( $source_profile['targets'][ $language->slug ] ) && 'copy' === $source_profile['targets'][ $language->slug ]) || (isset( $profile['targets'][ $language->slug ] ) && 'copy' === $profile['targets'][ $language->slug ] ) && isset( $document->source )) ) {
125
- if ( isset( $document->desc_array[ $language->slug ] ) ) {
126
- return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
127
- } else {
128
- if ( $document ) {
129
- return $actions->copy_icon( $document->source, $language->slug );
130
- } else {
131
- return $actions->copy_icon( $object_id, $language->slug );
132
- }
133
- }
 
134
  } // translation disabled.
135
  elseif ( ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) && ! isset( $document->translations[ $language->locale ] ) ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
136
  return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
137
  } // source post is uploaded.
138
- elseif ( isset( $document->source ) && $document->source === $id ) {
139
- // source ready for upload.
140
- if ( $this->lgtm->can_upload( $type, $id ) ) {
141
- return $actions->upload_icon( $id );
142
- }
143
 
144
- // importing source.
145
- if ( $id === $object_id && 'importing' === $document->status ) {
146
  return Lingotek_Actions::importing_icon( $document );
147
  }
148
 
149
- // uploaded.
150
- return 'post' === $type ? Lingotek_Post_actions::uploaded_icon( $id ) : Lingotek_Term_actions::uploaded_icon( $id );
151
- } // translations.
152
  elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
153
  return Lingotek_Actions::translation_icon( $document, $language );
154
- } elseif ( ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
155
  return parent::term_column( '', $column, $object_id );
156
  } // translations exist but are not managed by Lingotek TMS.
157
  elseif ( empty( $document->source ) ) {
118
  // error_log('bool: ' . print_r($disabled, true) . PHP_EOL, 3, '/var/www/html/wp-content/plugins/lingotek-translation/error.log');
119
  // post ready for upload.
120
  if ( $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
121
+
122
  return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
123
  : ($document && (count( $document->desc_array ) >= 3) ? $actions->upload_icon( $object_id, true ) : $actions->upload_icon( $object_id ));
124
  } // if language is set to copy and profile is manual.
125
+ elseif ( ('post' === $type || 'term' === $type) && ((isset( $source_profile['targets'][ $language->slug ] ) && 'copy' === $source_profile['targets'][ $language->slug ]) || (isset( $profile['targets'][ $language->slug ] ) && 'copy' === $profile['targets'][ $language->slug ] ) && isset( $document->source )) ) {
126
+
127
+ if ( isset( $document->desc_array[ $language->slug ] ) ) {
128
+ return ('post' === $type) ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
129
+ } else {
130
+ if ( $document ) {
131
+ return $actions->copy_icon( $document->source, $language->slug );
132
+ } else {
133
+ return $actions->copy_icon( $object_id, $language->slug );
134
+ }
135
+ }
136
  } // translation disabled.
137
  elseif ( ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) && ! isset( $document->translations[ $language->locale ] ) ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
138
  return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
139
  } // source post is uploaded.
140
+ elseif ( isset( $document->source ) && $document->source === $id ) {
141
+ // source ready for upload.
142
+ if ( $this->lgtm->can_upload( $type, $id ) ) {
143
+ return $actions->upload_icon( $id );
144
+ }
145
 
146
+ // importing source.
147
+ if ( $id === $object_id && 'importing' === $document->status ) {
148
  return Lingotek_Actions::importing_icon( $document );
149
  }
150
 
151
+ // uploaded.
152
+ return 'post' === $type ? Lingotek_Post_actions::uploaded_icon( $id ) : Lingotek_Term_actions::uploaded_icon( $id );
153
+ } // translations.
154
  elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
155
  return Lingotek_Actions::translation_icon( $document, $language );
156
+ } elseif ( ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
157
  return parent::term_column( '', $column, $object_id );
158
  } // translations exist but are not managed by Lingotek TMS.
159
  elseif ( empty( $document->source ) ) {
admin/manage/view-edit-profile.php CHANGED
@@ -22,7 +22,6 @@ $profiles = $this->get_profiles_usage(get_option('lingotek_profiles'));
22
 
23
  $profile = isset($_GET['profile']) && array_key_exists($_GET['profile'], $profiles) ? $profiles[$_GET['profile']] : array();
24
  $disabled = isset($profile['profile']) && in_array($profile['profile'], array('automatic', 'manual')) ? 'disabled="disabled"' : '';
25
-
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']);
28
  $secondary_filter_id = array_search('okf_html@wordpress.fprm', $settings['secondary_filter_id']['options']);
@@ -192,11 +191,50 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
192
  </table>
193
  </td>
194
  </tr>
195
-
196
  <?php
197
  } ?>
198
- </table><?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
 
200
  <?php
201
  if (!empty($profile['profile']) && !in_array($profile['profile'], array('automatic', 'manual', 'disabled')) && empty($profile['usage']))
202
  printf(
22
 
23
  $profile = isset($_GET['profile']) && array_key_exists($_GET['profile'], $profiles) ? $profiles[$_GET['profile']] : array();
24
  $disabled = isset($profile['profile']) && in_array($profile['profile'], array('automatic', 'manual')) ? 'disabled="disabled"' : '';
 
25
  // Code to determine which filter scenario will be displayed. (Not configured, defaults, custom filters)
26
  $primary_filter_id = array_search('okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options']);
27
  $secondary_filter_id = array_search('okf_html@wordpress.fprm', $settings['secondary_filter_id']['options']);
191
  </table>
192
  </td>
193
  </tr>
 
194
  <?php
195
  } ?>
196
+ </table>
197
+
198
+ <?php $metadata = array(
199
+ "author_email" => "Author Email",
200
+ "author_name" => "Author Name",
201
+ "division" => "Business Division",
202
+ "unit" => "Business Unit",
203
+ "campaign_id" => "Campaign ID",
204
+ "channel" => "Channel",
205
+ "contact_email" => "Contact Email",
206
+ "contact_name" => "Contact Name",
207
+ "description" => "Content Description",
208
+ "domain" => "Domain",
209
+ "style_id" => "External Style ID",
210
+ "purchase_order" => "Purchase Order",
211
+ "reference_url" => "Reference URL",
212
+ "region" => "Region",
213
+ "require_review" => "Require Review"
214
+ ) ?>
215
+ <h3><?php _e('Document Metadata', 'lingotek-translation'); ?></h3>
216
+ <table class="form-table">
217
+ <?php
218
+ foreach ($metadata as $key => $data){
219
+ $index = array_search($key,array_keys($metadata));
220
+ if ($index == 0){
221
+ printf('<tr>');
222
+ }
223
+ if ($index %3 == 0){
224
+ printf('</tr>');
225
+ printf('<tr>');
226
+ }
227
+ if (isset($profile[$key])){
228
+ printf('<th>&nbsp; %s <br><input type="text" name="%s" value="%s"></th>', $data ,$key, $profile[$key]);
229
+ }
230
+ else{
231
+ printf('<th>&nbsp; %s <br><input type="text" name="%s"></th>', $data, $key);
232
+ }
233
+ }
234
+ ?>
235
+ </table>
236
 
237
+ <?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
238
  <?php
239
  if (!empty($profile['profile']) && !in_array($profile['profile'], array('automatic', 'manual', 'disabled')) && empty($profile['usage']))
240
  printf(
admin/manage/view-profiles.php CHANGED
@@ -33,8 +33,8 @@ if (!empty($_POST)) {
33
  if (!empty($_POST['name']))
34
  $profiles[$profile_id]['name'] = strip_tags($_POST['name']);
35
 
36
- foreach (array('upload', 'download', 'project_id', 'workflow_id', 'primary_filter_id', 'secondary_filter_id') as $key) {
37
- if (isset($_POST[$key]) && in_array($_POST[$key], array_keys($settings[$key]['options'])))
38
  $profiles[$profile_id][$key] = $_POST[$key];
39
 
40
  if (empty($_POST[$key]) || 'default' == $_POST[$key])
33
  if (!empty($_POST['name']))
34
  $profiles[$profile_id]['name'] = strip_tags($_POST['name']);
35
 
36
+ foreach (array('upload', 'download', 'project_id', 'workflow_id', 'primary_filter_id', 'secondary_filter_id','author_email', 'author_name','division','unit','campaign_id','channel','contact_email','contact_name','description','domain','style_id','purchase_order','reference_url','region','require_review') as $key) {
37
+ if (isset($_POST[$key]) )
38
  $profiles[$profile_id][$key] = $_POST[$key];
39
 
40
  if (empty($_POST[$key]) || 'default' == $_POST[$key])
admin/strings-table.php CHANGED
@@ -101,7 +101,7 @@ class Lingotek_Strings_Table extends WP_List_Table {
101
  if ( $language_only === $this->get_first_language_column() ) {
102
  if ( isset( $errors[ $item['context'] ] ) ) {
103
  $api_error = Lingotek_Actions::retrieve_api_error( $errors[ $item['context'] ] );
104
- echo esc_html( Lingotek_Actions::display_error_icon( 'error', $api_error ) );
105
  }
106
  }
107
  }
101
  if ( $language_only === $this->get_first_language_column() ) {
102
  if ( isset( $errors[ $item['context'] ] ) ) {
103
  $api_error = Lingotek_Actions::retrieve_api_error( $errors[ $item['context'] ] );
104
+ echo Lingotek_Actions::display_error_icon( 'error', $api_error );
105
  }
106
  }
107
  }
admin/term-actions.php CHANGED
@@ -159,6 +159,13 @@ class Lingotek_Term_actions extends Lingotek_Actions {
159
  $this->lgtm->upload_term((int) $_GET['term'], $taxnow);
160
  break;
161
 
 
 
 
 
 
 
 
162
  default:
163
  if (!$this->_manage_actions($action))
164
  return; // do not redirect if this is not one of our actions
159
  $this->lgtm->upload_term((int) $_GET['term'], $taxnow);
160
  break;
161
 
162
+ case 'lingotek-copy':
163
+ check_admin_referer( 'lingotek-copy' );
164
+ $term_to_copy = get_term( (int) filter_input( INPUT_GET, 'term' ) );
165
+ $target = filter_input( INPUT_GET, 'target' );
166
+ $this->lgtm->copy_term( $term_to_copy, $target, $taxnow);
167
+ break;
168
+
169
  default:
170
  if (!$this->_manage_actions($action))
171
  return; // do not redirect if this is not one of our actions
include/group-string.php CHANGED
@@ -112,7 +112,7 @@ class Lingotek_Group_String extends Lingotek_Group {
112
  $this->save();
113
  }
114
  }
115
-
116
  /*
117
  * returns the content to translate
118
  *
@@ -128,7 +128,7 @@ class Lingotek_Group_String extends Lingotek_Group {
128
  }
129
  return json_encode($arr);
130
  }
131
-
132
  /*
133
  * requests translations to Lingotek TMS
134
  *
112
  $this->save();
113
  }
114
  }
115
+
116
  /*
117
  * returns the content to translate
118
  *
128
  }
129
  return json_encode($arr);
130
  }
131
+
132
  /*
133
  * requests translations to Lingotek TMS
134
  *
include/group.php CHANGED
@@ -208,7 +208,7 @@ abstract class Lingotek_Group {
208
  * @param object $source_language language of the source
209
  */
210
  protected function _request_translations($source_language) {
211
-
212
  $type_id;
213
  $client = new Lingotek_API();
214
 
208
  * @param object $source_language language of the source
209
  */
210
  protected function _request_translations($source_language) {
211
+
212
  $type_id;
213
  $client = new Lingotek_API();
214
 
include/model.php CHANGED
@@ -230,8 +230,8 @@ class Lingotek_Model {
230
  if (!is_wp_error($new_post_id)) {
231
  PLL()->model->post->set_language($new_post_id, $cp_lang);
232
  wp_set_object_terms($new_post_id, $document->term_id, 'post_translations');
233
- $GLOBALS['polylang']->sync->copy_taxonomies($document->source, $new_post_id, $cp_lang->slug);
234
- $GLOBALS['polylang']->sync->copy_post_metas($document->source, $new_post_id, $cp_lang->slug);
235
  Lingotek_Group_Post::copy_or_ignore_metas($post->ID, $new_post_id);
236
  $document->desc_array[$target] = $new_post_id;
237
  $document->save();
@@ -245,7 +245,7 @@ class Lingotek_Model {
245
 
246
  public function copy_term($term, $target, $taxonomy) {
247
  self::$copying_term = true;
248
- $document = $this->get_group('term', $term->term_id);
249
  $cp_lang = $this->pllm->get_language($target);
250
  $cp_term = (array) $term;
251
  //unset($cp_term['term_id']);
@@ -317,7 +317,10 @@ class Lingotek_Model {
317
  'workflow_id' => self::get_profile_option('workflow_id', $post->post_type, $language, false, $post_id),
318
  'external_url' => $external_url,
319
  );
320
-
 
 
 
321
  $filter_ids = array();
322
  if (self::get_profile_option('primary_filter_id', $post->post_type, $language, false, $post_id)) {
323
  $filter_ids['fprm_id'] = self::get_profile_option('primary_filter_id',$post->post_type, $language, false, $post_id);
@@ -406,7 +409,7 @@ class Lingotek_Model {
406
 
407
  // If a translation profile has targets set to copy then copy them
408
  $targets_to_copy = $this->targets_to_be_copied($profile);
409
- if (!empty($targets_to_copy)) {
410
  foreach ($targets_to_copy as $target) {
411
  $this->copy_term($term, $target, $taxonomy);
412
  }
230
  if (!is_wp_error($new_post_id)) {
231
  PLL()->model->post->set_language($new_post_id, $cp_lang);
232
  wp_set_object_terms($new_post_id, $document->term_id, 'post_translations');
233
+ $GLOBALS['polylang']->sync->taxonomies->copy($document->source, $new_post_id, $cp_lang->slug);
234
+ $GLOBALS['polylang']->sync->post_metas->copy($document->source, $new_post_id, $cp_lang->slug);
235
  Lingotek_Group_Post::copy_or_ignore_metas($post->ID, $new_post_id);
236
  $document->desc_array[$target] = $new_post_id;
237
  $document->save();
245
 
246
  public function copy_term($term, $target, $taxonomy) {
247
  self::$copying_term = true;
248
+ $document = $this->get_group('term', $term->term_id);
249
  $cp_lang = $this->pllm->get_language($target);
250
  $cp_term = (array) $term;
251
  //unset($cp_term['term_id']);
317
  'workflow_id' => self::get_profile_option('workflow_id', $post->post_type, $language, false, $post_id),
318
  'external_url' => $external_url,
319
  );
320
+ foreach (array('author_email', 'author_name','division','unit','campaign_id','channel','contact_email','contact_name','description','domain','style_id','purchase_order','reference_url','region','require_review') as $key) {
321
+ if (isset($profile[$key]) )
322
+ $params[$key] = $profile[$key];
323
+ }
324
  $filter_ids = array();
325
  if (self::get_profile_option('primary_filter_id', $post->post_type, $language, false, $post_id)) {
326
  $filter_ids['fprm_id'] = self::get_profile_option('primary_filter_id',$post->post_type, $language, false, $post_id);
409
 
410
  // If a translation profile has targets set to copy then copy them
411
  $targets_to_copy = $this->targets_to_be_copied($profile);
412
+ if (!empty($targets_to_copy) && $upload == 'automatic') {
413
  foreach ($targets_to_copy as $target) {
414
  $this->copy_term($term, $target, $taxonomy);
415
  }
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.3.7
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
@@ -16,7 +16,7 @@ if ( ! function_exists( 'add_action' ) ) {
16
  exit();
17
  }
18
 
19
- define( 'LINGOTEK_VERSION', '1.3.7' ); // plugin version (should match above meta).
20
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
21
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) ); // plugin name as known by WP.
22
  define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );// plugin slug (should match above meta: Text Domain).
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.3.8
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
16
  exit();
17
  }
18
 
19
+ define( 'LINGOTEK_VERSION', '1.3.8' ); // plugin version (should match above meta).
20
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
21
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) ); // plugin name as known by WP.
22
  define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );// plugin slug (should match above meta: Text Domain).
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: 4.9
7
- Stable tag: 1.3.7
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -119,9 +119,16 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
119
  2. Polylang and Lingotek work together seamlessly. Continue to use Polylang for content that you want to translate inside WordPress, while sending other content to be translated by Lingotek. The orange icons indicate Lingotek statuses/actions while the blue icons continue to represent Polylang actions.
120
  3. Use translation profiles. One of the most time-consuming activities of any multilingual web-site project is managing the ongoing flow of changes and additions to site content and configurations. Translation profiles were created to allow you to create and save and re-use your translation settings.
121
  4. Content type profiles. Manually choosing which content to upload and download is rarely what a content administrator wants to do, and automating the upload of every change is not workable because there are various types of content. Each type of translatable content can be assigned to a customizable profile. For example, by default, we like to have Posts use an Automatic profile so that content will automatically be uploaded for translation and the resulting translations automatically be downloaded back into WordPress.
 
122
 
123
  == Changelog ==
124
 
 
 
 
 
 
 
125
  = 1.3.7 (2018-2-23) =
126
 
127
  * Added ability to download translations at any point of the content's workflow
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
  Tested up to: 4.9
7
+ Stable tag: 1.3.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
119
  2. Polylang and Lingotek work together seamlessly. Continue to use Polylang for content that you want to translate inside WordPress, while sending other content to be translated by Lingotek. The orange icons indicate Lingotek statuses/actions while the blue icons continue to represent Polylang actions.
120
  3. Use translation profiles. One of the most time-consuming activities of any multilingual web-site project is managing the ongoing flow of changes and additions to site content and configurations. Translation profiles were created to allow you to create and save and re-use your translation settings.
121
  4. Content type profiles. Manually choosing which content to upload and download is rarely what a content administrator wants to do, and automating the upload of every change is not workable because there are various types of content. Each type of translatable content can be assigned to a customizable profile. For example, by default, we like to have Posts use an Automatic profile so that content will automatically be uploaded for translation and the resulting translations automatically be downloaded back into WordPress.
122
+ 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.
123
 
124
  == Changelog ==
125
 
126
+ = 1.3.8 (2018-7-11) =
127
+
128
+ * Added document metadata fields to translation profiles
129
+ * Added manual copying of categories and tags
130
+ * Fixed other minor bugs
131
+
132
  = 1.3.7 (2018-2-23) =
133
 
134
  * Added ability to download translations at any point of the content's workflow