Version Description
(2015-08-28) =
- Added the option to set a Translation Profile per Post/Page which will override the Content Type default Translation Profile
- The selected Translation Profile is now displayed on bulk display of Posts/Pages
- Minor fixes for real-time translation status updates
- Fixed a bug that prevented updating of content
- Custom fields enhancements and fixes
- Moved Content Type Configuration, Translation Profiles, and Custom Fields tabs from the Settings Page to the Manage Page
- Fixed Lingotek Dashboard counting error
Download this release
Release Info
Developer | erichie |
Plugin | Lingotek Translation |
Version | 1.1 |
Comparing to | |
See all releases |
Code changes from version 1.0.9 to 1.1
- admin/actions.php +5 -0
- admin/admin.php +41 -14
- admin/custom-fields-table.php +6 -0
- admin/filters-columns.php +3 -2
- admin/filters-post.php +150 -14
- admin/{settings → manage}/view-content.php +1 -1
- admin/{settings → manage}/view-custom-fields.php +11 -5
- admin/{settings → manage}/view-edit-profile.php +13 -8
- admin/{settings → manage}/view-profiles.php +2 -2
- admin/post-actions.php +126 -1
- admin/profiles-table.php +2 -2
- admin/settings.php +0 -3
- admin/settings/view-defaults.php +1 -2
- admin/tutorial/features.php +3 -3
- admin/view-dashboard.php +2 -2
- admin/view-manage.php +4 -1
- include/api.php +1 -1
- include/group-post.php +82 -54
- include/group.php +4 -4
- include/model.php +29 -12
- js/updater.js +3 -0
- lingotek.php +2 -2
- readme.txt +12 -2
admin/actions.php
CHANGED
@@ -394,6 +394,11 @@ abstract class Lingotek_Actions {
|
|
394 |
case 'lingotek-delete':
|
395 |
check_admin_referer('lingotek-delete');
|
396 |
$document->disassociate();
|
|
|
|
|
|
|
|
|
|
|
397 |
break;
|
398 |
|
399 |
default:
|
394 |
case 'lingotek-delete':
|
395 |
check_admin_referer('lingotek-delete');
|
396 |
$document->disassociate();
|
397 |
+
if (isset($_GET['lingotek_redirect']) && $_GET['lingotek_redirect'] == true) {
|
398 |
+
$site_id = get_current_blog_id();
|
399 |
+
wp_redirect(get_site_url($site_id, '/wp-admin/edit.php?post_type=page'));
|
400 |
+
exit();
|
401 |
+
}
|
402 |
break;
|
403 |
|
404 |
default:
|
admin/admin.php
CHANGED
@@ -48,8 +48,18 @@ class Lingotek_Admin {
|
|
48 |
$content_metadata = array();
|
49 |
foreach($object_ids as $object_id) {
|
50 |
$id = $object_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
$document = $lgtm->get_group($taxonomy, $object_id);
|
52 |
-
if ($document) {
|
53 |
if($document->source !== $object_id){
|
54 |
$document = $lgtm->get_group($taxonomy, $document->source);
|
55 |
}
|
@@ -57,7 +67,7 @@ class Lingotek_Admin {
|
|
57 |
$source_language = $terms ? pll_get_term_language($document->source, 'locale')
|
58 |
: pll_get_post_language($document->source, 'locale');
|
59 |
$existing_translations = $pllm->get_translations($taxonomy, $source_id);
|
60 |
-
|
61 |
if(count($existing_translations) > 1){
|
62 |
$content_metadata[$id]['existing_trans'] = true;
|
63 |
}
|
@@ -67,6 +77,18 @@ class Lingotek_Admin {
|
|
67 |
$content_metadata[$id]['source_status'] = $document->status;
|
68 |
$target_status = $document->status == 'edited' || $document->status == null ? 'edited' : 'current';
|
69 |
$content_metadata[$id][$source_language]['status'] = $document->source == $object_id ? $document->status : $target_status;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
if(is_array($document->translations)){
|
71 |
foreach($document->translations as $locale => $translation_status) {
|
72 |
$content_metadata[$id][$locale]['status'] = $translation_status;
|
@@ -75,15 +97,17 @@ class Lingotek_Admin {
|
|
75 |
}
|
76 |
}
|
77 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
-
|
80 |
-
foreach($languages as $language){
|
81 |
-
foreach($content_metadata as $group => $status){
|
82 |
-
if(!isset($status[$language])){
|
83 |
-
$content_metadata[$group][$language]['status'] = "none";
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}
|
87 |
//get the nonces associated with the different actions
|
88 |
$content_metadata['request_nonce'] = $this->lingotek_get_matching_nonce('lingotek-request');
|
89 |
$content_metadata['download_nonce'] = $this->lingotek_get_matching_nonce('lingotek-download');
|
@@ -293,14 +317,17 @@ class Lingotek_Admin {
|
|
293 |
'workflow_id' => array(
|
294 |
'label' => $defaults ? __('Default Workflow', 'wp-lingotek') : __('Workflow', 'wp-lingotek'),
|
295 |
'options' => $resources['workflows'],
|
|
|
296 |
),
|
297 |
'primary_filter_id' => array(
|
298 |
'label' => $defaults ? __('Primary Filter', 'wp-lingotek') : __('Primary Filter', 'wp-lingotek'),
|
299 |
'options' => $resources['filters'],
|
|
|
300 |
),
|
301 |
'secondary_filter_id' => array(
|
302 |
'label' => $defaults ? __('Secondary Filter', 'wp-lingotek') : __('Secondary Filter', 'wp-lingotek'),
|
303 |
'options' => $resources['filters'],
|
|
|
304 |
),
|
305 |
);
|
306 |
}
|
@@ -351,7 +378,10 @@ class Lingotek_Admin {
|
|
351 |
|
352 |
$api_data = $client->get_projects($community_id);
|
353 |
$projects = array();
|
354 |
-
|
|
|
|
|
|
|
355 |
foreach ($api_data->entities as $project) {
|
356 |
$projects[$project->properties->id] = $project->properties->title;
|
357 |
}
|
@@ -363,9 +393,6 @@ class Lingotek_Admin {
|
|
363 |
natcasesort($projects); //order by title (case-insensitive)
|
364 |
$refresh_success['projects'] = TRUE;
|
365 |
}
|
366 |
-
else if ($api_data == 'empty') {
|
367 |
-
add_settings_error('lingotek_community_resources', 'error', __('Your Community currently has no projects.', 'wp-lingotek'), 'error');
|
368 |
-
}
|
369 |
else {
|
370 |
add_settings_error('lingotek_community_resources', 'error', __('Projects could not be refreshed', 'wp-lingotek'), 'error');
|
371 |
}
|
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 |
}
|
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 |
}
|
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;
|
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
|
112 |
$content_metadata['request_nonce'] = $this->lingotek_get_matching_nonce('lingotek-request');
|
113 |
$content_metadata['download_nonce'] = $this->lingotek_get_matching_nonce('lingotek-download');
|
317 |
'workflow_id' => array(
|
318 |
'label' => $defaults ? __('Default Workflow', 'wp-lingotek') : __('Workflow', 'wp-lingotek'),
|
319 |
'options' => $resources['workflows'],
|
320 |
+
'description' => __('Changes will affect new entities only', 'wp-lingotek')
|
321 |
),
|
322 |
'primary_filter_id' => array(
|
323 |
'label' => $defaults ? __('Primary Filter', 'wp-lingotek') : __('Primary Filter', 'wp-lingotek'),
|
324 |
'options' => $resources['filters'],
|
325 |
+
'description' => __('Changes will affect new entities only', 'wp-lingotek')
|
326 |
),
|
327 |
'secondary_filter_id' => array(
|
328 |
'label' => $defaults ? __('Secondary Filter', 'wp-lingotek') : __('Secondary Filter', 'wp-lingotek'),
|
329 |
'options' => $resources['filters'],
|
330 |
+
'description' => __('Changes will affect new entities only', 'wp-lingotek')
|
331 |
),
|
332 |
);
|
333 |
}
|
378 |
|
379 |
$api_data = $client->get_projects($community_id);
|
380 |
$projects = array();
|
381 |
+
if (empty($api_data)) {
|
382 |
+
add_settings_error('lingotek_community_resources', 'error', __('Your Community currently has no projects.', 'wp-lingotek'), 'error');
|
383 |
+
}
|
384 |
+
else if ($api_data !== FALSE) {
|
385 |
foreach ($api_data->entities as $project) {
|
386 |
$projects[$project->properties->id] = $project->properties->title;
|
387 |
}
|
393 |
natcasesort($projects); //order by title (case-insensitive)
|
394 |
$refresh_success['projects'] = TRUE;
|
395 |
}
|
|
|
|
|
|
|
396 |
else {
|
397 |
add_settings_error('lingotek_community_resources', 'error', __('Projects could not be refreshed', 'wp-lingotek'), 'error');
|
398 |
}
|
admin/custom-fields-table.php
CHANGED
@@ -104,6 +104,12 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
104 |
if (!empty($_REQUEST['orderby'])) // no sort by default
|
105 |
usort($data, 'usort_reorder');
|
106 |
|
|
|
107 |
$this->items = $data;
|
|
|
|
|
|
|
|
|
|
|
108 |
}
|
109 |
}
|
104 |
if (!empty($_REQUEST['orderby'])) // no sort by default
|
105 |
usort($data, 'usort_reorder');
|
106 |
|
107 |
+
$total_items = count($data);
|
108 |
$this->items = $data;
|
109 |
+
|
110 |
+
$this->set_pagination_args(array(
|
111 |
+
'total_items' => $total_items,
|
112 |
+
'per_page' => count($data),
|
113 |
+
));
|
114 |
}
|
115 |
}
|
admin/filters-columns.php
CHANGED
@@ -37,7 +37,8 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
37 |
* @return array modified list of columns
|
38 |
*/
|
39 |
protected function add_column($columns, $before) {
|
40 |
-
|
|
|
41 |
$end = array_slice($columns, $n);
|
42 |
$columns = array_slice($columns, 0, $n);
|
43 |
}
|
@@ -98,7 +99,7 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
98 |
// FIXME not very clean
|
99 |
$actions = 'post' == $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
|
100 |
|
101 |
-
$profile = Lingotek_Model::get_profile($this->content_type, $language);
|
102 |
$disabled = 'disabled' == $profile['profile'];
|
103 |
|
104 |
// post ready for upload
|
37 |
* @return array modified list of columns
|
38 |
*/
|
39 |
protected function add_column($columns, $before) {
|
40 |
+
$n = array_search($before, array_keys($columns));
|
41 |
+
if ($n) {
|
42 |
$end = array_slice($columns, $n);
|
43 |
$columns = array_slice($columns, 0, $n);
|
44 |
}
|
99 |
// FIXME not very clean
|
100 |
$actions = 'post' == $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
|
101 |
|
102 |
+
$profile = Lingotek_Model::get_profile($this->content_type, $language, $object_id);
|
103 |
$disabled = 'disabled' == $profile['profile'];
|
104 |
|
105 |
// post ready for upload
|
admin/filters-post.php
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
*/
|
10 |
class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
11 |
public $lgtm; // Lingotek model
|
|
|
12 |
|
13 |
/*
|
14 |
* Constructor
|
@@ -19,6 +20,7 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
19 |
parent::__construct($polylang);
|
20 |
|
21 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
|
|
22 |
|
23 |
// automatic upload
|
24 |
add_action('post_updated', array(&$this, 'post_updated'), 10, 3);
|
@@ -26,6 +28,12 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
26 |
// trash sync
|
27 |
add_action('trashed_post', array(&$this, 'trash_post'));
|
28 |
add_action('untrashed_post', array(&$this, 'untrash_post'));
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
/*
|
@@ -37,11 +45,75 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
37 |
global $post_ID;
|
38 |
if ($this->model->is_translated_post_type($post_type)) {
|
39 |
$document = $this->lgtm->get_group('post', $post_ID);
|
40 |
-
if (empty($document->source))
|
41 |
parent::add_meta_boxes($post_type);
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
/*
|
46 |
* uploads a post when saved for the first time
|
47 |
*
|
@@ -52,13 +124,25 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
52 |
* @param bool $update whether it is an update or not
|
53 |
*/
|
54 |
public function save_post($post_id, $post, $update) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
if (!$this->model->is_translated_post_type($post->post_type))
|
56 |
return;
|
57 |
-
|
58 |
if (!isset($_REQUEST['import'])) {
|
59 |
parent::save_post($post_id, $post, $update);
|
60 |
|
61 |
-
if (!wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, $this->model->get_post_language($post_id)) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
|
62 |
$this->lgtm->upload_post($post_id);
|
63 |
}
|
64 |
}
|
@@ -99,17 +183,6 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
99 |
* @param object $post_before
|
100 |
*/
|
101 |
public function post_updated($post_id, $post_after, $post_before) {
|
102 |
-
if ($this->can_save_post_data($post_id, $post_after, true)) {
|
103 |
-
$document = $this->lgtm->get_group('post', $post_id);
|
104 |
-
|
105 |
-
if ($document && $post_id == $document->source && md5(Lingotek_Group_Post::get_content($post_after)) != md5(Lingotek_Group_Post::get_content($post_before))) {
|
106 |
-
$document->source_edited();
|
107 |
-
|
108 |
-
if ($document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status($post_after->post_status)) {
|
109 |
-
$this->lgtm->upload_post($post_id);
|
110 |
-
}
|
111 |
-
}
|
112 |
-
}
|
113 |
}
|
114 |
|
115 |
/*
|
@@ -157,6 +230,18 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
157 |
}
|
158 |
$this->lgtm->delete_post($post_id);
|
159 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
}
|
161 |
|
162 |
/*
|
@@ -182,4 +267,55 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
182 |
foreach ($this->get_translations_to_sync($post_id) as $tr_id)
|
183 |
wp_untrash_post($tr_id);
|
184 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
}
|
9 |
*/
|
10 |
class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
11 |
public $lgtm; // Lingotek model
|
12 |
+
public $pllm;
|
13 |
|
14 |
/*
|
15 |
* Constructor
|
20 |
parent::__construct($polylang);
|
21 |
|
22 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
23 |
+
$this->pllm = &$GLOBALS['polylang']->model;
|
24 |
|
25 |
// automatic upload
|
26 |
add_action('post_updated', array(&$this, 'post_updated'), 10, 3);
|
28 |
// trash sync
|
29 |
add_action('trashed_post', array(&$this, 'trash_post'));
|
30 |
add_action('untrashed_post', array(&$this, 'untrash_post'));
|
31 |
+
|
32 |
+
add_filter('manage_posts_columns', array(&$this, 'add_profile_column'));
|
33 |
+
add_action('manage_posts_custom_column', array(&$this, 'add_profile_column_data'), 10, 3);
|
34 |
+
|
35 |
+
add_filter('manage_pages_columns', array(&$this, 'add_profile_column'));
|
36 |
+
add_action('manage_pages_custom_column', array(&$this, 'add_profile_column_data'), 10, 3);
|
37 |
}
|
38 |
|
39 |
/*
|
45 |
global $post_ID;
|
46 |
if ($this->model->is_translated_post_type($post_type)) {
|
47 |
$document = $this->lgtm->get_group('post', $post_ID);
|
48 |
+
if (empty($document->source)) {
|
49 |
parent::add_meta_boxes($post_type);
|
50 |
+
}
|
51 |
+
else {
|
52 |
+
add_action( 'edit_form_top', array( &$this, 'edit_form_top' ) );
|
53 |
+
}
|
54 |
}
|
55 |
}
|
56 |
|
57 |
+
/*
|
58 |
+
* adds a column to display the post or page translation profile
|
59 |
+
*
|
60 |
+
* @since 1.1
|
61 |
+
*/
|
62 |
+
public function add_profile_column($columns) {
|
63 |
+
$n = array_search('date', array_keys($columns));
|
64 |
+
if ($n) {
|
65 |
+
$end = array_slice($columns, $n);
|
66 |
+
$columns = array_slice($columns, 0, $n);
|
67 |
+
}
|
68 |
+
|
69 |
+
$columns['profile'] = 'Profile';
|
70 |
+
return isset($end) ? array_merge($columns, $end) : $columns;
|
71 |
+
}
|
72 |
+
|
73 |
+
/*
|
74 |
+
* finds the translation profile for a post or page and if not set then displays the content type default profile
|
75 |
+
*
|
76 |
+
* @since 1.1
|
77 |
+
*/
|
78 |
+
public function add_profile_column_data($column_name, $post_id) {
|
79 |
+
if ($column_name == 'profile') {
|
80 |
+
$document = $this->lgtm->get_group('post', $post_id);
|
81 |
+
if (isset($document->source)) {
|
82 |
+
$post_id = $document->source;
|
83 |
+
}
|
84 |
+
$profiles = Lingotek::get_profiles();
|
85 |
+
$content_profiles = get_option('lingotek_content_type');
|
86 |
+
$post_profile = Lingotek_Post_actions::get_post_profile($post_id);
|
87 |
+
$post_language = $this->pllm->get_post_language($post_id);
|
88 |
+
$post_type = 'post';
|
89 |
+
if (isset($_REQUEST['post_type'])) {
|
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 |
+
}
|
105 |
+
|
106 |
+
/*
|
107 |
+
* outputs hidden fields so that Polylang get correct information when its metabox is removed
|
108 |
+
*
|
109 |
+
* @since 1.10
|
110 |
+
*/
|
111 |
+
public function edit_form_top() {
|
112 |
+
global $post_ID;
|
113 |
+
printf( '<input type="hidden" id="post_lang_choice" name="post_lang_choice" value="%s" />', pll_get_post_language( $post_ID ) );
|
114 |
+
wp_nonce_field('pll_language', '_pll_nonce');
|
115 |
+
}
|
116 |
+
|
117 |
/*
|
118 |
* uploads a post when saved for the first time
|
119 |
*
|
124 |
* @param bool $update whether it is an update or not
|
125 |
*/
|
126 |
public function save_post($post_id, $post, $update) {
|
127 |
+
if ($this->can_save_post_data($post_id, $post, true)) {
|
128 |
+
$document = $this->lgtm->get_group('post', $post_id);
|
129 |
+
// updated post
|
130 |
+
if ($document && $post_id == $document->source && $this->post_hash_has_changed($post)) {
|
131 |
+
$document->source_edited();
|
132 |
+
|
133 |
+
if ($document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status)) {
|
134 |
+
$this->lgtm->upload_post($post_id);
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
if (!$this->model->is_translated_post_type($post->post_type))
|
140 |
return;
|
141 |
+
// new post
|
142 |
if (!isset($_REQUEST['import'])) {
|
143 |
parent::save_post($post_id, $post, $update);
|
144 |
|
145 |
+
if (!wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, $this->model->get_post_language($post_id), false, $post_id) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
|
146 |
$this->lgtm->upload_post($post_id);
|
147 |
}
|
148 |
}
|
183 |
* @param object $post_before
|
184 |
*/
|
185 |
public function post_updated($post_id, $post_after, $post_before) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
187 |
|
188 |
/*
|
230 |
}
|
231 |
$this->lgtm->delete_post($post_id);
|
232 |
}
|
233 |
+
// delete lingotek_profile term upon post deletion
|
234 |
+
$terms = wp_get_object_terms($post_id, 'lingotek_profile');
|
235 |
+
$term = array_pop($terms);
|
236 |
+
if ($term) {
|
237 |
+
wp_delete_term($term->term_id, 'lingotek_profile');
|
238 |
+
}
|
239 |
+
//delete lingotek_hash term upon post deletion
|
240 |
+
$hash_terms = wp_get_object_terms($post_id, 'lingotek_hash');
|
241 |
+
$hash_term = array_pop($hash_terms);
|
242 |
+
if ($hash_term) {
|
243 |
+
wp_delete_term($hash_term->term_id, 'lingotek_hash');
|
244 |
+
}
|
245 |
}
|
246 |
|
247 |
/*
|
267 |
foreach ($this->get_translations_to_sync($post_id) as $tr_id)
|
268 |
wp_untrash_post($tr_id);
|
269 |
}
|
270 |
+
|
271 |
+
/*
|
272 |
+
* checks stored hash against current hash to report change
|
273 |
+
*
|
274 |
+
* @since 1.0
|
275 |
+
*
|
276 |
+
* @param wp_post $post_after
|
277 |
+
*/
|
278 |
+
protected function post_hash_has_changed($post_after) {
|
279 |
+
if ($post_after->post_status === 'trash') {
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
$document_id = 'lingotek_hash_' . $post_after->ID;
|
283 |
+
$new_hash = md5(Lingotek_Group_Post::get_content($post_after));
|
284 |
+
$old_term = $this->get_post_hash($post_after->ID);
|
285 |
+
$old_hash = $old_term->description;
|
286 |
+
|
287 |
+
// new or updated page
|
288 |
+
if ($old_hash === null || strcmp($new_hash, $old_hash)) {
|
289 |
+
if (empty($old_term)) {
|
290 |
+
wp_insert_term($document_id, 'lingotek_hash', array('description' => $new_hash));
|
291 |
+
}
|
292 |
+
else {
|
293 |
+
wp_update_term((int) $old_term->term_id, 'lingotek_hash', array('description' => $new_hash));
|
294 |
+
}
|
295 |
+
|
296 |
+
wp_set_object_terms($post_after->ID, $document_id, 'lingotek_hash');
|
297 |
+
return true;
|
298 |
+
}
|
299 |
+
else {
|
300 |
+
return false;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
/*
|
305 |
+
* returns a lingotek post hash if it exists
|
306 |
+
*
|
307 |
+
* @since 1.0
|
308 |
+
*
|
309 |
+
* @param int $post_id
|
310 |
+
*/
|
311 |
+
protected function get_post_hash($post_id) {
|
312 |
+
if (taxonomy_exists('lingotek_hash')) {
|
313 |
+
$terms = wp_get_object_terms($post_id, 'lingotek_hash');
|
314 |
+
$term = array_pop($terms);
|
315 |
+
return $term;
|
316 |
+
}
|
317 |
+
else {
|
318 |
+
return null;
|
319 |
+
}
|
320 |
+
}
|
321 |
}
|
admin/{settings → manage}/view-content.php
RENAMED
@@ -81,7 +81,7 @@ foreach ($data as $key => $item) {
|
|
81 |
<h3><?php _e('Content Type Configuration', 'wp-lingotek'); ?></h3>
|
82 |
<p class="description"><?php _e('Content types can be configured to use any translation profile. Additionally, translation profiles can be set based on the language the content was authored in.', 'wp-lingotek'); ?></p>
|
83 |
|
84 |
-
<form id="lingotek-content-types" method="post" action="admin.php?page=wp-
|
85 |
wp_nonce_field('lingotek-content-types', '_wpnonce_lingotek-content-types');
|
86 |
|
87 |
$table = new Lingotek_Content_Table($content_types);
|
81 |
<h3><?php _e('Content Type Configuration', 'wp-lingotek'); ?></h3>
|
82 |
<p class="description"><?php _e('Content types can be configured to use any translation profile. Additionally, translation profiles can be set based on the language the content was authored in.', 'wp-lingotek'); ?></p>
|
83 |
|
84 |
+
<form id="lingotek-content-types" method="post" action="admin.php?page=wp-lingotek_manage&sm=content" class="validate"><?php
|
85 |
wp_nonce_field('lingotek-content-types', '_wpnonce_lingotek-content-types');
|
86 |
|
87 |
$table = new Lingotek_Content_Table($content_types);
|
admin/{settings → manage}/view-custom-fields.php
RENAMED
@@ -6,12 +6,18 @@ $items = array();
|
|
6 |
|
7 |
if (!empty($_POST)) {
|
8 |
check_admin_referer('lingotek-custom-fields', '_wpnonce_lingotek-custom-fields');
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
11 |
|
12 |
if (!empty($_POST['refresh'])) {
|
13 |
-
|
|
|
14 |
}
|
|
|
15 |
}
|
16 |
|
17 |
$items = Lingotek_Group_Post::get_cached_meta_values();
|
@@ -19,9 +25,9 @@ $items = Lingotek_Group_Post::get_cached_meta_values();
|
|
19 |
?>
|
20 |
|
21 |
<h3><?php _e('Custom Field Configuration', 'wp-lingotek'); ?></h3>
|
22 |
-
<p class="description"><?php _e('Custom Fields can be translated, copied, or ignored.', 'wp-lingotek'); ?></p>
|
23 |
|
24 |
-
<form id="lingotek-custom-fields" method="post" action="admin.php?page=wp-
|
25 |
wp_nonce_field('lingotek-custom-fields', '_wpnonce_lingotek-custom-fields');
|
26 |
|
27 |
$table = new Lingotek_Custom_Fields_Table();
|
6 |
|
7 |
if (!empty($_POST)) {
|
8 |
check_admin_referer('lingotek-custom-fields', '_wpnonce_lingotek-custom-fields');
|
9 |
+
|
10 |
+
if (!empty($_POST['submit'])) {
|
11 |
+
$arr = empty($_POST['settings']) ? array() : $_POST['settings'];
|
12 |
+
update_option('lingotek_custom_fields', $arr);
|
13 |
+
add_settings_error('lingotek_custom_fields_save', 'custom_fields', __('Your <i>Custom Fields</i> were sucessfully saved.', 'wp-lingotek'), 'updated');
|
14 |
+
}
|
15 |
|
16 |
if (!empty($_POST['refresh'])) {
|
17 |
+
Lingotek_Group_Post::get_updated_meta_values();
|
18 |
+
add_settings_error('lingotek_custom_fields_refresh', 'custom_fields', __('Your <i>Custom Fields</i> were sucessfully identified.', 'wp-lingotek'), 'updated');
|
19 |
}
|
20 |
+
settings_errors();
|
21 |
}
|
22 |
|
23 |
$items = Lingotek_Group_Post::get_cached_meta_values();
|
25 |
?>
|
26 |
|
27 |
<h3><?php _e('Custom Field Configuration', 'wp-lingotek'); ?></h3>
|
28 |
+
<p class="description"><?php _e('Custom Fields can be translated, copied, or ignored. Click "Refresh Custom Fields" to identify and enable your custom fields.', 'wp-lingotek'); ?></p>
|
29 |
|
30 |
+
<form id="lingotek-custom-fields" method="post" action="admin.php?page=wp-lingotek_manage&sm=custom-fields" class="validate"><?php
|
31 |
wp_nonce_field('lingotek-custom-fields', '_wpnonce_lingotek-custom-fields');
|
32 |
|
33 |
$table = new Lingotek_Custom_Fields_Table();
|
admin/{settings → manage}/view-edit-profile.php
RENAMED
@@ -55,7 +55,7 @@ unset($settings['primary_filter_id']['options'][$secondary_filter_id]);
|
|
55 |
unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
56 |
?>
|
57 |
|
58 |
-
<form id="lingotek-edit-profile" method="post" action="admin.php?page=wp-
|
59 |
<?php wp_nonce_field('lingotek-edit-profile', '_wpnonce_lingotek-edit-profile');?>
|
60 |
<input name="profile" type="hidden" value="<?php echo empty($profile['profile']) ? '' : esc_attr($profile['profile']); ?>">
|
61 |
|
@@ -63,11 +63,13 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
63 |
<tr>
|
64 |
<th scope="row"><?php printf('<label for="%s">%s</label>', 'name' , __('Profile name', 'wp-lingotek')); ?></th>
|
65 |
<td><?php
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
)
|
|
|
|
|
71 |
</td>
|
72 |
</tr>
|
73 |
</table>
|
@@ -174,6 +176,9 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
174 |
<td><?php
|
175 |
printf('<select name="%1$s" id="%1$s" %2$s>', $custom_key, in_array($key, array('upload', 'download')) ? $disabled : '');
|
176 |
foreach ($setting['options'] as $id => $title) {
|
|
|
|
|
|
|
177 |
$selected = isset($profile['custom'][$key][$language->slug]) && $profile['custom'][$key][$language->slug] == $id ? 'selected="selected"' : '';
|
178 |
echo "\n\t<option value='" . esc_attr($id) . "' $selected>" . esc_html($title) . '</option>';
|
179 |
} ?>
|
@@ -195,9 +200,9 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
195 |
if (!empty($profile['profile']) && !in_array($profile['profile'], array('automatic', 'manual', 'disabled')) && empty($profile['usage']))
|
196 |
printf(
|
197 |
'<a href="%s" class="button" onclick = "return confirm(\'%s\');">%s</a>',
|
198 |
-
esc_url(wp_nonce_url('admin.php?page=wp-
|
199 |
__('You are about to permanently delete this profile. Are you sure?', 'wp-lingotek'),
|
200 |
__('Delete', 'wp-lingotek')
|
201 |
);
|
202 |
-
?> <a href="admin.php?page=wp-
|
203 |
</form>
|
55 |
unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
56 |
?>
|
57 |
|
58 |
+
<form id="lingotek-edit-profile" method="post" action="admin.php?page=wp-lingotek_manage&sm=profiles" class="validate">
|
59 |
<?php wp_nonce_field('lingotek-edit-profile', '_wpnonce_lingotek-edit-profile');?>
|
60 |
<input name="profile" type="hidden" value="<?php echo empty($profile['profile']) ? '' : esc_attr($profile['profile']); ?>">
|
61 |
|
63 |
<tr>
|
64 |
<th scope="row"><?php printf('<label for="%s">%s</label>', 'name' , __('Profile name', 'wp-lingotek')); ?></th>
|
65 |
<td><?php
|
66 |
+
if (!empty($profile)) {
|
67 |
+
$profile_name = $disabled ? __($profile['name'],'wp-lingotek') : $profile['name']; // localize canned profile names
|
68 |
+
}
|
69 |
+
printf('<input name="name" id="name" type="text" value="%s" %s>',
|
70 |
+
empty($profile['name']) ? '' : esc_attr($profile_name),
|
71 |
+
$disabled
|
72 |
+
); ?>
|
73 |
</td>
|
74 |
</tr>
|
75 |
</table>
|
176 |
<td><?php
|
177 |
printf('<select name="%1$s" id="%1$s" %2$s>', $custom_key, in_array($key, array('upload', 'download')) ? $disabled : '');
|
178 |
foreach ($setting['options'] as $id => $title) {
|
179 |
+
if ($id === 'default' && $key === 'workflow_id') {
|
180 |
+
$id = $defaults['workflow_id'];
|
181 |
+
}
|
182 |
$selected = isset($profile['custom'][$key][$language->slug]) && $profile['custom'][$key][$language->slug] == $id ? 'selected="selected"' : '';
|
183 |
echo "\n\t<option value='" . esc_attr($id) . "' $selected>" . esc_html($title) . '</option>';
|
184 |
} ?>
|
200 |
if (!empty($profile['profile']) && !in_array($profile['profile'], array('automatic', 'manual', 'disabled')) && empty($profile['usage']))
|
201 |
printf(
|
202 |
'<a href="%s" class="button" onclick = "return confirm(\'%s\');">%s</a>',
|
203 |
+
esc_url(wp_nonce_url('admin.php?page=wp-lingotek_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile='.$profile['profile'], 'delete-profile')),
|
204 |
__('You are about to permanently delete this profile. Are you sure?', 'wp-lingotek'),
|
205 |
__('Delete', 'wp-lingotek')
|
206 |
);
|
207 |
+
?> <a href="admin.php?page=wp-lingotek_manage&sm=profiles" class="button"> <?php _e('Cancel', 'wp-lingotek'); ?></a>
|
208 |
</form>
|
admin/{settings → manage}/view-profiles.php
RENAMED
@@ -14,7 +14,7 @@ if (isset($_GET['lingotek_action']) && 'delete-profile' == $_GET['lingotek_actio
|
|
14 |
update_option('lingotek_profiles', $profiles);
|
15 |
add_settings_error('lingotek_profile', 'default', __('Your translation profile was sucessfully deleted.', 'wp-lingotek'), 'updated');
|
16 |
set_transient('settings_errors', get_settings_errors(), 30);
|
17 |
-
wp_redirect(admin_url('admin.php?page=wp-
|
18 |
exit;
|
19 |
}
|
20 |
}
|
@@ -89,7 +89,7 @@ $table->prepare_items($profiles);
|
|
89 |
$table->display();
|
90 |
printf(
|
91 |
'<a href="%s" class="button button-primary">%s</a>',
|
92 |
-
admin_url('admin.php?page=wp-
|
93 |
__('Add New Profile', 'wp-lingotek')
|
94 |
);
|
95 |
|
14 |
update_option('lingotek_profiles', $profiles);
|
15 |
add_settings_error('lingotek_profile', 'default', __('Your translation profile was sucessfully deleted.', 'wp-lingotek'), 'updated');
|
16 |
set_transient('settings_errors', get_settings_errors(), 30);
|
17 |
+
wp_redirect(admin_url('admin.php?page=wp-lingotek_manage&sm=profiles&settings-updated=1'));
|
18 |
exit;
|
19 |
}
|
20 |
}
|
89 |
$table->display();
|
90 |
printf(
|
91 |
'<a href="%s" class="button button-primary">%s</a>',
|
92 |
+
admin_url('admin.php?page=wp-lingotek_manage&sm=edit-profile'),
|
93 |
__('Add New Profile', 'wp-lingotek')
|
94 |
);
|
95 |
|
admin/post-actions.php
CHANGED
@@ -29,6 +29,10 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
29 |
// manage bulk actions, row actions and icon actions
|
30 |
add_action('load-edit.php', array(&$this, 'manage_actions'));
|
31 |
add_action('load-upload.php', array(&$this, 'manage_actions'));
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
|
34 |
/*
|
@@ -69,7 +73,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
69 |
|
70 |
$language = $this->pllm->get_post_language($post->ID);
|
71 |
if (!empty($language)) {
|
72 |
-
$profile = Lingotek_Model::get_profile($post->post_type, $language);
|
73 |
if ('disabled' == $profile['profile'])
|
74 |
unset($actions['lingotek-upload']);
|
75 |
}
|
@@ -190,4 +194,125 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
190 |
$this->lgtm->upload_post((int) $_POST['id']);
|
191 |
die();
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
29 |
// manage bulk actions, row actions and icon actions
|
30 |
add_action('load-edit.php', array(&$this, 'manage_actions'));
|
31 |
add_action('load-upload.php', array(&$this, 'manage_actions'));
|
32 |
+
|
33 |
+
// add meta box on post and page edit pages, and hook on save
|
34 |
+
add_action('add_meta_boxes', array(&$this, 'lingotek_add_meta_boxes'));
|
35 |
+
add_action('save_post', array(&$this, 'lingotek_save_meta_boxes'));
|
36 |
}
|
37 |
|
38 |
/*
|
73 |
|
74 |
$language = $this->pllm->get_post_language($post->ID);
|
75 |
if (!empty($language)) {
|
76 |
+
$profile = Lingotek_Model::get_profile($post->post_type, $language, $post->ID);
|
77 |
if ('disabled' == $profile['profile'])
|
78 |
unset($actions['lingotek-upload']);
|
79 |
}
|
194 |
$this->lgtm->upload_post((int) $_POST['id']);
|
195 |
die();
|
196 |
}
|
197 |
+
|
198 |
+
/*
|
199 |
+
* adds the lingotek profile meta box on edit pages
|
200 |
+
*
|
201 |
+
* @since 0.1
|
202 |
+
*/
|
203 |
+
public function lingotek_add_meta_boxes() {
|
204 |
+
global $post;
|
205 |
+
$lgtm = new Lingotek_Model();
|
206 |
+
$group = $lgtm->get_group($post->post_type, $post->ID);
|
207 |
+
|
208 |
+
// if it's a new page, $group will be null, so don't check if it's a source page
|
209 |
+
if ($group) {
|
210 |
+
$desc_array = $group->desc_array;
|
211 |
+
$source_id = $desc_array['lingotek']['source'];
|
212 |
+
// only display the meta box if it's a source
|
213 |
+
if (isset($desc_array['lingotek']['source']) && $post->ID != $source_id) {
|
214 |
+
return;
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'wp-lingotek'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'post', 'side', 'default');
|
219 |
+
add_meta_box('lingotek_page_meta_box', __('Lingotek Translation', 'wp-lingotek'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'page', 'side', 'default');
|
220 |
+
}
|
221 |
+
|
222 |
+
/*
|
223 |
+
* builds the html for the edit post and edit page meta boxes
|
224 |
+
*
|
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)) {
|
240 |
+
$selected[$post_profile->description] = $profiles[$post_profile->description];
|
241 |
+
unset($profiles[$post_profile->description]);
|
242 |
+
$profiles = array_merge($selected, $profiles);
|
243 |
+
}
|
244 |
+
|
245 |
+
if (isset($group->source)) { // Disables selection of a different profile if content has been uploaded to Lingotek
|
246 |
+
$args = array(
|
247 |
+
'document_id' => $group->document_id,
|
248 |
+
'action' => 'lingotek-delete',
|
249 |
+
'noheader' => true,
|
250 |
+
);
|
251 |
+
if ($post_type == 'page') {
|
252 |
+
$args['lingotek_redirect'] = true;
|
253 |
+
}
|
254 |
+
$site_id = get_current_blog_id();
|
255 |
+
$url = $post_type == 'page' ? get_site_url($site_id, '/wp-admin/edit.php?post_type=page') : get_site_url($site_id, '/wp-admin/edit.php');
|
256 |
+
$disassociate_url = wp_nonce_url(add_query_arg($args, $url), 'lingotek-delete');
|
257 |
+
$remove_post = 'post=' . $post->ID;
|
258 |
+
$disassociate_url = str_replace($remove_post, '', $disassociate_url);
|
259 |
+
$prefs = Lingotek_Model::get_prefs();
|
260 |
+
$confirm_message = isset($prefs['delete_document_from_tms']) === false ? __('Are you sure you want to do this?', 'wp-lingotek') : __('Are you sure you want to do this? The document will be deleted from Lingotek TMS.', 'wp-lingotek');
|
261 |
+
$confirm_message = sprintf(' onclick = "return confirm(\'%s\');"', $confirm_message);
|
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() {
|
279 |
+
if (!isset($_POST['lingotek_profile_meta'])) {
|
280 |
+
return;
|
281 |
+
}
|
282 |
+
|
283 |
+
global $post;
|
284 |
+
$profile_choice = $_POST['lingotek_profile_meta'];
|
285 |
+
$document_id = 'lingotek_profile_' . $post->ID;
|
286 |
+
$term = self::get_post_profile($post->ID);
|
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 |
+
}
|
296 |
+
elseif ($profile_choice != 'default') {
|
297 |
+
if (empty($term)) {
|
298 |
+
wp_insert_term($document_id, 'lingotek_profile', array('description' => $profile_choice));
|
299 |
+
}
|
300 |
+
else {
|
301 |
+
wp_update_term((int) $term->term_id, 'lingotek_profile', array('description' => $profile_choice));
|
302 |
+
}
|
303 |
+
|
304 |
+
wp_set_object_terms($post->ID, $document_id, 'lingotek_profile');
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
public static function get_post_profile($post_id) {
|
309 |
+
if (taxonomy_exists('lingotek_profile')) {
|
310 |
+
$terms = wp_get_object_terms($post_id, 'lingotek_profile');
|
311 |
+
$term = array_pop($terms);
|
312 |
+
return $term;
|
313 |
+
}
|
314 |
+
else {
|
315 |
+
return 'false';
|
316 |
+
}
|
317 |
+
}
|
318 |
}
|
admin/profiles-table.php
CHANGED
@@ -59,14 +59,14 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
59 |
if ('disabled' != $item['profile'])
|
60 |
$actions[] = sprintf(
|
61 |
'<a href=%s>%s</a>',
|
62 |
-
esc_url(admin_url('admin.php?page=wp-
|
63 |
__('Edit', 'wp-lingotek')
|
64 |
);
|
65 |
|
66 |
if (!in_array($item['profile'], array('automatic', 'manual', 'disabled')) && empty($item['usage']))
|
67 |
$actions[] = sprintf(
|
68 |
'<a href="%s" onclick = "return confirm(\'%s\');">%s</a>',
|
69 |
-
esc_url(wp_nonce_url('admin.php?page=wp-
|
70 |
__('You are about to permanently delete this profile. Are you sure?', 'wp-lingotek'),
|
71 |
__('Delete', 'wp-lingotek')
|
72 |
);
|
59 |
if ('disabled' != $item['profile'])
|
60 |
$actions[] = sprintf(
|
61 |
'<a href=%s>%s</a>',
|
62 |
+
esc_url(admin_url('admin.php?page=wp-lingotek_manage&sm=edit-profile&profile='.$item['profile'])),
|
63 |
__('Edit', 'wp-lingotek')
|
64 |
);
|
65 |
|
66 |
if (!in_array($item['profile'], array('automatic', 'manual', 'disabled')) && empty($item['usage']))
|
67 |
$actions[] = sprintf(
|
68 |
'<a href="%s" onclick = "return confirm(\'%s\');">%s</a>',
|
69 |
+
esc_url(wp_nonce_url('admin.php?page=wp-lingotek_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile='.$item['profile'], 'delete-profile')),
|
70 |
__('You are about to permanently delete this profile. Are you sure?', 'wp-lingotek'),
|
71 |
__('Delete', 'wp-lingotek')
|
72 |
);
|
admin/settings.php
CHANGED
@@ -13,9 +13,6 @@
|
|
13 |
|
14 |
$community_required_menu_items = array(
|
15 |
'defaults' => __('Defaults', 'wp-lingotek'),
|
16 |
-
'profiles' => __('Translation Profiles', 'wp-lingotek'),
|
17 |
-
'content' => __('Content Type Configuration', 'wp-lingotek'),
|
18 |
-
'custom-fields' => __('Custom Fields', 'wp-lingotek'),
|
19 |
'preferences' => __('Preferences', 'wp-lingotek'),
|
20 |
//'advanced' => __('Advanced', 'wp-lingotek'),
|
21 |
//'logging' => __('Logging', 'wp-lingotek'),
|
13 |
|
14 |
$community_required_menu_items = array(
|
15 |
'defaults' => __('Defaults', 'wp-lingotek'),
|
|
|
|
|
|
|
16 |
'preferences' => __('Preferences', 'wp-lingotek'),
|
17 |
//'advanced' => __('Advanced', 'wp-lingotek'),
|
18 |
//'logging' => __('Logging', 'wp-lingotek'),
|
admin/settings/view-defaults.php
CHANGED
@@ -103,9 +103,8 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
103 |
</select><?php
|
104 |
if ('project_id' == $key) { ?>
|
105 |
<?php
|
106 |
-
$client = new Lingotek_API();
|
107 |
|
108 |
-
if (
|
109 |
<script> document.getElementById('project_id').style.display = 'none';</script>
|
110 |
<input type="text" name="new_project" id="new_project" placeholder="<?php _e('Enter new project name', 'wp-lingotek') ?>" />
|
111 |
<?php }
|
103 |
</select><?php
|
104 |
if ('project_id' == $key) { ?>
|
105 |
<?php
|
|
|
106 |
|
107 |
+
if (empty($setting['options'])) { ?>
|
108 |
<script> document.getElementById('project_id').style.display = 'none';</script>
|
109 |
<input type="text" name="new_project" id="new_project" placeholder="<?php _e('Enter new project name', 'wp-lingotek') ?>" />
|
110 |
<?php }
|
admin/tutorial/features.php
CHANGED
@@ -21,12 +21,12 @@
|
|
21 |
|
22 |
<div class="changelog feature-section three-col">
|
23 |
<div>
|
24 |
-
<a href="admin.php?page=wp-
|
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-
|
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>
|
@@ -41,7 +41,7 @@
|
|
41 |
|
42 |
<div class="changelog feature-section three-col">
|
43 |
<div>
|
44 |
-
<a href="admin.php?page=wp-
|
45 |
<h3><?php _e( 'Need Extra Services?', 'wp-lingotek'); ?></h3>
|
46 |
<p><?php _e( 'Start the process of getting extra services.', 'wp-lingotek'); ?></p>
|
47 |
<ul style="list-style-type: circle;">
|
21 |
|
22 |
<div class="changelog feature-section three-col">
|
23 |
<div>
|
24 |
+
<a href="admin.php?page=wp-lingotek_manage&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&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>
|
41 |
|
42 |
<div class="changelog feature-section three-col">
|
43 |
<div>
|
44 |
+
<a href="admin.php?page=wp-lingotek_manage&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>
|
47 |
<ul style="list-style-type: circle;">
|
admin/view-dashboard.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
<script>
|
4 |
var cms_data = <?php echo json_encode($cms_data); ?>
|
5 |
</script>
|
6 |
-
<link rel="stylesheet" href="
|
7 |
-
<script src="
|
8 |
<div ltk-dashboard ng-app="LingotekApp" style="margin-top: -15px;"></div>
|
9 |
</div>
|
3 |
<script>
|
4 |
var cms_data = <?php echo json_encode($cms_data); ?>
|
5 |
</script>
|
6 |
+
<link rel="stylesheet" href="https://gmc.lingotek.com/v2/styles/ltk.css">
|
7 |
+
<script src="https://gmc.lingotek.com/v2/ltk.min.js"></script>
|
8 |
<div ltk-dashboard ng-app="LingotekApp" style="margin-top: -15px;"></div>
|
9 |
</div>
|
admin/view-manage.php
CHANGED
@@ -4,6 +4,9 @@
|
|
4 |
<?php
|
5 |
|
6 |
$menu_items = array(
|
|
|
|
|
|
|
7 |
'string-groups' => __('String Groups', 'wp-lingotek'),
|
8 |
'strings' => __('Strings', 'wp-lingotek'),
|
9 |
);
|
@@ -36,4 +39,4 @@
|
|
36 |
echo "TO-DO: create <i>" . 'manage/view-' . $submenu . ".php</i>";
|
37 |
?>
|
38 |
|
39 |
-
</div>
|
4 |
<?php
|
5 |
|
6 |
$menu_items = array(
|
7 |
+
'content' => __('Content Type Configuration', 'wp-lingotek'),
|
8 |
+
'profiles' => __('Translation Profiles', 'wp-lingotek'),
|
9 |
+
'custom-fields' => __('Custom Fields', 'wp-lingotek'),
|
10 |
'string-groups' => __('String Groups', 'wp-lingotek'),
|
11 |
'strings' => __('Strings', 'wp-lingotek'),
|
12 |
);
|
39 |
echo "TO-DO: create <i>" . 'manage/view-' . $submenu . ".php</i>";
|
40 |
?>
|
41 |
|
42 |
+
</div>
|
include/api.php
CHANGED
@@ -265,7 +265,7 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
265 |
public function get_projects($community_id) {
|
266 |
$response = $this->get(add_query_arg(array('community_id' => $community_id, 'limit' => 100), $this->api_url . '/project'));
|
267 |
if (wp_remote_retrieve_response_code($response) == 204) {
|
268 |
-
return
|
269 |
}
|
270 |
return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
|
271 |
}
|
265 |
public function get_projects($community_id) {
|
266 |
$response = $this->get(add_query_arg(array('community_id' => $community_id, 'limit' => 100), $this->api_url . '/project'));
|
267 |
if (wp_remote_retrieve_response_code($response) == 204) {
|
268 |
+
return array();// there are currently no projects
|
269 |
}
|
270 |
return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
|
271 |
}
|
include/group-post.php
CHANGED
@@ -28,7 +28,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
28 |
),
|
29 |
$language->slug => $object_id // for Polylang
|
30 |
);
|
31 |
-
|
32 |
self::_create($object_id, $document_id, $data, 'post_translations');
|
33 |
}
|
34 |
|
@@ -107,6 +107,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
107 |
*/
|
108 |
static public function get_custom_fields_from_wp_postmeta($post_ID = NULL) {
|
109 |
$custom_fields = get_option('lingotek_custom_fields', array());
|
|
|
110 |
$arr = array();
|
111 |
$keys = array();
|
112 |
|
@@ -128,14 +129,11 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
128 |
|
129 |
foreach ($posts as $post) {
|
130 |
$metadata = has_meta($post->ID);
|
131 |
-
foreach ($metadata as $key => $
|
132 |
-
if ($
|
133 |
-
unset($metadata[$key]);
|
134 |
-
}
|
135 |
-
if (in_array($value['meta_key'], $keys)) {
|
136 |
unset($metadata[$key]);
|
137 |
}
|
138 |
-
$keys [] = $
|
139 |
}
|
140 |
$arr = array_merge($arr, $metadata);
|
141 |
}
|
@@ -143,6 +141,17 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
143 |
return apply_filters('lingotek_post_custom_fields', $arr);
|
144 |
}
|
145 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
/*
|
147 |
* updates meta (custom) fields values in the lingotek_custom_fields option
|
148 |
*
|
@@ -158,41 +167,33 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
158 |
$items = array();
|
159 |
|
160 |
foreach ($custom_fields_from_postmeta as $cf) {
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
// no lingotek setting
|
162 |
if (!array_key_exists($cf['meta_key'], $custom_fields_from_lingotek)) {
|
163 |
// no lingotek setting, but there's a wpml setting
|
164 |
if (array_key_exists($cf['meta_key'], $custom_fields_from_wpml)) {
|
165 |
$custom_fields[$cf['meta_key']] = $custom_fields_from_wpml[$cf['meta_key']];
|
166 |
-
$arr = array(
|
167 |
-
'meta_key' => $cf['meta_key'],
|
168 |
-
'setting' => $custom_fields_from_wpml[$cf['meta_key']],
|
169 |
-
);
|
170 |
}
|
171 |
// no lingotek setting, no wpml setting, so save default setting of ignore
|
172 |
else {
|
173 |
-
|
174 |
-
$arr = array(
|
175 |
-
'meta_key' => $cf['meta_key'],
|
176 |
-
'setting' => 'ignore',
|
177 |
-
);
|
178 |
}
|
179 |
-
|
180 |
// lingotek already has this field setting saved
|
181 |
else {
|
182 |
-
|
183 |
-
$arr = array(
|
184 |
-
'meta_key' => $cf['meta_key'],
|
185 |
-
'setting' => $custom_fields_from_lingotek[$cf['meta_key']],
|
186 |
-
);
|
187 |
}
|
188 |
-
|
189 |
-
}
|
190 |
|
191 |
if ($post_ID) {
|
192 |
$custom_fields = array_merge($custom_fields_from_lingotek, $custom_fields);
|
193 |
}
|
194 |
update_option('lingotek_custom_fields', $custom_fields);
|
195 |
-
return $items;
|
196 |
}
|
197 |
|
198 |
/*
|
@@ -209,6 +210,9 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
209 |
|
210 |
if (is_array($custom_fields_from_lingotek)) {
|
211 |
foreach ($custom_fields_from_lingotek as $key => $setting) {
|
|
|
|
|
|
|
212 |
$arr = array(
|
213 |
'meta_key' => $key,
|
214 |
'setting' => $setting,
|
@@ -305,25 +309,14 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
305 |
$tr_post['ID'] = $tr_id;
|
306 |
|
307 |
// copy or ignore metas
|
308 |
-
$
|
309 |
-
foreach ($custom_fields as $key => $setting) {
|
310 |
-
if ('copy' === $setting) {
|
311 |
-
$source_meta = current(get_post_meta($post->ID, $key)) ;
|
312 |
-
update_post_meta($tr_id, $key, $source_meta);
|
313 |
-
}
|
314 |
-
elseif ('ignore' === $setting) {
|
315 |
-
delete_post_meta($tr_id, $key);
|
316 |
-
}
|
317 |
-
}
|
318 |
|
319 |
// translate metas
|
320 |
-
if (
|
321 |
-
|
322 |
-
update_post_meta($tr_id, $key, $meta);
|
323 |
}
|
324 |
|
325 |
wp_update_post($tr_post);
|
326 |
-
|
327 |
$this->safe_translation_status_update($locale, 'current');
|
328 |
}
|
329 |
|
@@ -348,7 +341,6 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
348 |
if ($tr_id) {
|
349 |
$tr_lang = $this->pllm->get_language($locale);
|
350 |
$this->pllm->set_post_language($tr_id, $tr_lang);
|
351 |
-
|
352 |
$this->safe_translation_status_update($locale, 'current', array($tr_lang->slug => $tr_id));
|
353 |
wp_set_object_terms($tr_id, $this->term_id, 'post_translations');
|
354 |
|
@@ -356,21 +348,11 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
356 |
$GLOBALS['polylang']->sync->copy_post_metas($this->source, $tr_id, $tr_lang->slug);
|
357 |
|
358 |
// copy or ignore metas
|
359 |
-
$
|
360 |
-
foreach ($custom_fields as $key => $setting) {
|
361 |
-
if ('copy' === $setting) {
|
362 |
-
$source_meta = current(get_post_meta($post->ID, $key)) ;
|
363 |
-
update_post_meta($tr_id, $key, $source_meta);
|
364 |
-
}
|
365 |
-
elseif ('ignore' === $setting) {
|
366 |
-
delete_post_meta($tr_id, $key);
|
367 |
-
}
|
368 |
-
}
|
369 |
|
370 |
// translate metas
|
371 |
-
if (
|
372 |
-
|
373 |
-
update_post_meta($tr_id, $key, $meta);
|
374 |
}
|
375 |
}
|
376 |
}
|
@@ -382,6 +364,38 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
382 |
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
383 |
}
|
384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
/*
|
386 |
* checks if content should be automatically uploaded
|
387 |
*
|
@@ -390,7 +404,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
390 |
* @return bool
|
391 |
*/
|
392 |
public function is_automatic_upload() {
|
393 |
-
return 'automatic' == Lingotek_Model::get_profile_option('upload', get_post_type($this->source), $this->get_source_language());
|
394 |
}
|
395 |
|
396 |
/*
|
@@ -403,4 +417,18 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
403 |
public function get_source_language() {
|
404 |
return $this->pllm->get_post_language($this->source);
|
405 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
}
|
28 |
),
|
29 |
$language->slug => $object_id // for Polylang
|
30 |
);
|
31 |
+
self::save_hash_on_upload($object_id);
|
32 |
self::_create($object_id, $document_id, $data, 'post_translations');
|
33 |
}
|
34 |
|
107 |
*/
|
108 |
static public function get_custom_fields_from_wp_postmeta($post_ID = NULL) {
|
109 |
$custom_fields = get_option('lingotek_custom_fields', array());
|
110 |
+
$meta_black_list = array('_encloseme', '_edit_last', '_edit_lock', '_wp_trash_meta_status', '_wp_trash_meta_time');
|
111 |
$arr = array();
|
112 |
$keys = array();
|
113 |
|
129 |
|
130 |
foreach ($posts as $post) {
|
131 |
$metadata = has_meta($post->ID);
|
132 |
+
foreach ($metadata as $key => $meta) {
|
133 |
+
if (in_array($meta['meta_key'], $meta_black_list) || in_array($meta['meta_key'], $keys)) {
|
|
|
|
|
|
|
134 |
unset($metadata[$key]);
|
135 |
}
|
136 |
+
$keys [] = $meta['meta_key'];
|
137 |
}
|
138 |
$arr = array_merge($arr, $metadata);
|
139 |
}
|
141 |
return apply_filters('lingotek_post_custom_fields', $arr);
|
142 |
}
|
143 |
|
144 |
+
/*
|
145 |
+
* tests whether a meta belongs to the Advanced Custom Fields plugin
|
146 |
+
*
|
147 |
+
* @since 0.2
|
148 |
+
*
|
149 |
+
* @return bool
|
150 |
+
*/
|
151 |
+
protected static function is_advanced_custom_fields_meta($key, $value) {
|
152 |
+
return ((substr($key, 0, strlen('_')) === '_') && (substr($value, 0, strlen('field_')) === 'field_' )) ? TRUE : FALSE;
|
153 |
+
}
|
154 |
+
|
155 |
/*
|
156 |
* updates meta (custom) fields values in the lingotek_custom_fields option
|
157 |
*
|
167 |
$items = array();
|
168 |
|
169 |
foreach ($custom_fields_from_postmeta as $cf) {
|
170 |
+
// hide-copy means hide from user, and always copy to translations (Advanced Custom Fields plugin)
|
171 |
+
if (self::is_advanced_custom_fields_meta($cf['meta_key'], $cf['meta_value'])) {
|
172 |
+
$custom_fields[$cf['meta_key']] = 'hide-copy';
|
173 |
+
continue;
|
174 |
+
}
|
175 |
+
|
176 |
// no lingotek setting
|
177 |
if (!array_key_exists($cf['meta_key'], $custom_fields_from_lingotek)) {
|
178 |
// no lingotek setting, but there's a wpml setting
|
179 |
if (array_key_exists($cf['meta_key'], $custom_fields_from_wpml)) {
|
180 |
$custom_fields[$cf['meta_key']] = $custom_fields_from_wpml[$cf['meta_key']];
|
|
|
|
|
|
|
|
|
181 |
}
|
182 |
// no lingotek setting, no wpml setting, so save default setting of ignore
|
183 |
else {
|
184 |
+
$custom_fields[$cf['meta_key']] = 'ignore';
|
|
|
|
|
|
|
|
|
185 |
}
|
186 |
+
}
|
187 |
// lingotek already has this field setting saved
|
188 |
else {
|
189 |
+
$custom_fields[$cf['meta_key']] = $custom_fields_from_lingotek[$cf['meta_key']];
|
|
|
|
|
|
|
|
|
190 |
}
|
191 |
+
}
|
|
|
192 |
|
193 |
if ($post_ID) {
|
194 |
$custom_fields = array_merge($custom_fields_from_lingotek, $custom_fields);
|
195 |
}
|
196 |
update_option('lingotek_custom_fields', $custom_fields);
|
|
|
197 |
}
|
198 |
|
199 |
/*
|
210 |
|
211 |
if (is_array($custom_fields_from_lingotek)) {
|
212 |
foreach ($custom_fields_from_lingotek as $key => $setting) {
|
213 |
+
if ($setting === 'hide-copy') {
|
214 |
+
continue;
|
215 |
+
}
|
216 |
$arr = array(
|
217 |
'meta_key' => $key,
|
218 |
'setting' => $setting,
|
309 |
$tr_post['ID'] = $tr_id;
|
310 |
|
311 |
// copy or ignore metas
|
312 |
+
self::copy_or_ignore_metas($post->ID, $tr_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
// translate metas
|
315 |
+
if (isset($translation['metas'])) {
|
316 |
+
self::copy_translated_metas($translation['metas'], $tr_id);
|
|
|
317 |
}
|
318 |
|
319 |
wp_update_post($tr_post);
|
|
|
320 |
$this->safe_translation_status_update($locale, 'current');
|
321 |
}
|
322 |
|
341 |
if ($tr_id) {
|
342 |
$tr_lang = $this->pllm->get_language($locale);
|
343 |
$this->pllm->set_post_language($tr_id, $tr_lang);
|
|
|
344 |
$this->safe_translation_status_update($locale, 'current', array($tr_lang->slug => $tr_id));
|
345 |
wp_set_object_terms($tr_id, $this->term_id, 'post_translations');
|
346 |
|
348 |
$GLOBALS['polylang']->sync->copy_post_metas($this->source, $tr_id, $tr_lang->slug);
|
349 |
|
350 |
// copy or ignore metas
|
351 |
+
self::copy_or_ignore_metas($post->ID, $tr_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
|
353 |
// translate metas
|
354 |
+
if (isset($translation['metas'])) {
|
355 |
+
self::copy_translated_metas($translation['metas'], $tr_id);
|
|
|
356 |
}
|
357 |
}
|
358 |
}
|
364 |
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
365 |
}
|
366 |
|
367 |
+
/*
|
368 |
+
* copies source meta strings to translations or deletes meta if set to ignore
|
369 |
+
*
|
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) {
|
377 |
+
if ('copy' === $setting || 'hide-copy' === $setting) {
|
378 |
+
$source_meta = current(get_post_meta($post_id, $key)) ;
|
379 |
+
update_post_meta($tr_id, $key, $source_meta);
|
380 |
+
}
|
381 |
+
elseif ('ignore' === $setting) {
|
382 |
+
delete_post_meta($tr_id, $key);
|
383 |
+
}
|
384 |
+
}
|
385 |
+
}
|
386 |
+
|
387 |
+
/*
|
388 |
+
* inserts translated meta values into translations
|
389 |
+
*
|
390 |
+
* @since 1.0.9
|
391 |
+
*/
|
392 |
+
protected static function copy_translated_metas($translation_metas, $tr_id) {
|
393 |
+
if (!empty($translation_metas)) {
|
394 |
+
foreach ($translation_metas as $key => $meta)
|
395 |
+
update_post_meta($tr_id, $key, $meta);
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
/*
|
400 |
* checks if content should be automatically uploaded
|
401 |
*
|
404 |
* @return bool
|
405 |
*/
|
406 |
public function is_automatic_upload() {
|
407 |
+
return 'automatic' == Lingotek_Model::get_profile_option('upload', get_post_type($this->source), $this->get_source_language(), false, $this->source);
|
408 |
}
|
409 |
|
410 |
/*
|
417 |
public function get_source_language() {
|
418 |
return $this->pllm->get_post_language($this->source);
|
419 |
}
|
420 |
+
|
421 |
+
/*
|
422 |
+
* creates hash for lingotek_hash term
|
423 |
+
*
|
424 |
+
* @since 1.0.9
|
425 |
+
*/
|
426 |
+
protected static function save_hash_on_upload($object_id) {
|
427 |
+
$post = get_post($object_id);
|
428 |
+
$document_id = 'lingotek_hash_' . $post->ID;
|
429 |
+
$new_hash = md5(Lingotek_Group_Post::get_content($post));
|
430 |
+
|
431 |
+
wp_insert_term($document_id, 'lingotek_hash', array('description' => $new_hash));
|
432 |
+
wp_set_object_terms($post->ID, $document_id, 'lingotek_hash');
|
433 |
+
}
|
434 |
}
|
include/group.php
CHANGED
@@ -177,7 +177,7 @@ abstract class Lingotek_Group {
|
|
177 |
public function request_translation($locale) {
|
178 |
$client = new Lingotek_API();
|
179 |
$language = $this->pllm->get_language($locale);
|
180 |
-
$workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $this->get_source_language(), $language);
|
181 |
$args = $workflow ? array('workflow_id' => $workflow) : array();
|
182 |
|
183 |
if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
|
@@ -200,7 +200,7 @@ abstract class Lingotek_Group {
|
|
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);
|
204 |
$args = $workflow ? array('workflow_id' => $workflow) : array();
|
205 |
$client->request_translation($this->document_id, $lang->lingotek_locale, $args);
|
206 |
$this->status = 'current';
|
@@ -283,7 +283,7 @@ abstract class Lingotek_Group {
|
|
283 |
* @return bool
|
284 |
*/
|
285 |
public function is_automatic_download($locale) {
|
286 |
-
return 'automatic' == Lingotek_Model::get_profile_option('download', $this->type, $this->get_source_language(), $this->pllm->get_language($locale));
|
287 |
}
|
288 |
|
289 |
/*
|
@@ -295,7 +295,7 @@ abstract class Lingotek_Group {
|
|
295 |
* @param object $language
|
296 |
*/
|
297 |
public function is_disabled_target($language) {
|
298 |
-
$profile = Lingotek_Model::get_profile($this->type, $language);
|
299 |
return isset($profile['targets'][$language->slug]) && 'disabled' == $profile['targets'][$language->slug];
|
300 |
}
|
301 |
}
|
177 |
public function request_translation($locale) {
|
178 |
$client = new Lingotek_API();
|
179 |
$language = $this->pllm->get_language($locale);
|
180 |
+
$workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $this->get_source_language(), $language, $this->source);
|
181 |
$args = $workflow ? array('workflow_id' => $workflow) : array();
|
182 |
|
183 |
if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
|
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';
|
283 |
* @return bool
|
284 |
*/
|
285 |
public function is_automatic_download($locale) {
|
286 |
+
return 'automatic' == Lingotek_Model::get_profile_option('download', $this->type, $this->get_source_language(), $this->pllm->get_language($locale), $this->source);
|
287 |
}
|
288 |
|
289 |
/*
|
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 |
}
|
include/model.php
CHANGED
@@ -16,6 +16,9 @@ class Lingotek_Model {
|
|
16 |
*/
|
17 |
public function __construct() {
|
18 |
$this->pllm = $GLOBALS['polylang']->model;
|
|
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/*
|
@@ -109,10 +112,21 @@ class Lingotek_Model {
|
|
109 |
* @param object $language
|
110 |
* @return array
|
111 |
*/
|
112 |
-
static public function get_profile($type, $language) {
|
113 |
$content_types = get_option('lingotek_content_type');
|
114 |
$profiles = get_option('lingotek_profiles');
|
115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
// default profile is manual except for post
|
117 |
$default = 'post' == $type ? 'automatic' : 'manual';
|
118 |
|
@@ -152,8 +166,8 @@ class Lingotek_Model {
|
|
152 |
* @param object $target_language optional, needed to get custom target informations 'workflow_id' | 'download'
|
153 |
* @return string | bool either the option or false if the translation is disabled
|
154 |
*/
|
155 |
-
static public function get_profile_option($item, $type, $source_language, $target_language = false) {
|
156 |
-
$profile = self::get_profile($type, $source_language);
|
157 |
if ('disabled' == $profile['profile'])
|
158 |
return false;
|
159 |
|
@@ -180,7 +194,7 @@ class Lingotek_Model {
|
|
180 |
if (empty($post) || empty($language))
|
181 |
return;
|
182 |
|
183 |
-
$profile = self::get_profile($post->post_type, $language);
|
184 |
if ('disabled' == $profile['profile'])
|
185 |
return;
|
186 |
|
@@ -191,17 +205,17 @@ class Lingotek_Model {
|
|
191 |
'title' => $post->post_title,
|
192 |
'content' => Lingotek_Group_Post::get_content($post),
|
193 |
'locale_code' => $language->lingotek_locale,
|
194 |
-
'project_id' => self::get_profile_option('project_id', $post->post_type, $language),
|
195 |
-
'workflow_id' => self::get_profile_option('workflow_id', $post->post_type, $language),
|
196 |
'external_url' => $external_url,
|
197 |
);
|
198 |
|
199 |
$filter_ids = array();
|
200 |
-
if (self::get_profile_option('primary_filter_id', $post->post_type, $language)) {
|
201 |
-
$filter_ids['fprm_id'] = self::get_profile_option('primary_filter_id',$post->post_type, $language);
|
202 |
}
|
203 |
-
if (self::get_profile_option('secondary_filter_id', $post->post_type, $language)) {
|
204 |
-
$filter_ids['fprm_subfilter_id'] = self::get_profile_option('secondary_filter_id',$post->post_type, $language);
|
205 |
}
|
206 |
$params = array_merge($params, $filter_ids);
|
207 |
|
@@ -567,8 +581,11 @@ class Lingotek_Model {
|
|
567 |
$group = unserialize($group);
|
568 |
if (isset($group['lingotek']['translations'])) {
|
569 |
foreach ($group['lingotek']['translations'] as $locale => $status) {
|
570 |
-
if (('pending' == $status || 'ready' == $status) && $language = $this->pllm->get_language($locale))
|
571 |
-
$sources[$language->slug]
|
|
|
|
|
|
|
572 |
}
|
573 |
}
|
574 |
}
|
16 |
*/
|
17 |
public function __construct() {
|
18 |
$this->pllm = $GLOBALS['polylang']->model;
|
19 |
+
|
20 |
+
register_taxonomy('lingotek_profile', null , array('label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false));
|
21 |
+
register_taxonomy('lingotek_hash', null , array('label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false));
|
22 |
}
|
23 |
|
24 |
/*
|
112 |
* @param object $language
|
113 |
* @return array
|
114 |
*/
|
115 |
+
static public function get_profile($type, $language, $post_id = null) {
|
116 |
$content_types = get_option('lingotek_content_type');
|
117 |
$profiles = get_option('lingotek_profiles');
|
118 |
|
119 |
+
// If a profile is set for a specific post/page get that first
|
120 |
+
if ($post_id) {
|
121 |
+
$terms = get_terms('lingotek_profile', 'orderby=count&hide_empty=0');
|
122 |
+
foreach ($terms as $term) {
|
123 |
+
$extracted_post_id = str_replace('lingotek_profile_', '', $term->name);
|
124 |
+
if ($extracted_post_id == $post_id) {
|
125 |
+
return $profiles[$term->description];
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
// default profile is manual except for post
|
131 |
$default = 'post' == $type ? 'automatic' : 'manual';
|
132 |
|
166 |
* @param object $target_language optional, needed to get custom target informations 'workflow_id' | 'download'
|
167 |
* @return string | bool either the option or false if the translation is disabled
|
168 |
*/
|
169 |
+
static public function get_profile_option($item, $type, $source_language, $target_language = false, $post_id = null) {
|
170 |
+
$profile = self::get_profile($type, $source_language, $post_id);
|
171 |
if ('disabled' == $profile['profile'])
|
172 |
return false;
|
173 |
|
194 |
if (empty($post) || empty($language))
|
195 |
return;
|
196 |
|
197 |
+
$profile = self::get_profile($post->post_type, $language, $post_id);
|
198 |
if ('disabled' == $profile['profile'])
|
199 |
return;
|
200 |
|
205 |
'title' => $post->post_title,
|
206 |
'content' => Lingotek_Group_Post::get_content($post),
|
207 |
'locale_code' => $language->lingotek_locale,
|
208 |
+
'project_id' => self::get_profile_option('project_id', $post->post_type, $language, false, $post_id),
|
209 |
+
'workflow_id' => self::get_profile_option('workflow_id', $post->post_type, $language, false, $post_id),
|
210 |
'external_url' => $external_url,
|
211 |
);
|
212 |
|
213 |
$filter_ids = array();
|
214 |
+
if (self::get_profile_option('primary_filter_id', $post->post_type, $language, false, $post_id)) {
|
215 |
+
$filter_ids['fprm_id'] = self::get_profile_option('primary_filter_id',$post->post_type, $language, false, $post_id);
|
216 |
}
|
217 |
+
if (self::get_profile_option('secondary_filter_id', $post->post_type, $language, false, $post_id)) {
|
218 |
+
$filter_ids['fprm_subfilter_id'] = self::get_profile_option('secondary_filter_id',$post->post_type, $language, false, $post_id);
|
219 |
}
|
220 |
$params = array_merge($params, $filter_ids);
|
221 |
|
581 |
$group = unserialize($group);
|
582 |
if (isset($group['lingotek']['translations'])) {
|
583 |
foreach ($group['lingotek']['translations'] as $locale => $status) {
|
584 |
+
if (('pending' == $status || 'ready' == $status) && $language = $this->pllm->get_language($locale)) {
|
585 |
+
if ($sources[$language->slug] > 0) {
|
586 |
+
$sources[$language->slug]--;
|
587 |
+
}
|
588 |
+
}
|
589 |
}
|
590 |
}
|
591 |
}
|
js/updater.js
CHANGED
@@ -96,6 +96,9 @@ jQuery(document).ready(function($) {
|
|
96 |
$(td).find('.pll_icon_edit').remove();
|
97 |
updateUploadIndicator(td, data, key, locale);
|
98 |
}
|
|
|
|
|
|
|
99 |
else if ($(td).find('.pll_icon_add').length > 0 && data[key][data[key]['source']]['status'] === 'none'){
|
100 |
break;
|
101 |
}
|
96 |
$(td).find('.pll_icon_edit').remove();
|
97 |
updateUploadIndicator(td, data, key, locale);
|
98 |
}
|
99 |
+
else if (data[key][locale]['status'] === 'disabled' || data[key]['source'] === 'disabled') {
|
100 |
+
$(td).find('.lingotek-color').remove();
|
101 |
+
}
|
102 |
else if ($(td).find('.pll_icon_add').length > 0 && data[key][data[key]['source']]['status'] === 'none'){
|
103 |
break;
|
104 |
}
|
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.
|
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.
|
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
|
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'); // 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.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -58,7 +58,7 @@ Wherever third party code has been used, credit has been given in the code’s c
|
|
58 |
|
59 |
= Do you like Lingotek? =
|
60 |
|
61 |
-
Don't hesitate to [give your feedback](
|
62 |
|
63 |
== Installation ==
|
64 |
|
@@ -115,6 +115,16 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
|
|
115 |
|
116 |
== Changelog ==
|
117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
= 1.0.9 (2015-08-19) =
|
119 |
|
120 |
* Fixed error with YouTube videos not displaying in translations
|
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 |
|
58 |
|
59 |
= Do you like Lingotek? =
|
60 |
|
61 |
+
Don't hesitate to [give your feedback](https://wordpress.org/support/view/plugin-reviews/lingotek-translation). It will help make the plugin better. Other [contributions](https://wordpress.org/support/plugin/lingotek-translation) (helping other users on the support forum) are welcome!
|
62 |
|
63 |
== Installation ==
|
64 |
|
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
|
121 |
+
* The selected Translation Profile is now displayed on bulk display of Posts/Pages
|
122 |
+
* Minor fixes for real-time translation status updates
|
123 |
+
* Fixed a bug that prevented updating of content
|
124 |
+
* Custom fields enhancements and fixes
|
125 |
+
* Moved Content Type Configuration, Translation Profiles, and Custom Fields tabs from the Settings Page to the Manage Page
|
126 |
+
* Fixed Lingotek Dashboard counting error
|
127 |
+
|
128 |
= 1.0.9 (2015-08-19) =
|
129 |
|
130 |
* Fixed error with YouTube videos not displaying in translations
|