Lingotek Translation - Version 1.1.1

Version Description

(2015-09-11) =

  • Added better logging and display of Lingotek API errors
  • New Translation Profile option to copy content from source language to target languages
  • Fixes for display of selected Profile
  • Minor fixes for real-time translation status updates
Download this release

Release Info

Developer erichie
Plugin Icon 128x128 Lingotek Translation
Version 1.1.1
Comparing to
See all releases

Code changes from version 1.1 to 1.1.1

admin/actions.php CHANGED
@@ -94,6 +94,11 @@ abstract class Lingotek_Actions {
94
  'title' => __('The target translation is no longer current as the source content has been updated', 'wp-lingotek'),
95
  'icon' => 'edit'
96
  ),
 
 
 
 
 
97
  );
98
 
99
  $this->type = $type;
@@ -181,6 +186,19 @@ abstract class Lingotek_Actions {
181
  self::$icons[$name]['icon'], self::$icons[$name]['title'], esc_url($link), $additional);
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  /*
185
  * outputs an upload icon
186
  *
@@ -294,8 +312,14 @@ abstract class Lingotek_Actions {
294
 
295
  // remove disabled target language from untranslated languages list
296
  foreach ($untranslated as $k => $v) {
297
- if ($document->is_disabled_target($this->pllm->get_language($k)))
 
 
 
 
 
298
  unset($untranslated[$k]);
 
299
  }
300
 
301
  if ('current' == $document->status && !empty($untranslated))
@@ -418,8 +442,9 @@ abstract class Lingotek_Actions {
418
 
419
  if ($document = $this->lgtm->get_group($this->type, $_POST['id'])) {
420
  foreach ($document->translations as $locale => $status) {
421
- if ('pending' == $status || 'ready' == $status)
422
  $document->create_translation($locale);
 
423
  }
424
  }
425
  die();
@@ -432,8 +457,9 @@ abstract class Lingotek_Actions {
432
  */
433
  public function ajax_request() {
434
  check_ajax_referer('lingotek_progress', '_lingotek_nonce');
435
- if ($document = $this->lgtm->get_group($this->type, $_POST['id']))
436
  $document->request_translations();
 
437
  die();
438
  }
439
 
@@ -458,8 +484,9 @@ abstract class Lingotek_Actions {
458
  */
459
  public function ajax_delete() {
460
  check_ajax_referer('lingotek_progress', '_lingotek_nonce');
461
- if ($document = $this->lgtm->get_group($this->type, $_POST['id']))
462
- $document->disassociate();
 
463
  die();
464
  }
465
  }
94
  'title' => __('The target translation is no longer current as the source content has been updated', 'wp-lingotek'),
95
  'icon' => 'edit'
96
  ),
97
+
98
+ 'error' => array(
99
+ 'title' => __('There was an error contacting Lingotek', 'wp-lingotek'),
100
+ 'icon' => 'warning'
101
+ ),
102
  );
103
 
104
  $this->type = $type;
186
  self::$icons[$name]['icon'], self::$icons[$name]['title'], esc_url($link), $additional);
187
  }
188
 
189
+ /*
190
+ * outputs an API error icon
191
+ *
192
+ * @since 0.2
193
+ *
194
+ * @param string $name
195
+ * @param string $additional parameters to add (js, target)
196
+ */
197
+ public static function display_error_icon($name, $api_error, $additional = '') {
198
+ return sprintf('<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
199
+ self::$icons[$name]['icon'], self::$icons[$name]['title'] . "\n" . $api_error, $additional);
200
+ }
201
+
202
  /*
203
  * outputs an upload icon
204
  *
312
 
313
  // remove disabled target language from untranslated languages list
314
  foreach ($untranslated as $k => $v) {
315
+ if ($this->type == 'term') {
316
+ if ($document->is_disabled_target($language, $this->pllm->get_language($k)))
317
+ unset($untranslated[$k]);
318
+ }
319
+ else {
320
+ if ($document->is_disabled_target($language, $this->pllm->get_language($k)))
321
  unset($untranslated[$k]);
322
+ }
323
  }
324
 
325
  if ('current' == $document->status && !empty($untranslated))
442
 
443
  if ($document = $this->lgtm->get_group($this->type, $_POST['id'])) {
444
  foreach ($document->translations as $locale => $status) {
445
+ if ('pending' == $status || 'ready' == $status) {
446
  $document->create_translation($locale);
447
+ }
448
  }
449
  }
450
  die();
457
  */
458
  public function ajax_request() {
459
  check_ajax_referer('lingotek_progress', '_lingotek_nonce');
460
+ if ($document = $this->lgtm->get_group($this->type, $_POST['id'])) {
461
  $document->request_translations();
462
+ }
463
  die();
464
  }
465
 
484
  */
485
  public function ajax_delete() {
486
  check_ajax_referer('lingotek_progress', '_lingotek_nonce');
487
+ if ($document = $this->lgtm->get_group($this->type, $_POST['id'])) {
488
+ $document->disassociate();
489
+ }
490
  die();
491
  }
492
  }
admin/admin.php CHANGED
@@ -31,7 +31,6 @@ class Lingotek_Admin {
31
  add_action('network_admin_menu', array($this, 'add_network_admin_menu'));
32
  }
33
  public function ajax_get_current_status(){
34
- global $wpdb;
35
  $lgtm = &$GLOBALS['wp_lingotek']->model;
36
  $pllm = $GLOBALS['polylang']->model;
37
  $languages = pll_languages_list(array('fields' => 'locale'));
@@ -40,72 +39,83 @@ class Lingotek_Admin {
40
  return;
41
  }
42
  $terms = isset($_POST['terms_translations']);
43
- $taxonomy = $terms ? 'term'
44
- : 'post';
45
 
46
  //The main array consists of
47
  //ids and nonces. Each id has a source language, languages with statuses, and a workbench link
48
  $content_metadata = array();
49
  foreach($object_ids as $object_id) {
50
  $id = $object_id;
51
- if ($taxonomy == 'post') {
52
- $content_metadata[$id] = array(
53
- 'existing_trans' => false,
54
- 'source' => false,
55
- 'doc_id' => null,
56
- 'source_id' => null,
57
- 'source_status' => null,
58
- );
59
- }
60
-
61
- $document = $lgtm->get_group($taxonomy, $object_id);
62
- if ($document && isset($document->source) && isset($document->document_id) && isset($document->status) && isset($document->translations)) {
63
- if($document->source !== $object_id){
64
- $document = $lgtm->get_group($taxonomy, $document->source);
65
- }
66
- $source_id = $document->source !== null ? $document->source : $object_id;
67
- $source_language = $terms ? pll_get_term_language($document->source, 'locale')
68
- : pll_get_post_language($document->source, 'locale');
69
- $existing_translations = $pllm->get_translations($taxonomy, $source_id);
70
-
71
- if(count($existing_translations) > 1){
72
- $content_metadata[$id]['existing_trans'] = true;
73
- }
74
- $content_metadata[$id]['source'] = $source_language;
75
- $content_metadata[$id]['doc_id'] = $document->document_id;
76
- $content_metadata[$id]['source_id'] = $document->source;
77
- $content_metadata[$id]['source_status'] = $document->status;
78
- $target_status = $document->status == 'edited' || $document->status == null ? 'edited' : 'current';
79
- $content_metadata[$id][$source_language]['status'] = $document->source == $object_id ? $document->status : $target_status;
80
-
81
- //fills in missing languages to be able to update all the ones listed on Wordpress
82
- foreach ($languages as $language) {
83
- foreach ($content_metadata as $group => $status) {
84
- if (!isset($status[$language])) {
85
- $content_metadata[$group][$language]['status'] = "none";
86
- if ($document->is_disabled_target($pllm->get_language($language))) {
87
- $content_metadata[$group][$language]['status'] = 'disabled';
88
- }
 
 
 
 
 
 
89
  }
90
- }
91
- }
92
- if(is_array($document->translations)){
93
- foreach($document->translations as $locale => $translation_status) {
94
- $content_metadata[$id][$locale]['status'] = $translation_status;
95
- $workbench_link = Lingotek_Actions::workbench_link($document->document_id, $locale);
96
- $content_metadata[$id][$locale]['workbench_link'] = $workbench_link;
97
- }
98
- }
99
- }
100
- $language = pll_get_post_language($id);
101
- $post_language = $pllm->get_language($language);
102
- $taxonomy = get_post_type($id);
103
- if ($post_language) {
104
- $profile = Lingotek_Model::get_profile($taxonomy, $post_language, $id);
105
- if ($profile['profile'] == 'disabled') {
106
- $content_metadata[$id]['source'] = 'disabled';
107
  }
108
  }
 
 
 
 
 
 
 
 
 
109
  }
110
 
111
  //get the nonces associated with the different actions
31
  add_action('network_admin_menu', array($this, 'add_network_admin_menu'));
32
  }
33
  public function ajax_get_current_status(){
 
34
  $lgtm = &$GLOBALS['wp_lingotek']->model;
35
  $pllm = $GLOBALS['polylang']->model;
36
  $languages = pll_languages_list(array('fields' => 'locale'));
39
  return;
40
  }
41
  $terms = isset($_POST['terms_translations']);
 
 
42
 
43
  //The main array consists of
44
  //ids and nonces. Each id has a source language, languages with statuses, and a workbench link
45
  $content_metadata = array();
46
  foreach($object_ids as $object_id) {
47
  $id = $object_id;
48
+ $type = $terms ? 'term' : 'post';
49
+ if (isset($_POST['taxonomy'])) {
50
+ $taxonomy = $_POST['taxonomy'];
51
+ if (strpos($_POST['taxonomy'], '&')) {
52
+ $taxonomy = strstr($_POST['taxonomy'], '&', true);
53
+ }
54
+ }
55
+ else {
56
+ $taxonomy = get_post_type($id);
57
+ }
58
+ $content_metadata[$id] = array(
59
+ 'existing_trans' => false,
60
+ 'source' => false,
61
+ 'doc_id' => null,
62
+ 'source_id' => null,
63
+ 'source_status' => null,
64
+ );
65
+
66
+ $document = $lgtm->get_group($type, $object_id);
67
+ if ($document && isset($document->source) && isset($document->document_id) && isset($document->status) && isset($document->translations)) {
68
+ if($document->source !== (int) $object_id){
69
+ $document = $lgtm->get_group($type, $document->source);
70
+ }
71
+ $source_id = $document->source !== null ? $document->source : $object_id;
72
+ $source_language = $terms ? pll_get_term_language($document->source, 'locale')
73
+ : pll_get_post_language($document->source, 'locale');
74
+ $existing_translations = $pllm->get_translations($type, $source_id);
75
+
76
+ if(count($existing_translations) > 1){
77
+ $content_metadata[$id]['existing_trans'] = true;
78
+ }
79
+ $content_metadata[$id]['source'] = $source_language;
80
+ $content_metadata[$id]['doc_id'] = $document->document_id;
81
+ $content_metadata[$id]['source_id'] = $document->source;
82
+ $content_metadata[$id]['source_status'] = $document->status;
83
+ $target_status = $document->status == 'edited' || $document->status == null ? 'edited' : 'current';
84
+ $content_metadata[$id][$source_language]['status'] = $document->source == $object_id ? $document->status : $target_status;
85
+
86
+ if(is_array($document->translations)){
87
+ foreach($document->translations as $locale => $translation_status) {
88
+ $content_metadata[$id][$locale]['status'] = $translation_status;
89
+ $workbench_link = Lingotek_Actions::workbench_link($document->document_id, $locale);
90
+ $content_metadata[$id][$locale]['workbench_link'] = $workbench_link;
91
+ }
92
  }
93
+
94
+ //fills in missing languages, makes life easier for the updater
95
+ foreach ($languages as $language) {
96
+ foreach ($content_metadata as $group => $status) {
97
+ $language_obj = $pllm->get_language($source_language);
98
+ $profile = Lingotek_Model::get_profile($taxonomy, $language_obj, $group);
99
+ if ($profile['profile'] != 'disabled' && $status['source'] != false) {
100
+ if (!isset($status[$language])) {
101
+ $content_metadata[$group][$language]['status'] = "none";
102
+ if ($document->is_disabled_target($pllm->get_language($source_language), $pllm->get_language($language))) {
103
+ $content_metadata[$group][$language]['status'] = 'disabled';
104
+ }
105
+ }
106
+ }
107
+ }
 
 
108
  }
109
  }
110
+
111
+ $language = $type == 'post' ? pll_get_post_language($id) : pll_get_term_language($id);
112
+ $language = $pllm->get_language($language);
113
+ if ($language) {
114
+ $profile = Lingotek_Model::get_profile($taxonomy, $language, $id);
115
+ if ($profile['profile'] == 'disabled' && $content_metadata[$id]['source'] == false) {
116
+ $content_metadata[$id]['source'] = 'disabled';
117
+ }
118
+ }
119
  }
120
 
121
  //get the nonces associated with the different actions
admin/filters-columns.php CHANGED
@@ -105,13 +105,13 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
105
  // post ready for upload
106
  if ($this->lgtm->can_upload($type, $object_id) && $object_id == $id) {
107
  return $disabled ?
108
- ('post' == $type ? parent::post_column($column, $object_id)
109
- : parent::term_column('', $column, $object_id))
110
  : $actions->upload_icon($object_id);
111
  }
112
 
113
  // translation disabled
114
- elseif (isset($document->source) && $document->is_disabled_target($language)) {
115
  return 'post' == $type ? parent::post_column($column, $object_id) : parent::term_column('', $column, $object_id);
116
  }
117
 
@@ -131,6 +131,10 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
131
  return 'post' == $type ? Lingotek_Post_actions::uploaded_icon($id) : Lingotek_Term_actions::uploaded_icon($id);
132
  }
133
 
 
 
 
 
134
  // translations
135
  elseif (isset($document->translations[$language->locale]) || (isset($document->source) && 'current' == $document->status)){
136
  return Lingotek_Actions::translation_icon($document, $language);
@@ -138,8 +142,8 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
138
 
139
  // translations exist but are not managed by Lingotek TMS
140
  elseif (empty($document->source)) {
141
- return $object_id == $id && !$disabled ? $actions->upload_icon($object_id, true)
142
- : ('post' == $type ? parent::post_column($column, $object_id)
143
  : parent::term_column('', $column, $object_id));
144
  }
145
 
@@ -160,7 +164,27 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
160
  */
161
  public function post_column($column, $post_id) {
162
  $this->content_type = get_post_type($post_id);
 
163
  echo $this->_column('post', $column, $post_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
 
166
  /*
@@ -182,4 +206,54 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
182
  return $this->_column('term', $column, $term_id, $custom_data);
183
  }
184
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }
105
  // post ready for upload
106
  if ($this->lgtm->can_upload($type, $object_id) && $object_id == $id) {
107
  return $disabled ?
108
+ ('post' == $type ? parent::post_column($column, $object_id)
109
+ : parent::term_column('', $column, $object_id))
110
  : $actions->upload_icon($object_id);
111
  }
112
 
113
  // translation disabled
114
+ elseif (isset($document->source) && $document->is_disabled_target($lang, $language) && !isset($document->translations[$language->locale])) {
115
  return 'post' == $type ? parent::post_column($column, $object_id) : parent::term_column('', $column, $object_id);
116
  }
117
 
131
  return 'post' == $type ? Lingotek_Post_actions::uploaded_icon($id) : Lingotek_Term_actions::uploaded_icon($id);
132
  }
133
 
134
+ elseif ($type == 'term' && !isset($document->translations[$language->locale]) && $document->source != $object_id) {
135
+ return parent::term_column('', $column, $object_id);
136
+ }
137
+
138
  // translations
139
  elseif (isset($document->translations[$language->locale]) || (isset($document->source) && 'current' == $document->status)){
140
  return Lingotek_Actions::translation_icon($document, $language);
142
 
143
  // translations exist but are not managed by Lingotek TMS
144
  elseif (empty($document->source)) {
145
+ return $object_id == $id && !$disabled ? $actions->upload_icon($object_id, true)
146
+ : ('post' == $type ? parent::post_column($column, $object_id)
147
  : parent::term_column('', $column, $object_id));
148
  }
149
 
164
  */
165
  public function post_column($column, $post_id) {
166
  $this->content_type = get_post_type($post_id);
167
+
168
  echo $this->_column('post', $column, $post_id);
169
+
170
+ // checking for api errors
171
+ $column_language_only = substr($column, 0, 11);
172
+ $group = $this->lgtm->get_group('post', $post_id);
173
+
174
+ if ($group) {
175
+ $source = $group->desc_array['lingotek']['source'];
176
+ // remove the remnants of previous API errors if there aren't any current errors
177
+ if (isset($group->desc_array['lingotek']['api_errors'])) {
178
+ $api_errors = $group->desc_array['lingotek']['api_errors'];
179
+ if (empty($api_errors)) {
180
+ unset($group->desc_array['lingotek']['api_errors']);
181
+ }
182
+ }
183
+ if ($column_language_only == $this->get_first_language_column() && $post_id === $source && isset($group->desc_array['lingotek']['api_errors'])) {
184
+ $error = $this->retrieve_api_error($group);
185
+ echo Lingotek_Actions::display_error_icon('error', $error);
186
+ }
187
+ }
188
  }
189
 
190
  /*
206
  return $this->_column('term', $column, $term_id, $custom_data);
207
  }
208
  }
209
+
210
+
211
+ /*
212
+ * collects and returns all API errors in the group object
213
+ *
214
+ * @since 1.1
215
+ *
216
+ * @param string $group
217
+ */
218
+ protected function retrieve_api_error($group) {
219
+ $api_error = "\n";
220
+
221
+ if (isset($group->desc_array['lingotek']['api_errors']['source_status'])){
222
+ $source_status = $group->desc_array['lingotek']['api_errors']['source_status'];
223
+ $api_error = $api_error . $source_status . "\n";
224
+ }
225
+ if (isset($group->desc_array['lingotek']['api_errors']['translations_status'])){
226
+ $translations_status = $group->desc_array['lingotek']['api_errors']['translations_status'];
227
+ $api_error = $api_error . $translations_status . "\n";
228
+ }
229
+ if (isset($group->desc_array['lingotek']['api_errors']['request_translation'])){
230
+ $request_translation = $group->desc_array['lingotek']['api_errors']['request_translation'];
231
+ $api_error = $api_error . $request_translation . "\n";
232
+ }
233
+ if (isset($group->desc_array['lingotek']['api_errors']['_request_translations'])) {
234
+ $request_translations = $group->desc_array['lingotek']['api_errors']['_request_translations'];
235
+ foreach ($request_translations as $lang => $error) {
236
+ $api_error = $api_error . $error . "\n";
237
+ }
238
+ }
239
+ if (isset($group->desc_array['lingotek']['api_errors']['create_translation'])) {
240
+ $create_translation = $group->desc_array['lingotek']['api_errors']['create_translation'];
241
+ foreach ($create_translation as $locale => $error) {
242
+ $api_error = $api_error . $error . "\n";
243
+ }
244
+ }
245
+ if (isset($group->desc_array['lingotek']['api_errors']['disassociate'])) {
246
+ $disassociate = $group->desc_array['lingotek']['api_errors']['disassociate'];
247
+ $api_error = $api_error . $disassociate . "\n";
248
+ }
249
+ if (isset($group->desc_array['lingotek']['api_errors']['patch'])) {
250
+ $patch = $group->desc_array['lingotek']['api_errors']['patch'];
251
+ $api_error = $api_error . $patch . "\n";
252
+ }
253
+ if (isset($group->desc_array['lingotek']['api_errors']['upload'])) {
254
+ $upload = $group->desc_array['lingotek']['api_errors']['upload'];
255
+ $api_error = $api_error . $upload . "\n";
256
+ }
257
+ return $api_error;
258
+ }
259
  }
admin/filters-post.php CHANGED
@@ -90,15 +90,23 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
90
  $post_type = $_REQUEST['post_type'];
91
  }
92
 
93
- if (isset($content_profiles[$post_type]['sources'][$post_language->slug])) {
 
 
 
94
  $profile = $content_profiles[$post_type]['sources'][$post_language->slug];
95
  echo $profiles[$profile]['name'];
96
  }
97
- else if ($post_profile) {
98
- echo $profiles[$post_profile->description]['name'] . sprintf('<a title="%s">%s</a>', __('Not set to the content default profile', 'wp-lingotek'), '*');
99
  }
100
  else {
101
- echo $profiles[$content_profiles[$post_type]['profile']]['name'];
 
 
 
 
 
102
  }
103
  }
104
  }
90
  $post_type = $_REQUEST['post_type'];
91
  }
92
 
93
+ if ($post_profile) {
94
+ echo $profiles[$post_profile->description]['name'] . sprintf('<a title="%s">%s</a>', __('Not set to the content default profile', 'wp-lingotek'), '*');
95
+ }
96
+ else if ($post_language && isset($content_profiles[$post_type]['sources'][$post_language->slug])) {
97
  $profile = $content_profiles[$post_type]['sources'][$post_language->slug];
98
  echo $profiles[$profile]['name'];
99
  }
100
+ else if (!empty($content_profiles)) {
101
+ echo $profiles[$content_profiles[$post_type]['profile']]['name'];
102
  }
103
  else {
104
+ if ($post_type == 'post') {
105
+ _e('Automatic', 'wp-lingotek');
106
+ }
107
+ else if ($post_type == 'page') {
108
+ _e('Manual', 'wp-lingotek');
109
+ }
110
  }
111
  }
112
  }
admin/manage/view-edit-profile.php CHANGED
@@ -14,6 +14,7 @@ foreach ($settings as $key => $setting) {
14
  $target_settings = array(
15
  'default' => __('Use default settings', 'wp-lingotek'),
16
  'custom' => __('Use custom settings', 'wp-lingotek'),
 
17
  'disabled' => __('Disabled', 'wp-lingotek')
18
  );
19
 
@@ -125,7 +126,7 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
125
 
126
  foreach ($this->pllm->get_languages_list() as $language) { ?>
127
  <tr>
128
- <th scope="row"><?php printf('<label for="%s">%s</label>', esc_attr($language->slug) , esc_html($language->name)); ?><?php
129
 
130
  printf('<a id="%1$s_details_link" %2$s class="dashicons dashicons-arrow-right" onclick="%3$s">%4$s</a>',
131
  esc_attr($language->slug),
14
  $target_settings = array(
15
  'default' => __('Use default settings', 'wp-lingotek'),
16
  'custom' => __('Use custom settings', 'wp-lingotek'),
17
+ 'copy' => __('Copy source language', 'wp-lingotek'),
18
  'disabled' => __('Disabled', 'wp-lingotek')
19
  );
20
 
126
 
127
  foreach ($this->pllm->get_languages_list() as $language) { ?>
128
  <tr>
129
+ <th scope="row"><?php printf('<label for="%s">%s (%s)</label>', esc_attr($language->slug) , esc_html($language->name), esc_attr($language->locale)); ?><?php
130
 
131
  printf('<a id="%1$s_details_link" %2$s class="dashicons dashicons-arrow-right" onclick="%3$s">%4$s</a>',
132
  esc_attr($language->slug),
admin/manage/view-profiles.php CHANGED
@@ -55,6 +55,7 @@ if (!empty($_POST)) {
55
  }
56
 
57
  case 'disabled':
 
58
  $profiles[$profile]['targets'][$language->slug] = $_POST['targets'][$language->slug];
59
  break;
60
 
55
  }
56
 
57
  case 'disabled':
58
+ case 'copy':
59
  $profiles[$profile]['targets'][$language->slug] = $_POST['targets'][$language->slug];
60
  break;
61
 
admin/manage/view-string-groups.php CHANGED
@@ -1,4 +1,5 @@
1
  <h3><?php _e('String Groups', 'wp-lingotek'); ?></h3>
 
2
  <p class="description"><?php printf(__('Manage group translation of system, widget, and plugin-specific strings. View individual strings on the <a href="%s"><b>Strings</b></a> page.', 'wp-lingotek'), 'admin.php?page=wp-lingotek_manage&sm=strings'); ?></p>
3
  <?php
4
 
@@ -27,7 +28,7 @@ else {
27
 
28
  $table->prepare_items($data); ?>
29
 
30
- <form id="lingotek-strings" method="post" action="admin.php?page=wp-lingotek_manage&amp;noheader=true"><?php
31
  $table->display(); ?>
32
  </form><?php
33
 
1
  <h3><?php _e('String Groups', 'wp-lingotek'); ?></h3>
2
+
3
  <p class="description"><?php printf(__('Manage group translation of system, widget, and plugin-specific strings. View individual strings on the <a href="%s"><b>Strings</b></a> page.', 'wp-lingotek'), 'admin.php?page=wp-lingotek_manage&sm=strings'); ?></p>
4
  <?php
5
 
28
 
29
  $table->prepare_items($data); ?>
30
 
31
+ <form id="lingotek-strings" method="post" action="admin.php?page=wp-lingotek_manage&amp;noheader=true&amp;sm=string-groups"><?php
32
  $table->display(); ?>
33
  </form><?php
34
 
admin/post-actions.php CHANGED
@@ -225,15 +225,23 @@ class Lingotek_Post_actions extends Lingotek_Actions {
225
  * @since 0.1
226
  */
227
  public static function lingotek_edit_meta_box_html() {
 
 
228
  global $post;
229
  $post_type = get_post_type($post->ID);
230
  $lgtm = new Lingotek_Model();
231
  $group = $lgtm->get_group('post', $post->ID);
232
  $profiles = Lingotek::get_profiles();
233
  $content_profiles = get_option('lingotek_content_type');
 
 
234
  $content_default_profile = array('default' => array(
235
- 'name' => __('Content Default (', 'wp-lingotek') . $profiles[$content_profiles[$post->post_type]['profile']]['name'] . ')', // Adds in the name of the content type default profile
236
  ));
 
 
 
 
237
  $profiles = array_merge($content_default_profile, $profiles);
238
  $post_profile = self::get_post_profile($post->ID);
239
  if (isset($post_profile)) {
@@ -262,17 +270,18 @@ class Lingotek_Post_actions extends Lingotek_Actions {
262
  printf('<strong>%s</strong><br><br>', __('Translation Profile', 'wp-lingotek'));
263
  printf('<em>%s</em><br>', __('Disassociate this content to change the Translation Profile', 'wp-lingotek'));
264
  printf(('<a class="button button-small" href="%s" %s>%s</a><br><br>'), esc_url($disassociate_url), $confirm_message, __('Disassociate', 'wp-lingotek'));
265
- printf('<select disabled class="custom-field-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
266
  }
267
  else {
268
  printf('<strong>%s</strong><br><br>', __('Translation Profile', 'wp-lingotek'));
269
- printf('<select class="custom-field-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
270
  }
271
 
272
  foreach ($profiles as $key => $profile) {
273
  echo "\n\t<option value=" . esc_attr($key) . ">" . esc_attr($profile['name']) . '</option>';
274
  }
275
  echo '</select>';
 
276
  }
277
 
278
  public function lingotek_save_meta_boxes() {
@@ -287,9 +296,6 @@ class Lingotek_Post_actions extends Lingotek_Actions {
287
  $post_language = $this->get_language($post->ID);
288
  $content_profiles = get_option('lingotek_content_type');
289
 
290
- if ($profile_choice == 'default' && isset($content_profiles[$post->post_type]['sources'][$post_language->slug])) {
291
- $profile_choice = $content_profiles[$post->post_type]['sources'][$post_language->slug];
292
- }
293
  if ($profile_choice == 'default' && !empty($term)) {
294
  wp_delete_term((int) $term->term_id, 'lingotek_profile');
295
  }
@@ -315,4 +321,17 @@ class Lingotek_Post_actions extends Lingotek_Actions {
315
  return 'false';
316
  }
317
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  }
225
  * @since 0.1
226
  */
227
  public static function lingotek_edit_meta_box_html() {
228
+ wp_enqueue_script('lingotek_defaults', LINGOTEK_URL .'/js/defaults.js');
229
+
230
  global $post;
231
  $post_type = get_post_type($post->ID);
232
  $lgtm = new Lingotek_Model();
233
  $group = $lgtm->get_group('post', $post->ID);
234
  $profiles = Lingotek::get_profiles();
235
  $content_profiles = get_option('lingotek_content_type');
236
+ $language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
237
+ $default_name = empty($content_profiles) == false ? $profiles[$content_profiles[$post->post_type]['profile']]['name'] : ($post_type == 'page' ? __('Manual', 'wp-lingotek') : __('Automatic', 'wp-lingotek'));
238
  $content_default_profile = array('default' => array(
239
+ 'name' => __('Content Default', 'wp-lingotek') . ' (' . $default_name . ')', // Adds in the name of the content type default profile
240
  ));
241
+ $language_profiles['defaults'] = array(
242
+ 'content_default' => $default_name,
243
+ 'title' => __('Content Default', 'wp-lingotek'),
244
+ );
245
  $profiles = array_merge($content_default_profile, $profiles);
246
  $post_profile = self::get_post_profile($post->ID);
247
  if (isset($post_profile)) {
270
  printf('<strong>%s</strong><br><br>', __('Translation Profile', 'wp-lingotek'));
271
  printf('<em>%s</em><br>', __('Disassociate this content to change the Translation Profile', 'wp-lingotek'));
272
  printf(('<a class="button button-small" href="%s" %s>%s</a><br><br>'), esc_url($disassociate_url), $confirm_message, __('Disassociate', 'wp-lingotek'));
273
+ printf('<select disabled class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
274
  }
275
  else {
276
  printf('<strong>%s</strong><br><br>', __('Translation Profile', 'wp-lingotek'));
277
+ printf('<select class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
278
  }
279
 
280
  foreach ($profiles as $key => $profile) {
281
  echo "\n\t<option value=" . esc_attr($key) . ">" . esc_attr($profile['name']) . '</option>';
282
  }
283
  echo '</select>';
284
+ echo '<div id="lingotek-language-profiles" style="display: none;">'.json_encode($language_profiles).'</div>';
285
  }
286
 
287
  public function lingotek_save_meta_boxes() {
296
  $post_language = $this->get_language($post->ID);
297
  $content_profiles = get_option('lingotek_content_type');
298
 
 
 
 
299
  if ($profile_choice == 'default' && !empty($term)) {
300
  wp_delete_term((int) $term->term_id, 'lingotek_profile');
301
  }
321
  return 'false';
322
  }
323
  }
324
+
325
+ public static function retrieve_lang_Profiles($post_type, $profiles, $content_profiles) {
326
+ $language_profiles = array();
327
+
328
+ if(isset($content_profiles[$post_type]['sources'])) {
329
+ $sources = $content_profiles[$post_type]['sources'];
330
+ foreach($sources as $lang_code => $profile) {
331
+ $language_profiles[$lang_code] = $profiles[$profile]['name'];
332
+ }
333
+ }
334
+
335
+ return $language_profiles;
336
+ }
337
  }
admin/tutorial/credits.php CHANGED
@@ -11,41 +11,54 @@ $team = array(
11
  'title'=>'Lead Developer',
12
  'image_url'=>'https://www.gravatar.com/avatar/d79b46c94a52b4679c308986ef05eac2',
13
  'url'=>'https://profiles.wordpress.org/smithworx'),
14
- 'brian'=>array(
15
- 'name'=>'Brian Isle',
16
- 'title'=>'Quality Assurance',
17
- 'image_url'=>'https://www.gravatar.com/avatar/5f43658c382412d8f120cb5595d9bf03',
18
- 'url'=>'https://profiles.wordpress.org/bisle'),
19
  'edward'=>array(
20
  'name'=>'Edward Richards',
21
- 'title'=>'Developer',
22
  'image_url'=>'https://www.gravatar.com/avatar/a0ab415173b16d2ac476077d587bea96',
23
  'url'=>'https://profiles.wordpress.org/erichie'),
 
 
 
24
  'calvin'=>array(
25
  'name'=>'Calvin Scharffs',
26
  'title'=>'Marketing Guru',
27
  'image_url'=>'https://www.gravatar.com/avatar/d18e8bf783f63bf893e143cf04e0034d',
28
  'url'=>'https://profiles.wordpress.org/cscharffs'),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  'brad'=>array(
30
  'name'=>'Brad Ross',
31
  'title'=>'Product Management',
32
  'image_url'=>'https://www.gravatar.com/avatar/477601d2c0c8c8dd31c021e3bae3841c',
33
  'url'=>'https://profiles.wordpress.org/bradross12/'),
 
 
 
 
 
 
 
 
 
 
34
  'laura'=>array(
35
  'name'=>'Laura White',
36
  'title'=>'Tech Writer',
37
  'image_url'=>'https://www.gravatar.com/avatar/56c44e12c3431aca766d06c6019201ff',
38
  'url'=>'https://profiles.wordpress.org/laurakaysc'),
39
- 'seth'=>array(
40
- 'name'=>'Seth White',
41
- 'title'=>'Developer',
42
- 'image_url'=>'https://www.gravatar.com/avatar/53706ce5472909827db3e582bb4bccf2',
43
- 'url'=>'https://profiles.wordpress.org/sethwhite'),
44
- 'joey'=>array(
45
- 'name'=>'Joseph Hovik',
46
- 'title'=>'Developer',
47
- 'image_url'=>'https://www.gravatar.com/avatar/171f66a729d063bb6ee4e0e51135a120',
48
- 'url'=>'https://profiles.wordpress.org/jbhovik'),
49
  );
50
 
51
  $contributors = array(
@@ -54,24 +67,24 @@ $contributors = array(
54
  'title'=>'',
55
  'image_url'=>'https://www.gravatar.com/avatar/77447d8ad56b4ba5ea8f3900b3245c41',
56
  'url'=>'https://profiles.wordpress.org/furrever'),
57
-
58
  );
59
 
60
  shuffle($team);
 
61
  shuffle($contributors);
62
 
63
  ?>
64
 
65
  <p class="about-description"><?php _e('The Lingotek plugin for WordPress is created with love.', 'wp-lingotek'); ?></p>
66
 
67
- <h4 class="wp-people-group"><?php _e('Team', 'wp-lingotek'); ?></h4>
68
 
69
  <ul class="wp-people-group">
70
  <?php
71
 
72
  foreach($team as $person_key=>$person){
73
  printf('<li class="wp-person" id="wp-person-%s">
74
- <a href="%s" target="_blank"><img src="%s?s=60&d=mm&r=G" srcset="%s?s=120&d=mm&r=G 2x" class="gravatar" alt="%s"></a>
75
  <a class="web" href="%s" target="_blank">%s</a>
76
  <span class="title">%s</span>
77
  </li>',$person_key,$person['url'],$person['image_url'],$person['image_url'],$person['name'],$person['url'],$person['name'],$person['title']);
@@ -85,9 +98,17 @@ shuffle($contributors);
85
  <ul class="wp-people-group">
86
  <?php
87
 
 
 
 
 
 
 
 
 
88
  foreach($contributors as $person_key=>$person){
89
  printf('<li class="wp-person" id="wp-person-%s">
90
- <a href="%s" target="_blank"><img src="%s?s=60&d=mm&r=G" srcset="%s?s=120&d=mm&r=G 2x" class="gravatar" alt="%s"></a>
91
  <a class="web" href="%s" target="_blank">%s</a>
92
  <span class="title">%s</span>
93
  </li>',$person_key,$person['url'],$person['image_url'],$person['image_url'],$person['name'],$person['url'],$person['name'],$person['title']);
11
  'title'=>'Lead Developer',
12
  'image_url'=>'https://www.gravatar.com/avatar/d79b46c94a52b4679c308986ef05eac2',
13
  'url'=>'https://profiles.wordpress.org/smithworx'),
 
 
 
 
 
14
  'edward'=>array(
15
  'name'=>'Edward Richards',
16
+ 'title'=>'Lead Developer',
17
  'image_url'=>'https://www.gravatar.com/avatar/a0ab415173b16d2ac476077d587bea96',
18
  'url'=>'https://profiles.wordpress.org/erichie'),
19
+ );
20
+
21
+ $team_contributors = array(
22
  'calvin'=>array(
23
  'name'=>'Calvin Scharffs',
24
  'title'=>'Marketing Guru',
25
  'image_url'=>'https://www.gravatar.com/avatar/d18e8bf783f63bf893e143cf04e0034d',
26
  'url'=>'https://profiles.wordpress.org/cscharffs'),
27
+ 'joey'=>array(
28
+ 'name'=>'Joseph Hovik',
29
+ 'title'=>'Developer',
30
+ 'image_url'=>'https://www.gravatar.com/avatar/171f66a729d063bb6ee4e0e51135a120',
31
+ 'url'=>'https://profiles.wordpress.org/jbhovik'),
32
+ 'seth'=>array(
33
+ 'name'=>'Seth White',
34
+ 'title'=>'Developer',
35
+ 'image_url'=>'https://www.gravatar.com/avatar/53706ce5472909827db3e582bb4bccf2',
36
+ 'url'=>'https://profiles.wordpress.org/sethwhite'),
37
+ 'brian'=>array(
38
+ 'name'=>'Brian Isle',
39
+ 'title'=>'Quality Assurance',
40
+ 'image_url'=>'https://www.gravatar.com/avatar/5f43658c382412d8f120cb5595d9bf03',
41
+ 'url'=>'https://profiles.wordpress.org/bisle'),
42
  'brad'=>array(
43
  'name'=>'Brad Ross',
44
  'title'=>'Product Management',
45
  'image_url'=>'https://www.gravatar.com/avatar/477601d2c0c8c8dd31c021e3bae3841c',
46
  'url'=>'https://profiles.wordpress.org/bradross12/'),
47
+ 'clark'=>array(
48
+ 'name'=>'Clark Fuller',
49
+ 'title'=>'Support',
50
+ 'image_url'=>'https://www.gravatar.com/avatar/622c9cece3cd4ff8245e93892e1ea1cc',
51
+ 'url'=>'https://profiles.wordpress.org/clarticus'),
52
+ 'nathan'=>array(
53
+ 'name'=>'Nathan Overlin',
54
+ 'title'=>'Support',
55
+ 'image_url'=>'https://www.gravatar.com/avatar/602038ac19d5295415269aedc8d6ebf4',
56
+ 'url'=>'https://profiles.wordpress.org/noverlin'),
57
  'laura'=>array(
58
  'name'=>'Laura White',
59
  'title'=>'Tech Writer',
60
  'image_url'=>'https://www.gravatar.com/avatar/56c44e12c3431aca766d06c6019201ff',
61
  'url'=>'https://profiles.wordpress.org/laurakaysc'),
 
 
 
 
 
 
 
 
 
 
62
  );
63
 
64
  $contributors = array(
67
  'title'=>'',
68
  'image_url'=>'https://www.gravatar.com/avatar/77447d8ad56b4ba5ea8f3900b3245c41',
69
  'url'=>'https://profiles.wordpress.org/furrever'),
 
70
  );
71
 
72
  shuffle($team);
73
+ shuffle($team_contributors);
74
  shuffle($contributors);
75
 
76
  ?>
77
 
78
  <p class="about-description"><?php _e('The Lingotek plugin for WordPress is created with love.', 'wp-lingotek'); ?></p>
79
 
80
+ <h4 class="wp-people-group"><?php _e('Project Leaders', 'wp-lingotek'); ?></h4>
81
 
82
  <ul class="wp-people-group">
83
  <?php
84
 
85
  foreach($team as $person_key=>$person){
86
  printf('<li class="wp-person" id="wp-person-%s">
87
+ <a href="%s" target="_blank"><img src="%s?s=60&d=monsterid&r=G" srcset="%s?s=120&d=monsterid&r=G 2x" class="gravatar" alt="%s"></a>
88
  <a class="web" href="%s" target="_blank">%s</a>
89
  <span class="title">%s</span>
90
  </li>',$person_key,$person['url'],$person['image_url'],$person['image_url'],$person['name'],$person['url'],$person['name'],$person['title']);
98
  <ul class="wp-people-group">
99
  <?php
100
 
101
+ foreach($team_contributors as $person_key=>$person){
102
+ printf('<li class="wp-person" id="wp-person-%s">
103
+ <a href="%s" target="_blank"><img src="%s?s=60&d=monsterid&r=G" srcset="%s?s=120&d=monsterid&r=G 2x" class="gravatar" alt="%s"></a>
104
+ <a class="web" href="%s" target="_blank">%s</a>
105
+ <span class="title">%s</span>
106
+ </li>',$person_key,$person['url'],$person['image_url'],$person['image_url'],$person['name'],$person['url'],$person['name'],$person['title']);
107
+ }
108
+
109
  foreach($contributors as $person_key=>$person){
110
  printf('<li class="wp-person" id="wp-person-%s">
111
+ <a href="%s" target="_blank"><img src="%s?s=60&d=monsterid&r=G" srcset="%s?s=120&d=monsterid&r=G 2x" class="gravatar" alt="%s"></a>
112
  <a class="web" href="%s" target="_blank">%s</a>
113
  <span class="title">%s</span>
114
  </li>',$person_key,$person['url'],$person['image_url'],$person['image_url'],$person['name'],$person['url'],$person['name'],$person['title']);
admin/tutorial/features.php CHANGED
@@ -1,16 +1,16 @@
1
 
2
- <div class="changelog feature-section three-col">
3
- <div>
4
  <a href="admin.php?page=wp-lingotek"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/add-languages.png'; ?>"></a>
5
  <h3><?php _e( 'Translate into new languages', 'wp-lingotek' ); ?></h3>
6
  <p><?php printf( __( 'Easily translate your site into new languages by adding the desired language to your site. Lingotek allows you to quickly add any of the most frequently used locales using the <a href="%s" title="Translation &gt; Dashboard">Translation Dashboard</a>.', 'wp-lingotek' ), 'admin.php?page=wp-lingotek' ); ?></p>
7
  </div>
8
- <div>
9
  <img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/automatic-translation.gif'; ?>">
10
  <h3><?php _e( 'Automatically translate content', 'wp-lingotek' ); ?></h3>
11
  <p><?php _e( "Machine translation is an excellent option if you're on a tight budget, looking for near-instant results, and are okay with less-than-perfect quality. The plugin allows you to quickly and automatically translate your site (the cost is covered by Lingotek for up to 100,000 characters).", 'wp-lingotek'); ?></p>
12
  </div>
13
- <div class="last-feature">
14
  <img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/polylang-compatible.png'; ?>">
15
  <h3><?php _e( 'Fully compatible with Polylang', 'wp-lingotek' ); ?></h3>
16
  <p><?php printf( __( '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 <b style="color: %s">orange</b> icons indicate Lingotek statuses/actions while the <b style="color: %s">blue</b> icons continue to represent Polylang actions.', 'wp-lingotek' ), 'darkorange', '#0473a8' ); ?></p>
@@ -19,18 +19,18 @@
19
  </div>
20
 
21
 
22
- <div class="changelog feature-section three-col">
23
- <div>
24
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-profiles.png'; ?>"></a>
25
  <h3><?php _e( 'Use translation profiles', 'wp-lingotek'); ?></h3>
26
  <p><?php _e( '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.', 'wp-lingotek'); ?></p>
27
  </div>
28
- <div>
29
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=content"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/content-types.png'; ?>"></a>
30
  <h3><?php _e( 'Content type profiles', 'wp-lingotek'); ?></h3>
31
  <p><?php _e( '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 <i>Automatic</i> profile so that content will automatically be uploaded for translation and the resulting translations automatically be downloaded back into WordPress.', 'wp-lingotek'); ?></p>
32
  </div>
33
- <div class="last-feature">
34
  <img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation.png'; ?>">
35
  <h3><?php _e( 'Request professional translation', 'wp-lingotek'); ?></h3>
36
  <p><?php _e( "Use your own translation agency or tap into Lingotek's network of more than 5,000+ in-country translators. Content transfer is fully automated between WordPress and Lingotek. You'll have full visibility into the translation process every step of the way. And once the translations are completed, they'll automatically download and publish to your website according to the preferences you've set.", 'wp-lingotek'); ?></p>
@@ -39,8 +39,8 @@
39
  </div>
40
 
41
 
42
- <div class="changelog feature-section three-col">
43
- <div>
44
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-services.png'; ?>"></a>
45
  <h3><?php _e( 'Need Extra Services?', 'wp-lingotek'); ?></h3>
46
  <p><?php _e( 'Start the process of getting extra services.', 'wp-lingotek'); ?></p>
@@ -52,8 +52,8 @@
52
  </ul>
53
  <a href="http://www.lingotek.com/wordpress/extra_services" class="button button-primary" target="_blank"><?php _e('Request Services', 'wp-lingotek'); ?></a>
54
  </div>
55
- <div>
56
  </div>
57
- <div class="last-feature">
58
  </div>
59
  </div>
1
 
2
+ <div class="feature-section three-col">
3
+ <div class="col">
4
  <a href="admin.php?page=wp-lingotek"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/add-languages.png'; ?>"></a>
5
  <h3><?php _e( 'Translate into new languages', 'wp-lingotek' ); ?></h3>
6
  <p><?php printf( __( 'Easily translate your site into new languages by adding the desired language to your site. Lingotek allows you to quickly add any of the most frequently used locales using the <a href="%s" title="Translation &gt; Dashboard">Translation Dashboard</a>.', 'wp-lingotek' ), 'admin.php?page=wp-lingotek' ); ?></p>
7
  </div>
8
+ <div class="col">
9
  <img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/automatic-translation.gif'; ?>">
10
  <h3><?php _e( 'Automatically translate content', 'wp-lingotek' ); ?></h3>
11
  <p><?php _e( "Machine translation is an excellent option if you're on a tight budget, looking for near-instant results, and are okay with less-than-perfect quality. The plugin allows you to quickly and automatically translate your site (the cost is covered by Lingotek for up to 100,000 characters).", 'wp-lingotek'); ?></p>
12
  </div>
13
+ <div class="col">
14
  <img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/polylang-compatible.png'; ?>">
15
  <h3><?php _e( 'Fully compatible with Polylang', 'wp-lingotek' ); ?></h3>
16
  <p><?php printf( __( '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 <b style="color: %s">orange</b> icons indicate Lingotek statuses/actions while the <b style="color: %s">blue</b> icons continue to represent Polylang actions.', 'wp-lingotek' ), 'darkorange', '#0473a8' ); ?></p>
19
  </div>
20
 
21
 
22
+ <div class="feature-section three-col">
23
+ <div class="col">
24
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-profiles.png'; ?>"></a>
25
  <h3><?php _e( 'Use translation profiles', 'wp-lingotek'); ?></h3>
26
  <p><?php _e( '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.', 'wp-lingotek'); ?></p>
27
  </div>
28
+ <div class="col">
29
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=content"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/content-types.png'; ?>"></a>
30
  <h3><?php _e( 'Content type profiles', 'wp-lingotek'); ?></h3>
31
  <p><?php _e( '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 <i>Automatic</i> profile so that content will automatically be uploaded for translation and the resulting translations automatically be downloaded back into WordPress.', 'wp-lingotek'); ?></p>
32
  </div>
33
+ <div class="col">
34
  <img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation.png'; ?>">
35
  <h3><?php _e( 'Request professional translation', 'wp-lingotek'); ?></h3>
36
  <p><?php _e( "Use your own translation agency or tap into Lingotek's network of more than 5,000+ in-country translators. Content transfer is fully automated between WordPress and Lingotek. You'll have full visibility into the translation process every step of the way. And once the translations are completed, they'll automatically download and publish to your website according to the preferences you've set.", 'wp-lingotek'); ?></p>
39
  </div>
40
 
41
 
42
+ <div class="feature-section three-col">
43
+ <div class="col">
44
  <a href="admin.php?page=wp-lingotek_manage&amp;sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-services.png'; ?>"></a>
45
  <h3><?php _e( 'Need Extra Services?', 'wp-lingotek'); ?></h3>
46
  <p><?php _e( 'Start the process of getting extra services.', 'wp-lingotek'); ?></p>
52
  </ul>
53
  <a href="http://www.lingotek.com/wordpress/extra_services" class="button button-primary" target="_blank"><?php _e('Request Services', 'wp-lingotek'); ?></a>
54
  </div>
55
+ <div class="col">
56
  </div>
57
+ <div class="col">
58
  </div>
59
  </div>
css/admin.css CHANGED
@@ -86,6 +86,9 @@ a.dashicons {
86
  border: 1px solid #e5e5e5;
87
  }
88
 
 
 
 
89
 
90
  /* utilities */
91
 
86
  border: 1px solid #e5e5e5;
87
  }
88
 
89
+ .lingotek-error {
90
+ color: #FF0000;
91
+ }
92
 
93
  /* utilities */
94
 
include/api.php CHANGED
@@ -187,6 +187,11 @@ class Lingotek_API extends Lingotek_HTTP {
187
  $translations[$e->properties->locale_code] = $e->properties->percent_complete;
188
  }
189
  }
 
 
 
 
 
190
 
191
  return empty($translations) ? array() : $translations;
192
  }
187
  $translations[$e->properties->locale_code] = $e->properties->percent_complete;
188
  }
189
  }
190
+ else {
191
+ if (wp_remote_retrieve_response_code($response) != 404) {
192
+ return false;
193
+ }
194
+ }
195
 
196
  return empty($translations) ? array() : $translations;
197
  }
include/group-post.php CHANGED
@@ -292,8 +292,16 @@ class Lingotek_Group_Post extends Lingotek_Group {
292
 
293
  $client = new Lingotek_API();
294
 
295
- if (false === ($translation = $client->get_translation($this->document_id, $locale)))
 
 
 
296
  return;
 
 
 
 
 
297
 
298
  self::$creating_translation = true;
299
  $prefs = Lingotek_Model::get_prefs(); // need an array by default
@@ -370,7 +378,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
370
  * @since 1.0.9
371
  */
372
 
373
- protected static function copy_or_ignore_metas($post_id, $tr_id) {
374
  // copy or ignore metas
375
  $custom_fields = get_option('lingotek_custom_fields', array());
376
  foreach ($custom_fields as $key => $setting) {
292
 
293
  $client = new Lingotek_API();
294
 
295
+ if (false === ($translation = $client->get_translation($this->document_id, $locale))) {
296
+ // Error reporting here causes problems. FIXME
297
+ // $this->desc_array['lingotek']['api_errors']['create_translation'][$locale] = __('Error downloading ', 'wp-lingotek') . $locale . __(' translation for post ', 'wp-lingotek') . $this->source;
298
+ // $this->save();
299
  return;
300
+ }
301
+ // else {
302
+ // unset($this->desc_array['lingotek']['api_errors']['create_translation'][$locale]);
303
+ // $this->save();
304
+ // }
305
 
306
  self::$creating_translation = true;
307
  $prefs = Lingotek_Model::get_prefs(); // need an array by default
378
  * @since 1.0.9
379
  */
380
 
381
+ public static function copy_or_ignore_metas($post_id, $tr_id) {
382
  // copy or ignore metas
383
  $custom_fields = get_option('lingotek_custom_fields', array());
384
  foreach ($custom_fields as $key => $setting) {
include/group.php CHANGED
@@ -139,6 +139,11 @@ abstract class Lingotek_Group {
139
  if ($res) {
140
  $this->status = 'importing';
141
  $this->translations = array_fill_keys(array_keys($this->translations), 'pending');
 
 
 
 
 
142
  $this->save();
143
  }
144
  }
@@ -151,10 +156,18 @@ abstract class Lingotek_Group {
151
  public function source_status() {
152
  $client = new Lingotek_API();
153
 
154
- if ('importing' == $this->status && $client->document_exists($this->document_id)) {
155
- $this->status = 'current';
156
- $this->save();
 
 
157
  }
 
 
 
 
 
 
158
  }
159
 
160
  /*
@@ -181,9 +194,15 @@ abstract class Lingotek_Group {
181
  $args = $workflow ? array('workflow_id' => $workflow) : array();
182
 
183
  if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
184
- $client->request_translation($this->document_id, $language->locale, $args);
185
- $this->status = 'current';
186
- $this->translations[$language->locale] = 'pending';
 
 
 
 
 
 
187
  $this->save();
188
  }
189
  }
@@ -199,12 +218,17 @@ abstract class Lingotek_Group {
199
  $client = new Lingotek_API();
200
 
201
  foreach ($this->pllm->get_languages_list() as $lang) {
202
- if ($source_language->slug != $lang->slug && !$this->is_disabled_target($lang) && empty($this->translations[$lang->locale])) {
203
  $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $source_language, $lang, $this->source);
204
  $args = $workflow ? array('workflow_id' => $workflow) : array();
205
- $client->request_translation($this->document_id, $lang->lingotek_locale, $args);
206
- $this->status = 'current';
207
- $this->translations[$lang->locale] = 'pending';
 
 
 
 
 
208
  }
209
  }
210
 
@@ -219,13 +243,20 @@ abstract class Lingotek_Group {
219
  public function translations_status() {
220
  $client = new Lingotek_API();
221
  $translations = $client->get_translations_status($this->document_id); // key are Lingotek locales
222
- foreach($this->translations as $locale => $status) {
223
- $lingotek_locale = $this->pllm->get_language($locale)->lingotek_locale;
224
- if ('current' != $status && isset($translations[$lingotek_locale]) && 100 == $translations[$lingotek_locale])
225
- $this->translations[$locale] = 'ready';
 
 
 
 
 
 
 
 
 
226
  }
227
-
228
- $this->save();
229
  }
230
 
231
  /*
@@ -294,8 +325,13 @@ abstract class Lingotek_Group {
294
  * @param string $type post type or taxonomy
295
  * @param object $language
296
  */
297
- public function is_disabled_target($language) {
298
  $profile = Lingotek_Model::get_profile($this->type, $language, $this->source);
299
- return isset($profile['targets'][$language->slug]) && 'disabled' == $profile['targets'][$language->slug];
 
 
 
 
 
300
  }
301
  }
139
  if ($res) {
140
  $this->status = 'importing';
141
  $this->translations = array_fill_keys(array_keys($this->translations), 'pending');
142
+ unset($this->desc_array['lingotek']['api_errors']['patch']);
143
+ $this->save();
144
+ }
145
+ else {
146
+ $this->desc_array['lingotek']['api_errors']['patch'] = __('Error uploading updated post ', 'wp-lingotek') . $this->source;
147
  $this->save();
148
  }
149
  }
156
  public function source_status() {
157
  $client = new Lingotek_API();
158
 
159
+ if ($client->document_exists($this->document_id)) {
160
+ unset($this->desc_array['lingotek']['api_errors']['source_status']);
161
+ if ('importing' == $this->status) {
162
+ $this->status = 'current';
163
+ }
164
  }
165
+ // note api errors
166
+ else {
167
+ $this->desc_array['lingotek']['api_errors']['source_status'] = __('Error updating translation status of post ', 'wp-lingotek') . $this->source;
168
+ }
169
+
170
+ $this->save();
171
  }
172
 
173
  /*
194
  $args = $workflow ? array('workflow_id' => $workflow) : array();
195
 
196
  if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
197
+ if ($client->request_translation($this->document_id, $language->locale, $args)) {
198
+ $this->status = 'current';
199
+ $this->translations[$language->locale] = 'pending';
200
+ unset($this->desc_array['lingotek']['api_errors']['request_translation']);
201
+ }
202
+ else {
203
+ $this->desc_array['lingotek']['api_errors']['request_translation'] = __('Error requesting translations for post ', 'wp-lingotek') . $this->source;
204
+ }
205
+
206
  $this->save();
207
  }
208
  }
218
  $client = new Lingotek_API();
219
 
220
  foreach ($this->pllm->get_languages_list() as $lang) {
221
+ if ($source_language->slug != $lang->slug && !$this->is_disabled_target($source_language, $lang) && empty($this->translations[$lang->locale])) {
222
  $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $source_language, $lang, $this->source);
223
  $args = $workflow ? array('workflow_id' => $workflow) : array();
224
+ if ($client->request_translation($this->document_id, $lang->lingotek_locale, $args)) {
225
+ $this->status = 'current';
226
+ $this->translations[$lang->locale] = 'pending';
227
+ unset($this->desc_array['lingotek']['api_errors']['_request_translations'][$lang->name]);
228
+ }
229
+ else {
230
+ $this->desc_array['lingotek']['api_errors']['_request_translations'][$lang->name] = __('Error requesting translation for ', 'wp-lingotek') . $lang->name . __(' for post ', 'wp-lingotek') . $this->source;
231
+ }
232
  }
233
  }
234
 
243
  public function translations_status() {
244
  $client = new Lingotek_API();
245
  $translations = $client->get_translations_status($this->document_id); // key are Lingotek locales
246
+ if ($translations !== false) {
247
+ foreach($this->translations as $locale => $status) {
248
+ $lingotek_locale = $this->pllm->get_language($locale)->lingotek_locale;
249
+ if ('current' != $status && isset($translations[$lingotek_locale]) && 100 == $translations[$lingotek_locale])
250
+ $this->translations[$locale] = 'ready';
251
+ }
252
+ unset($this->desc_array['lingotek']['api_errors']['translations_status']);
253
+ $this->save();
254
+ }
255
+ // take note of api errors
256
+ else {
257
+ $this->desc_array['lingotek']['api_errors']['translations_status'] = __('Error checking translations status of post ', 'wp-lingotek') . $this->source;
258
+ $this->save();
259
  }
 
 
260
  }
261
 
262
  /*
325
  * @param string $type post type or taxonomy
326
  * @param object $language
327
  */
328
+ public function is_disabled_target($language, $target = null) {
329
  $profile = Lingotek_Model::get_profile($this->type, $language, $this->source);
330
+ if ($target) {
331
+ return isset($profile['targets'][$target->slug]) && ('disabled' == $profile['targets'][$target->slug] || 'copy' == $profile['targets'][$target->slug]);
332
+ }
333
+ else {
334
+ return isset($profile['targets'][$language->slug]) && ('disabled' == $profile['targets'][$language->slug] || 'copy' == $profile['targets'][$language->slug]);
335
+ }
336
  }
337
  }
include/model.php CHANGED
@@ -151,7 +151,7 @@ class Lingotek_Model {
151
  'delete' => 1,
152
  ),
153
  );
154
- $prefs = get_option('lingotek_prefs', $default);
155
  return $prefs;
156
  }
157
 
@@ -181,6 +181,80 @@ class Lingotek_Model {
181
  return $defaults[$item];
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  /*
185
  * uploads a new post to Lingotek TMS
186
  *
@@ -228,6 +302,22 @@ class Lingotek_Model {
228
 
229
  if ($document_id) {
230
  Lingotek_Group_Post::create($post->ID , $language, $document_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  }
232
  }
233
  }
@@ -280,6 +370,14 @@ class Lingotek_Model {
280
  Lingotek_Group_Term::create($term_id, $taxonomy , $language, $document_id);
281
  }
282
  }
 
 
 
 
 
 
 
 
283
  }
284
 
285
  /*
@@ -301,10 +399,10 @@ class Lingotek_Model {
301
  $group = $strings[$group]['context'];
302
  }
303
 
304
- // check that we have a valid string group
305
  if (!in_array($group, wp_list_pluck(self::get_strings(), 'context')))
306
  return;
307
-
308
  $client = new Lingotek_API();
309
 
310
  $params = array(
@@ -461,7 +559,7 @@ class Lingotek_Model {
461
  static $r = array();
462
  if (!empty($r[$post_type]))
463
  return $r[$post_type];
464
-
465
  if (!post_type_exists($post_type))
466
  return;
467
 
@@ -478,6 +576,10 @@ class Lingotek_Model {
478
 
479
  $targets = $this->get_target_count($groups);
480
 
 
 
 
 
481
  foreach ($this->pllm->get_languages_list() as $language) {
482
  // counts all the posts in one language
483
  $n = $wpdb->get_var($wpdb->prepare("
@@ -489,8 +591,37 @@ class Lingotek_Model {
489
  $language->term_taxonomy_id, $post_type
490
  ));
491
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  // if a post is not a target, then it is source
493
  $sources[$language->slug] = $n - $targets[$language->slug];
 
494
  }
495
 
496
  // untranslated posts have no associated translation group in DB
@@ -507,13 +638,11 @@ class Lingotek_Model {
507
  'post_translations', $post_type
508
  ));
509
 
510
-
511
-
512
  // untranslated = total - translated
513
  // total of posts translations groups = untranslated + number of translation groups stored in DB
514
  $count_posts = (array) wp_count_posts($post_type);
515
  unset($count_posts['trash'], $count_posts['auto-draft']); // don't count trash and auto-draft
516
- $total = array_sum($count_posts) - $n_translated + count($groups);
517
 
518
  return $r[$post_type] = compact('sources', 'targets', 'total');
519
  }
@@ -532,7 +661,7 @@ class Lingotek_Model {
532
  static $r = array();
533
  if (!empty($r[$taxonomy]))
534
  return $r[$taxonomy];
535
-
536
  if (!taxonomy_exists($taxonomy))
537
  return;
538
 
@@ -548,6 +677,9 @@ class Lingotek_Model {
548
 
549
  $targets = $this->get_target_count($groups);
550
 
 
 
 
551
  foreach ($this->pllm->get_languages_list() as $language) {
552
  // counts all the terms in one language
553
  $n = $wpdb->get_var($wpdb->prepare("
@@ -558,8 +690,32 @@ class Lingotek_Model {
558
  $language->tl_term_taxonomy_id, $taxonomy
559
  ));
560
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
  // if a term is not a target, then it is a source
562
  $sources[$language->slug] = $n - $targets[$language->slug];
 
563
  }
564
 
565
  $total = count($groups);
@@ -594,6 +750,7 @@ class Lingotek_Model {
594
  }
595
  }
596
 
 
597
  return $r[$taxonomy] = compact('sources', 'targets', 'total');
598
  }
599
  }
151
  'delete' => 1,
152
  ),
153
  );
154
+ $prefs = array_merge($default, get_option('lingotek_prefs', $default)); // ensure defaults are set for missing keys
155
  return $prefs;
156
  }
157
 
181
  return $defaults[$item];
182
  }
183
 
184
+ /*
185
+ * find targets that are set to copy in a profile
186
+ *
187
+ * @since 1.1.1
188
+ *
189
+ * @param array $profile (use get_profile to retrieve)
190
+ * @return array of targets that should be copied. if none exist returns empty array
191
+ */
192
+ public function targets_to_be_copied($profile) {
193
+ if (isset($profile['targets']) && in_array('copy', $profile['targets'])) {
194
+ $targets_to_copy = array_keys($profile['targets'], 'copy');
195
+ return $targets_to_copy;
196
+ }
197
+ else {
198
+ return array();
199
+ }
200
+ }
201
+
202
+ /*
203
+ * copy a post from the source language to a target language
204
+ *
205
+ * @since 1.1.1
206
+ *
207
+ * @param object $post
208
+ * @param string $target polylang language slug (ex: en, de, fr, etc)
209
+ * @return $new_post_id if copy of post is successful, false otherwise
210
+ */
211
+ public function copy_post($post, $target) {
212
+ $document = $this->get_group('post', $post->ID);
213
+ $prefs = self::get_prefs();
214
+ $cp_lang = $this->pllm->get_language($target);
215
+ $cp_post = (array) $post;
216
+ $cp_post['post_status'] = ($prefs['download_post_status'] === 'SAME_AS_SOURCE')? $post->post_status : $prefs['download_post_status']; // status
217
+ unset($cp_post['ID']);
218
+ unset($cp_post['post_name']);
219
+ if (!isset($document->desc_array[$target])) {
220
+ $new_post_id = wp_insert_post($cp_post, true);
221
+ if (!is_wp_error($new_post_id)) {
222
+ $this->pllm->set_post_language($new_post_id, $cp_lang);
223
+ wp_set_object_terms($new_post_id, $document->term_id, 'post_translations');
224
+ $GLOBALS['polylang']->sync->copy_post_metas($document->source, $new_post_id, $cp_lang->slug);
225
+ Lingotek_Group_Post::copy_or_ignore_metas($post->ID, $new_post_id);
226
+ $document->desc_array[$target] = $new_post_id;
227
+ $document->save();
228
+ return $new_post_id;
229
+ }
230
+ else {
231
+ return false;
232
+ }
233
+ }
234
+ else {
235
+ return false;
236
+ }
237
+ }
238
+
239
+ public function copy_term($term, $target, $taxonomy) {
240
+ $document = $this->get_group('term', $term->term_id);
241
+ $cp_lang = $this->pllm->get_language($target);
242
+ $cp_term = (array) $term;
243
+ //unset($cp_term['term_id']);
244
+
245
+ if (isset($cp_term['slug']) && term_exists($cp_term['slug'])) {
246
+ $cp_term['slug'] .= '-' . $cp_lang->slug;
247
+ }
248
+ $new_term = wp_insert_term($cp_term['name'], $taxonomy, $cp_term);
249
+
250
+ if (!is_wp_error($new_term)) {
251
+ $this->pllm->set_term_language($new_term['term_id'], $cp_lang);
252
+ wp_set_object_terms($new_term['term_id'], $document->term_id, 'term_translations');
253
+ $document->desc_array[$target] = $new_term['term_id'];
254
+ $document->save();
255
+ }
256
+ }
257
+
258
  /*
259
  * uploads a new post to Lingotek TMS
260
  *
302
 
303
  if ($document_id) {
304
  Lingotek_Group_Post::create($post->ID , $language, $document_id);
305
+ $group = $this->get_group('post', $post_id);
306
+ unset($group->desc_array['lingotek']['api_errors']['upload']);
307
+ $group->save();
308
+ }
309
+ else {
310
+ $group = $this->get_group('post', $post_id);
311
+ $group->desc_array['lingotek']['api_errors']['upload'] = __('Error uploading post ', 'wp-lingotek') . $group->source;
312
+ $group->save();
313
+ }
314
+ }
315
+
316
+ // If a translation profile has targets set to copy then copy them
317
+ $targets_to_copy = $this->targets_to_be_copied($profile);
318
+ if (!empty($targets_to_copy)) {
319
+ foreach ($targets_to_copy as $target) {
320
+ $this->copy_post($post, $target);
321
  }
322
  }
323
  }
370
  Lingotek_Group_Term::create($term_id, $taxonomy , $language, $document_id);
371
  }
372
  }
373
+
374
+ // If a translation profile has targets set to copy then copy them
375
+ $targets_to_copy = $this->targets_to_be_copied($profile);
376
+ if (!empty($targets_to_copy)) {
377
+ foreach ($targets_to_copy as $target) {
378
+ $this->copy_term($term, $target, $taxonomy);
379
+ }
380
+ }
381
  }
382
 
383
  /*
399
  $group = $strings[$group]['context'];
400
  }
401
 
402
+ // check that we have a valid string group
403
  if (!in_array($group, wp_list_pluck(self::get_strings(), 'context')))
404
  return;
405
+
406
  $client = new Lingotek_API();
407
 
408
  $params = array(
559
  static $r = array();
560
  if (!empty($r[$post_type]))
561
  return $r[$post_type];
562
+
563
  if (!post_type_exists($post_type))
564
  return;
565
 
576
 
577
  $targets = $this->get_target_count($groups);
578
 
579
+
580
+ $group_ids = array();
581
+ $disabled = array();
582
+
583
  foreach ($this->pllm->get_languages_list() as $language) {
584
  // counts all the posts in one language
585
  $n = $wpdb->get_var($wpdb->prepare("
591
  $language->term_taxonomy_id, $post_type
592
  ));
593
 
594
+ $objects = $wpdb->get_col($wpdb->prepare("
595
+ SELECT object_id FROM $wpdb->term_relationships AS tr
596
+ INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
597
+ WHERE tr.term_taxonomy_id = %d
598
+ AND p.post_type = %s
599
+ AND p.post_status NOT IN ('trash', 'auto-draft')",
600
+ $language->term_taxonomy_id, $post_type
601
+ ));
602
+
603
+ foreach ($groups as $group) {
604
+ $group = unserialize($group);
605
+ if (array_key_exists($language->slug, $group)) {
606
+ $group_ids[] = $group[$language->slug];
607
+ }
608
+ }
609
+
610
+ $count = 0;
611
+ foreach ($objects as $object) {
612
+ $id = $object;
613
+ if (!in_array($id, $group_ids)) {
614
+ $profile = self::get_profile($post_type, $language, $id);
615
+ if ($profile['profile'] == 'disabled' && in_array($id, $objects)) {
616
+ $count += 1;
617
+ }
618
+ }
619
+ }
620
+ $disabled[$language->slug] = $count;
621
+
622
  // if a post is not a target, then it is source
623
  $sources[$language->slug] = $n - $targets[$language->slug];
624
+ $sources[$language->slug] -= $disabled[$language->slug];
625
  }
626
 
627
  // untranslated posts have no associated translation group in DB
638
  'post_translations', $post_type
639
  ));
640
 
 
 
641
  // untranslated = total - translated
642
  // total of posts translations groups = untranslated + number of translation groups stored in DB
643
  $count_posts = (array) wp_count_posts($post_type);
644
  unset($count_posts['trash'], $count_posts['auto-draft']); // don't count trash and auto-draft
645
+ $total = array_sum($count_posts) - $n_translated + count($groups) - array_sum($disabled);
646
 
647
  return $r[$post_type] = compact('sources', 'targets', 'total');
648
  }
661
  static $r = array();
662
  if (!empty($r[$taxonomy]))
663
  return $r[$taxonomy];
664
+
665
  if (!taxonomy_exists($taxonomy))
666
  return;
667
 
677
 
678
  $targets = $this->get_target_count($groups);
679
 
680
+ $group_ids = array();
681
+ $disabled = array();
682
+
683
  foreach ($this->pllm->get_languages_list() as $language) {
684
  // counts all the terms in one language
685
  $n = $wpdb->get_var($wpdb->prepare("
690
  $language->tl_term_taxonomy_id, $taxonomy
691
  ));
692
 
693
+ $objects = $wpdb->get_col($wpdb->prepare("
694
+ SELECT object_id FROM $wpdb->term_relationships AS tr
695
+ INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = tr.object_id
696
+ WHERE tr.term_taxonomy_id = %d
697
+ AND tt.taxonomy = %s",
698
+ $language->tl_term_taxonomy_id, $taxonomy
699
+ ));
700
+
701
+ $count = 0;
702
+ foreach ($groups as $group) {
703
+ $group = unserialize($group);
704
+ if (array_key_exists($language->slug, $group)) {
705
+ $group_ids[] = $group[$language->slug];
706
+ $profile = self::get_profile($taxonomy, $language, $group[$language->slug]);
707
+ if ($profile['profile'] == 'disabled' && !isset($group['lingotek'])) {
708
+ $count += 1;
709
+ }
710
+ }
711
+ }
712
+
713
+
714
+ $disabled[$language->slug] = $count;
715
+
716
  // if a term is not a target, then it is a source
717
  $sources[$language->slug] = $n - $targets[$language->slug];
718
+ $sources[$language->slug] -= $disabled[$language->slug];
719
  }
720
 
721
  $total = count($groups);
750
  }
751
  }
752
 
753
+ $total -= array_sum($disabled);
754
  return $r[$taxonomy] = compact('sources', 'targets', 'total');
755
  }
756
  }
js/defaults.js CHANGED
@@ -15,4 +15,18 @@ function toggleTextbox () {
15
  document.getElementById('callback_label').style.display = 'initial';
16
  document.getElementById('create').innerHTML = '+ Create New Project';
17
  }
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  document.getElementById('callback_label').style.display = 'initial';
16
  document.getElementById('create').innerHTML = '+ Create New Project';
17
  }
18
+ }
19
+
20
+
21
+ jQuery(document).ready(function($) {
22
+ if ($('#lingotek_profile_meta').val() == 'default') {
23
+ $('#post_lang_choice').change(function(){
24
+ var pl_choice = $('#post_lang_choice').val();
25
+ var content_profiles = $('#lingotek-language-profiles').text();
26
+ var content_json = $.parseJSON(content_profiles);
27
+ var profile_name = content_json[pl_choice] ? content_json[pl_choice] : content_json.defaults.content_default;
28
+
29
+ $('#lingotek_profile_meta option:first').text(content_json.defaults.title + ' (' + profile_name + ')');
30
+ }).change();
31
+ }
32
+ });
js/updater.js CHANGED
@@ -12,6 +12,7 @@ jQuery(document).ready(function($) {
12
  if(url.indexOf('taxonomy') > -1){
13
  var begin = url.indexOf('taxonomy=') + 'taxonomy='.length;
14
  taxonomy_type = url.substring(begin);
 
15
  }
16
 
17
  if($('.edit-tags-php').length > 0){
@@ -43,10 +44,18 @@ jQuery(document).ready(function($) {
43
  },10000);
44
 
45
  function update_indicators(data){
46
- $('.lingotek-request').remove();
47
- $('.lingotek-status').remove();
48
- $('.lingotek-upload').remove();
49
- $('.lingotek-download').remove();
 
 
 
 
 
 
 
 
50
  for(var key in data){
51
  var source_id = key != data[key]['source_id'] && data[key]['source_id'] !== null
52
  ? data[key]['source_id']
@@ -114,7 +123,7 @@ jQuery(document).ready(function($) {
114
  $(td).find('.pll_icon_edit').remove();
115
  $(td).find('.lingotek-color').remove();
116
  var indicator = $('<div></div>').addClass('lingotek-color dashicons dashicons-no');
117
- $(td).append(indicator);
118
  }
119
  break;
120
  }
@@ -129,7 +138,7 @@ jQuery(document).ready(function($) {
129
  .attr('title',title)
130
  .attr('target','_blank')
131
  .addClass('lingotek-color dashicons dashicons-' + icon);
132
- $(td).append(request_link);
133
  }
134
 
135
  function updateGenericBulkLink(tr, data, key, action, title, text){
@@ -189,7 +198,7 @@ jQuery(document).ready(function($) {
189
  + '&_wpnonce=' + data['upload_nonce'])
190
  .attr('title','Upload Now')
191
  .addClass('lingotek-color dashicons dashicons-upload');
192
- $(td).append(request_link);
193
  }
194
 
195
  function updateIndicator(td, data, key, locale, action, title, dashicon){
@@ -202,7 +211,7 @@ jQuery(document).ready(function($) {
202
  + '&_wpnonce='+data[action + '_nonce'])
203
  .attr('title', title)
204
  .addClass('lingotek-color dashicons dashicons-' + dashicon);
205
- $(td).append(request_link);
206
  }
207
 
208
  function updateCurrentIndicator(td,data,key,locale, source_id){
@@ -223,7 +232,7 @@ jQuery(document).ready(function($) {
223
  }
224
  $(request_link).attr('title','Source uploaded')
225
  .addClass('lingotek-color dashicons dashicons-yes');
226
- $(td).append(request_link);
227
  }
228
  else {
229
  updateWorkbenchIcon(td, data, key, locale, 'Current', 'edit');
12
  if(url.indexOf('taxonomy') > -1){
13
  var begin = url.indexOf('taxonomy=') + 'taxonomy='.length;
14
  taxonomy_type = url.substring(begin);
15
+ post_data['taxonomy'] = taxonomy_type;
16
  }
17
 
18
  if($('.edit-tags-php').length > 0){
44
  },10000);
45
 
46
  function update_indicators(data){
47
+ var doc_id_present = false;
48
+ for(var key in data){
49
+ if(data[key].doc_id !== null && data[key].doc_id !== undefined){
50
+ doc_id_present = true;
51
+ }
52
+ }
53
+ if(doc_id_present === true){
54
+ $('.lingotek-request').remove();
55
+ $('.lingotek-status').remove();
56
+ $('.lingotek-upload').remove();
57
+ $('.lingotek-download').remove();
58
+ }
59
  for(var key in data){
60
  var source_id = key != data[key]['source_id'] && data[key]['source_id'] !== null
61
  ? data[key]['source_id']
123
  $(td).find('.pll_icon_edit').remove();
124
  $(td).find('.lingotek-color').remove();
125
  var indicator = $('<div></div>').addClass('lingotek-color dashicons dashicons-no');
126
+ $(td).prepend(indicator);
127
  }
128
  break;
129
  }
138
  .attr('title',title)
139
  .attr('target','_blank')
140
  .addClass('lingotek-color dashicons dashicons-' + icon);
141
+ $(td).prepend(request_link);
142
  }
143
 
144
  function updateGenericBulkLink(tr, data, key, action, title, text){
198
  + '&_wpnonce=' + data['upload_nonce'])
199
  .attr('title','Upload Now')
200
  .addClass('lingotek-color dashicons dashicons-upload');
201
+ $(td).prepend(request_link);
202
  }
203
 
204
  function updateIndicator(td, data, key, locale, action, title, dashicon){
211
  + '&_wpnonce='+data[action + '_nonce'])
212
  .attr('title', title)
213
  .addClass('lingotek-color dashicons dashicons-' + dashicon);
214
+ $(td).prepend(request_link);
215
  }
216
 
217
  function updateCurrentIndicator(td,data,key,locale, source_id){
232
  }
233
  $(request_link).attr('title','Source uploaded')
234
  .addClass('lingotek-color dashicons dashicons-yes');
235
+ $(td).prepend(request_link);
236
  }
237
  else {
238
  updateWorkbenchIcon(td, data, key, locale, 'Current', 'edit');
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.1
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
@@ -15,7 +15,7 @@ GitHub Plugin URI: https://github.com/lingotek/wp-lingotek
15
  if (!function_exists('add_action'))
16
  exit();
17
 
18
- define('LINGOTEK_VERSION', '1.1'); // plugin version (should match above meta)
19
  define('LINGOTEK_MIN_PLL_VERSION', '1.7.4.2');
20
  define('LINGOTEK_BASENAME', plugin_basename(__FILE__)); // plugin name as known by WP
21
  define('LINGOTEK_PLUGIN_SLUG', 'wp-lingotek');// 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.1.1
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
15
  if (!function_exists('add_action'))
16
  exit();
17
 
18
+ define('LINGOTEK_VERSION', '1.1.1'); // plugin version (should match above meta)
19
  define('LINGOTEK_MIN_PLL_VERSION', '1.7.4.2');
20
  define('LINGOTEK_BASENAME', plugin_basename(__FILE__)); // plugin name as known by WP
21
  define('LINGOTEK_PLUGIN_SLUG', 'wp-lingotek');// 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.3
7
- Stable tag: 1.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -65,7 +65,10 @@ Don't hesitate to [give your feedback](https://wordpress.org/support/view/plugin
65
  1. Make sure you have [Polylang](https://wordpress.org/plugins/polylang/) installed as it provides the framework for the Lingotek plugin.
66
  1. Upload the `wp-lingotek` folder to the `/wp-content/plugins/` directory.
67
  1. Activate the Lingotek plugin through the 'Plugins' menu in Wordpress.
68
- 1. Create a Lingotek account by going to the `Translation` menu that appears in your admin menu.
 
 
 
69
 
70
  == Frequently Asked Questions ==
71
 
@@ -115,6 +118,13 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
115
 
116
  == Changelog ==
117
 
 
 
 
 
 
 
 
118
  = 1.1 (2015-08-28) =
119
 
120
  * Added the option to set a Translation Profile per Post/Page which will override the Content Type default Translation Profile
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
  Tested up to: 4.3
7
+ Stable tag: 1.1.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
65
  1. Make sure you have [Polylang](https://wordpress.org/plugins/polylang/) installed as it provides the framework for the Lingotek plugin.
66
  1. Upload the `wp-lingotek` folder to the `/wp-content/plugins/` directory.
67
  1. Activate the Lingotek plugin through the 'Plugins' menu in Wordpress.
68
+ 1. Navigate to the `Translation` menu that appears in your admin menu.
69
+ 1. From here you can create a new Lingotek account if you do not have one, or you can connect to an existing Lingotek account.
70
+ 1. After creating a new account or connecting with your existing account you will be redirected to the Lingotek Translation tutorial and admin pages.
71
+ 1. For more information and help visit [Getting Started](https://lingotek.atlassian.net/wiki/pages/viewpage.action?pageId=28053814) in the Lingotek Translation Documentation or contact support@lingotek.com
72
 
73
  == Frequently Asked Questions ==
74
 
118
 
119
  == Changelog ==
120
 
121
+ = 1.1.1 (2015-09-11) =
122
+
123
+ * Added better logging and display of Lingotek API errors
124
+ * New Translation Profile option to copy content from source language to target languages
125
+ * Fixes for display of selected Profile
126
+ * Minor fixes for real-time translation status updates
127
+
128
  = 1.1 (2015-08-28) =
129
 
130
  * Added the option to set a Translation Profile per Post/Page which will override the Content Type default Translation Profile