Version Description
(2021-07-07) = * Fixed WordPress: consume the download_interim_translation callback
Download this release
Release Info
Developer | sowmiya2021 |
Plugin | Lingotek Translation |
Version | 1.4.14 |
Comparing to | |
See all releases |
Code changes from version 1.4.13 to 1.4.14
- .travis.yml +71 -0
- admin/actions.php +368 -203
- admin/admin.php +154 -140
- admin/content-table.php +42 -31
- admin/custom-fields-table.php +39 -28
- admin/filters-columns.php +133 -127
- admin/filters-media.php +2 -1
- admin/filters-post.php +175 -162
- admin/filters-term.php +13 -13
- admin/import.php +50 -36
- admin/import/FormatConverter.php +206 -182
- admin/import/StandardImportObject.php +90 -81
- admin/import/import-table.php +447 -394
- admin/import/view-content.php +122 -109
- admin/import/view-settings.php +78 -64
- admin/manage/view-content.php +64 -66
- admin/manage/view-custom-fields.php +98 -88
- admin/manage/view-edit-profile.php +227 -184
- admin/manage/view-profiles.php +83 -69
- admin/manage/view-string-groups.php +36 -28
- admin/manage/view-strings.php +27 -20
- admin/post-actions.php +95 -97
- admin/profiles-table.php +35 -25
- admin/settings.php +20 -16
- admin/settings/connect-account.php +22 -22
- admin/settings/view-account.php +85 -77
- admin/settings/view-defaults.php +60 -42
- admin/settings/view-preferences.php +80 -73
- admin/settings/view-utilities.php +17 -14
- admin/string-actions.php +4 -6
- admin/strings-table.php +55 -44
- admin/table-string.php +18 -11
- admin/term-actions.php +80 -68
- admin/tutorial/content.php +74 -59
- admin/tutorial/credits.php +124 -81
- admin/tutorial/faq.php +28 -28
- admin/tutorial/features.php +17 -17
- admin/utilities.php +67 -52
- admin/view-dashboard.php +2 -2
- admin/view-manage.php +44 -39
- admin/view-network.php +114 -109
- admin/view-tutorial.php +32 -27
- admin/workflows/credit-card-to-path.php +44 -44
- admin/workflows/professional-translation-workflow.php +239 -260
- admin/workflows/workflow-factory.php +10 -10
- admin/workflows/workflow.php +77 -73
- admin/wp-import.php +7 -7
- bin/githook-pre-commit.sh +37 -0
- bin/githook-prepare-commit-msg.sh +46 -0
- bin/install-git-hooks.sh +25 -0
- bin/install-wp-tests.sh +181 -0
- include/api.php +729 -476
- include/callback.php +99 -94
- include/dashboard.php +169 -159
- include/group-post.php +264 -255
- include/group-string.php +75 -50
- include/group-term.php +55 -54
- include/group.php +234 -231
- include/http.php +69 -38
- include/logger.php +38 -34
- include/model.php +561 -474
- include/plugins-compat.php +12 -11
- include/pointer.php +29 -25
- js/updater.js +24 -8
- lingotek.php +370 -353
- phpcs.xml +79 -0
- phpunit.xml +15 -0
- readme.txt +5 -2
- tests/README.md +46 -0
- tests/bootstrap.php +42 -0
- tests/test-lingotek-installation.php +86 -0
- uninstall.php +17 -16
.travis.yml
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
sudo: false
|
2 |
+
dist: trusty
|
3 |
+
|
4 |
+
language: php
|
5 |
+
|
6 |
+
notifications:
|
7 |
+
email:
|
8 |
+
on_success: never
|
9 |
+
on_failure: change
|
10 |
+
|
11 |
+
branches:
|
12 |
+
only:
|
13 |
+
- master
|
14 |
+
|
15 |
+
cache:
|
16 |
+
directories:
|
17 |
+
- $HOME/.composer/cache
|
18 |
+
|
19 |
+
matrix:
|
20 |
+
include:
|
21 |
+
- php: 7.4
|
22 |
+
env: WP_VERSION=latest
|
23 |
+
- php: 7.3
|
24 |
+
env: WP_VERSION=latest
|
25 |
+
- php: 7.2
|
26 |
+
env: WP_VERSION=latest
|
27 |
+
- php: 7.1
|
28 |
+
env: WP_VERSION=latest
|
29 |
+
- php: 7.0
|
30 |
+
env: WP_VERSION=latest
|
31 |
+
- php: 5.6
|
32 |
+
env: WP_VERSION=3.8
|
33 |
+
- php: 5.6
|
34 |
+
env: WP_VERSION=latest
|
35 |
+
- php: 5.6
|
36 |
+
env: WP_VERSION=trunk
|
37 |
+
- php: 5.6
|
38 |
+
env: WP_TRAVISCI=phpcs
|
39 |
+
|
40 |
+
before_script:
|
41 |
+
- export PATH="$HOME/.composer/vendor/bin:$PATH"
|
42 |
+
- |
|
43 |
+
if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then
|
44 |
+
phpenv config-rm xdebug.ini
|
45 |
+
else
|
46 |
+
echo "xdebug.ini does not exist"
|
47 |
+
fi
|
48 |
+
- |
|
49 |
+
if [[ ! -z "$WP_VERSION" ]] ; then
|
50 |
+
bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
|
51 |
+
composer global require "phpunit/phpunit=4.8.*|5.7.*"
|
52 |
+
fi
|
53 |
+
- |
|
54 |
+
if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
|
55 |
+
composer global require wp-coding-standards/wpcs
|
56 |
+
composer global require phpcompatibility/php-compatibility
|
57 |
+
composer global require phpcompatibility/phpcompatibility-paragonie
|
58 |
+
composer global require phpcompatibility/phpcompatibility-wp
|
59 |
+
phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs,$HOME/.composer/vendor/phpcompatibility/php-compatibility,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-paragonie,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-wp
|
60 |
+
fi
|
61 |
+
|
62 |
+
script:
|
63 |
+
- |
|
64 |
+
if [[ ! -z "$WP_VERSION" ]] ; then
|
65 |
+
phpunit
|
66 |
+
WP_MULTISITE=1 phpunit
|
67 |
+
fi
|
68 |
+
- |
|
69 |
+
if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
|
70 |
+
phpcs
|
71 |
+
fi
|
admin/actions.php
CHANGED
@@ -79,106 +79,106 @@ abstract class Lingotek_Actions {
|
|
79 |
*/
|
80 |
public function __construct( $type ) {
|
81 |
// confirm message.
|
82 |
-
self::$confirm_message
|
83 |
-
self::$confirm_delete
|
84 |
-
self::$confirm_cancel
|
85 |
-
self::$confirm_delete_translation = sprintf(' onclick = "return confirm(\'%s\');"', __( 'Translation will be deleted from WordPress. The associated translation in the TMS will be cancelled. Are you sure?', 'lingotek-translation' ) );
|
86 |
-
self::$confirm_cancel_translation = sprintf(' onclick = "return confirm(\'%s\');"', __( 'You are about to cancel this translation in your Lingotek community. Are you sure?', 'lingotek-translation' ) );
|
87 |
// row actions.
|
88 |
self::$actions = array(
|
89 |
-
'upload'
|
90 |
'action' => __( 'Upload to Lingotek', 'lingotek-translation' ),
|
91 |
'progress' => __( 'Uploading...', 'lingotek-translation' ),
|
92 |
'description' => __( 'Upload this item to Lingotek TMS', 'lingotek-translation' ),
|
93 |
),
|
94 |
|
95 |
-
'request'
|
96 |
'action' => __( 'Request translations', 'lingotek-translation' ),
|
97 |
'progress' => __( 'Requesting translations...', 'lingotek-translation' ),
|
98 |
'description' => __( 'Request translations of this item to Lingotek TMS', 'lingotek-translation' ),
|
99 |
),
|
100 |
|
101 |
-
'status'
|
102 |
'action' => __( 'Update translations status', 'lingotek-translation' ),
|
103 |
'progress' => __( 'Updating translations status...', 'lingotek-translation' ),
|
104 |
'description' => __( 'Update translations status of this item in Lingotek TMS', 'lingotek-translation' ),
|
105 |
),
|
106 |
|
107 |
-
'download'
|
108 |
'action' => __( 'Download translations', 'lingotek-translation' ),
|
109 |
'progress' => __( 'Downloading translations...', 'lingotek-translation' ),
|
110 |
'description' => __( 'Download translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
111 |
),
|
112 |
|
113 |
-
'cancel'
|
114 |
'action' => __( 'Cancel translations', 'lingotek-translation' ),
|
115 |
'progress' => __( 'Cancelling translations...', 'lingotek-translation' ),
|
116 |
'description' => __( 'Cancel the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
117 |
),
|
118 |
|
119 |
-
'delete'
|
120 |
'action' => __( 'Delete translations', 'lingotek-translation' ),
|
121 |
'progress' => __( 'Deleting translations...', 'lingotek-translation' ),
|
122 |
'description' => __( 'Delete the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
123 |
),
|
124 |
|
125 |
'cancel-translation' => array(
|
126 |
-
'action' => __('Cancel translation', 'lingotek-translation'),
|
127 |
-
'progress' => __('Cancelling translation', 'lingotek-translation'),
|
128 |
-
'description' => __('Cancel this translation from Lingotek TMS', 'lingotek-translation'),
|
129 |
),
|
130 |
|
131 |
'delete-translation' => array(
|
132 |
-
'action' => __('Delete translation', 'lingotek-translation'),
|
133 |
-
'progress' => __('Deleting translation', 'lingotek-translation'),
|
134 |
-
'description' => __('Delete this translation from Lingotek TMS', 'lingotek-translation'),
|
135 |
),
|
136 |
);
|
137 |
|
138 |
// action icons
|
139 |
self::$icons = array(
|
140 |
-
'upload'
|
141 |
'title' => __( 'Upload Now', 'lingotek-translation' ),
|
142 |
'icon' => 'upload',
|
143 |
),
|
144 |
|
145 |
-
'importing'
|
146 |
'title' => __( 'Importing source', 'lingotek-translation' ),
|
147 |
'icon' => 'clock',
|
148 |
),
|
149 |
|
150 |
-
'failed'
|
151 |
'title' => __( 'Upload Failed. Click to re-upload', 'lingotek-translation' ),
|
152 |
'icon' => 'no',
|
153 |
-
'class' => 'lingotek-failed-color'
|
154 |
),
|
155 |
|
156 |
-
'uploaded'
|
157 |
'title' => __( 'Source uploaded', 'lingotek-translation' ),
|
158 |
'icon' => 'yes',
|
159 |
),
|
160 |
|
161 |
-
'request'
|
162 |
'title' => __( 'Request a translation', 'lingotek-translation' ),
|
163 |
'icon' => 'plus',
|
164 |
),
|
165 |
|
166 |
-
'pending'
|
167 |
'title' => __( 'In Progress', 'lingotek-translation' ),
|
168 |
'icon' => 'clock',
|
169 |
),
|
170 |
|
171 |
-
'ready'
|
172 |
'title' => __( 'Ready to download', 'lingotek-translation' ),
|
173 |
'icon' => 'download',
|
174 |
),
|
175 |
|
176 |
-
'interim'
|
177 |
-
'title' => __('Interim Translation Downloaded', 'lingotek-translation'),
|
178 |
-
'icon'
|
179 |
),
|
180 |
|
181 |
-
'current'
|
182 |
'title' => __( 'Current', 'lingotek-translation' ),
|
183 |
'icon' => 'edit',
|
184 |
),
|
@@ -188,19 +188,19 @@ abstract class Lingotek_Actions {
|
|
188 |
'icon' => 'edit',
|
189 |
),
|
190 |
|
191 |
-
'error'
|
192 |
'title' => __( 'There was an error contacting Lingotek', 'lingotek-translation' ),
|
193 |
'icon' => 'no',
|
194 |
),
|
195 |
|
196 |
-
'copy'
|
197 |
'title' => __( 'Copy source language', 'lingotek-translation' ),
|
198 |
'icon' => 'welcome-add-page',
|
199 |
),
|
200 |
|
201 |
-
'cancelled'
|
202 |
-
'title' => __('Translation has been cancelled', 'lingotek-translation'),
|
203 |
-
'icon'
|
204 |
),
|
205 |
);
|
206 |
|
@@ -213,13 +213,13 @@ abstract class Lingotek_Actions {
|
|
213 |
add_action( 'wp_ajax_estimate_cost', array( &$this, 'ajax_estimate_cost' ) );
|
214 |
add_action( 'wp_ajax_request_professional_translation', array( &$this, 'ajax_request_professional_translation' ) );
|
215 |
add_action( 'wp_ajax_get_user_payment_information', array( &$this, 'ajax_get_user_payment_information' ) );
|
216 |
-
add_action( 'wp_ajax_get_ltk_terms_and_conditions', array( &$this, 'ajax_get_ltk_terms_and_conditions' ) );
|
217 |
|
218 |
foreach ( array_keys( self::$actions ) as $action ) {
|
219 |
-
if(strpos($action, '-translation')){
|
220 |
continue;
|
221 |
}
|
222 |
-
add_action( 'wp_ajax_lingotek_progress_' . $this->type . '_' . $action
|
223 |
}
|
224 |
}
|
225 |
|
@@ -229,12 +229,12 @@ abstract class Lingotek_Actions {
|
|
229 |
* @since 0.1
|
230 |
*
|
231 |
* @param string $document_id
|
232 |
-
* @param string $locale Lingotek locale
|
233 |
-
* @return string
|
234 |
*/
|
235 |
public static function workbench_link( $document_id, $locale ) {
|
236 |
-
$document_id = $document_id
|
237 |
-
$locale
|
238 |
return Lingotek_API::PRODUCTION_URL . "/workbench/document/$document_id/locale/$locale";
|
239 |
}
|
240 |
|
@@ -245,16 +245,28 @@ abstract class Lingotek_Actions {
|
|
245 |
*
|
246 |
* @param string $name
|
247 |
* @param string $link
|
248 |
-
* @param string $additional
|
249 |
*/
|
250 |
public static function display_icon( $name, $link, $additional = '' ) {
|
251 |
-
self::link_to_settings_if_not_connected($link);
|
252 |
-
if (
|
253 |
-
return sprintf(
|
254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
-
return sprintf(
|
257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
}
|
259 |
|
260 |
/**
|
@@ -263,65 +275,83 @@ abstract class Lingotek_Actions {
|
|
263 |
* @since 1.2
|
264 |
*
|
265 |
* @param string $name
|
266 |
-
* @param string $
|
|
|
267 |
*/
|
268 |
public static function display_error_icon( $name, $api_error, $additional = '' ) {
|
269 |
-
return sprintf(
|
270 |
-
|
|
|
|
|
|
|
|
|
271 |
}
|
272 |
-
|
273 |
/**
|
274 |
* Outputs an upload icon
|
275 |
*
|
276 |
* @since 0.2
|
277 |
*
|
278 |
* @param int|string $object_id
|
279 |
-
* @param bool
|
280 |
*/
|
281 |
public function upload_icon( $object_id, $confirm = false ) {
|
282 |
-
$args = array(
|
283 |
-
|
284 |
-
|
|
|
|
|
|
|
|
|
285 |
}
|
286 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-upload' );
|
287 |
-
self::link_to_settings_if_not_connected($link);
|
288 |
return self::display_icon( 'upload', $link, $confirm ? self::$confirm_message : '' );
|
289 |
}
|
290 |
|
291 |
-
/**
|
292 |
* Outputs a cancelled icon
|
293 |
*
|
294 |
* @since 1.4.13
|
295 |
*
|
296 |
* @param int|string $object_id
|
297 |
* id of the object
|
298 |
-
* @param bool
|
299 |
* boolean to show if icon is for a target or source document
|
300 |
-
* @param bool
|
301 |
* boolean to enable the cancel confirm pop up
|
302 |
*/
|
303 |
public function cancelled_icon( $object_id, $target = false, $confirm = false ) {
|
304 |
$action = $target ? 'edit' : 'lingotek-upload';
|
305 |
-
$args
|
306 |
-
|
307 |
-
|
|
|
|
|
|
|
|
|
308 |
}
|
309 |
-
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), $action);
|
310 |
-
self::link_to_settings_if_not_connected($link);
|
311 |
-
return self::display_icon( 'cancelled', $link, $confirm ? self::$confirm_message : '');
|
312 |
}
|
313 |
|
314 |
/**
|
315 |
* Outputs a copy icon
|
316 |
*
|
317 |
* @param int|string $object_id
|
318 |
-
* @param string
|
319 |
-
* @param bool
|
320 |
*/
|
321 |
public function copy_icon( $object_id, $target, $confirm = false ) {
|
322 |
-
$args = array(
|
|
|
|
|
|
|
|
|
|
|
323 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-copy' );
|
324 |
-
self::link_to_settings_if_not_connected($link);
|
325 |
return self::display_icon( 'copy', $link, $confirm ? self::$confirm_message : '' );
|
326 |
}
|
327 |
|
@@ -333,9 +363,13 @@ abstract class Lingotek_Actions {
|
|
333 |
* @param object $document
|
334 |
*/
|
335 |
public static function importing_icon( $document ) {
|
336 |
-
$args = array(
|
|
|
|
|
|
|
|
|
337 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-status' );
|
338 |
-
self::link_to_settings_if_not_connected($link);
|
339 |
return self::display_icon( 'importing', $link );
|
340 |
}
|
341 |
|
@@ -350,41 +384,71 @@ abstract class Lingotek_Actions {
|
|
350 |
public static function translation_icon( $document, $language ) {
|
351 |
if ( isset( $document->translations[ $language->locale ] ) ) {
|
352 |
if ( 'ready' === $document->translations[ $language->locale ] ) {
|
353 |
-
$link = wp_nonce_url(
|
354 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
return self::display_icon( $document->translations[ $language->locale ], $link );
|
356 |
} elseif ( 'not-current' === $document->translations[ $language->locale ] ) {
|
357 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
358 |
-
|
|
|
359 |
return $custom_icon;
|
360 |
} else {
|
361 |
$link = self::workbench_link( $document->document_id, $language->lingotek_locale );
|
362 |
-
self::link_to_settings_if_not_connected($link);
|
363 |
return self::display_icon( $document->translations[ $language->locale ], $link, ' target="_blank"' );
|
364 |
-
}
|
365 |
} else {
|
366 |
-
$link = wp_nonce_url(
|
367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
return self::display_icon( 'request', $link );
|
369 |
-
}
|
370 |
}
|
371 |
|
372 |
/**
|
373 |
* Outputs icon for failed import callback
|
374 |
*
|
375 |
* @since 1.4.3
|
376 |
-
*
|
377 |
*/
|
378 |
-
public function failed_import_icon($name, $object_id) {
|
379 |
-
$args = array(
|
380 |
-
|
381 |
-
|
|
|
|
|
|
|
|
|
382 |
}
|
383 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-upload' );
|
384 |
-
self::link_to_settings_if_not_connected($link);
|
385 |
|
386 |
-
return sprintf(
|
387 |
-
|
|
|
|
|
|
|
|
|
|
|
388 |
}
|
389 |
|
390 |
/**
|
@@ -392,36 +456,36 @@ abstract class Lingotek_Actions {
|
|
392 |
*
|
393 |
* @since 0.2
|
394 |
*
|
395 |
-
* @param array $args
|
396 |
-
* @param bool $warning
|
397 |
* @return string
|
398 |
*/
|
399 |
protected function get_action_link( $args, $warning = false ) {
|
400 |
-
$action
|
401 |
-
$args['action']
|
402 |
$args['noheader'] = true;
|
403 |
-
if (isset($args['string'])) {
|
404 |
-
$args['string'] =
|
405 |
}
|
406 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-' . $action );
|
407 |
-
self::link_to_settings_if_not_connected($link);
|
408 |
-
|
409 |
-
switch($action){
|
410 |
case 'delete-translation':
|
411 |
$message = self::$confirm_delete_translation;
|
412 |
-
|
413 |
case 'delete':
|
414 |
$message = self::$confirm_delete;
|
415 |
-
|
416 |
case 'cancel-translation':
|
417 |
$message = self::$confirm_cancel_translation;
|
418 |
-
|
419 |
case 'cancel':
|
420 |
$message = self::$confirm_cancel;
|
421 |
-
|
422 |
default:
|
423 |
$message = self::$confirm_message;
|
424 |
-
|
425 |
}
|
426 |
|
427 |
return sprintf(
|
@@ -433,10 +497,9 @@ abstract class Lingotek_Actions {
|
|
433 |
);
|
434 |
}
|
435 |
|
436 |
-
private static function link_to_settings_if_not_connected(&$link)
|
437 |
-
|
438 |
-
|
439 |
-
$link = get_site_url(null, '/wp-admin/admin.php?page=lingotek-translation_settings');
|
440 |
}
|
441 |
}
|
442 |
|
@@ -445,8 +508,8 @@ abstract class Lingotek_Actions {
|
|
445 |
*
|
446 |
* @since 0.2
|
447 |
*
|
448 |
-
* @param array
|
449 |
-
* @param $id
|
450 |
* @return array
|
451 |
*/
|
452 |
protected function _row_actions( $actions, $id ) {
|
@@ -455,19 +518,22 @@ abstract class Lingotek_Actions {
|
|
455 |
return $actions;
|
456 |
}
|
457 |
$document = $this->lgtm->get_group( $this->type, $id );
|
458 |
-
|
459 |
$target_id = $id;
|
460 |
-
if ( $this->type
|
461 |
$id = $document->desc_array['lingotek']['source'];
|
462 |
}
|
463 |
|
464 |
-
if ( $this->lgtm->can_upload( $this->type, $id ) || (isset( $document->source ) && 'string' !== $this->type && $this->lgtm->can_upload( $this->type, $document->source )) ) {
|
465 |
if ( $document ) {
|
466 |
$desc_array = $document->desc_array;
|
467 |
unset( $desc_array['lingotek'] );
|
468 |
-
$data = array(
|
|
|
|
|
|
|
469 |
if ( count( $desc_array ) >= 2 ) {
|
470 |
-
$actions['lingotek-upload'] = $this->get_action_link( $data
|
471 |
} else {
|
472 |
$actions['lingotek-upload'] = $this->get_action_link( $data );
|
473 |
}
|
@@ -477,29 +543,55 @@ abstract class Lingotek_Actions {
|
|
477 |
* update translation status option.
|
478 |
*/
|
479 |
if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
|
480 |
-
$actions['lingotek-status'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
481 |
}
|
482 |
|
483 |
if ( $document->has_translation_status( 'ready' ) ) {
|
484 |
-
$actions['lingotek-download'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
485 |
}
|
486 |
} else {
|
487 |
-
$actions['lingotek-upload'] = $this->get_action_link(
|
488 |
-
|
|
|
|
|
|
|
|
|
|
|
489 |
} elseif ( isset( $document->translations ) ) {
|
490 |
// translations to download ?
|
491 |
if ( $document->has_translation_status( 'ready' ) ) {
|
492 |
-
$actions['lingotek-download'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
493 |
}
|
494 |
|
495 |
-
if ($document->has_translation_status('interim')) {
|
496 |
-
$actions['lingotek-status'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
497 |
}
|
498 |
|
499 |
//need to request translations?
|
500 |
-
$language
|
501 |
$all_locales = array_flip( $this->pllm->get_languages_list( array( 'fields' => 'locale' ) ) );
|
502 |
-
|
|
|
503 |
unset( $all_locales[ $language->locale ] );
|
504 |
}
|
505 |
$untranslated = array_diff_key( $all_locales, $document->translations );
|
@@ -512,25 +604,70 @@ abstract class Lingotek_Actions {
|
|
512 |
}
|
513 |
|
514 |
if ( 'current' === $document->status && ! empty( $untranslated ) ) {
|
515 |
-
$actions['lingotek-request'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
516 |
}
|
517 |
|
518 |
// offers to update translations status
|
519 |
if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
|
520 |
-
$actions['lingotek-status'] = $this->get_action_link(
|
|
|
|
|
|
|
|
|
|
|
521 |
}
|
522 |
} elseif ( empty( $document->source ) ) {
|
523 |
-
$actions['lingotek-upload'] = $this->get_action_link(
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
}
|
531 |
-
|
532 |
-
|
533 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
|
535 |
return $actions;
|
536 |
}
|
@@ -544,9 +681,10 @@ abstract class Lingotek_Actions {
|
|
544 |
*/
|
545 |
protected function _add_bulk_actions( $bulk_actions ) {
|
546 |
foreach ( self::$actions as $action => $strings ) {
|
547 |
-
if(strpos($action, '-translation')){
|
548 |
continue;
|
549 |
}
|
|
|
550 |
$bulk_actions[ 'bulk-lingotek-' . $action ] = __( $strings['action'], $action );
|
551 |
if ( null !== filter_input( INPUT_GET, 'bulk-lingotek-' . $action ) ) {
|
552 |
$text = $strings['progress'];
|
@@ -561,27 +699,29 @@ abstract class Lingotek_Actions {
|
|
561 |
|
562 |
/**
|
563 |
* Outputs javascript data for progress.js
|
564 |
-
* wp_localize_script($handle, $name, $data) $handle needs to be lingotek_myhandle
|
565 |
-
* where myhandle is handle of script you loaded previously with wp_enqueue_script (probably in admin.php)
|
566 |
*
|
567 |
* @since 0.1
|
568 |
*/
|
569 |
public function admin_enqueue_scripts() {
|
570 |
foreach ( array_keys( self::$actions ) as $action ) {
|
571 |
if ( null !== filter_input( INPUT_GET, "bulk-lingotek-$action" ) ) {
|
572 |
-
$action_message =
|
573 |
-
$data
|
574 |
-
'action' => null === filter_input( INPUT_GET, 'page' ) ? (null === filter_input( INPUT_GET, 'taxonomy' ) ? "post_$action" : "term_$action") : "string_$action",
|
575 |
'taxonomy' => null === filter_input( INPUT_GET, 'taxonomy' ) || ! taxonomy_exists( wp_unslash( filter_input( INPUT_GET, 'taxonomy' ) ) ) ? '' : filter_input( INPUT_GET, 'taxonomy' ),
|
576 |
-
'sendback' => remove_query_arg( array( "bulk-lingotek-$action", 'ids', 'lingotek_warning', 'locales'), wp_get_referer() ),
|
577 |
'ids' => array_map( 'intval', explode( ',', filter_input( INPUT_GET, 'ids' ) ) ),
|
578 |
-
|
|
|
|
|
579 |
'nonce' => wp_create_nonce( 'lingotek_progress' ),
|
580 |
);
|
581 |
-
if (null!== filter_input( INPUT_GET, 'locales')){
|
582 |
-
$data['locales'] = explode( ',', filter_input( INPUT_GET, 'locales'));
|
583 |
}
|
584 |
-
wp_localize_script('lingotek_progress', 'lingotek_data', $data);
|
585 |
return;
|
586 |
}
|
587 |
}
|
@@ -592,13 +732,13 @@ abstract class Lingotek_Actions {
|
|
592 |
*
|
593 |
* @since 0.2
|
594 |
*
|
595 |
-
* @param string $action
|
596 |
-
* @return bool
|
597 |
*/
|
598 |
protected function _manage_actions( $action ) {
|
599 |
if ( null !== filter_input( INPUT_GET, 'document_id' ) ) {
|
600 |
$document_id = filter_input( INPUT_GET, 'document_id' );
|
601 |
-
$document
|
602 |
}
|
603 |
|
604 |
switch ( $action ) {
|
@@ -610,13 +750,31 @@ abstract class Lingotek_Actions {
|
|
610 |
|
611 |
case 'lingotek-request':
|
612 |
check_admin_referer( 'lingotek-request' );
|
613 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
614 |
null !== filter_input( INPUT_GET, 'locale' ) ? $document->request_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->request_translations();
|
615 |
break;
|
616 |
|
617 |
case 'lingotek-download':
|
618 |
check_admin_referer( 'lingotek-download' );
|
619 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
620 |
null !== filter_input( INPUT_GET, 'locale' ) ? $document->create_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->create_translations();
|
621 |
break;
|
622 |
|
@@ -632,7 +790,7 @@ abstract class Lingotek_Actions {
|
|
632 |
exit();
|
633 |
}
|
634 |
break;
|
635 |
-
|
636 |
case 'lingotek-cancel':
|
637 |
check_admin_referer( 'lingotek-cancel' );
|
638 |
$document->cancel();
|
@@ -644,34 +802,34 @@ abstract class Lingotek_Actions {
|
|
644 |
break;
|
645 |
|
646 |
case 'lingotek-delete-translation':
|
647 |
-
check_admin_referer('lingotek-delete-translation');
|
648 |
-
$target_locale = filter_input(INPUT_GET, 'target_locale');
|
649 |
-
$target_id
|
650 |
-
$language
|
651 |
-
$document->delete_translation($language, $target_id);
|
652 |
-
if(null !== filter_input(INPUT_GET, 'lingotek_redirect') && filter_input(INPUT_GET, 'lingotek_redirect') === true) {
|
653 |
$site_id = get_current_blog_id();
|
654 |
-
wp_safe_redirect(get_site_url($site_id, '/wp-admin/edit.php?post_type=page'));
|
655 |
exit();
|
656 |
}
|
657 |
break;
|
658 |
|
659 |
case 'lingotek-cancel-translation':
|
660 |
-
check_admin_referer('lingotek-cancel-translation');
|
661 |
-
$target_locale = filter_input(INPUT_GET, 'target_locale');
|
662 |
-
$target_id
|
663 |
-
$language
|
664 |
-
$document->cancel_translation($language, $target_id);
|
665 |
-
if(null !== filter_input(INPUT_GET, 'lingotek_redirect') && filter_input(INPUT_GET, 'lingotek_redirect') === true) {
|
666 |
$site_id = get_current_blog_id();
|
667 |
-
wp_safe_redirect(get_site_url($site_id, '/wp-admin/edit.php?post_type=page'));
|
668 |
exit();
|
669 |
}
|
670 |
break;
|
671 |
-
|
672 |
default:
|
673 |
return false;
|
674 |
-
}
|
675 |
|
676 |
return true;
|
677 |
}
|
@@ -683,9 +841,10 @@ abstract class Lingotek_Actions {
|
|
683 |
*/
|
684 |
public function ajax_download() {
|
685 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
686 |
-
|
|
|
687 |
foreach ( $document->translations as $locale => $status ) {
|
688 |
-
if ( 'pending' === $status || 'ready' === $status || 'interim' === $status || 'current' === $status) {
|
689 |
$document->create_translation( $locale );
|
690 |
}
|
691 |
}
|
@@ -700,7 +859,8 @@ abstract class Lingotek_Actions {
|
|
700 |
*/
|
701 |
public function ajax_request() {
|
702 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
703 |
-
|
|
|
704 |
$document->request_translations();
|
705 |
}
|
706 |
die();
|
@@ -713,7 +873,8 @@ abstract class Lingotek_Actions {
|
|
713 |
*/
|
714 |
public function ajax_status() {
|
715 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
716 |
-
|
|
|
717 |
$document->source_status();
|
718 |
$document->translations_status();
|
719 |
}
|
@@ -727,33 +888,36 @@ abstract class Lingotek_Actions {
|
|
727 |
*/
|
728 |
public function ajax_delete() {
|
729 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
730 |
-
$id
|
731 |
-
$language = PLL()->model->post->get_language($id);
|
732 |
$document = $this->lgtm->get_group( $this->type, $id );
|
|
|
733 |
if ( $document && $document->source == $id ) {
|
734 |
/**it was left as disassociate so that the delete functionality wouldn't break as it
|
735 |
* did when changing disassociate to delete/cancel in other connectors
|
736 |
*/
|
737 |
$document->delete();
|
738 |
-
|
739 |
-
|
|
|
740 |
}
|
741 |
die();
|
742 |
}
|
743 |
|
744 |
/**
|
745 |
* Ajax response cancel translations and showing progress
|
746 |
-
*
|
747 |
*/
|
748 |
public function ajax_cancel() {
|
749 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
750 |
-
$id
|
751 |
-
$language = PLL()->model->post->get_language($id);
|
752 |
-
$document = $this->lgtm->get_group( $this->type, $id);
|
|
|
753 |
if ( $document && $document->source == $id ) {
|
754 |
$document->cancel();
|
755 |
-
|
756 |
-
|
|
|
757 |
}
|
758 |
die();
|
759 |
}
|
@@ -763,29 +927,30 @@ abstract class Lingotek_Actions {
|
|
763 |
*/
|
764 |
public function ajax_estimate_cost() {
|
765 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
766 |
-
$document_id
|
767 |
-
$locale
|
768 |
$lingotek_auth = filter_input( INPUT_GET, 'Authorization-Lingotek' );
|
769 |
-
$client
|
770 |
-
$response
|
771 |
-
echo
|
772 |
die();
|
773 |
}
|
774 |
|
775 |
/**
|
776 |
-
|
777 |
-
|
778 |
public function ajax_request_professional_translation() {
|
779 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
780 |
-
$post_vars = filter_input_array(INPUT_POST);
|
781 |
-
$client
|
782 |
-
$response
|
783 |
-
if (true === $response['data']['transaction_approved']) {
|
784 |
-
foreach ($post_vars['translations'] as $document_id => $locales) {
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
$
|
|
|
789 |
}
|
790 |
} else {
|
791 |
// TODO: what if a document doesn't exists? T_T
|
@@ -793,22 +958,22 @@ abstract class Lingotek_Actions {
|
|
793 |
}
|
794 |
}
|
795 |
|
796 |
-
echo
|
797 |
die();
|
798 |
}
|
799 |
|
800 |
public function ajax_get_ltk_terms_and_conditions() {
|
801 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
802 |
$client = new Lingotek_API();
|
803 |
-
echo
|
804 |
die();
|
805 |
}
|
806 |
|
807 |
public function ajax_get_user_payment_information() {
|
808 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
809 |
-
$client
|
810 |
$response = $client->get_user_payment_information();
|
811 |
-
echo
|
812 |
die();
|
813 |
}
|
814 |
|
@@ -817,7 +982,7 @@ abstract class Lingotek_Actions {
|
|
817 |
*
|
818 |
* @since 1.1
|
819 |
*
|
820 |
-
* @param string errors
|
821 |
*/
|
822 |
public static function retrieve_api_error( $errors ) {
|
823 |
$api_error = "\n";
|
79 |
*/
|
80 |
public function __construct( $type ) {
|
81 |
// confirm message.
|
82 |
+
self::$confirm_message = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'You are about to overwrite existing translations. Are you sure?', 'lingotek-translation' ) );
|
83 |
+
self::$confirm_delete = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'Content will be deleted from WordPress. The associated content in the TMS will be cancelled. Are you sure?', 'lingotek-translation' ) );
|
84 |
+
self::$confirm_cancel = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'You are about to cancel existing translations in your Lingotek community. Are you sure?', 'lingotek-translation' ) );
|
85 |
+
self::$confirm_delete_translation = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'Translation will be deleted from WordPress. The associated translation in the TMS will be cancelled. Are you sure?', 'lingotek-translation' ) );
|
86 |
+
self::$confirm_cancel_translation = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'You are about to cancel this translation in your Lingotek community. Are you sure?', 'lingotek-translation' ) );
|
87 |
// row actions.
|
88 |
self::$actions = array(
|
89 |
+
'upload' => array(
|
90 |
'action' => __( 'Upload to Lingotek', 'lingotek-translation' ),
|
91 |
'progress' => __( 'Uploading...', 'lingotek-translation' ),
|
92 |
'description' => __( 'Upload this item to Lingotek TMS', 'lingotek-translation' ),
|
93 |
),
|
94 |
|
95 |
+
'request' => array(
|
96 |
'action' => __( 'Request translations', 'lingotek-translation' ),
|
97 |
'progress' => __( 'Requesting translations...', 'lingotek-translation' ),
|
98 |
'description' => __( 'Request translations of this item to Lingotek TMS', 'lingotek-translation' ),
|
99 |
),
|
100 |
|
101 |
+
'status' => array(
|
102 |
'action' => __( 'Update translations status', 'lingotek-translation' ),
|
103 |
'progress' => __( 'Updating translations status...', 'lingotek-translation' ),
|
104 |
'description' => __( 'Update translations status of this item in Lingotek TMS', 'lingotek-translation' ),
|
105 |
),
|
106 |
|
107 |
+
'download' => array(
|
108 |
'action' => __( 'Download translations', 'lingotek-translation' ),
|
109 |
'progress' => __( 'Downloading translations...', 'lingotek-translation' ),
|
110 |
'description' => __( 'Download translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
111 |
),
|
112 |
|
113 |
+
'cancel' => array(
|
114 |
'action' => __( 'Cancel translations', 'lingotek-translation' ),
|
115 |
'progress' => __( 'Cancelling translations...', 'lingotek-translation' ),
|
116 |
'description' => __( 'Cancel the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
117 |
),
|
118 |
|
119 |
+
'delete' => array(
|
120 |
'action' => __( 'Delete translations', 'lingotek-translation' ),
|
121 |
'progress' => __( 'Deleting translations...', 'lingotek-translation' ),
|
122 |
'description' => __( 'Delete the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
123 |
),
|
124 |
|
125 |
'cancel-translation' => array(
|
126 |
+
'action' => __( 'Cancel translation', 'lingotek-translation' ),
|
127 |
+
'progress' => __( 'Cancelling translation', 'lingotek-translation' ),
|
128 |
+
'description' => __( 'Cancel this translation from Lingotek TMS', 'lingotek-translation' ),
|
129 |
),
|
130 |
|
131 |
'delete-translation' => array(
|
132 |
+
'action' => __( 'Delete translation', 'lingotek-translation' ),
|
133 |
+
'progress' => __( 'Deleting translation', 'lingotek-translation' ),
|
134 |
+
'description' => __( 'Delete this translation from Lingotek TMS', 'lingotek-translation' ),
|
135 |
),
|
136 |
);
|
137 |
|
138 |
// action icons
|
139 |
self::$icons = array(
|
140 |
+
'upload' => array(
|
141 |
'title' => __( 'Upload Now', 'lingotek-translation' ),
|
142 |
'icon' => 'upload',
|
143 |
),
|
144 |
|
145 |
+
'importing' => array(
|
146 |
'title' => __( 'Importing source', 'lingotek-translation' ),
|
147 |
'icon' => 'clock',
|
148 |
),
|
149 |
|
150 |
+
'failed' => array(
|
151 |
'title' => __( 'Upload Failed. Click to re-upload', 'lingotek-translation' ),
|
152 |
'icon' => 'no',
|
153 |
+
'class' => 'lingotek-failed-color',
|
154 |
),
|
155 |
|
156 |
+
'uploaded' => array(
|
157 |
'title' => __( 'Source uploaded', 'lingotek-translation' ),
|
158 |
'icon' => 'yes',
|
159 |
),
|
160 |
|
161 |
+
'request' => array(
|
162 |
'title' => __( 'Request a translation', 'lingotek-translation' ),
|
163 |
'icon' => 'plus',
|
164 |
),
|
165 |
|
166 |
+
'pending' => array(
|
167 |
'title' => __( 'In Progress', 'lingotek-translation' ),
|
168 |
'icon' => 'clock',
|
169 |
),
|
170 |
|
171 |
+
'ready' => array(
|
172 |
'title' => __( 'Ready to download', 'lingotek-translation' ),
|
173 |
'icon' => 'download',
|
174 |
),
|
175 |
|
176 |
+
'interim' => array(
|
177 |
+
'title' => __( 'Interim Translation Downloaded', 'lingotek-translation' ),
|
178 |
+
'icon' => 'edit',
|
179 |
),
|
180 |
|
181 |
+
'current' => array(
|
182 |
'title' => __( 'Current', 'lingotek-translation' ),
|
183 |
'icon' => 'edit',
|
184 |
),
|
188 |
'icon' => 'edit',
|
189 |
),
|
190 |
|
191 |
+
'error' => array(
|
192 |
'title' => __( 'There was an error contacting Lingotek', 'lingotek-translation' ),
|
193 |
'icon' => 'no',
|
194 |
),
|
195 |
|
196 |
+
'copy' => array(
|
197 |
'title' => __( 'Copy source language', 'lingotek-translation' ),
|
198 |
'icon' => 'welcome-add-page',
|
199 |
),
|
200 |
|
201 |
+
'cancelled' => array(
|
202 |
+
'title' => __( 'Translation has been cancelled', 'lingotek-translation' ),
|
203 |
+
'icon' => 'warning',
|
204 |
),
|
205 |
);
|
206 |
|
213 |
add_action( 'wp_ajax_estimate_cost', array( &$this, 'ajax_estimate_cost' ) );
|
214 |
add_action( 'wp_ajax_request_professional_translation', array( &$this, 'ajax_request_professional_translation' ) );
|
215 |
add_action( 'wp_ajax_get_user_payment_information', array( &$this, 'ajax_get_user_payment_information' ) );
|
216 |
+
add_action( 'wp_ajax_get_ltk_terms_and_conditions', array( &$this, 'ajax_get_ltk_terms_and_conditions' ) );
|
217 |
|
218 |
foreach ( array_keys( self::$actions ) as $action ) {
|
219 |
+
if ( strpos( $action, '-translation' ) ) {
|
220 |
continue;
|
221 |
}
|
222 |
+
add_action( 'wp_ajax_lingotek_progress_' . $this->type . '_' . $action, array( &$this, 'ajax_' . $action ) );
|
223 |
}
|
224 |
}
|
225 |
|
229 |
* @since 0.1
|
230 |
*
|
231 |
* @param string $document_id
|
232 |
+
* @param string $locale Lingotek locale.
|
233 |
+
* @return string Workbench link.
|
234 |
*/
|
235 |
public static function workbench_link( $document_id, $locale ) {
|
236 |
+
$document_id = ! empty( $document_id ) ? $document_id : '';
|
237 |
+
$locale = $locale ? Lingotek::map_to_lingotek_locale( $locale ) : '';
|
238 |
return Lingotek_API::PRODUCTION_URL . "/workbench/document/$document_id/locale/$locale";
|
239 |
}
|
240 |
|
245 |
*
|
246 |
* @param string $name
|
247 |
* @param string $link
|
248 |
+
* @param string $additional Parameters to add (js, target).
|
249 |
*/
|
250 |
public static function display_icon( $name, $link, $additional = '' ) {
|
251 |
+
self::link_to_settings_if_not_connected( $link );
|
252 |
+
if ( 'interim' === $name ) {
|
253 |
+
return sprintf(
|
254 |
+
'<a class="lingotek-interim-color dashicons dashicons-%s dashicons-%s-lingotek" title="%s" href="%s"%s></a>',
|
255 |
+
self::$icons[ $name ]['icon'],
|
256 |
+
self::$icons[ $name ]['icon'],
|
257 |
+
self::$icons[ $name ]['title'],
|
258 |
+
esc_url( $link ),
|
259 |
+
$additional
|
260 |
+
);
|
261 |
}
|
262 |
+
return sprintf(
|
263 |
+
'<a class="lingotek-color dashicons dashicons-%s dashicons-%s-lingotek" title="%s" href="%s"%s></a>',
|
264 |
+
self::$icons[ $name ]['icon'],
|
265 |
+
self::$icons[ $name ]['icon'],
|
266 |
+
self::$icons[ $name ]['title'],
|
267 |
+
esc_url( $link ),
|
268 |
+
$additional
|
269 |
+
);
|
270 |
}
|
271 |
|
272 |
/**
|
275 |
* @since 1.2
|
276 |
*
|
277 |
* @param string $name
|
278 |
+
* @param string $api_error
|
279 |
+
* @param string $additional Parameters to add (js, target).
|
280 |
*/
|
281 |
public static function display_error_icon( $name, $api_error, $additional = '' ) {
|
282 |
+
return sprintf(
|
283 |
+
'<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
|
284 |
+
self::$icons[ $name ]['icon'],
|
285 |
+
self::$icons[ $name ]['title'] . "\n" . $api_error,
|
286 |
+
$additional
|
287 |
+
);
|
288 |
}
|
289 |
+
|
290 |
/**
|
291 |
* Outputs an upload icon
|
292 |
*
|
293 |
* @since 0.2
|
294 |
*
|
295 |
* @param int|string $object_id
|
296 |
+
* @param bool $confirm
|
297 |
*/
|
298 |
public function upload_icon( $object_id, $confirm = false ) {
|
299 |
+
$args = array(
|
300 |
+
$this->type => $object_id,
|
301 |
+
'action' => 'lingotek-upload',
|
302 |
+
'noheader' => true,
|
303 |
+
);
|
304 |
+
if ( isset( $args['string'] ) ) {
|
305 |
+
$args['string'] = rawurlencode( $args['string'] );
|
306 |
}
|
307 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-upload' );
|
308 |
+
self::link_to_settings_if_not_connected( $link );
|
309 |
return self::display_icon( 'upload', $link, $confirm ? self::$confirm_message : '' );
|
310 |
}
|
311 |
|
312 |
+
/**
|
313 |
* Outputs a cancelled icon
|
314 |
*
|
315 |
* @since 1.4.13
|
316 |
*
|
317 |
* @param int|string $object_id
|
318 |
* id of the object
|
319 |
+
* @param bool $target
|
320 |
* boolean to show if icon is for a target or source document
|
321 |
+
* @param bool $confirm
|
322 |
* boolean to enable the cancel confirm pop up
|
323 |
*/
|
324 |
public function cancelled_icon( $object_id, $target = false, $confirm = false ) {
|
325 |
$action = $target ? 'edit' : 'lingotek-upload';
|
326 |
+
$args = array(
|
327 |
+
$this->type => $object_id,
|
328 |
+
'action' => $action,
|
329 |
+
'noheader' => true,
|
330 |
+
);
|
331 |
+
if ( isset( $args['string'] ) ) {
|
332 |
+
$args['string'] = rawurlencode( $args['string'] );
|
333 |
}
|
334 |
+
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), $action );
|
335 |
+
self::link_to_settings_if_not_connected( $link );
|
336 |
+
return self::display_icon( 'cancelled', $link, $confirm ? self::$confirm_message : '' );
|
337 |
}
|
338 |
|
339 |
/**
|
340 |
* Outputs a copy icon
|
341 |
*
|
342 |
* @param int|string $object_id
|
343 |
+
* @param string $target
|
344 |
+
* @param bool $confirm
|
345 |
*/
|
346 |
public function copy_icon( $object_id, $target, $confirm = false ) {
|
347 |
+
$args = array(
|
348 |
+
$this->type => $object_id,
|
349 |
+
'target' => $target,
|
350 |
+
'action' => 'lingotek-copy',
|
351 |
+
'noheader' => true,
|
352 |
+
);
|
353 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-copy' );
|
354 |
+
self::link_to_settings_if_not_connected( $link );
|
355 |
return self::display_icon( 'copy', $link, $confirm ? self::$confirm_message : '' );
|
356 |
}
|
357 |
|
363 |
* @param object $document
|
364 |
*/
|
365 |
public static function importing_icon( $document ) {
|
366 |
+
$args = array(
|
367 |
+
'document_id' => $document->document_id,
|
368 |
+
'action' => 'lingotek-status',
|
369 |
+
'noheader' => true,
|
370 |
+
);
|
371 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-status' );
|
372 |
+
self::link_to_settings_if_not_connected( $link );
|
373 |
return self::display_icon( 'importing', $link );
|
374 |
}
|
375 |
|
384 |
public static function translation_icon( $document, $language ) {
|
385 |
if ( isset( $document->translations[ $language->locale ] ) ) {
|
386 |
if ( 'ready' === $document->translations[ $language->locale ] ) {
|
387 |
+
$link = wp_nonce_url(
|
388 |
+
add_query_arg(
|
389 |
+
array(
|
390 |
+
'document_id' => $document->document_id,
|
391 |
+
'locale' => $language->locale,
|
392 |
+
'action' => 'lingotek-download',
|
393 |
+
'noheader' => true,
|
394 |
+
)
|
395 |
+
),
|
396 |
+
'lingotek-download'
|
397 |
+
);
|
398 |
+
self::link_to_settings_if_not_connected( $link );
|
399 |
return self::display_icon( $document->translations[ $language->locale ], $link );
|
400 |
} elseif ( 'not-current' === $document->translations[ $language->locale ] ) {
|
401 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
402 |
+
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found,Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
|
403 |
+
} elseif ( 'current' !== $document->translations[ $language->locale ] && $custom_icon = $document->get_custom_in_progress_icon( $language ) ) {
|
404 |
return $custom_icon;
|
405 |
} else {
|
406 |
$link = self::workbench_link( $document->document_id, $language->lingotek_locale );
|
407 |
+
self::link_to_settings_if_not_connected( $link );
|
408 |
return self::display_icon( $document->translations[ $language->locale ], $link, ' target="_blank"' );
|
409 |
+
}//end if
|
410 |
} else {
|
411 |
+
$link = wp_nonce_url(
|
412 |
+
add_query_arg(
|
413 |
+
array(
|
414 |
+
'document_id' => $document->document_id,
|
415 |
+
'locale' => $language->locale,
|
416 |
+
'action' => 'lingotek-request',
|
417 |
+
'noheader' => true,
|
418 |
+
),
|
419 |
+
defined( 'DOING_AJAX' ) && DOING_AJAX ? wp_get_referer() : wp_get_referer()
|
420 |
+
),
|
421 |
+
'lingotek-request'
|
422 |
+
);
|
423 |
+
self::link_to_settings_if_not_connected( $link );
|
424 |
return self::display_icon( 'request', $link );
|
425 |
+
}//end if
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
* Outputs icon for failed import callback
|
430 |
*
|
431 |
* @since 1.4.3
|
|
|
432 |
*/
|
433 |
+
public function failed_import_icon( $name, $object_id ) {
|
434 |
+
$args = array(
|
435 |
+
$this->type => $object_id,
|
436 |
+
'action' => 'lingotek-upload',
|
437 |
+
'noheader' => true,
|
438 |
+
);
|
439 |
+
if ( isset( $args['string'] ) ) {
|
440 |
+
$args['string'] = rawurlencode( $args['string'] );
|
441 |
}
|
442 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-upload' );
|
443 |
+
self::link_to_settings_if_not_connected( $link );
|
444 |
|
445 |
+
return sprintf(
|
446 |
+
'<a class="%s dashicons dashicons-%s" title="%s" href="%s"></a>',
|
447 |
+
self::$icons[ $name ]['class'],
|
448 |
+
self::$icons[ $name ]['icon'],
|
449 |
+
self::$icons[ $name ]['title'],
|
450 |
+
esc_url( $link )
|
451 |
+
);
|
452 |
}
|
453 |
|
454 |
/**
|
456 |
*
|
457 |
* @since 0.2
|
458 |
*
|
459 |
+
* @param array $args Parameters to add to the link.
|
460 |
+
* @param bool $warning Whether to display an alert or not, optional, defaults to false.
|
461 |
* @return string
|
462 |
*/
|
463 |
protected function get_action_link( $args, $warning = false ) {
|
464 |
+
$action = $args['action'];
|
465 |
+
$args['action'] = 'lingotek-' . $action;
|
466 |
$args['noheader'] = true;
|
467 |
+
if ( isset( $args['string'] ) ) {
|
468 |
+
$args['string'] = rawurlencode( $args['string'] );
|
469 |
}
|
470 |
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-' . $action );
|
471 |
+
self::link_to_settings_if_not_connected( $link );
|
472 |
+
|
473 |
+
switch ( $action ) {
|
474 |
case 'delete-translation':
|
475 |
$message = self::$confirm_delete_translation;
|
476 |
+
break;
|
477 |
case 'delete':
|
478 |
$message = self::$confirm_delete;
|
479 |
+
break;
|
480 |
case 'cancel-translation':
|
481 |
$message = self::$confirm_cancel_translation;
|
482 |
+
break;
|
483 |
case 'cancel':
|
484 |
$message = self::$confirm_cancel;
|
485 |
+
break;
|
486 |
default:
|
487 |
$message = self::$confirm_message;
|
488 |
+
break;
|
489 |
}
|
490 |
|
491 |
return sprintf(
|
497 |
);
|
498 |
}
|
499 |
|
500 |
+
private static function link_to_settings_if_not_connected( &$link ) {
|
501 |
+
if ( ! get_option( 'lingotek_token' ) || ! get_option( 'lingotek_community' ) ) {
|
502 |
+
$link = get_site_url( null, '/wp-admin/admin.php?page=lingotek-translation_settings' );
|
|
|
503 |
}
|
504 |
}
|
505 |
|
508 |
*
|
509 |
* @since 0.2
|
510 |
*
|
511 |
+
* @param array $actions List of action links.
|
512 |
+
* @param mixed $id Object id.
|
513 |
* @return array
|
514 |
*/
|
515 |
protected function _row_actions( $actions, $id ) {
|
518 |
return $actions;
|
519 |
}
|
520 |
$document = $this->lgtm->get_group( $this->type, $id );
|
521 |
+
|
522 |
$target_id = $id;
|
523 |
+
if ( 'string' !== $this->type && isset( $document->desc_array['lingotek']['source'] ) ) {
|
524 |
$id = $document->desc_array['lingotek']['source'];
|
525 |
}
|
526 |
|
527 |
+
if ( $this->lgtm->can_upload( $this->type, $id ) || ( isset( $document->source ) && 'string' !== $this->type && $this->lgtm->can_upload( $this->type, $document->source ) ) ) {
|
528 |
if ( $document ) {
|
529 |
$desc_array = $document->desc_array;
|
530 |
unset( $desc_array['lingotek'] );
|
531 |
+
$data = array(
|
532 |
+
$this->type => $id,
|
533 |
+
'action' => 'upload',
|
534 |
+
);
|
535 |
if ( count( $desc_array ) >= 2 ) {
|
536 |
+
$actions['lingotek-upload'] = $this->get_action_link( $data, true );
|
537 |
} else {
|
538 |
$actions['lingotek-upload'] = $this->get_action_link( $data );
|
539 |
}
|
543 |
* update translation status option.
|
544 |
*/
|
545 |
if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
|
546 |
+
$actions['lingotek-status'] = $this->get_action_link(
|
547 |
+
array(
|
548 |
+
'document_id' => $document->document_id,
|
549 |
+
'action' => 'status',
|
550 |
+
)
|
551 |
+
);
|
552 |
}
|
553 |
|
554 |
if ( $document->has_translation_status( 'ready' ) ) {
|
555 |
+
$actions['lingotek-download'] = $this->get_action_link(
|
556 |
+
array(
|
557 |
+
'document_id' => $document->document_id,
|
558 |
+
'action' => 'download',
|
559 |
+
)
|
560 |
+
);
|
561 |
}
|
562 |
} else {
|
563 |
+
$actions['lingotek-upload'] = $this->get_action_link(
|
564 |
+
array(
|
565 |
+
$this->type => $id,
|
566 |
+
'action' => 'upload',
|
567 |
+
)
|
568 |
+
);
|
569 |
+
}//end if
|
570 |
} elseif ( isset( $document->translations ) ) {
|
571 |
// translations to download ?
|
572 |
if ( $document->has_translation_status( 'ready' ) ) {
|
573 |
+
$actions['lingotek-download'] = $this->get_action_link(
|
574 |
+
array(
|
575 |
+
'document_id' => $document->document_id,
|
576 |
+
'action' => 'download',
|
577 |
+
)
|
578 |
+
);
|
579 |
}
|
580 |
|
581 |
+
if ( $document->has_translation_status( 'interim' ) ) {
|
582 |
+
$actions['lingotek-status'] = $this->get_action_link(
|
583 |
+
array(
|
584 |
+
'document_id' => $document->document_id,
|
585 |
+
'action' => 'status',
|
586 |
+
)
|
587 |
+
);
|
588 |
}
|
589 |
|
590 |
//need to request translations?
|
591 |
+
$language = $this->get_language( $document->source );
|
592 |
$all_locales = array_flip( $this->pllm->get_languages_list( array( 'fields' => 'locale' ) ) );
|
593 |
+
// In case a language has been deleted.
|
594 |
+
if ( ! empty( $language ) ) {
|
595 |
unset( $all_locales[ $language->locale ] );
|
596 |
}
|
597 |
$untranslated = array_diff_key( $all_locales, $document->translations );
|
604 |
}
|
605 |
|
606 |
if ( 'current' === $document->status && ! empty( $untranslated ) ) {
|
607 |
+
$actions['lingotek-request'] = $this->get_action_link(
|
608 |
+
array(
|
609 |
+
'document_id' => $document->document_id,
|
610 |
+
'action' => 'request',
|
611 |
+
)
|
612 |
+
);
|
613 |
}
|
614 |
|
615 |
// offers to update translations status
|
616 |
if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
|
617 |
+
$actions['lingotek-status'] = $this->get_action_link(
|
618 |
+
array(
|
619 |
+
'document_id' => $document->document_id,
|
620 |
+
'action' => 'status',
|
621 |
+
)
|
622 |
+
);
|
623 |
}
|
624 |
} elseif ( empty( $document->source ) ) {
|
625 |
+
$actions['lingotek-upload'] = $this->get_action_link(
|
626 |
+
array(
|
627 |
+
$this->type => $id,
|
628 |
+
'action' => 'upload',
|
629 |
+
),
|
630 |
+
true
|
631 |
+
);
|
632 |
+
}//end if
|
633 |
+
|
634 |
+
$target_locale = $this->get_language( $target_id )->locale;
|
635 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
636 |
+
if ( $id == $target_id && isset( $document->source ) && 'cancelled' !== $document->status ) {
|
637 |
+
$actions['lingotek-cancel'] = $this->get_action_link(
|
638 |
+
array(
|
639 |
+
'document_id' => $document->document_id,
|
640 |
+
'action' => 'cancel',
|
641 |
+
),
|
642 |
+
true
|
643 |
+
);
|
644 |
+
$actions['lingotek-delete'] = $this->get_action_link(
|
645 |
+
array(
|
646 |
+
'document_id' => $document->document_id,
|
647 |
+
'action' => 'delete',
|
648 |
+
),
|
649 |
+
true
|
650 |
+
);
|
651 |
+
} elseif ( isset( $document->source ) && isset( $document->translations[ $target_locale ] ) && 'cancelled' !== $document->translations[ $target_locale ] ) {
|
652 |
+
$actions['lingotek-cancel-translation'] = $this->get_action_link(
|
653 |
+
array(
|
654 |
+
'document_id' => $document->document_id,
|
655 |
+
'target_id' => $target_id,
|
656 |
+
'target_locale' => $target_locale,
|
657 |
+
'action' => 'cancel-translation',
|
658 |
+
),
|
659 |
+
true
|
660 |
+
);
|
661 |
+
$actions['lingotek-delete-translation'] = $this->get_action_link(
|
662 |
+
array(
|
663 |
+
'document_id' => $document->document_id,
|
664 |
+
'target_id' => $target_id,
|
665 |
+
'target_locale' => $target_locale,
|
666 |
+
'action' => 'delete-translation',
|
667 |
+
),
|
668 |
+
true
|
669 |
+
);
|
670 |
+
}//end if
|
671 |
|
672 |
return $actions;
|
673 |
}
|
681 |
*/
|
682 |
protected function _add_bulk_actions( $bulk_actions ) {
|
683 |
foreach ( self::$actions as $action => $strings ) {
|
684 |
+
if ( strpos( $action, '-translation' ) ) {
|
685 |
continue;
|
686 |
}
|
687 |
+
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain
|
688 |
$bulk_actions[ 'bulk-lingotek-' . $action ] = __( $strings['action'], $action );
|
689 |
if ( null !== filter_input( INPUT_GET, 'bulk-lingotek-' . $action ) ) {
|
690 |
$text = $strings['progress'];
|
699 |
|
700 |
/**
|
701 |
* Outputs javascript data for progress.js
|
702 |
+
* wp_localize_script($handle, $name, $data) $handle needs to be lingotek_myhandle
|
703 |
+
* where myhandle is handle of script you loaded previously with wp_enqueue_script (probably in admin.php)
|
704 |
*
|
705 |
* @since 0.1
|
706 |
*/
|
707 |
public function admin_enqueue_scripts() {
|
708 |
foreach ( array_keys( self::$actions ) as $action ) {
|
709 |
if ( null !== filter_input( INPUT_GET, "bulk-lingotek-$action" ) ) {
|
710 |
+
$action_message = 'delete' === $action ? 'cancel' : $action;
|
711 |
+
$data = array(
|
712 |
+
'action' => null === filter_input( INPUT_GET, 'page' ) ? ( null === filter_input( INPUT_GET, 'taxonomy' ) ? "post_$action" : "term_$action" ) : "string_$action",
|
713 |
'taxonomy' => null === filter_input( INPUT_GET, 'taxonomy' ) || ! taxonomy_exists( wp_unslash( filter_input( INPUT_GET, 'taxonomy' ) ) ) ? '' : filter_input( INPUT_GET, 'taxonomy' ),
|
714 |
+
'sendback' => remove_query_arg( array( "bulk-lingotek-$action", 'ids', 'lingotek_warning', 'locales' ), wp_get_referer() ),
|
715 |
'ids' => array_map( 'intval', explode( ',', filter_input( INPUT_GET, 'ids' ) ) ),
|
716 |
+
// TODO: Fix this based on the possible $action_message values.
|
717 |
+
// phpcs:ignore WordPress.WP.I18n.InterpolatedVariableText
|
718 |
+
'warning' => null === filter_input( INPUT_GET, 'lingotek_warning' ) ? ( null === filter_input( INPUT_GET, 'lingotek_remove' ) ? '' : __( "You are about to $action_message existing translations from your Lingotek community. Are you sure?", 'lingotek-translation' ) ) : __( 'You are about to overwrite existing translations. Are you sure?', 'lingotek-translation' ),
|
719 |
'nonce' => wp_create_nonce( 'lingotek_progress' ),
|
720 |
);
|
721 |
+
if ( null !== filter_input( INPUT_GET, 'locales' ) ) {
|
722 |
+
$data['locales'] = explode( ',', filter_input( INPUT_GET, 'locales' ) );
|
723 |
}
|
724 |
+
wp_localize_script( 'lingotek_progress', 'lingotek_data', $data );
|
725 |
return;
|
726 |
}
|
727 |
}
|
732 |
*
|
733 |
* @since 0.2
|
734 |
*
|
735 |
+
* @param string $action Action name.
|
736 |
+
* @return bool True if the action was managed, false otherwise.
|
737 |
*/
|
738 |
protected function _manage_actions( $action ) {
|
739 |
if ( null !== filter_input( INPUT_GET, 'document_id' ) ) {
|
740 |
$document_id = filter_input( INPUT_GET, 'document_id' );
|
741 |
+
$document = $this->lgtm->get_group_by_id( $document_id );
|
742 |
}
|
743 |
|
744 |
switch ( $action ) {
|
750 |
|
751 |
case 'lingotek-request':
|
752 |
check_admin_referer( 'lingotek-request' );
|
753 |
+
Lingotek_Logger::info(
|
754 |
+
'User requested to translate an item',
|
755 |
+
array(
|
756 |
+
'document_id' => isset( $document_id ) ? $document_id : '',
|
757 |
+
'locale' => filter_input(
|
758 |
+
INPUT_GET,
|
759 |
+
'locale'
|
760 |
+
),
|
761 |
+
)
|
762 |
+
);
|
763 |
null !== filter_input( INPUT_GET, 'locale' ) ? $document->request_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->request_translations();
|
764 |
break;
|
765 |
|
766 |
case 'lingotek-download':
|
767 |
check_admin_referer( 'lingotek-download' );
|
768 |
+
Lingotek_Logger::info(
|
769 |
+
'User requested to download translation',
|
770 |
+
array(
|
771 |
+
'document_id' => isset( $document_id ) ? $document_id : '',
|
772 |
+
'locale' => filter_input(
|
773 |
+
INPUT_GET,
|
774 |
+
'locale'
|
775 |
+
),
|
776 |
+
)
|
777 |
+
);
|
778 |
null !== filter_input( INPUT_GET, 'locale' ) ? $document->create_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->create_translations();
|
779 |
break;
|
780 |
|
790 |
exit();
|
791 |
}
|
792 |
break;
|
793 |
+
|
794 |
case 'lingotek-cancel':
|
795 |
check_admin_referer( 'lingotek-cancel' );
|
796 |
$document->cancel();
|
802 |
break;
|
803 |
|
804 |
case 'lingotek-delete-translation':
|
805 |
+
check_admin_referer( 'lingotek-delete-translation' );
|
806 |
+
$target_locale = filter_input( INPUT_GET, 'target_locale' );
|
807 |
+
$target_id = filter_input( INPUT_GET, 'target_id' );
|
808 |
+
$language = PLL()->model->post->get_language( $target_id );
|
809 |
+
$document->delete_translation( $language, $target_id );
|
810 |
+
if ( null !== filter_input( INPUT_GET, 'lingotek_redirect' ) && filter_input( INPUT_GET, 'lingotek_redirect' ) === true ) {
|
811 |
$site_id = get_current_blog_id();
|
812 |
+
wp_safe_redirect( get_site_url( $site_id, '/wp-admin/edit.php?post_type=page' ) );
|
813 |
exit();
|
814 |
}
|
815 |
break;
|
816 |
|
817 |
case 'lingotek-cancel-translation':
|
818 |
+
check_admin_referer( 'lingotek-cancel-translation' );
|
819 |
+
$target_locale = filter_input( INPUT_GET, 'target_locale' );
|
820 |
+
$target_id = filter_input( INPUT_GET, 'target_id' );
|
821 |
+
$language = PLL()->model->post->get_language( $target_id );
|
822 |
+
$document->cancel_translation( $language, $target_id );
|
823 |
+
if ( null !== filter_input( INPUT_GET, 'lingotek_redirect' ) && filter_input( INPUT_GET, 'lingotek_redirect' ) === true ) {
|
824 |
$site_id = get_current_blog_id();
|
825 |
+
wp_safe_redirect( get_site_url( $site_id, '/wp-admin/edit.php?post_type=page' ) );
|
826 |
exit();
|
827 |
}
|
828 |
break;
|
829 |
+
|
830 |
default:
|
831 |
return false;
|
832 |
+
}//end switch
|
833 |
|
834 |
return true;
|
835 |
}
|
841 |
*/
|
842 |
public function ajax_download() {
|
843 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
844 |
+
$document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) );
|
845 |
+
if ( $document ) {
|
846 |
foreach ( $document->translations as $locale => $status ) {
|
847 |
+
if ( 'pending' === $status || 'ready' === $status || 'interim' === $status || 'current' === $status ) {
|
848 |
$document->create_translation( $locale );
|
849 |
}
|
850 |
}
|
859 |
*/
|
860 |
public function ajax_request() {
|
861 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
862 |
+
$document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) );
|
863 |
+
if ( $document ) {
|
864 |
$document->request_translations();
|
865 |
}
|
866 |
die();
|
873 |
*/
|
874 |
public function ajax_status() {
|
875 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
876 |
+
$document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) );
|
877 |
+
if ( $document ) {
|
878 |
$document->source_status();
|
879 |
$document->translations_status();
|
880 |
}
|
888 |
*/
|
889 |
public function ajax_delete() {
|
890 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
891 |
+
$id = filter_input( INPUT_POST, 'id' );
|
892 |
+
$language = PLL()->model->post->get_language( $id );
|
893 |
$document = $this->lgtm->get_group( $this->type, $id );
|
894 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
895 |
if ( $document && $document->source == $id ) {
|
896 |
/**it was left as disassociate so that the delete functionality wouldn't break as it
|
897 |
* did when changing disassociate to delete/cancel in other connectors
|
898 |
*/
|
899 |
$document->delete();
|
900 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
901 |
+
} elseif ( $document && $document->source != $id && $language ) {
|
902 |
+
$document->delete_translation( $language, $id );
|
903 |
}
|
904 |
die();
|
905 |
}
|
906 |
|
907 |
/**
|
908 |
* Ajax response cancel translations and showing progress
|
|
|
909 |
*/
|
910 |
public function ajax_cancel() {
|
911 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
912 |
+
$id = filter_input( INPUT_POST, 'id' );
|
913 |
+
$language = PLL()->model->post->get_language( $id );
|
914 |
+
$document = $this->lgtm->get_group( $this->type, $id );
|
915 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
916 |
if ( $document && $document->source == $id ) {
|
917 |
$document->cancel();
|
918 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
919 |
+
} elseif ( $document && $document->source != $id && $language ) {
|
920 |
+
$document->cancel_translation( $language, $id );
|
921 |
}
|
922 |
die();
|
923 |
}
|
927 |
*/
|
928 |
public function ajax_estimate_cost() {
|
929 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
930 |
+
$document_id = filter_input( INPUT_GET, 'document_id' );
|
931 |
+
$locale = filter_input( INPUT_GET, 'locale' );
|
932 |
$lingotek_auth = filter_input( INPUT_GET, 'Authorization-Lingotek' );
|
933 |
+
$client = new Lingotek_API();
|
934 |
+
$response = $client->get_cost_estimate( $lingotek_auth, $document_id, $locale );
|
935 |
+
echo wp_json_encode( $response );
|
936 |
die();
|
937 |
}
|
938 |
|
939 |
/**
|
940 |
+
* Ajax call to request professional translation of a document through bridge.
|
941 |
+
*/
|
942 |
public function ajax_request_professional_translation() {
|
943 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
944 |
+
$post_vars = filter_input_array( INPUT_POST );
|
945 |
+
$client = new Lingotek_API();
|
946 |
+
$response = $client->request_professional_translation_bulk( $post_vars['workflow_id'], $post_vars['translations'], $post_vars['total_estimate'], $post_vars['summary'] );
|
947 |
+
if ( true === $response['data']['transaction_approved'] ) {
|
948 |
+
foreach ( $post_vars['translations'] as $document_id => $locales ) {
|
949 |
+
$document = $this->lgtm->get_group( $post_vars['type'], $post_vars['ids'][ $document_id ] );
|
950 |
+
if ( $document ) {
|
951 |
+
foreach ( $locales as $locale ) {
|
952 |
+
$locale = $post_vars['lingotek_locale_to_wp_locale'][ $locale ];
|
953 |
+
$document->update_translation_status( $locale, 'pending' );
|
954 |
}
|
955 |
} else {
|
956 |
// TODO: what if a document doesn't exists? T_T
|
958 |
}
|
959 |
}
|
960 |
|
961 |
+
echo wp_json_encode( $response );
|
962 |
die();
|
963 |
}
|
964 |
|
965 |
public function ajax_get_ltk_terms_and_conditions() {
|
966 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
967 |
$client = new Lingotek_API();
|
968 |
+
echo wp_json_encode( $client->get_lingotek_terms_and_conditions() );
|
969 |
die();
|
970 |
}
|
971 |
|
972 |
public function ajax_get_user_payment_information() {
|
973 |
check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
|
974 |
+
$client = new Lingotek_API();
|
975 |
$response = $client->get_user_payment_information();
|
976 |
+
echo wp_json_encode( $response );
|
977 |
die();
|
978 |
}
|
979 |
|
982 |
*
|
983 |
* @since 1.1
|
984 |
*
|
985 |
+
* @param string $errors
|
986 |
*/
|
987 |
public static function retrieve_api_error( $errors ) {
|
988 |
$api_error = "\n";
|
admin/admin.php
CHANGED
@@ -15,9 +15,9 @@ class Lingotek_Admin {
|
|
15 |
* @since 0.1
|
16 |
*/
|
17 |
public function __construct() {
|
18 |
-
$plugin
|
19 |
$this->plugin_slug = $plugin->get_plugin_slug();
|
20 |
-
$this->dashboard
|
21 |
|
22 |
$this->pllm = $GLOBALS['polylang']->model;
|
23 |
|
@@ -26,45 +26,48 @@ class Lingotek_Admin {
|
|
26 |
// adds a 'settings' link in the plugins table.
|
27 |
add_filter( 'plugin_action_links_' . LINGOTEK_BASENAME, array( &$this, 'plugin_action_links' ) );
|
28 |
|
29 |
-
// adds the link to the languages panel in the
|
30 |
add_action( 'admin_menu', array( &$this, 'add_menus' ) );
|
31 |
|
32 |
-
add_action( 'load-translation_page_lingotek-translation_manage',
|
33 |
add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 );
|
34 |
|
35 |
add_action( 'wp_ajax_' . $this->ajax_dashboard_language_endpoint, array( &$this->dashboard, 'ajax_language_dashboard' ) );
|
36 |
add_action( 'wp_ajax_get_current_status', array( $this, 'ajax_get_current_status' ) );
|
37 |
// Network admin menu.
|
38 |
add_action( 'network_admin_menu', array( $this, 'add_network_admin_menu' ) );
|
39 |
-
add_action('wp_ajax_lingotek_authorization_action', array($this,'lingotek_authorization_action'));
|
40 |
}
|
41 |
|
42 |
public function lingotek_authorization_action() {
|
43 |
-
$access_token = $_SERVER['HTTP_TOKEN'];
|
44 |
-
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
* Gets current status.
|
49 |
*/
|
50 |
public function ajax_get_current_status() {
|
51 |
-
$lgtm
|
52 |
-
$pllm
|
53 |
-
$languages
|
54 |
-
$post_vars
|
55 |
-
$object_ids = isset($post_vars['check_ids']) ? $post_vars['check_ids'] :
|
56 |
if ( null === $object_ids ) {
|
57 |
return;
|
58 |
}
|
59 |
-
$terms_translations = $this->get_if_exists($post_vars,'terms_translations');
|
60 |
-
$terms
|
61 |
|
62 |
// The main array consists of ids and nonces. Each id has a source language, languages with statuses, and a workbench link.
|
63 |
$content_metadata = array();
|
64 |
foreach ( $object_ids as $object_id ) {
|
65 |
-
$id
|
66 |
-
$type
|
67 |
-
$taxonomy = $this->get_if_exists($post_vars,'taxonomy');
|
68 |
if ( ! empty( $taxonomy ) ) {
|
69 |
if ( strpos( $taxonomy, '&' ) ) {
|
70 |
$taxonomy = strstr( $taxonomy, '&', true );
|
@@ -73,12 +76,12 @@ class Lingotek_Admin {
|
|
73 |
$taxonomy = get_post_type( $id );
|
74 |
}
|
75 |
$content_metadata[ $id ] = array(
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
|
83 |
$document = $lgtm->get_group( $type, $object_id );
|
84 |
if ( $document && ! isset( $document->source ) && count( $document->desc_array ) >= 3 ) {
|
@@ -88,46 +91,47 @@ class Lingotek_Admin {
|
|
88 |
if ( $document->source !== (int) $object_id ) {
|
89 |
$document = $lgtm->get_group( $type, $document->source );
|
90 |
}
|
91 |
-
$source_id
|
92 |
-
$source_language
|
93 |
: pll_get_post_language( $document->source, 'locale' );
|
94 |
-
$existing_translations =
|
95 |
|
96 |
if ( count( $existing_translations ) > 1 ) {
|
97 |
$content_metadata[ $id ]['existing_trans'] = true;
|
98 |
}
|
99 |
-
$content_metadata[ $id ]['source']
|
100 |
-
$content_metadata[ $id ]['doc_id']
|
101 |
-
$content_metadata[ $id ]['source_id']
|
102 |
$content_metadata[ $id ]['source_status'] = $document->status;
|
103 |
-
$target_status
|
104 |
$content_metadata[ $id ][ $source_language ]['status'] = $document->source === $object_id ? $document->status : $target_status;
|
105 |
if ( is_array( $document->translations ) ) {
|
106 |
foreach ( $document->translations as $locale => $translation_status ) {
|
107 |
-
$content_metadata[ $id ][ $locale ]['status']
|
108 |
-
$workbench_link
|
109 |
$content_metadata[ $id ][ $locale ]['workbench_link'] = $workbench_link;
|
110 |
}
|
111 |
}
|
112 |
|
113 |
// fills in missing languages, makes life easier for the updater.
|
114 |
foreach ( $languages as $language ) {
|
115 |
-
if (!Lingotek::is_allowed_tms_locale($language)) {
|
|
|
116 |
foreach ( $content_metadata as $group => $status ) {
|
117 |
-
$language_obj
|
118 |
$target_lang_obj = $pllm->get_language( $language );
|
119 |
-
$profile
|
120 |
if ( 'disabled' !== $profile['profile'] && false !== $status['source'] ) {
|
121 |
if ( ! isset( $status[ $language ] ) ) {
|
122 |
$content_metadata[ $group ][ $language ]['status'] = 'none';
|
123 |
-
if ( $document->is_disabled_target( $pllm->get_language( $source_language ), $pllm->get_language( $language ) ) || (isset( $document->desc_array[ $target_lang_obj->slug ] ) && ! isset( $document->source )) ) {
|
124 |
$content_metadata[ $group ][ $language ]['status'] = 'disabled';
|
125 |
}
|
126 |
}
|
127 |
}
|
128 |
}
|
129 |
}
|
130 |
-
}
|
131 |
|
132 |
$language = 'post' === $type ? pll_get_post_language( $id ) : pll_get_term_language( $id );
|
133 |
$language = $pllm->get_language( $language );
|
@@ -137,13 +141,13 @@ class Lingotek_Admin {
|
|
137 |
$content_metadata[ $id ]['source'] = 'disabled';
|
138 |
}
|
139 |
}
|
140 |
-
}
|
141 |
|
142 |
// get the nonces associated with the different actions.
|
143 |
-
$content_metadata['request_nonce']
|
144 |
$content_metadata['download_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-download' );
|
145 |
-
$content_metadata['upload_nonce']
|
146 |
-
$content_metadata['status_nonce']
|
147 |
wp_send_json( $content_metadata );
|
148 |
}
|
149 |
|
@@ -156,7 +160,7 @@ class Lingotek_Admin {
|
|
156 |
public function lingotek_get_matching_nonce( $action ) {
|
157 |
$upload_link = wp_nonce_url( add_query_arg( array( 'action' => $action ) ), $action );
|
158 |
$nonce_begin = strpos( $upload_link, 'wpnonce=' ) + 8;
|
159 |
-
$nonce
|
160 |
return $nonce;
|
161 |
}
|
162 |
|
@@ -201,20 +205,20 @@ class Lingotek_Admin {
|
|
201 |
// 2 => int,bool 1 to enqueue script before </body> instead of in the head. Default is false (see wp_enqueue_script in wp doc)
|
202 |
// FIXME: check if I can load more scripts in footer.
|
203 |
$scripts = array(
|
204 |
-
'progress'
|
205 |
-
'updater'
|
206 |
);
|
207 |
|
208 |
$styles = array(
|
209 |
-
'admin'
|
210 |
);
|
211 |
|
212 |
foreach ( $scripts as $script => $v ) {
|
213 |
if ( in_array( $screen->base, $v[0], true ) ) {
|
214 |
wp_enqueue_script( 'lingotek_' . $script, LINGOTEK_URL . '/js/' . $script . $suffix . '.js', $v[1], LINGOTEK_VERSION, $v[2] );
|
215 |
-
$lingotek_prefs
|
216 |
-
$auto_update_interval = isset($lingotek_prefs['auto_update_status']) ? intval($lingotek_prefs['auto_update_status']) : 10;
|
217 |
-
wp_localize_script( 'lingotek_' . $script, 'updater_data', array('interval' => $auto_update_interval));
|
218 |
}
|
219 |
}
|
220 |
|
@@ -225,9 +229,9 @@ class Lingotek_Admin {
|
|
225 |
}
|
226 |
|
227 |
//for target select dropdown modal
|
228 |
-
if (in_array($screen->base, array('edit', 'upload', 'edit-tags'), true)){
|
229 |
-
wp_enqueue_script('lingotek_select2_js', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js', array());
|
230 |
-
wp_enqueue_style('lingotek_select2_css', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css', array());
|
231 |
}
|
232 |
}
|
233 |
|
@@ -245,17 +249,19 @@ class Lingotek_Admin {
|
|
245 |
}
|
246 |
|
247 |
/**
|
248 |
-
* Adds the links to the Lingotek panels in the
|
249 |
*
|
250 |
* @since 0.0.1
|
251 |
*/
|
252 |
public function add_menus() {
|
|
|
253 |
add_menu_page(
|
254 |
-
$title
|
255 |
$title,
|
256 |
'manage_options',
|
257 |
$this->plugin_slug,
|
258 |
-
array( $this, 'display_dashboard_page' ),
|
|
|
259 |
);
|
260 |
|
261 |
add_submenu_page( $this->plugin_slug, __( 'Translation Dashboard', 'lingotek-translation' ), __( 'Dashboard', 'lingotek-translation' ), 'manage_options', $this->plugin_slug, array( $this, 'display_dashboard_page' ) );
|
@@ -265,7 +271,7 @@ class Lingotek_Admin {
|
|
265 |
|
266 |
$selected_options = Lingotek_Model::get_prefs();
|
267 |
if ( isset( $selected_options['import_enabled'] ) && '1' === $selected_options['import_enabled']['enabled'] ) {
|
268 |
-
add_submenu_page( $this->plugin_slug, __( 'Lingotek Import', 'lingotek-translation' ), __( 'Import', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_import', array( $this, 'display_import_page' ) );
|
269 |
}
|
270 |
/**
|
271 |
* Displays the settings page
|
@@ -283,14 +289,20 @@ class Lingotek_Admin {
|
|
283 |
}
|
284 |
|
285 |
// connect Lingotek account.
|
286 |
-
$database_token_details = get_option('lingotek_token',
|
287 |
-
$access_token
|
288 |
if ( ! empty( $access_token ) && empty( $delete_access_token ) ) {
|
289 |
// set and get token details.
|
290 |
-
$client
|
291 |
$token_details = $client->get_token_details( $access_token );
|
292 |
if ( $token_details && strlen( $token_details->login_id ) ) {
|
293 |
-
update_option(
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account has been successfully connected.', 'lingotek-translation' ), 'updated' );
|
295 |
} else {
|
296 |
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account was not connected. The Access Token received was invalid.', 'lingotek-translation' ), 'error' );
|
@@ -299,7 +311,7 @@ class Lingotek_Admin {
|
|
299 |
|
300 |
// set page key primarily used for form submissions.
|
301 |
$page_key = $this->plugin_slug . '_settings';
|
302 |
-
$sm
|
303 |
if ( ! empty( $sm ) ) {
|
304 |
$page_key .= '&sm=' . sanitize_text_field( $sm );
|
305 |
}
|
@@ -318,13 +330,13 @@ class Lingotek_Admin {
|
|
318 |
}
|
319 |
|
320 |
$token_details = self::has_token_details();
|
321 |
-
$redirect_url
|
322 |
|
323 |
if ( $token_details ) {
|
324 |
$access_token = $token_details['access_token'];
|
325 |
-
$login_id
|
326 |
-
$base_url
|
327 |
-
include
|
328 |
} else {
|
329 |
$connect_url = '';
|
330 |
// connect cloak redirect.
|
@@ -332,13 +344,13 @@ class Lingotek_Admin {
|
|
332 |
if ( ! empty( $connect ) ) {
|
333 |
update_option( 'lingotek_base_url', Lingotek_API::PRODUCTION_URL );
|
334 |
$client = new Lingotek_API();
|
335 |
-
echo '<div class="wrap"><p class="description">' . esc_html( __( 'Redirecting to Lingotek to connect your account...','lingotek-translation' ) ) . '</p></div>';
|
336 |
|
337 |
-
$connect_url = (0 === strcasecmp( $connect,'new' )) ? $client->get_new_url( $redirect_url ) : $client->get_connect_url( $redirect_url );
|
338 |
}
|
339 |
-
$connect_account_cloak_url_new
|
340 |
$connect_account_cloak_url_prod = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=production' );
|
341 |
-
include
|
342 |
}
|
343 |
}
|
344 |
|
@@ -351,44 +363,39 @@ class Lingotek_Admin {
|
|
351 |
* @return array
|
352 |
*/
|
353 |
public function get_profiles_settings( $defaults = false ) {
|
354 |
-
|
355 |
$resources = get_option( 'lingotek_community_resources' );
|
356 |
-
$options
|
357 |
-
'manual'
|
|
|
358 |
);
|
359 |
|
360 |
-
|
361 |
-
if (/**get_option('lingotek_automatic_enabled')*/ true) {
|
362 |
-
$options['automatic'] = __( 'Automatic', 'lingotek-translation' );
|
363 |
-
}
|
364 |
-
|
365 |
$download_options = array(
|
366 |
-
'manual'
|
367 |
'automatic' => __( 'Automatic', 'lingotek-translation' ),
|
368 |
);
|
369 |
|
370 |
return array(
|
371 |
-
'upload'
|
372 |
'label' => __( 'Upload content', 'lingotek-translation' ),
|
373 |
'options' => $options,
|
374 |
'description' => __( 'How should new and modified content be uploaded to Lingotek?', 'lingotek-translation' ),
|
375 |
),
|
376 |
-
'download'
|
377 |
'label' => __( 'Download translations', 'lingotek-translation' ),
|
378 |
'options' => $download_options,
|
379 |
'description' => __( 'How should completed translations be downloaded to WordPress?', 'lingotek-translation' ),
|
380 |
),
|
381 |
-
'project_id'
|
382 |
-
'label'
|
383 |
'options' => $resources['projects'],
|
384 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
385 |
),
|
386 |
-
'workflow_id'
|
387 |
-
'label'
|
388 |
'options' => $resources['workflows'],
|
389 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
390 |
),
|
391 |
-
'primary_filter_id'
|
392 |
'label' => $defaults ? __( 'Primary Filter', 'lingotek-translation' ) : __( 'Primary Filter', 'lingotek-translation' ),
|
393 |
'options' => $resources['filters'],
|
394 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
@@ -423,7 +430,8 @@ class Lingotek_Admin {
|
|
423 |
$profiles[ $content_types[ $type ]['profile'] ]['usage'] += 1;
|
424 |
} elseif ( 'post' === $type ) {
|
425 |
$profiles['automatic']['usage'] += 1;
|
426 |
-
} else {
|
|
|
427 |
}
|
428 |
|
429 |
if ( isset( $content_types[ $type ]['sources'] ) ) {
|
@@ -444,9 +452,9 @@ class Lingotek_Admin {
|
|
444 |
* @param bool $update_first_project_callback boolean flag.
|
445 |
*/
|
446 |
public function set_community_resources( $community_id, $update_first_project_callback = false ) {
|
447 |
-
$client
|
448 |
$refresh_success = array(
|
449 |
-
'projects'
|
450 |
'workflows' => false,
|
451 |
);
|
452 |
|
@@ -461,11 +469,12 @@ class Lingotek_Admin {
|
|
461 |
$client->update_callback_url( $project->properties->id );
|
462 |
}
|
463 |
}
|
464 |
-
|
|
|
465 |
$refresh_success['projects'] = true;
|
466 |
}
|
467 |
|
468 |
-
$api_data
|
469 |
$default_workflows = array(
|
470 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
471 |
'ddf6e3c0-0688-11e2-892e-0800200c9a66' => 'Machine Translation + Post-Edit',
|
@@ -475,7 +484,7 @@ class Lingotek_Admin {
|
|
475 |
'2210b148-0c44-4ae2-91d0-ca2ee47c069e' => 'Translation + 3 reviews',
|
476 |
'7993b4d7-4ada-46d0-93d5-858db46c4c7d' => 'Translation Only',
|
477 |
);
|
478 |
-
$workflows
|
479 |
if ( $api_data ) {
|
480 |
foreach ( $api_data->entities as $workflow ) {
|
481 |
$workflows[ $workflow->properties->id ] = $workflow->properties->title;
|
@@ -486,16 +495,17 @@ class Lingotek_Admin {
|
|
486 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
487 |
);
|
488 |
}
|
489 |
-
|
490 |
-
|
|
|
491 |
$workflows['ltk-professional-translation'] = 'Lingotek Professional Translation';
|
492 |
}
|
493 |
-
$workflows
|
494 |
$refresh_success['workflows'] = true;
|
495 |
}
|
496 |
-
|
497 |
$api_data = $client->get_filters();
|
498 |
-
$filters
|
499 |
if ( $api_data && $api_data->properties->total > 0 ) {
|
500 |
foreach ( $api_data->entities as $filter ) {
|
501 |
if ( ! $filter->properties->is_public ) {
|
@@ -505,20 +515,20 @@ class Lingotek_Admin {
|
|
505 |
$filters[ $filter->properties->id ] = $filter->properties->title;
|
506 |
}
|
507 |
}
|
508 |
-
$primary_filter_id
|
509 |
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $filters, true );
|
510 |
-
$defaults
|
511 |
-
if (
|
512 |
-
$defaults['primary_filter_id']
|
513 |
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
514 |
update_option( 'lingotek_defaults', $defaults );
|
515 |
}
|
516 |
}
|
517 |
|
518 |
$resources = array(
|
519 |
-
'projects'
|
520 |
'workflows' => $workflows,
|
521 |
-
'filters'
|
522 |
);
|
523 |
|
524 |
if ( true === $refresh_success['projects'] || true === $refresh_success['workflows'] ) {
|
@@ -532,13 +542,13 @@ class Lingotek_Admin {
|
|
532 |
* Ensures valid defaults.
|
533 |
*/
|
534 |
public function ensure_valid_defaults() {
|
535 |
-
$resources
|
536 |
-
$defaults
|
537 |
$valid_default = array();
|
538 |
foreach ( $resources as $resource_key => $options ) {
|
539 |
-
$key
|
540 |
$valid_default[ $key ] = 0;
|
541 |
-
if (
|
542 |
continue;
|
543 |
}
|
544 |
foreach ( $options as $option_key => $option_val ) {
|
@@ -552,7 +562,7 @@ class Lingotek_Admin {
|
|
552 |
}
|
553 |
}
|
554 |
foreach ( $valid_default as $key => $valid ) {
|
555 |
-
$resource_key = substr( $key,0,strpos( $key,'_' ) ) . 's';
|
556 |
if ( $valid ) {
|
557 |
continue;
|
558 |
} else {
|
@@ -562,6 +572,7 @@ class Lingotek_Admin {
|
|
562 |
$num_valid_defaults = array_sum( $valid_default );
|
563 |
|
564 |
if ( $num_valid_defaults < count( $valid_default ) ) {
|
|
|
565 |
add_settings_error( 'lingotek_defaults', 'community-selected', sprintf( __( 'Your <a href="%s"><i>Defaults</i></a> have been updated to valid options for this community.', 'lingotek-translation' ), admin_url( 'admin.php?page=lingotek-translation_settings&sm=defaults' ) ), 'updated' );
|
566 |
}
|
567 |
unset( $defaults['filter_id'] );
|
@@ -581,7 +592,7 @@ class Lingotek_Admin {
|
|
581 |
*/
|
582 |
ob_start();
|
583 |
if ( self::has_token_details() ) {
|
584 |
-
include
|
585 |
} else {
|
586 |
$this->display_settings_page();
|
587 |
}
|
@@ -594,11 +605,14 @@ class Lingotek_Admin {
|
|
594 |
* @since 0.2
|
595 |
*/
|
596 |
public function load_manage_page() {
|
597 |
-
add_screen_option(
|
598 |
-
'
|
599 |
-
|
600 |
-
|
601 |
-
|
|
|
|
|
|
|
602 |
}
|
603 |
|
604 |
/**
|
@@ -626,34 +640,34 @@ class Lingotek_Admin {
|
|
626 |
$token_details = self::has_token_details();
|
627 |
if ( $token_details ) {
|
628 |
$community_id = get_option( 'lingotek_community' );
|
629 |
-
$defaults
|
630 |
-
$user
|
631 |
|
632 |
// The data that will be passed to the Lingotek GMC dashboard.
|
633 |
$cms_data = array(
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
);
|
653 |
-
include
|
654 |
} else {
|
655 |
$this->display_settings_page();
|
656 |
-
}
|
657 |
}
|
658 |
|
659 |
/**
|
@@ -663,7 +677,7 @@ class Lingotek_Admin {
|
|
663 |
*/
|
664 |
public static function has_token_details() {
|
665 |
$token_details = get_option( 'lingotek_token' );
|
666 |
-
$has_token
|
667 |
if ( false !== $token_details && key_exists( 'access_token', $token_details ) && key_exists( 'login_id', $token_details ) && strlen( $token_details['access_token'] ) && strlen( $token_details['login_id'] ) ) {
|
668 |
$has_token = true;
|
669 |
return $token_details;
|
@@ -676,7 +690,7 @@ class Lingotek_Admin {
|
|
676 |
*/
|
677 |
public function display_network_settings_page() {
|
678 |
if ( is_multisite() && self::has_token_details() ) {
|
679 |
-
include
|
680 |
} else {
|
681 |
$this->display_settings_page();
|
682 |
}
|
@@ -696,7 +710,7 @@ class Lingotek_Admin {
|
|
696 |
*/
|
697 |
public function display_tutorial_page() {
|
698 |
if ( self::has_token_details() ) {
|
699 |
-
include
|
700 |
} else {
|
701 |
$this->display_settings_page();
|
702 |
}
|
@@ -708,14 +722,14 @@ class Lingotek_Admin {
|
|
708 |
public function display_import_page() {
|
709 |
if ( self::has_token_details() ) {
|
710 |
settings_errors();
|
711 |
-
include
|
712 |
} else {
|
713 |
$this->display_settings_page();
|
714 |
}
|
715 |
}
|
716 |
|
717 |
-
private function get_if_exists($array, $key){
|
718 |
-
return is_array($array) && array_key_exists($key, $array) ? $array[$key] : null;
|
719 |
}
|
720 |
|
721 |
}
|
15 |
* @since 0.1
|
16 |
*/
|
17 |
public function __construct() {
|
18 |
+
$plugin = Lingotek::get_instance();
|
19 |
$this->plugin_slug = $plugin->get_plugin_slug();
|
20 |
+
$this->dashboard = new Lingotek_Dashboard( $plugin );
|
21 |
|
22 |
$this->pllm = $GLOBALS['polylang']->model;
|
23 |
|
26 |
// adds a 'settings' link in the plugins table.
|
27 |
add_filter( 'plugin_action_links_' . LINGOTEK_BASENAME, array( &$this, 'plugin_action_links' ) );
|
28 |
|
29 |
+
// adds the link to the languages panel in the WordPress admin menu.
|
30 |
add_action( 'admin_menu', array( &$this, 'add_menus' ) );
|
31 |
|
32 |
+
add_action( 'load-translation_page_lingotek-translation_manage', array( &$this, 'load_manage_page' ) );
|
33 |
add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 );
|
34 |
|
35 |
add_action( 'wp_ajax_' . $this->ajax_dashboard_language_endpoint, array( &$this->dashboard, 'ajax_language_dashboard' ) );
|
36 |
add_action( 'wp_ajax_get_current_status', array( $this, 'ajax_get_current_status' ) );
|
37 |
// Network admin menu.
|
38 |
add_action( 'network_admin_menu', array( $this, 'add_network_admin_menu' ) );
|
39 |
+
add_action( 'wp_ajax_lingotek_authorization_action', array( $this, 'lingotek_authorization_action' ) );
|
40 |
}
|
41 |
|
42 |
public function lingotek_authorization_action() {
|
43 |
+
$access_token = isset( $_SERVER['HTTP_TOKEN'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_TOKEN'] ) ) : null;
|
44 |
+
if ( is_null( $access_token ) ) {
|
45 |
+
Lingotek_Logger::error( 'access_token was empty in lingotek_authorization_action().' );
|
46 |
+
}
|
47 |
+
update_option( 'lingotek_token', array( 'access_token' => $access_token ) );
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
* Gets current status.
|
52 |
*/
|
53 |
public function ajax_get_current_status() {
|
54 |
+
$lgtm = &$GLOBALS['wp_lingotek']->model;
|
55 |
+
$pllm = $GLOBALS['polylang']->model;
|
56 |
+
$languages = pll_languages_list( array( 'fields' => 'locale' ) );
|
57 |
+
$post_vars = filter_input_array( INPUT_POST );
|
58 |
+
$object_ids = isset( $post_vars['check_ids'] ) ? $post_vars['check_ids'] : null;
|
59 |
if ( null === $object_ids ) {
|
60 |
return;
|
61 |
}
|
62 |
+
$terms_translations = $this->get_if_exists( $post_vars, 'terms_translations' );
|
63 |
+
$terms = ! empty( $terms_translations );
|
64 |
|
65 |
// The main array consists of ids and nonces. Each id has a source language, languages with statuses, and a workbench link.
|
66 |
$content_metadata = array();
|
67 |
foreach ( $object_ids as $object_id ) {
|
68 |
+
$id = $object_id;
|
69 |
+
$type = $terms ? 'term' : 'post';
|
70 |
+
$taxonomy = $this->get_if_exists( $post_vars, 'taxonomy' );
|
71 |
if ( ! empty( $taxonomy ) ) {
|
72 |
if ( strpos( $taxonomy, '&' ) ) {
|
73 |
$taxonomy = strstr( $taxonomy, '&', true );
|
76 |
$taxonomy = get_post_type( $id );
|
77 |
}
|
78 |
$content_metadata[ $id ] = array(
|
79 |
+
'existing_trans' => false,
|
80 |
+
'source' => false,
|
81 |
+
'doc_id' => null,
|
82 |
+
'source_id' => null,
|
83 |
+
'source_status' => null,
|
84 |
+
);
|
85 |
|
86 |
$document = $lgtm->get_group( $type, $object_id );
|
87 |
if ( $document && ! isset( $document->source ) && count( $document->desc_array ) >= 3 ) {
|
91 |
if ( $document->source !== (int) $object_id ) {
|
92 |
$document = $lgtm->get_group( $type, $document->source );
|
93 |
}
|
94 |
+
$source_id = null !== $document->source ? $document->source : $object_id;
|
95 |
+
$source_language = $terms ? pll_get_term_language( $document->source, 'locale' )
|
96 |
: pll_get_post_language( $document->source, 'locale' );
|
97 |
+
$existing_translations = ( 'term' === $type ) ? PLL()->model->term->get_translations( $source_id ) : PLL()->model->post->get_translations( $source_id );
|
98 |
|
99 |
if ( count( $existing_translations ) > 1 ) {
|
100 |
$content_metadata[ $id ]['existing_trans'] = true;
|
101 |
}
|
102 |
+
$content_metadata[ $id ]['source'] = $source_language;
|
103 |
+
$content_metadata[ $id ]['doc_id'] = $document->document_id;
|
104 |
+
$content_metadata[ $id ]['source_id'] = $document->source;
|
105 |
$content_metadata[ $id ]['source_status'] = $document->status;
|
106 |
+
$target_status = 'edited' === $document->status || null === $document->status ? 'edited' : $document->status;
|
107 |
$content_metadata[ $id ][ $source_language ]['status'] = $document->source === $object_id ? $document->status : $target_status;
|
108 |
if ( is_array( $document->translations ) ) {
|
109 |
foreach ( $document->translations as $locale => $translation_status ) {
|
110 |
+
$content_metadata[ $id ][ $locale ]['status'] = $translation_status;
|
111 |
+
$workbench_link = Lingotek_Actions::workbench_link( $document->document_id, $locale );
|
112 |
$content_metadata[ $id ][ $locale ]['workbench_link'] = $workbench_link;
|
113 |
}
|
114 |
}
|
115 |
|
116 |
// fills in missing languages, makes life easier for the updater.
|
117 |
foreach ( $languages as $language ) {
|
118 |
+
if ( ! Lingotek::is_allowed_tms_locale( $language ) ) {
|
119 |
+
continue; }
|
120 |
foreach ( $content_metadata as $group => $status ) {
|
121 |
+
$language_obj = $pllm->get_language( $source_language );
|
122 |
$target_lang_obj = $pllm->get_language( $language );
|
123 |
+
$profile = Lingotek_Model::get_profile( $taxonomy, $language_obj, $group );
|
124 |
if ( 'disabled' !== $profile['profile'] && false !== $status['source'] ) {
|
125 |
if ( ! isset( $status[ $language ] ) ) {
|
126 |
$content_metadata[ $group ][ $language ]['status'] = 'none';
|
127 |
+
if ( $document->is_disabled_target( $pllm->get_language( $source_language ), $pllm->get_language( $language ) ) || ( isset( $document->desc_array[ $target_lang_obj->slug ] ) && ! isset( $document->source ) ) ) {
|
128 |
$content_metadata[ $group ][ $language ]['status'] = 'disabled';
|
129 |
}
|
130 |
}
|
131 |
}
|
132 |
}
|
133 |
}
|
134 |
+
}//end if
|
135 |
|
136 |
$language = 'post' === $type ? pll_get_post_language( $id ) : pll_get_term_language( $id );
|
137 |
$language = $pllm->get_language( $language );
|
141 |
$content_metadata[ $id ]['source'] = 'disabled';
|
142 |
}
|
143 |
}
|
144 |
+
}//end foreach
|
145 |
|
146 |
// get the nonces associated with the different actions.
|
147 |
+
$content_metadata['request_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-request' );
|
148 |
$content_metadata['download_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-download' );
|
149 |
+
$content_metadata['upload_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-upload' );
|
150 |
+
$content_metadata['status_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-status' );
|
151 |
wp_send_json( $content_metadata );
|
152 |
}
|
153 |
|
160 |
public function lingotek_get_matching_nonce( $action ) {
|
161 |
$upload_link = wp_nonce_url( add_query_arg( array( 'action' => $action ) ), $action );
|
162 |
$nonce_begin = strpos( $upload_link, 'wpnonce=' ) + 8;
|
163 |
+
$nonce = substr( $upload_link, $nonce_begin );
|
164 |
return $nonce;
|
165 |
}
|
166 |
|
205 |
// 2 => int,bool 1 to enqueue script before </body> instead of in the head. Default is false (see wp_enqueue_script in wp doc)
|
206 |
// FIXME: check if I can load more scripts in footer.
|
207 |
$scripts = array(
|
208 |
+
'progress' => array( array( 'edit', 'upload', 'edit-tags', 'translation_page_lingotek-translation_manage', 'translation_page_lingotek-translation_settings' ), array( 'jquery-ui-progressbar', 'jquery-ui-dialog', 'wp-ajax-response' ), 1 ),
|
209 |
+
'updater' => array( array( 'edit', 'upload', 'edit-tags' ), array( 'jquery-ui-progressbar', 'jquery-ui-dialog', 'wp-ajax-response' ), 1 ),
|
210 |
);
|
211 |
|
212 |
$styles = array(
|
213 |
+
'admin' => array( array( 'edit', 'upload', 'edit-tags', 'translation_page_lingotek-translation_manage', 'translation_page_lingotek-translation_settings' ), array( 'wp-jquery-ui-dialog' ) ),
|
214 |
);
|
215 |
|
216 |
foreach ( $scripts as $script => $v ) {
|
217 |
if ( in_array( $screen->base, $v[0], true ) ) {
|
218 |
wp_enqueue_script( 'lingotek_' . $script, LINGOTEK_URL . '/js/' . $script . $suffix . '.js', $v[1], LINGOTEK_VERSION, $v[2] );
|
219 |
+
$lingotek_prefs = get_option( 'lingotek_prefs' );
|
220 |
+
$auto_update_interval = isset( $lingotek_prefs['auto_update_status'] ) ? intval( $lingotek_prefs['auto_update_status'] ) : 10;
|
221 |
+
wp_localize_script( 'lingotek_' . $script, 'updater_data', array( 'interval' => $auto_update_interval ) );
|
222 |
}
|
223 |
}
|
224 |
|
229 |
}
|
230 |
|
231 |
//for target select dropdown modal
|
232 |
+
if ( in_array( $screen->base, array( 'edit', 'upload', 'edit-tags' ), true ) ) {
|
233 |
+
wp_enqueue_script( 'lingotek_select2_js', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js', array(), LINGOTEK_VERSION, false );
|
234 |
+
wp_enqueue_style( 'lingotek_select2_css', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css', array(), LINGOTEK_VERSION );
|
235 |
}
|
236 |
}
|
237 |
|
249 |
}
|
250 |
|
251 |
/**
|
252 |
+
* Adds the links to the Lingotek panels in the WordPress admin menu
|
253 |
*
|
254 |
* @since 0.0.1
|
255 |
*/
|
256 |
public function add_menus() {
|
257 |
+
$title = __( 'Translation', 'lingotek-translation' );
|
258 |
add_menu_page(
|
259 |
+
$title,
|
260 |
$title,
|
261 |
'manage_options',
|
262 |
$this->plugin_slug,
|
263 |
+
array( $this, 'display_dashboard_page' ),
|
264 |
+
'dashicons-translation'
|
265 |
);
|
266 |
|
267 |
add_submenu_page( $this->plugin_slug, __( 'Translation Dashboard', 'lingotek-translation' ), __( 'Dashboard', 'lingotek-translation' ), 'manage_options', $this->plugin_slug, array( $this, 'display_dashboard_page' ) );
|
271 |
|
272 |
$selected_options = Lingotek_Model::get_prefs();
|
273 |
if ( isset( $selected_options['import_enabled'] ) && '1' === $selected_options['import_enabled']['enabled'] ) {
|
274 |
+
add_submenu_page( $this->plugin_slug, __( 'Lingotek Import', 'lingotek-translation' ), __( 'Import', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_import', array( $this, 'display_import_page' ) ); }
|
275 |
}
|
276 |
/**
|
277 |
* Displays the settings page
|
289 |
}
|
290 |
|
291 |
// connect Lingotek account.
|
292 |
+
$database_token_details = get_option( 'lingotek_token', array() );
|
293 |
+
$access_token = isset( $database_token_details['access_token'] ) ? $database_token_details['access_token'] : null;
|
294 |
if ( ! empty( $access_token ) && empty( $delete_access_token ) ) {
|
295 |
// set and get token details.
|
296 |
+
$client = new Lingotek_API();
|
297 |
$token_details = $client->get_token_details( $access_token );
|
298 |
if ( $token_details && strlen( $token_details->login_id ) ) {
|
299 |
+
update_option(
|
300 |
+
'lingotek_token',
|
301 |
+
array(
|
302 |
+
'access_token' => $access_token,
|
303 |
+
'login_id' => $token_details->login_id,
|
304 |
+
)
|
305 |
+
);
|
306 |
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account has been successfully connected.', 'lingotek-translation' ), 'updated' );
|
307 |
} else {
|
308 |
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account was not connected. The Access Token received was invalid.', 'lingotek-translation' ), 'error' );
|
311 |
|
312 |
// set page key primarily used for form submissions.
|
313 |
$page_key = $this->plugin_slug . '_settings';
|
314 |
+
$sm = filter_input( INPUT_GET, 'sm' );
|
315 |
if ( ! empty( $sm ) ) {
|
316 |
$page_key .= '&sm=' . sanitize_text_field( $sm );
|
317 |
}
|
330 |
}
|
331 |
|
332 |
$token_details = self::has_token_details();
|
333 |
+
$redirect_url = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&sm=account' );
|
334 |
|
335 |
if ( $token_details ) {
|
336 |
$access_token = $token_details['access_token'];
|
337 |
+
$login_id = $token_details['login_id'];
|
338 |
+
$base_url = get_option( 'lingotek_base_url' );
|
339 |
+
include LINGOTEK_ADMIN_INC . '/settings.php';
|
340 |
} else {
|
341 |
$connect_url = '';
|
342 |
// connect cloak redirect.
|
344 |
if ( ! empty( $connect ) ) {
|
345 |
update_option( 'lingotek_base_url', Lingotek_API::PRODUCTION_URL );
|
346 |
$client = new Lingotek_API();
|
347 |
+
echo '<div class="wrap"><p class="description">' . esc_html( __( 'Redirecting to Lingotek to connect your account...', 'lingotek-translation' ) ) . '</p></div>';
|
348 |
|
349 |
+
$connect_url = ( 0 === strcasecmp( $connect, 'new' ) ) ? $client->get_new_url( $redirect_url ) : $client->get_connect_url( $redirect_url );
|
350 |
}
|
351 |
+
$connect_account_cloak_url_new = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=new' );
|
352 |
$connect_account_cloak_url_prod = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=production' );
|
353 |
+
include LINGOTEK_ADMIN_INC . '/settings/connect-account.php';
|
354 |
}
|
355 |
}
|
356 |
|
363 |
* @return array
|
364 |
*/
|
365 |
public function get_profiles_settings( $defaults = false ) {
|
|
|
366 |
$resources = get_option( 'lingotek_community_resources' );
|
367 |
+
$options = array(
|
368 |
+
'manual' => __( 'Manual', 'lingotek-translation' ),
|
369 |
+
'automatic' => __( 'Automatic', 'lingotek-translation' ),
|
370 |
);
|
371 |
|
|
|
|
|
|
|
|
|
|
|
372 |
$download_options = array(
|
373 |
+
'manual' => __( 'Manual', 'lingotek-translation' ),
|
374 |
'automatic' => __( 'Automatic', 'lingotek-translation' ),
|
375 |
);
|
376 |
|
377 |
return array(
|
378 |
+
'upload' => array(
|
379 |
'label' => __( 'Upload content', 'lingotek-translation' ),
|
380 |
'options' => $options,
|
381 |
'description' => __( 'How should new and modified content be uploaded to Lingotek?', 'lingotek-translation' ),
|
382 |
),
|
383 |
+
'download' => array(
|
384 |
'label' => __( 'Download translations', 'lingotek-translation' ),
|
385 |
'options' => $download_options,
|
386 |
'description' => __( 'How should completed translations be downloaded to WordPress?', 'lingotek-translation' ),
|
387 |
),
|
388 |
+
'project_id' => array(
|
389 |
+
'label' => $defaults ? __( 'Default Project', 'lingotek-translation' ) : __( 'Project', 'lingotek-translation' ),
|
390 |
'options' => $resources['projects'],
|
391 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
392 |
),
|
393 |
+
'workflow_id' => array(
|
394 |
+
'label' => $defaults ? __( 'Default Workflow', 'lingotek-translation' ) : __( 'Workflow', 'lingotek-translation' ),
|
395 |
'options' => $resources['workflows'],
|
396 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
397 |
),
|
398 |
+
'primary_filter_id' => array(
|
399 |
'label' => $defaults ? __( 'Primary Filter', 'lingotek-translation' ) : __( 'Primary Filter', 'lingotek-translation' ),
|
400 |
'options' => $resources['filters'],
|
401 |
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
430 |
$profiles[ $content_types[ $type ]['profile'] ]['usage'] += 1;
|
431 |
} elseif ( 'post' === $type ) {
|
432 |
$profiles['automatic']['usage'] += 1;
|
433 |
+
} else {
|
434 |
+
$profiles['manual']['usage'] += 1;
|
435 |
}
|
436 |
|
437 |
if ( isset( $content_types[ $type ]['sources'] ) ) {
|
452 |
* @param bool $update_first_project_callback boolean flag.
|
453 |
*/
|
454 |
public function set_community_resources( $community_id, $update_first_project_callback = false ) {
|
455 |
+
$client = new Lingotek_API();
|
456 |
$refresh_success = array(
|
457 |
+
'projects' => false,
|
458 |
'workflows' => false,
|
459 |
);
|
460 |
|
469 |
$client->update_callback_url( $project->properties->id );
|
470 |
}
|
471 |
}
|
472 |
+
// Order by title (case-insensitive).
|
473 |
+
natcasesort( $projects );
|
474 |
$refresh_success['projects'] = true;
|
475 |
}
|
476 |
|
477 |
+
$api_data = $client->get_workflows( $community_id );
|
478 |
$default_workflows = array(
|
479 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
480 |
'ddf6e3c0-0688-11e2-892e-0800200c9a66' => 'Machine Translation + Post-Edit',
|
484 |
'2210b148-0c44-4ae2-91d0-ca2ee47c069e' => 'Translation + 3 reviews',
|
485 |
'7993b4d7-4ada-46d0-93d5-858db46c4c7d' => 'Translation Only',
|
486 |
);
|
487 |
+
$workflows = array();
|
488 |
if ( $api_data ) {
|
489 |
foreach ( $api_data->entities as $workflow ) {
|
490 |
$workflows[ $workflow->properties->id ] = $workflow->properties->title;
|
495 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
496 |
);
|
497 |
}
|
498 |
+
// Order by title (case-insensitive).
|
499 |
+
natcasesort( $workflows );
|
500 |
+
if ( Lingotek_Professional_Translation_Workflow::is_allowed_user() ) {
|
501 |
$workflows['ltk-professional-translation'] = 'Lingotek Professional Translation';
|
502 |
}
|
503 |
+
$workflows = array_merge( array( 'project-default' => 'Use Project Default' ), $workflows );
|
504 |
$refresh_success['workflows'] = true;
|
505 |
}
|
506 |
+
|
507 |
$api_data = $client->get_filters();
|
508 |
+
$filters = array();
|
509 |
if ( $api_data && $api_data->properties->total > 0 ) {
|
510 |
foreach ( $api_data->entities as $filter ) {
|
511 |
if ( ! $filter->properties->is_public ) {
|
515 |
$filters[ $filter->properties->id ] = $filter->properties->title;
|
516 |
}
|
517 |
}
|
518 |
+
$primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $filters, true );
|
519 |
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $filters, true );
|
520 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
521 |
+
if ( empty( $defaults ) ) {
|
522 |
+
$defaults['primary_filter_id'] = $primary_filter_id;
|
523 |
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
524 |
update_option( 'lingotek_defaults', $defaults );
|
525 |
}
|
526 |
}
|
527 |
|
528 |
$resources = array(
|
529 |
+
'projects' => $projects,
|
530 |
'workflows' => $workflows,
|
531 |
+
'filters' => $filters,
|
532 |
);
|
533 |
|
534 |
if ( true === $refresh_success['projects'] || true === $refresh_success['workflows'] ) {
|
542 |
* Ensures valid defaults.
|
543 |
*/
|
544 |
public function ensure_valid_defaults() {
|
545 |
+
$resources = get_option( 'lingotek_community_resources' );
|
546 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
547 |
$valid_default = array();
|
548 |
foreach ( $resources as $resource_key => $options ) {
|
549 |
+
$key = substr( $resource_key, 0, strlen( $resource_key ) - 1 ) . '_id';
|
550 |
$valid_default[ $key ] = 0;
|
551 |
+
if ( empty( $defaults ) ) {
|
552 |
continue;
|
553 |
}
|
554 |
foreach ( $options as $option_key => $option_val ) {
|
562 |
}
|
563 |
}
|
564 |
foreach ( $valid_default as $key => $valid ) {
|
565 |
+
$resource_key = substr( $key, 0, strpos( $key, '_' ) ) . 's';
|
566 |
if ( $valid ) {
|
567 |
continue;
|
568 |
} else {
|
572 |
$num_valid_defaults = array_sum( $valid_default );
|
573 |
|
574 |
if ( $num_valid_defaults < count( $valid_default ) ) {
|
575 |
+
/* translators: %s: Admin url for Lingotek translation settings. */
|
576 |
add_settings_error( 'lingotek_defaults', 'community-selected', sprintf( __( 'Your <a href="%s"><i>Defaults</i></a> have been updated to valid options for this community.', 'lingotek-translation' ), admin_url( 'admin.php?page=lingotek-translation_settings&sm=defaults' ) ), 'updated' );
|
577 |
}
|
578 |
unset( $defaults['filter_id'] );
|
592 |
*/
|
593 |
ob_start();
|
594 |
if ( self::has_token_details() ) {
|
595 |
+
include LINGOTEK_ADMIN_INC . '/view-manage.php';
|
596 |
} else {
|
597 |
$this->display_settings_page();
|
598 |
}
|
605 |
* @since 0.2
|
606 |
*/
|
607 |
public function load_manage_page() {
|
608 |
+
add_screen_option(
|
609 |
+
'per_page',
|
610 |
+
array(
|
611 |
+
'label' => __( 'Strings groups', 'lingotek-translation' ),
|
612 |
+
'default' => 10,
|
613 |
+
'option' => 'lingotek_strings_per_page',
|
614 |
+
)
|
615 |
+
);
|
616 |
}
|
617 |
|
618 |
/**
|
640 |
$token_details = self::has_token_details();
|
641 |
if ( $token_details ) {
|
642 |
$community_id = get_option( 'lingotek_community' );
|
643 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
644 |
+
$user = wp_get_current_user();
|
645 |
|
646 |
// The data that will be passed to the Lingotek GMC dashboard.
|
647 |
$cms_data = array(
|
648 |
+
// lingotek.
|
649 |
+
'community_id' => $community_id,
|
650 |
+
'external_id' => $token_details['login_id'],
|
651 |
+
'workflow_id' => $defaults['workflow_id'],
|
652 |
+
'project_id' => $defaults['project_id'],
|
653 |
+
'first_name' => $user->display_name,
|
654 |
+
'last_name' => '',
|
655 |
+
'email' => get_bloginfo( 'admin_email' ),
|
656 |
+
// cms.
|
657 |
+
'cms_site_id' => site_url(),
|
658 |
+
'cms_site_key' => site_url(),
|
659 |
+
'cms_site_name' => get_bloginfo( 'name' ),
|
660 |
+
'cms_type' => 'Wordpress',
|
661 |
+
'cms_version' => get_bloginfo( 'version' ),
|
662 |
+
'cms_tag' => LINGOTEK_PLUGIN_SLUG,
|
663 |
+
'locale' => pll_current_language( 'lingotek_locale' ),
|
664 |
+
'module_version' => LINGOTEK_VERSION,
|
665 |
+
'endpoint_url' => $this->get_dashboard_endpoint(),
|
666 |
);
|
667 |
+
include LINGOTEK_ADMIN_INC . '/view-dashboard.php';
|
668 |
} else {
|
669 |
$this->display_settings_page();
|
670 |
+
}//end if
|
671 |
}
|
672 |
|
673 |
/**
|
677 |
*/
|
678 |
public static function has_token_details() {
|
679 |
$token_details = get_option( 'lingotek_token' );
|
680 |
+
$has_token = false;
|
681 |
if ( false !== $token_details && key_exists( 'access_token', $token_details ) && key_exists( 'login_id', $token_details ) && strlen( $token_details['access_token'] ) && strlen( $token_details['login_id'] ) ) {
|
682 |
$has_token = true;
|
683 |
return $token_details;
|
690 |
*/
|
691 |
public function display_network_settings_page() {
|
692 |
if ( is_multisite() && self::has_token_details() ) {
|
693 |
+
include LINGOTEK_ADMIN_INC . '/view-network.php';
|
694 |
} else {
|
695 |
$this->display_settings_page();
|
696 |
}
|
710 |
*/
|
711 |
public function display_tutorial_page() {
|
712 |
if ( self::has_token_details() ) {
|
713 |
+
include LINGOTEK_ADMIN_INC . '/view-tutorial.php';
|
714 |
} else {
|
715 |
$this->display_settings_page();
|
716 |
}
|
722 |
public function display_import_page() {
|
723 |
if ( self::has_token_details() ) {
|
724 |
settings_errors();
|
725 |
+
include LINGOTEK_ADMIN_INC . '/import.php';
|
726 |
} else {
|
727 |
$this->display_settings_page();
|
728 |
}
|
729 |
}
|
730 |
|
731 |
+
private function get_if_exists( $array, $key ) {
|
732 |
+
return is_array( $array ) && array_key_exists( $key, $array ) ? $array[ $key ] : null;
|
733 |
}
|
734 |
|
735 |
}
|
admin/content-table.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
-
|
|
|
5 |
}
|
6 |
|
7 |
/**
|
@@ -27,13 +28,16 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
27 |
* @param array $content_types array of content types.
|
28 |
* @since 0.2
|
29 |
*/
|
30 |
-
function __construct( $content_types ) {
|
31 |
-
parent::__construct(
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
35 |
|
36 |
-
$this->profiles
|
37 |
$this->content_types = $content_types;
|
38 |
}
|
39 |
|
@@ -44,14 +48,15 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
44 |
*
|
45 |
* @param array $item items.
|
46 |
*/
|
47 |
-
function column_name( $item ) {
|
48 |
global $polylang;
|
49 |
|
50 |
printf( '<span class="content-type-name">%s</span>', esc_html( $item['name'] ) );
|
51 |
|
52 |
// the source language for strings is always the default language.
|
53 |
if ( 'string' !== $item['type'] ) {
|
54 |
-
printf(
|
|
|
55 |
esc_attr( $item['type'] ),
|
56 |
"
|
57 |
d1 = document.getElementById('sources-name[" . esc_html( $item['type'] ) . "]');
|
@@ -71,10 +76,11 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
71 |
|
72 |
printf( '<ul class="sources-name" id="sources-name[%s]" style="display:none;">', esc_html( $item['type'] ) );
|
73 |
foreach ( $polylang->model->get_languages_list() as $language ) {
|
|
|
74 |
printf( '<li>%s</li>', sprintf( esc_html( __( '%s source', 'lingotek-translation' ) ), esc_html( $language->name ) ) );
|
75 |
}
|
76 |
echo '</ul>';
|
77 |
-
}
|
78 |
}
|
79 |
|
80 |
/**
|
@@ -84,12 +90,12 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
84 |
*
|
85 |
* @param array $item item.
|
86 |
*/
|
87 |
-
function column_profile( $item ) {
|
88 |
global $polylang;
|
89 |
|
90 |
printf( '<select class="content-type-profile" name="%1$s" id="%1$s">', esc_html( $item['type'] ) . '[profile]' );
|
91 |
foreach ( $this->profiles as $key => $profile ) {
|
92 |
-
$selected = (isset( $item['profile'] ) && $key === $item['profile']) ? 'selected="selected"' : '';
|
93 |
echo "\n\t<option value='" . esc_attr( $key ) . "' " . esc_html( $selected ) . '>' . esc_html( $profile['name'] ) . '</option>';
|
94 |
}
|
95 |
echo '</select>';
|
@@ -102,7 +108,7 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
102 |
foreach ( $polylang->model->get_languages_list() as $language ) {
|
103 |
printf( '<li><select name="%1$s" id="%1$s">', esc_html( $item['type'] ) . '[sources][' . esc_html( $language->slug ) . ']' );
|
104 |
foreach ( $options as $key => $profile ) {
|
105 |
-
$selected = (isset( $item['sources'][ $language->slug ] ) && $key === $item['sources'][ $language->slug ]) ? 'selected="selected"' : '';
|
106 |
echo "\n\t<option value='" . esc_attr( $key ) . "' " . esc_html( $selected ) . '>' . esc_html( $profile['name'] ) . '</option>';
|
107 |
}
|
108 |
echo '</select></li>';
|
@@ -124,7 +130,7 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
124 |
protected function display_fields( $labels, $values, $name ) {
|
125 |
foreach ( $labels as $key => $str ) {
|
126 |
if ( is_array( $str ) ) {
|
127 |
-
if ( 'metas' === $key
|
128 |
continue;
|
129 |
}
|
130 |
$this->display_fields( $str, isset( $values[ $key ] ) ? $values[ $key ] : array(), $name . "[$key]" );
|
@@ -146,10 +152,10 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
146 |
*
|
147 |
* @param array $item item.
|
148 |
*/
|
149 |
-
function column_fields( $item ) {
|
150 |
if ( ! empty( $item['fields'] ) ) {
|
151 |
echo '<ul class="content-type-fields">';
|
152 |
-
$this->display_fields( $item['fields']['label'], isset( $item['fields']['value'] ) ? $item['fields']['value'] : array()
|
153 |
echo '</ul>';
|
154 |
}
|
155 |
}
|
@@ -161,7 +167,7 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
161 |
*
|
162 |
* @return array the list of column titles
|
163 |
*/
|
164 |
-
function get_columns() {
|
165 |
return array(
|
166 |
'name' => __( 'Content Type', 'lingotek-translation' ),
|
167 |
'profile' => __( 'Profile', 'lingotek-translation' ),
|
@@ -176,7 +182,7 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
176 |
*
|
177 |
* @return array
|
178 |
*/
|
179 |
-
function get_sortable_columns() {
|
180 |
return array(
|
181 |
'name' => array( 'name', false ),
|
182 |
);
|
@@ -189,8 +195,8 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
189 |
*
|
190 |
* @param array $data data.
|
191 |
*/
|
192 |
-
function prepare_items( $data = array() ) {
|
193 |
-
$per_page
|
194 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
195 |
|
196 |
/**
|
@@ -201,23 +207,28 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
201 |
* @return int sort direction.
|
202 |
*/
|
203 |
function usort_reorder( $a, $b ) {
|
204 |
-
$order
|
205 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
206 |
-
|
207 |
-
|
|
|
|
|
208 |
};
|
209 |
|
210 |
-
|
|
|
211 |
usort( $data, 'usort_reorder' );
|
212 |
}
|
213 |
|
214 |
$total_items = count( $data );
|
215 |
-
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
216 |
-
|
217 |
-
$this->set_pagination_args(
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
222 |
}
|
223 |
}
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
// Since WP 3.1.
|
5 |
+
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
6 |
}
|
7 |
|
8 |
/**
|
28 |
* @param array $content_types array of content types.
|
29 |
* @since 0.2
|
30 |
*/
|
31 |
+
public function __construct( $content_types ) {
|
32 |
+
parent::__construct(
|
33 |
+
array(
|
34 |
+
// Do not translate (used for css class).
|
35 |
+
'plural' => 'lingotek-content',
|
36 |
+
'ajax' => false,
|
37 |
+
)
|
38 |
+
);
|
39 |
|
40 |
+
$this->profiles = Lingotek::get_profiles();
|
41 |
$this->content_types = $content_types;
|
42 |
}
|
43 |
|
48 |
*
|
49 |
* @param array $item items.
|
50 |
*/
|
51 |
+
protected function column_name( $item ) {
|
52 |
global $polylang;
|
53 |
|
54 |
printf( '<span class="content-type-name">%s</span>', esc_html( $item['name'] ) );
|
55 |
|
56 |
// the source language for strings is always the default language.
|
57 |
if ( 'string' !== $item['type'] ) {
|
58 |
+
printf(
|
59 |
+
'<a id="id[%s]" class="dashicons dashicons-arrow-right" onclick="%s" href="#"></a>',
|
60 |
esc_attr( $item['type'] ),
|
61 |
"
|
62 |
d1 = document.getElementById('sources-name[" . esc_html( $item['type'] ) . "]');
|
76 |
|
77 |
printf( '<ul class="sources-name" id="sources-name[%s]" style="display:none;">', esc_html( $item['type'] ) );
|
78 |
foreach ( $polylang->model->get_languages_list() as $language ) {
|
79 |
+
/* translators: %s: The language name. */
|
80 |
printf( '<li>%s</li>', sprintf( esc_html( __( '%s source', 'lingotek-translation' ) ), esc_html( $language->name ) ) );
|
81 |
}
|
82 |
echo '</ul>';
|
83 |
+
}//end if
|
84 |
}
|
85 |
|
86 |
/**
|
90 |
*
|
91 |
* @param array $item item.
|
92 |
*/
|
93 |
+
protected function column_profile( $item ) {
|
94 |
global $polylang;
|
95 |
|
96 |
printf( '<select class="content-type-profile" name="%1$s" id="%1$s">', esc_html( $item['type'] ) . '[profile]' );
|
97 |
foreach ( $this->profiles as $key => $profile ) {
|
98 |
+
$selected = ( isset( $item['profile'] ) && $key === $item['profile'] ) ? 'selected="selected"' : '';
|
99 |
echo "\n\t<option value='" . esc_attr( $key ) . "' " . esc_html( $selected ) . '>' . esc_html( $profile['name'] ) . '</option>';
|
100 |
}
|
101 |
echo '</select>';
|
108 |
foreach ( $polylang->model->get_languages_list() as $language ) {
|
109 |
printf( '<li><select name="%1$s" id="%1$s">', esc_html( $item['type'] ) . '[sources][' . esc_html( $language->slug ) . ']' );
|
110 |
foreach ( $options as $key => $profile ) {
|
111 |
+
$selected = ( isset( $item['sources'][ $language->slug ] ) && $key === $item['sources'][ $language->slug ] ) ? 'selected="selected"' : '';
|
112 |
echo "\n\t<option value='" . esc_attr( $key ) . "' " . esc_html( $selected ) . '>' . esc_html( $profile['name'] ) . '</option>';
|
113 |
}
|
114 |
echo '</select></li>';
|
130 |
protected function display_fields( $labels, $values, $name ) {
|
131 |
foreach ( $labels as $key => $str ) {
|
132 |
if ( is_array( $str ) ) {
|
133 |
+
if ( 'metas' === $key ) {
|
134 |
continue;
|
135 |
}
|
136 |
$this->display_fields( $str, isset( $values[ $key ] ) ? $values[ $key ] : array(), $name . "[$key]" );
|
152 |
*
|
153 |
* @param array $item item.
|
154 |
*/
|
155 |
+
protected function column_fields( $item ) {
|
156 |
if ( ! empty( $item['fields'] ) ) {
|
157 |
echo '<ul class="content-type-fields">';
|
158 |
+
$this->display_fields( $item['fields']['label'], isset( $item['fields']['value'] ) ? $item['fields']['value'] : array(), $item['type'] . '[fields]' );
|
159 |
echo '</ul>';
|
160 |
}
|
161 |
}
|
167 |
*
|
168 |
* @return array the list of column titles
|
169 |
*/
|
170 |
+
public function get_columns() {
|
171 |
return array(
|
172 |
'name' => __( 'Content Type', 'lingotek-translation' ),
|
173 |
'profile' => __( 'Profile', 'lingotek-translation' ),
|
182 |
*
|
183 |
* @return array
|
184 |
*/
|
185 |
+
public function get_sortable_columns() {
|
186 |
return array(
|
187 |
'name' => array( 'name', false ),
|
188 |
);
|
195 |
*
|
196 |
* @param array $data data.
|
197 |
*/
|
198 |
+
public function prepare_items( $data = array() ) {
|
199 |
+
$per_page = $this->get_items_per_page( 'lingotek_content_per_page' );
|
200 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
201 |
|
202 |
/**
|
207 |
* @return int sort direction.
|
208 |
*/
|
209 |
function usort_reorder( $a, $b ) {
|
210 |
+
$order = filter_input( INPUT_GET, 'order' );
|
211 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
212 |
+
// Determine sort order.
|
213 |
+
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
|
214 |
+
// Send final sort direction to usort.
|
215 |
+
return ( empty( $order ) || 'asc' === $order ) ? $result : -$result;
|
216 |
};
|
217 |
|
218 |
+
// No sort by default.
|
219 |
+
if ( ! empty( $orderby ) ) {
|
220 |
usort( $data, 'usort_reorder' );
|
221 |
}
|
222 |
|
223 |
$total_items = count( $data );
|
224 |
+
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
225 |
+
|
226 |
+
$this->set_pagination_args(
|
227 |
+
array(
|
228 |
+
'total_items' => $total_items,
|
229 |
+
'per_page' => $per_page,
|
230 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
231 |
+
)
|
232 |
+
);
|
233 |
}
|
234 |
}
|
admin/custom-fields-table.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
-
|
|
|
5 |
}
|
6 |
|
7 |
/**
|
@@ -26,11 +27,14 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
26 |
*
|
27 |
* @since 0.2
|
28 |
*/
|
29 |
-
function __construct() {
|
30 |
-
parent::__construct(
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
@@ -40,10 +44,11 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
40 |
*
|
41 |
* @param array $item item.
|
42 |
* @return string
|
|
|
|
|
43 |
*/
|
44 |
-
function column_meta_key( $item ) {
|
45 |
-
|
46 |
-
printf('<input type="checkbox" onClick="show(this);" class="boxes" name="%s" value="value1" > ',$item['meta_key'] );
|
47 |
return isset( $item['meta_key'] ) ? esc_html( $item['meta_key'] ) : '';
|
48 |
}
|
49 |
|
@@ -53,12 +58,12 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
53 |
* @since 0.2
|
54 |
*
|
55 |
* @param array $item item.
|
|
|
|
|
56 |
*/
|
57 |
-
function column_setting( $item ) {
|
58 |
-
|
59 |
-
$settings = array( 'translate', 'copy', 'ignore' );
|
60 |
$custom_field_choices = get_option( 'lingotek_custom_fields', array() );
|
61 |
-
//var_dump($custom_field_choices);
|
62 |
printf( '<select class="custom-field-setting" name="%1$s" id="%1$s">', 'settings[' . esc_html( $item['meta_key'] ) . ']' );
|
63 |
|
64 |
// select the option from the lingotek_custom_fields option.
|
@@ -80,11 +85,11 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
80 |
*
|
81 |
* @return array the list of column titles
|
82 |
*/
|
83 |
-
function get_columns() {
|
84 |
return array(
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
);
|
89 |
}
|
90 |
|
@@ -95,9 +100,10 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
95 |
*
|
96 |
* @return array
|
97 |
*/
|
98 |
-
function get_sortable_columns() {
|
99 |
return array(
|
100 |
-
|
|
|
101 |
);
|
102 |
}
|
103 |
|
@@ -108,7 +114,7 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
108 |
*
|
109 |
* @param array $data data.
|
110 |
*/
|
111 |
-
function prepare_items( $data = array() ) {
|
112 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
113 |
|
114 |
/**
|
@@ -119,22 +125,27 @@ class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
|
119 |
* @return int sort direction.
|
120 |
*/
|
121 |
function usort_reorder( $a, $b ) {
|
122 |
-
$order
|
123 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
124 |
-
|
125 |
-
|
|
|
|
|
126 |
};
|
127 |
|
128 |
-
|
|
|
129 |
usort( $data, 'usort_reorder' );
|
130 |
}
|
131 |
|
132 |
$total_items = count( $data );
|
133 |
$this->items = $data;
|
134 |
|
135 |
-
$this->set_pagination_args(
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
139 |
}
|
140 |
}
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
// Since WP 3.1.
|
5 |
+
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
6 |
}
|
7 |
|
8 |
/**
|
27 |
*
|
28 |
* @since 0.2
|
29 |
*/
|
30 |
+
public function __construct() {
|
31 |
+
parent::__construct(
|
32 |
+
array(
|
33 |
+
// Do not translate (used for css class).
|
34 |
+
'plural' => 'lingotek-custom-fields',
|
35 |
+
'ajax' => false,
|
36 |
+
)
|
37 |
+
);
|
38 |
}
|
39 |
|
40 |
/**
|
44 |
*
|
45 |
* @param array $item item.
|
46 |
* @return string
|
47 |
+
*
|
48 |
+
* @deprecated Unused?
|
49 |
*/
|
50 |
+
protected function column_meta_key( $item ) {
|
51 |
+
printf( '<input type="checkbox" onClick="show(this);" class="boxes" name="%s" value="value1" > ', esc_html( $item['meta_key'] ) );
|
|
|
52 |
return isset( $item['meta_key'] ) ? esc_html( $item['meta_key'] ) : '';
|
53 |
}
|
54 |
|
58 |
* @since 0.2
|
59 |
*
|
60 |
* @param array $item item.
|
61 |
+
*
|
62 |
+
* @deprecated Unused?
|
63 |
*/
|
64 |
+
protected function column_setting( $item ) {
|
65 |
+
$settings = array( 'translate', 'copy', 'ignore' );
|
|
|
66 |
$custom_field_choices = get_option( 'lingotek_custom_fields', array() );
|
|
|
67 |
printf( '<select class="custom-field-setting" name="%1$s" id="%1$s">', 'settings[' . esc_html( $item['meta_key'] ) . ']' );
|
68 |
|
69 |
// select the option from the lingotek_custom_fields option.
|
85 |
*
|
86 |
* @return array the list of column titles
|
87 |
*/
|
88 |
+
public function get_columns() {
|
89 |
return array(
|
90 |
+
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
91 |
+
'meta_key' => __( '<input type="checkbox" id="master" onClick="toggle(this);" value="value2" > Custom Field Key', 'lingotek-translation' ),
|
92 |
+
'setting' => __( 'Action', 'lingotek-translation' ),
|
93 |
);
|
94 |
}
|
95 |
|
100 |
*
|
101 |
* @return array
|
102 |
*/
|
103 |
+
public function get_sortable_columns() {
|
104 |
return array(
|
105 |
+
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
106 |
+
'meta_key' => array( 'meta_key', false ),
|
107 |
);
|
108 |
}
|
109 |
|
114 |
*
|
115 |
* @param array $data data.
|
116 |
*/
|
117 |
+
public function prepare_items( $data = array() ) {
|
118 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
119 |
|
120 |
/**
|
125 |
* @return int sort direction.
|
126 |
*/
|
127 |
function usort_reorder( $a, $b ) {
|
128 |
+
$order = filter_input( INPUT_GET, 'order' );
|
129 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
130 |
+
// Determine sort order.
|
131 |
+
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
|
132 |
+
// Send final sort direction to usort.
|
133 |
+
return ( empty( $order ) || 'asc' === $order ) ? $result : -$result;
|
134 |
};
|
135 |
|
136 |
+
// No sort by default.
|
137 |
+
if ( ! empty( $orderby ) ) {
|
138 |
usort( $data, 'usort_reorder' );
|
139 |
}
|
140 |
|
141 |
$total_items = count( $data );
|
142 |
$this->items = $data;
|
143 |
|
144 |
+
$this->set_pagination_args(
|
145 |
+
array(
|
146 |
+
'total_items' => $total_items,
|
147 |
+
'per_page' => count( $data ),
|
148 |
+
)
|
149 |
+
);
|
150 |
}
|
151 |
}
|
admin/filters-columns.php
CHANGED
@@ -42,14 +42,15 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
42 |
protected function add_column( $columns, $before ) {
|
43 |
$n = array_search( $before, array_keys( $columns ), true );
|
44 |
if ( $n ) {
|
45 |
-
$end
|
46 |
$columns = array_slice( $columns, 0, $n );
|
47 |
}
|
48 |
$this->print_patch_error();
|
49 |
$this->print_cancel_error();
|
50 |
foreach ( $this->model->get_languages_list() as $language ) {
|
51 |
$columns[ 'language_' . $language->locale ] = $language->flag ? $language->flag :
|
52 |
-
sprintf(
|
|
|
53 |
esc_html( "$language->name ($language->locale)" ),
|
54 |
esc_html( $language->slug )
|
55 |
);
|
@@ -59,41 +60,53 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
59 |
}
|
60 |
|
61 |
private function print_cancel_error() {
|
62 |
-
$lingotek_log_errors = get_option('lingotek_log_errors');
|
63 |
-
$message
|
64 |
-
if (get_option('disassociate_source_failed',
|
65 |
-
$message = str_replace('cancel', 'delete', $message);
|
66 |
-
printf(
|
|
|
67 |
<p>%s</p>
|
68 |
-
</div>',
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
73 |
<p>%s</p>
|
74 |
-
</div>',
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
78 |
<p>%s</p>
|
79 |
-
</div>',
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
<p>%s</p>
|
84 |
-
</div>',
|
85 |
-
|
86 |
-
|
|
|
|
|
87 |
}
|
88 |
|
89 |
private function print_patch_error() {
|
90 |
-
$lingotek_log_errors = get_option('lingotek_log_errors');
|
91 |
-
if (empty($lingotek_log_errors['patch_document_error'])) {
|
92 |
return;
|
93 |
}
|
94 |
-
printf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $lingotek_log_errors['patch_document_error']);
|
95 |
-
unset($lingotek_log_errors['patch_document_error']);
|
96 |
-
update_option('lingotek_log_errors', $lingotek_log_errors, false);
|
97 |
}
|
98 |
|
99 |
/**
|
@@ -108,11 +121,11 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
108 |
* @param item $custom_data data.
|
109 |
*/
|
110 |
protected function _column( $type, $column, $object_id, $custom_data = null ) {
|
111 |
-
$action
|
112 |
-
$get_action
|
113 |
$inline_lang_choice = filter_input( INPUT_POST, 'inline_lang_choice' );
|
114 |
-
$inline
|
115 |
-
$lang
|
116 |
|
117 |
if ( false === strpos( $column, 'language_' ) || ! $lang ) {
|
118 |
if ( $custom_data ) {
|
@@ -132,91 +145,82 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
132 |
printf( '<div class="hidden" id="lang_%d">%s</div>', esc_attr( $object_id ), esc_html( $lang->slug ) );
|
133 |
}
|
134 |
|
135 |
-
$id = (($inline && $lang->slug !== $this->model->get_language( filter_input( INPUT_POST, 'old_lang' ) )->slug) ?
|
136 |
-
($language->slug === $lang->slug ? $object_id : 0) :
|
137 |
-
'post' === $type) ? PLL()->model->post->get( $object_id, $language ) : PLL()->model->term->get( $object_id, $language );
|
138 |
|
139 |
$document = $this->lgtm->get_group( $type, $object_id );
|
140 |
if ( isset( $document->source ) ) {
|
141 |
$source_language = 'post' === $type ? PLL()->model->post->get_language( $document->source ) : PLL()->model->term->get_language( $document->source );
|
142 |
-
$source_profile
|
143 |
} else {
|
144 |
$source_language = $lang;
|
145 |
}
|
146 |
|
147 |
// FIXME not very clean.
|
148 |
-
$actions
|
149 |
-
$profile
|
150 |
-
$cancelled = isset($document->status) ? $document->status
|
151 |
-
$disabled
|
152 |
// post ready for upload.
|
153 |
-
if (
|
154 |
-
return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
|
155 |
-
: ($document && (count( $document->desc_array ) >= 3) ? $actions->upload_icon( $object_id, true ) : $actions->upload_icon( $object_id ));
|
156 |
-
}
|
157 |
-
|
158 |
-
'copy' === $
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
}
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
} // translation disabled.
|
172 |
-
elseif (( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) &&
|
173 |
-
! isset( $document->translations[ $language->locale ] ) ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
|
174 |
return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
|
175 |
-
}
|
176 |
-
|
177 |
-
//
|
178 |
-
|
179 |
-
|
180 |
-
if ( $this->lgtm->can_upload( $type, $id ) ) {
|
181 |
-
return $actions->upload_icon( $id );
|
182 |
}
|
183 |
-
|
184 |
-
|
185 |
return Lingotek_Actions::importing_icon( $document );
|
186 |
}
|
187 |
// source failed
|
188 |
-
if ($id === $object_id && 'failed' === $document->status) {
|
189 |
-
return $actions->failed_import_icon($document->status, $object_id);
|
190 |
}
|
191 |
-
|
192 |
-
}
|
193 |
-
|
194 |
return Lingotek_Actions::translation_icon( $document, $language );
|
195 |
-
}
|
196 |
-
elseif ( ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
|
197 |
return parent::term_column( '', $column, $object_id );
|
198 |
-
}
|
199 |
-
|
200 |
-
return $object_id === $id && ! $disabled ? $actions->upload_icon( $object_id, true ) : ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ));
|
201 |
-
}
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
}
|
209 |
-
// no translation.
|
210 |
-
else {
|
211 |
/**
|
212 |
* There is no record of a translation, but the entire document has been cancelled
|
213 |
* so we just mark all locales as cancelled since the user will have to re upload the document
|
214 |
*/
|
215 |
-
if ($document->status
|
216 |
-
return $actions->cancelled_icon($object_id, true);
|
217 |
}
|
218 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
219 |
-
}
|
220 |
}
|
221 |
|
222 |
/**
|
@@ -229,39 +233,40 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
229 |
* @param int $post_id post id.
|
230 |
*/
|
231 |
public function post_column( $column, $post_id ) {
|
232 |
-
if ( false === strpos( $column, 'language_' )) {
|
233 |
return;
|
234 |
}
|
235 |
$this->content_type = get_post_type( $post_id );
|
236 |
|
237 |
$allowed_html = array(
|
238 |
-
'a'
|
239 |
-
'href'
|
240 |
-
'class'
|
241 |
-
'title'
|
242 |
-
'target' => array()
|
243 |
),
|
244 |
'div' => array(
|
245 |
'title' => array(),
|
246 |
'class' => array(),
|
247 |
),
|
248 |
'img' => array(
|
249 |
-
'src' => array()
|
250 |
-
)
|
251 |
);
|
252 |
echo wp_kses( $this->_column( 'post', $column, $post_id ), $allowed_html );
|
253 |
|
254 |
/**
|
255 |
-
*
|
256 |
*/
|
257 |
-
$post
|
258 |
$source_language = PLL()->model->post->get_language( $post_id );
|
259 |
$target_language = $this->model->get_language( substr( $column, 9 ) );
|
260 |
-
if (is_object($source_language) && is_object($target_language)) {
|
261 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language, $post_id );
|
262 |
-
$workflow
|
263 |
// $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
264 |
-
|
|
|
265 |
}
|
266 |
|
267 |
// checking for api errors.
|
@@ -285,39 +290,40 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
285 |
* @param int $term_id term id.
|
286 |
*/
|
287 |
public function term_column( $custom_data, $column, $term_id ) {
|
288 |
-
if ( false === strpos( $column, 'language_' )) {
|
289 |
return;
|
290 |
}
|
291 |
-
$allowed_html
|
292 |
-
'a'
|
293 |
-
'href'
|
294 |
-
'class'
|
295 |
-
'title'
|
296 |
-
'target' => array()
|
297 |
),
|
298 |
-
'div'
|
299 |
'title' => array(),
|
300 |
'class' => array(),
|
301 |
),
|
302 |
'span' => array(
|
303 |
'class' => array(),
|
304 |
),
|
305 |
-
'img'
|
306 |
-
'src' => array()
|
307 |
-
)
|
308 |
);
|
309 |
$this->content_type = $GLOBALS['taxonomy'];
|
310 |
|
311 |
/**
|
312 |
-
*
|
313 |
*/
|
314 |
$source_language = PLL()->model->term->get_language( $term_id );
|
315 |
$target_language = $this->model->get_language( substr( $column, 9 ) );
|
316 |
-
if (is_object($source_language) && is_object($target_language)) {
|
317 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $this->content_type, $source_language, $target_language );
|
318 |
-
$workflow
|
319 |
// $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
320 |
-
|
|
|
321 |
}
|
322 |
|
323 |
if ( ! $custom_data ) {
|
@@ -340,19 +346,19 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
|
340 |
*/
|
341 |
protected function error_icon_html( $column, $object_id, $source_locale = null ) {
|
342 |
// checking for api errors.
|
343 |
-
$source_column
|
344 |
$column_language_only = substr( $column, 0, 11 );
|
345 |
-
$errors
|
346 |
|
347 |
if ( $source_column === $source_locale ) {
|
348 |
if ( isset( $errors[ $object_id ] ) ) {
|
349 |
-
$api_error
|
350 |
$allowed_html = array(
|
351 |
'a' => array(
|
352 |
-
'href'
|
353 |
-
'class'
|
354 |
-
'title'
|
355 |
-
'target' => array()
|
356 |
),
|
357 |
);
|
358 |
echo wp_kses( Lingotek_Actions::display_error_icon( 'error', $api_error ), $allowed_html );
|
42 |
protected function add_column( $columns, $before ) {
|
43 |
$n = array_search( $before, array_keys( $columns ), true );
|
44 |
if ( $n ) {
|
45 |
+
$end = array_slice( $columns, $n );
|
46 |
$columns = array_slice( $columns, 0, $n );
|
47 |
}
|
48 |
$this->print_patch_error();
|
49 |
$this->print_cancel_error();
|
50 |
foreach ( $this->model->get_languages_list() as $language ) {
|
51 |
$columns[ 'language_' . $language->locale ] = $language->flag ? $language->flag :
|
52 |
+
sprintf(
|
53 |
+
'<a href="" title="%s">%s</a>',
|
54 |
esc_html( "$language->name ($language->locale)" ),
|
55 |
esc_html( $language->slug )
|
56 |
);
|
60 |
}
|
61 |
|
62 |
private function print_cancel_error() {
|
63 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors' );
|
64 |
+
$message = isset( $lingotek_log_errors['disassociate_document_error'] ) ? $lingotek_log_errors['disassociate_document_error'] : '';
|
65 |
+
if ( get_option( 'disassociate_source_failed', false ) ) {
|
66 |
+
$message = str_replace( 'cancel', 'delete', $message );
|
67 |
+
printf(
|
68 |
+
'<div class="notice notice-warning is-dismissible">
|
69 |
<p>%s</p>
|
70 |
+
</div>',
|
71 |
+
esc_html( $message )
|
72 |
+
);
|
73 |
+
update_option( 'disassociate_source_failed', false );
|
74 |
+
} elseif ( get_option( 'disassociate_target_failed', false ) ) {
|
75 |
+
$message = str_replace( 'cancel', 'delete', $message );
|
76 |
+
printf(
|
77 |
+
'<div class="notice notice-warning is-dismissible">
|
78 |
<p>%s</p>
|
79 |
+
</div>',
|
80 |
+
esc_html( $message )
|
81 |
+
);
|
82 |
+
update_option( 'disassociate_target_failed', false );
|
83 |
+
} elseif ( get_option( 'cancel_source_failed', false ) ) {
|
84 |
+
printf(
|
85 |
+
'<div class="notice notice-warning is-dismissible">
|
86 |
<p>%s</p>
|
87 |
+
</div>',
|
88 |
+
esc_html( $message )
|
89 |
+
);
|
90 |
+
update_option( 'cancel_source_failed', false );
|
91 |
+
} elseif ( get_option( 'cancel_target_failed', false ) ) {
|
92 |
+
printf(
|
93 |
+
'<div class="notice notice-warning is-dismissible">
|
94 |
<p>%s</p>
|
95 |
+
</div>',
|
96 |
+
esc_html( $message )
|
97 |
+
);
|
98 |
+
update_option( 'cancel_target_failed', false );
|
99 |
+
}//end if
|
100 |
}
|
101 |
|
102 |
private function print_patch_error() {
|
103 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors' );
|
104 |
+
if ( empty( $lingotek_log_errors['patch_document_error'] ) ) {
|
105 |
return;
|
106 |
}
|
107 |
+
printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html( $lingotek_log_errors['patch_document_error'] ) );
|
108 |
+
unset( $lingotek_log_errors['patch_document_error'] );
|
109 |
+
update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
|
110 |
}
|
111 |
|
112 |
/**
|
121 |
* @param item $custom_data data.
|
122 |
*/
|
123 |
protected function _column( $type, $column, $object_id, $custom_data = null ) {
|
124 |
+
$action = 'post' === $type ? 'inline-save' : 'inline-save-tax';
|
125 |
+
$get_action = filter_input( INPUT_GET, 'action' );
|
126 |
$inline_lang_choice = filter_input( INPUT_POST, 'inline_lang_choice' );
|
127 |
+
$inline = defined( 'DOING_AJAX' ) && $get_action === $action && ! empty( $inline_lang_choice );
|
128 |
+
$lang = $inline ? $this->model->get_language( $inline_lang_choice ) : ( 'post' === $type ? PLL()->model->post->get_language( $object_id ) : PLL()->model->term->get_language( $object_id ) );
|
129 |
|
130 |
if ( false === strpos( $column, 'language_' ) || ! $lang ) {
|
131 |
if ( $custom_data ) {
|
145 |
printf( '<div class="hidden" id="lang_%d">%s</div>', esc_attr( $object_id ), esc_html( $lang->slug ) );
|
146 |
}
|
147 |
|
148 |
+
$id = ( ( $inline && $lang->slug !== $this->model->get_language( filter_input( INPUT_POST, 'old_lang' ) )->slug ) ?
|
149 |
+
( $language->slug === $lang->slug ? $object_id : 0 ) :
|
150 |
+
'post' === $type ) ? PLL()->model->post->get( $object_id, $language ) : PLL()->model->term->get( $object_id, $language );
|
151 |
|
152 |
$document = $this->lgtm->get_group( $type, $object_id );
|
153 |
if ( isset( $document->source ) ) {
|
154 |
$source_language = 'post' === $type ? PLL()->model->post->get_language( $document->source ) : PLL()->model->term->get_language( $document->source );
|
155 |
+
$source_profile = Lingotek_Model::get_profile( $this->content_type, $source_language, $document->source );
|
156 |
} else {
|
157 |
$source_language = $lang;
|
158 |
}
|
159 |
|
160 |
// FIXME not very clean.
|
161 |
+
$actions = 'post' === $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
|
162 |
+
$profile = Lingotek_Model::get_profile( $this->content_type, $language, $object_id );
|
163 |
+
$cancelled = isset( $document->status ) ? 'cancelled' === $document->status : false;
|
164 |
+
$disabled = 'disabled' === $profile['profile'] || ! Lingotek::is_allowed_tms_locale( $language->lingotek_locale );
|
165 |
// post ready for upload.
|
166 |
+
if ( ! $cancelled && $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
|
167 |
+
return $disabled ? ( 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ) )
|
168 |
+
: ( $document && ( count( $document->desc_array ) >= 3 ) ? $actions->upload_icon( $object_id, true ) : $actions->upload_icon( $object_id ) );
|
169 |
+
} elseif ( ( 'post' === $type || 'term' === $type ) && ( ( isset( $source_profile['targets'][ $language->slug ] ) &&
|
170 |
+
'copy' === $source_profile['targets'][ $language->slug ] ) || ( isset( $profile['targets'][ $language->slug ] ) &&
|
171 |
+
'copy' === $profile['targets'][ $language->slug ] ) && isset( $document->source ) ) ) {
|
172 |
+
if ( isset( $document->desc_array[ $language->slug ] ) ) {
|
173 |
+
return ( 'post' === $type ) ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
|
174 |
+
} else {
|
175 |
+
if ( $document ) {
|
176 |
+
return $actions->copy_icon( $document->source, $language->slug );
|
177 |
+
} else {
|
178 |
+
return $actions->copy_icon( $object_id, $language->slug );
|
179 |
}
|
180 |
+
}
|
181 |
+
} elseif ( ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) &&
|
182 |
+
! isset( $document->translations[ $language->locale ] ) ) || ! Lingotek::is_allowed_tms_locale( $language->lingotek_locale ) ) {
|
183 |
+
// translation disabled.
|
|
|
|
|
|
|
184 |
return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
|
185 |
+
} elseif ( ! $cancelled && isset( $document->source ) && $document->source === $id ) {
|
186 |
+
// Source post is uploaded.
|
187 |
+
// Source is ready for upload.
|
188 |
+
if ( $this->lgtm->can_upload( $type, $id ) ) {
|
189 |
+
return $actions->upload_icon( $id );
|
|
|
|
|
190 |
}
|
191 |
+
// importing source.
|
192 |
+
if ( $id === $object_id && 'importing' === $document->status ) {
|
193 |
return Lingotek_Actions::importing_icon( $document );
|
194 |
}
|
195 |
// source failed
|
196 |
+
if ( $id === $object_id && 'failed' === $document->status ) {
|
197 |
+
return $actions->failed_import_icon( $document->status, $object_id );
|
198 |
}
|
199 |
+
return 'post' === $type ? Lingotek_Post_Actions::uploaded_icon( $id ) : Lingotek_Term_actions::uploaded_icon( $id );
|
200 |
+
} elseif ( isset( $document->translations[ $language->locale ] ) || ( isset( $document->source ) && 'current' === $document->status ) ) {
|
201 |
+
// translations.
|
202 |
return Lingotek_Actions::translation_icon( $document, $language );
|
203 |
+
} elseif ( ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) || ! Lingotek::is_allowed_tms_locale( $language->lingotek_locale ) ) {
|
|
|
204 |
return parent::term_column( '', $column, $object_id );
|
205 |
+
} elseif ( empty( $document->source ) ) {
|
206 |
+
// translations exist but are not managed by Lingotek TMS.
|
207 |
+
return $object_id === $id && ! $disabled ? $actions->upload_icon( $object_id, true ) : ( 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ) );
|
208 |
+
} elseif ( 'failed' === $document->status ) {
|
209 |
+
return $actions->failed_import_icon( $document->status, $object_id );
|
210 |
+
} elseif ( $this->lgtm->can_upload( $type, $id ) && 'cancelled' === $document->status ) {
|
211 |
+
return $disabled ? ( 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ) )
|
212 |
+
: ( $document && ( count( $document->desc_array ) >= 3 ) ? $actions->cancelled_icon( $object_id, false, true ) : $actions->cancelled_icon( $object_id ) );
|
213 |
+
} else {
|
214 |
+
// no translation.
|
|
|
|
|
|
|
215 |
/**
|
216 |
* There is no record of a translation, but the entire document has been cancelled
|
217 |
* so we just mark all locales as cancelled since the user will have to re upload the document
|
218 |
*/
|
219 |
+
if ( 'cancelled' === $document->status ) {
|
220 |
+
return $actions->cancelled_icon( $object_id, true );
|
221 |
}
|
222 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
223 |
+
}//end if
|
224 |
}
|
225 |
|
226 |
/**
|
233 |
* @param int $post_id post id.
|
234 |
*/
|
235 |
public function post_column( $column, $post_id ) {
|
236 |
+
if ( false === strpos( $column, 'language_' ) ) {
|
237 |
return;
|
238 |
}
|
239 |
$this->content_type = get_post_type( $post_id );
|
240 |
|
241 |
$allowed_html = array(
|
242 |
+
'a' => array(
|
243 |
+
'href' => array(),
|
244 |
+
'class' => array(),
|
245 |
+
'title' => array(),
|
246 |
+
'target' => array(),
|
247 |
),
|
248 |
'div' => array(
|
249 |
'title' => array(),
|
250 |
'class' => array(),
|
251 |
),
|
252 |
'img' => array(
|
253 |
+
'src' => array(),
|
254 |
+
),
|
255 |
);
|
256 |
echo wp_kses( $this->_column( 'post', $column, $post_id ), $allowed_html );
|
257 |
|
258 |
/**
|
259 |
+
* Setup workflow specific logic for posts.
|
260 |
*/
|
261 |
+
$post = get_post( $post_id );
|
262 |
$source_language = PLL()->model->post->get_language( $post_id );
|
263 |
$target_language = $this->model->get_language( substr( $column, 9 ) );
|
264 |
+
if ( is_object( $source_language ) && is_object( $target_language ) ) {
|
265 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language, $post_id );
|
266 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
|
267 |
// $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
268 |
+
// Adds modal html to page.
|
269 |
+
$workflow->echo_posts_modal( $post_id, $target_language->locale );
|
270 |
}
|
271 |
|
272 |
// checking for api errors.
|
290 |
* @param int $term_id term id.
|
291 |
*/
|
292 |
public function term_column( $custom_data, $column, $term_id ) {
|
293 |
+
if ( false === strpos( $column, 'language_' ) ) {
|
294 |
return;
|
295 |
}
|
296 |
+
$allowed_html = array(
|
297 |
+
'a' => array(
|
298 |
+
'href' => array(),
|
299 |
+
'class' => array(),
|
300 |
+
'title' => array(),
|
301 |
+
'target' => array(),
|
302 |
),
|
303 |
+
'div' => array(
|
304 |
'title' => array(),
|
305 |
'class' => array(),
|
306 |
),
|
307 |
'span' => array(
|
308 |
'class' => array(),
|
309 |
),
|
310 |
+
'img' => array(
|
311 |
+
'src' => array(),
|
312 |
+
),
|
313 |
);
|
314 |
$this->content_type = $GLOBALS['taxonomy'];
|
315 |
|
316 |
/**
|
317 |
+
* Setup workflow specific logic for terms.
|
318 |
*/
|
319 |
$source_language = PLL()->model->term->get_language( $term_id );
|
320 |
$target_language = $this->model->get_language( substr( $column, 9 ) );
|
321 |
+
if ( is_object( $source_language ) && is_object( $target_language ) ) {
|
322 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $this->content_type, $source_language, $target_language );
|
323 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
|
324 |
// $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
325 |
+
// Adds modal html to page.
|
326 |
+
$workflow->echo_terms_modal( $term_id, $target_language->locale );
|
327 |
}
|
328 |
|
329 |
if ( ! $custom_data ) {
|
346 |
*/
|
347 |
protected function error_icon_html( $column, $object_id, $source_locale = null ) {
|
348 |
// checking for api errors.
|
349 |
+
$source_column = substr( $column, 9 );
|
350 |
$column_language_only = substr( $column, 0, 11 );
|
351 |
+
$errors = get_option( 'lingotek_log_errors' );
|
352 |
|
353 |
if ( $source_column === $source_locale ) {
|
354 |
if ( isset( $errors[ $object_id ] ) ) {
|
355 |
+
$api_error = Lingotek_Actions::retrieve_api_error( $errors[ $object_id ] );
|
356 |
$allowed_html = array(
|
357 |
'a' => array(
|
358 |
+
'href' => array(),
|
359 |
+
'class' => array(),
|
360 |
+
'title' => array(),
|
361 |
+
'target' => array(),
|
362 |
),
|
363 |
);
|
364 |
echo wp_kses( Lingotek_Actions::display_error_icon( 'error', $api_error ), $allowed_html );
|
admin/filters-media.php
CHANGED
@@ -25,7 +25,8 @@ class Lingotek_Filters_Media extends PLL_Admin_Filters_Media {
|
|
25 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
26 |
|
27 |
add_action( 'edit_attachment', array( &$this, 'edit_attachment' ) );
|
28 |
-
|
|
|
29 |
}
|
30 |
|
31 |
/**
|
25 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
26 |
|
27 |
add_action( 'edit_attachment', array( &$this, 'edit_attachment' ) );
|
28 |
+
// After Polylang.
|
29 |
+
add_action( 'add_attachment', array( &$this, 'add_attachment' ), 11 );
|
30 |
}
|
31 |
|
32 |
/**
|
admin/filters-post.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Modifies Polylang filters
|
5 |
* Manages automatic upload
|
6 |
* Manages delete / trash sync
|
@@ -8,234 +8,247 @@
|
|
8 |
* @since 0.1
|
9 |
*/
|
10 |
class Lingotek_Filters_Post extends PLL_CRUD_Posts {
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
public $pllm;
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
public $lingotek_prefs;
|
14 |
|
15 |
-
|
16 |
* Constructor
|
17 |
*
|
18 |
* @since 0.1
|
19 |
*/
|
20 |
-
public function __construct(&$polylang) {
|
21 |
-
parent::__construct($polylang);
|
22 |
|
23 |
-
$this->lgtm
|
24 |
-
$this->pllm
|
25 |
$this->lingotek_prefs = Lingotek_Model::get_prefs();
|
26 |
-
$pll_filter
|
27 |
|
28 |
// automatic upload
|
29 |
-
add_action('post_updated', array(&$this, 'post_updated'), 10, 3);
|
30 |
|
31 |
// trash sync
|
32 |
-
add_action('trashed_post', array(&$this, 'trash_post'));
|
33 |
-
add_action('untrashed_post', array(&$this, 'untrash_post'));
|
34 |
|
35 |
-
add_filter('manage_posts_columns', array(&$this, 'add_profile_column'));
|
36 |
-
add_action('manage_posts_custom_column', array(&$this, 'add_profile_column_data'), 10, 3);
|
37 |
|
38 |
-
add_filter('manage_pages_columns', array(&$this, 'add_profile_column'));
|
39 |
-
add_action('manage_pages_custom_column', array(&$this, 'add_profile_column_data'), 10, 3);
|
40 |
|
41 |
//apply language filter to preserve Polylang behavior of only showing documents of the current language
|
42 |
-
add_action('parse_query', array($pll_filter, 'parse_query'));
|
43 |
}
|
44 |
|
45 |
-
|
46 |
* controls whether to display the language metabox or not
|
47 |
*
|
48 |
* @since 0.1
|
49 |
*/
|
50 |
-
public function add_meta_boxes($post_type, $post = null) {
|
51 |
global $post_ID;
|
52 |
-
if ($this->model->is_translated_post_type($post_type)) {
|
53 |
-
$document = $this->lgtm->get_group('post', $post_ID);
|
54 |
-
if (empty($document->source)) {
|
55 |
-
parent::add_meta_boxes($post_type, $document);
|
56 |
-
}
|
57 |
-
else {
|
58 |
add_action( 'edit_form_top', array( &$this, 'edit_form_top' ) );
|
59 |
}
|
60 |
}
|
61 |
}
|
62 |
|
63 |
-
|
64 |
* adds a column to display the post or page translation profile
|
65 |
*
|
66 |
* @since 1.1
|
67 |
*/
|
68 |
-
public function add_profile_column($columns) {
|
69 |
-
$n = array_search('date', array_keys($columns));
|
70 |
-
if ($n) {
|
71 |
-
$end
|
72 |
-
$columns = array_slice($columns, 0, $n);
|
73 |
}
|
74 |
|
75 |
$columns['profile'] = 'Profile';
|
76 |
-
return isset($end) ? array_merge($columns, $end) : $columns;
|
77 |
}
|
78 |
|
79 |
-
|
80 |
* finds the translation profile for a post or page and if not set then displays the content type default profile
|
81 |
*
|
82 |
* @since 1.1
|
83 |
*/
|
84 |
-
public function add_profile_column_data($column_name, $post_id) {
|
85 |
-
if (
|
86 |
-
$document = $this->lgtm->get_group('post', $post_id);
|
87 |
-
if (isset($document->source)) {
|
88 |
$post_id = $document->source;
|
89 |
}
|
90 |
-
$profiles
|
91 |
-
$content_profiles = get_option('lingotek_content_type');
|
92 |
-
$post_profile
|
93 |
-
$post_language
|
94 |
-
$post_type
|
95 |
-
if (isset($_REQUEST['post_type'])) {
|
96 |
-
$post_type = $_REQUEST['post_type'];
|
97 |
}
|
98 |
|
99 |
-
if ($post_profile) {
|
100 |
-
echo $profiles[$post_profile->description]['name'] . sprintf('<a title="%s">%s</a>',
|
101 |
-
}
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
else if (!empty($content_profiles)) {
|
111 |
-
echo $profiles[$content_profiles[$post_type]['profile']]['name'];
|
112 |
}
|
113 |
-
|
114 |
-
_e('Manual', 'lingotek-translation');
|
115 |
-
}
|
116 |
-
}
|
117 |
}
|
118 |
|
119 |
-
|
120 |
-
*
|
121 |
*
|
122 |
* @since 1.10
|
123 |
*/
|
124 |
public function edit_form_top() {
|
125 |
global $post_ID;
|
126 |
-
printf( '<input type="hidden" id="post_lang_choice" name="post_lang_choice" value="%s" />', pll_get_post_language( $post_ID ) );
|
127 |
-
wp_nonce_field('pll_language', '_pll_nonce');
|
128 |
}
|
129 |
|
130 |
-
|
131 |
-
*
|
132 |
*
|
133 |
* @since 0.2
|
134 |
|
135 |
-
* @param int
|
136 |
* @param object $post
|
137 |
-
* @param bool $update whether it is an update or not
|
138 |
*/
|
139 |
-
public function save_post($post_id, $post) {
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
$
|
144 |
-
$document->pre_save_post($post_id, 'post', $language);
|
145 |
}
|
146 |
-
if ($this->can_save_post_data($post_id, $post, true)) {
|
147 |
// updated post
|
148 |
-
if ($document &&
|
149 |
-
|
150 |
-
$
|
151 |
-
$this->
|
|
|
152 |
$document->source_edited();
|
153 |
-
if ($document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status)) {
|
154 |
-
$this->lgtm->upload_post($post_id);
|
155 |
}
|
156 |
}
|
157 |
// Ensures languages are updated, even when no other element on the page has been changed.
|
158 |
-
if (isset($_POST['post_tr_lang'])) {
|
159 |
-
PLL()->model->post->save_translations($post_id, $_POST['post_tr_lang']);
|
160 |
}
|
161 |
}
|
162 |
|
163 |
-
if (
|
164 |
return;
|
|
|
165 |
// new post
|
166 |
-
if (!isset($_REQUEST['import'])) {
|
167 |
-
parent::save_post($post_id, $post);
|
168 |
-
if (
|
169 |
-
!wp_is_post_revision($post_id) &&
|
170 |
-
'auto-draft'
|
171 |
-
'automatic'
|
172 |
-
Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) &&
|
173 |
-
!(isset($_POST['action']) && 'heartbeat'
|
174 |
-
$this->lgtm->can_upload('post', $post_id) &&
|
175 |
-
$this->is_post_valid_for_upload_by_custom_terms($post_id, true)) {
|
176 |
-
|
177 |
-
$this->lgtm->upload_post($post_id);
|
178 |
}
|
179 |
}
|
180 |
}
|
181 |
|
182 |
-
|
183 |
* Allows the customer to interrupt the post upload by applying filter.
|
184 |
* By using This filter we are allowing users to implement custom logic on the post upload and check if it is valid
|
185 |
* for upload
|
186 |
*
|
187 |
* @since 1.3.1
|
188 |
-
*
|
189 |
* @author Soluto
|
190 |
*
|
191 |
-
* @param int
|
192 |
* @param bool $is_new_post
|
193 |
* @return bool
|
194 |
*/
|
195 |
-
protected function is_post_valid_for_upload_by_custom_terms($post_id, $is_new_post) {
|
196 |
$defaults = array();
|
197 |
-
$results
|
198 |
-
return !(in_array(false, $results));
|
199 |
}
|
200 |
|
201 |
-
|
202 |
* checks if we can act when saving a post
|
203 |
*
|
204 |
* @since 0.1
|
205 |
*
|
206 |
-
* @param int
|
207 |
* @param object $post
|
208 |
-
* @param bool
|
209 |
* @return bool
|
210 |
*/
|
211 |
-
protected function can_save_post_data($post_id, $post, $update) {
|
212 |
// does nothing except on post types which are filterable
|
213 |
// also don't act on revisions
|
214 |
-
if (
|
215 |
return false;
|
|
|
216 |
|
217 |
// capability check
|
218 |
// as 'wp_insert_post' can be called from outside WP admin
|
219 |
-
$post_type_object = get_post_type_object($post->post_type);
|
220 |
-
if (($update && !current_user_can($post_type_object->cap->edit_post, $post_id)) || (
|
221 |
return false;
|
|
|
222 |
|
223 |
return true;
|
224 |
}
|
225 |
|
226 |
-
|
227 |
* marks the post as edited if needed
|
228 |
*
|
229 |
* @since 0.1
|
230 |
*
|
231 |
-
* @param int
|
232 |
* @param object $post_after
|
233 |
* @param object $post_before
|
234 |
*/
|
235 |
-
public function post_updated($post_id, $post_after, $post_before) {
|
236 |
}
|
237 |
|
238 |
-
|
239 |
* get translations ids to sync for delete / trash / untrash
|
240 |
* since we can't sync all translations as we get conflicts when attempting to act two times on the same
|
241 |
*
|
@@ -244,105 +257,105 @@ class Lingotek_Filters_Post extends PLL_CRUD_Posts {
|
|
244 |
* @param int $post_id
|
245 |
* @return array
|
246 |
*/
|
247 |
-
protected function get_translations_to_sync($post_id) {
|
248 |
// don't synchronize disassociated posts
|
249 |
-
$group = $this->lgtm->get_group('post', $post_id);
|
250 |
-
if (empty($group->source))
|
251 |
-
return
|
|
|
252 |
|
253 |
-
if (isset($_REQUEST['media']) && is_array($_REQUEST['media']))
|
254 |
-
$post_ids = array_map('intval', $_REQUEST['media']);
|
255 |
-
elseif (!empty($_REQUEST['post']) && is_array($_REQUEST['post']))
|
256 |
-
$post_ids = array_map('intval', $_REQUEST['post']);
|
|
|
257 |
|
258 |
$post_ids[] = $post_id;
|
259 |
-
return array_diff(PLL()->model->post->get_translations($post_id), $post_ids);
|
260 |
}
|
261 |
|
262 |
-
|
263 |
* sync trash
|
264 |
*
|
265 |
* @since 0.1
|
266 |
*
|
267 |
* @param int $post_id
|
268 |
*/
|
269 |
-
public function trash_post($post_id) {
|
270 |
-
if (get_option(
|
271 |
return;
|
272 |
}
|
273 |
-
$group = $this->lgtm->get_group('post', $post_id);
|
274 |
|
275 |
-
if (isset($this->lingotek_prefs['trash_linked_content']['enabled'])) {
|
276 |
-
foreach ($this->get_translations_to_sync($post_id) as $tr_id)
|
277 |
-
wp_trash_post($tr_id);
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
else {
|
283 |
-
wp_trash_post($post_id);
|
284 |
-
if(isset($group->source)){
|
285 |
-
$this->lgtm->cancel_post($post_id);
|
286 |
}
|
287 |
}
|
288 |
-
|
289 |
}
|
290 |
|
291 |
-
|
292 |
* sync untrash
|
293 |
*
|
294 |
* @since 0.1
|
295 |
*
|
296 |
* @param int $post_id
|
297 |
*/
|
298 |
-
public function untrash_post($post_id) {
|
299 |
-
foreach ($this->get_translations_to_sync($post_id) as $tr_id)
|
300 |
-
wp_untrash_post($tr_id);
|
|
|
301 |
}
|
302 |
|
303 |
-
|
304 |
* checks stored hash against current hash to report change
|
305 |
*
|
306 |
* @since 1.0
|
307 |
*
|
308 |
* @param wp_post $post_after
|
309 |
*/
|
310 |
-
protected function post_hash_has_changed($post_after) {
|
311 |
-
if ($post_after->post_status
|
312 |
return false;
|
313 |
}
|
314 |
$document_id = 'lingotek_hash_' . $post_after->ID;
|
315 |
-
$new_hash
|
316 |
-
$old_term
|
317 |
-
$old_hash
|
318 |
|
319 |
// new or updated page
|
320 |
-
if (
|
321 |
-
if (empty($old_term)) {
|
322 |
-
wp_insert_term($document_id, 'lingotek_hash', array('description' => $new_hash));
|
323 |
}
|
324 |
-
wp_set_object_terms($post_after->ID, $document_id, 'lingotek_hash');
|
325 |
return true;
|
326 |
-
}
|
327 |
-
else {
|
328 |
return false;
|
329 |
}
|
330 |
}
|
331 |
|
332 |
-
|
333 |
-
*
|
334 |
*
|
335 |
* @since 1.0
|
336 |
*
|
337 |
* @param int $post_id
|
338 |
*/
|
339 |
-
protected function get_post_hash($post_id) {
|
340 |
-
if (taxonomy_exists('lingotek_hash')) {
|
341 |
-
$terms = wp_get_object_terms($post_id, 'lingotek_hash');
|
342 |
-
$term
|
343 |
return $term;
|
344 |
-
}
|
345 |
-
else {
|
346 |
return null;
|
347 |
}
|
348 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Modifies Polylang filters
|
5 |
* Manages automatic upload
|
6 |
* Manages delete / trash sync
|
8 |
* @since 0.1
|
9 |
*/
|
10 |
class Lingotek_Filters_Post extends PLL_CRUD_Posts {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Lingotek model.
|
14 |
+
*
|
15 |
+
* @var $lgtm
|
16 |
+
*/
|
17 |
+
public $lgtm;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Polylang model.
|
21 |
+
*
|
22 |
+
* @var $pllm
|
23 |
+
*/
|
24 |
public $pllm;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Lingotek preferences.
|
28 |
+
*
|
29 |
+
* @var $lingotek_prefs
|
30 |
+
*/
|
31 |
public $lingotek_prefs;
|
32 |
|
33 |
+
/**
|
34 |
* Constructor
|
35 |
*
|
36 |
* @since 0.1
|
37 |
*/
|
38 |
+
public function __construct( &$polylang ) {
|
39 |
+
parent::__construct( $polylang );
|
40 |
|
41 |
+
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
42 |
+
$this->pllm = &$GLOBALS['polylang']->model;
|
43 |
$this->lingotek_prefs = Lingotek_Model::get_prefs();
|
44 |
+
$pll_filter = new PLL_Admin_Filters_Post( $polylang );
|
45 |
|
46 |
// automatic upload
|
47 |
+
add_action( 'post_updated', array( &$this, 'post_updated' ), 10, 3 );
|
48 |
|
49 |
// trash sync
|
50 |
+
add_action( 'trashed_post', array( &$this, 'trash_post' ) );
|
51 |
+
add_action( 'untrashed_post', array( &$this, 'untrash_post' ) );
|
52 |
|
53 |
+
add_filter( 'manage_posts_columns', array( &$this, 'add_profile_column' ) );
|
54 |
+
add_action( 'manage_posts_custom_column', array( &$this, 'add_profile_column_data' ), 10, 3 );
|
55 |
|
56 |
+
add_filter( 'manage_pages_columns', array( &$this, 'add_profile_column' ) );
|
57 |
+
add_action( 'manage_pages_custom_column', array( &$this, 'add_profile_column_data' ), 10, 3 );
|
58 |
|
59 |
//apply language filter to preserve Polylang behavior of only showing documents of the current language
|
60 |
+
add_action( 'parse_query', array( $pll_filter, 'parse_query' ) );
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
* controls whether to display the language metabox or not
|
65 |
*
|
66 |
* @since 0.1
|
67 |
*/
|
68 |
+
public function add_meta_boxes( $post_type, $post = null ) {
|
69 |
global $post_ID;
|
70 |
+
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
71 |
+
$document = $this->lgtm->get_group( 'post', $post_ID );
|
72 |
+
if ( empty( $document->source ) ) {
|
73 |
+
parent::add_meta_boxes( $post_type, $document );
|
74 |
+
} else {
|
|
|
75 |
add_action( 'edit_form_top', array( &$this, 'edit_form_top' ) );
|
76 |
}
|
77 |
}
|
78 |
}
|
79 |
|
80 |
+
/**
|
81 |
* adds a column to display the post or page translation profile
|
82 |
*
|
83 |
* @since 1.1
|
84 |
*/
|
85 |
+
public function add_profile_column( $columns ) {
|
86 |
+
$n = array_search( 'date', array_keys( $columns ), true );
|
87 |
+
if ( $n ) {
|
88 |
+
$end = array_slice( $columns, $n );
|
89 |
+
$columns = array_slice( $columns, 0, $n );
|
90 |
}
|
91 |
|
92 |
$columns['profile'] = 'Profile';
|
93 |
+
return isset( $end ) ? array_merge( $columns, $end ) : $columns;
|
94 |
}
|
95 |
|
96 |
+
/**
|
97 |
* finds the translation profile for a post or page and if not set then displays the content type default profile
|
98 |
*
|
99 |
* @since 1.1
|
100 |
*/
|
101 |
+
public function add_profile_column_data( $column_name, $post_id ) {
|
102 |
+
if ( 'profile' === $column_name ) {
|
103 |
+
$document = $this->lgtm->get_group( 'post', $post_id );
|
104 |
+
if ( isset( $document->source ) ) {
|
105 |
$post_id = $document->source;
|
106 |
}
|
107 |
+
$profiles = Lingotek::get_profiles();
|
108 |
+
$content_profiles = get_option( 'lingotek_content_type' );
|
109 |
+
$post_profile = Lingotek_Post_Actions::get_post_profile( $post_id );
|
110 |
+
$post_language = PLL()->model->post->get_language( $post_id );
|
111 |
+
$post_type = 'post';
|
112 |
+
if ( isset( $_REQUEST['post_type'] ) ) {
|
113 |
+
$post_type = sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ) );
|
114 |
}
|
115 |
|
116 |
+
if ( $post_profile ) {
|
117 |
+
echo esc_html( $profiles[ $post_profile->description ]['name'] ) . sprintf( '<a title="%s">%s</a>', esc_attr__( 'Not set to the content default profile', 'lingotek-translation' ), '*' );
|
118 |
+
} elseif ( $post_language && isset( $content_profiles[ $post_type ]['sources'][ $post_language->slug ] ) ) {
|
119 |
+
$profile = $content_profiles[ $post_type ]['sources'][ $post_language->slug ];
|
120 |
+
echo esc_html( $profiles[ $profile ]['name'] );
|
121 |
+
} elseif ( ! empty( $content_profiles ) && ( ! isset( $content_profiles[ $post_type ] ) || ! isset( $profiles[ $content_profiles[ $post_type ]['profile'] ]['name'] ) ) ) {
|
122 |
+
echo esc_html__( 'Disabled', 'lingotek-translation' );
|
123 |
+
} elseif ( ! empty( $content_profiles ) ) {
|
124 |
+
echo esc_html( $profiles[ $content_profiles[ $post_type ]['profile'] ]['name'] );
|
125 |
+
} else {
|
126 |
+
esc_html_e( 'Manual', 'lingotek-translation' );
|
|
|
|
|
127 |
}
|
128 |
+
}//end if
|
|
|
|
|
|
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* Outputs hidden fields so that Polylang get correct information when its metabox is removed.
|
133 |
*
|
134 |
* @since 1.10
|
135 |
*/
|
136 |
public function edit_form_top() {
|
137 |
global $post_ID;
|
138 |
+
printf( '<input type="hidden" id="post_lang_choice" name="post_lang_choice" value="%s" />', esc_attr( pll_get_post_language( $post_ID ) ) );
|
139 |
+
wp_nonce_field( 'pll_language', '_pll_nonce' );
|
140 |
}
|
141 |
|
142 |
+
/**
|
143 |
+
* Uploads a post when saved for the first time
|
144 |
*
|
145 |
* @since 0.2
|
146 |
|
147 |
+
* @param int $post_id
|
148 |
* @param object $post
|
|
|
149 |
*/
|
150 |
+
public function save_post( $post_id, $post ) {
|
151 |
+
$document = $this->lgtm->get_group( 'post', $post_id );
|
152 |
+
if ( $document ) {
|
153 |
+
$language = PLL()->model->post->get_language( $post_id );
|
154 |
+
$document->pre_save_post( $post_id, 'post', $language );
|
|
|
155 |
}
|
156 |
+
if ( $this->can_save_post_data( $post_id, $post, true ) ) {
|
157 |
// updated post
|
158 |
+
if ( $document &&
|
159 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
160 |
+
$post_id == $document->source &&
|
161 |
+
$this->post_hash_has_changed( $post ) &&
|
162 |
+
$this->is_post_valid_for_upload_by_custom_terms( $post_id, false ) ) {
|
163 |
$document->source_edited();
|
164 |
+
if ( $document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status( $post->post_status ) ) {
|
165 |
+
$this->lgtm->upload_post( $post_id );
|
166 |
}
|
167 |
}
|
168 |
// Ensures languages are updated, even when no other element on the page has been changed.
|
169 |
+
if ( isset( $_POST['post_tr_lang'] ) ) {
|
170 |
+
PLL()->model->post->save_translations( $post_id, sanitize_text_field( wp_unslash( $_POST['post_tr_lang'] ) ) );
|
171 |
}
|
172 |
}
|
173 |
|
174 |
+
if ( ! $this->model->is_translated_post_type( $post->post_type ) ) {
|
175 |
return;
|
176 |
+
}
|
177 |
// new post
|
178 |
+
if ( ! isset( $_REQUEST['import'] ) ) {
|
179 |
+
parent::save_post( $post_id, $post );
|
180 |
+
if ( ! $document &&
|
181 |
+
! wp_is_post_revision( $post_id ) &&
|
182 |
+
'auto-draft' !== $post->post_status &&
|
183 |
+
'automatic' === Lingotek_Model::get_profile_option( 'upload', $post->post_type, PLL()->model->post->get_language( $post_id ), false, $post_id ) &&
|
184 |
+
Lingotek_Group_Post::is_valid_auto_upload_post_status( $post->post_status ) &&
|
185 |
+
! ( isset( $_POST['action'] ) && 'heartbeat' === $_POST['action'] ) &&
|
186 |
+
$this->lgtm->can_upload( 'post', $post_id ) &&
|
187 |
+
$this->is_post_valid_for_upload_by_custom_terms( $post_id, true ) ) {
|
188 |
+
$this->lgtm->upload_post( $post_id );
|
|
|
189 |
}
|
190 |
}
|
191 |
}
|
192 |
|
193 |
+
/**
|
194 |
* Allows the customer to interrupt the post upload by applying filter.
|
195 |
* By using This filter we are allowing users to implement custom logic on the post upload and check if it is valid
|
196 |
* for upload
|
197 |
*
|
198 |
* @since 1.3.1
|
199 |
+
*
|
200 |
* @author Soluto
|
201 |
*
|
202 |
+
* @param int $post_id
|
203 |
* @param bool $is_new_post
|
204 |
* @return bool
|
205 |
*/
|
206 |
+
protected function is_post_valid_for_upload_by_custom_terms( $post_id, $is_new_post ) {
|
207 |
$defaults = array();
|
208 |
+
$results = apply_filters( 'lingotek_is_post_valid_for_upload', $defaults, $post_id, $is_new_post );
|
209 |
+
return ! ( in_array( false, $results, true ) );
|
210 |
}
|
211 |
|
212 |
+
/**
|
213 |
* checks if we can act when saving a post
|
214 |
*
|
215 |
* @since 0.1
|
216 |
*
|
217 |
+
* @param int $post_id
|
218 |
* @param object $post
|
219 |
+
* @param bool $update Whether it is an update or not.
|
220 |
* @return bool
|
221 |
*/
|
222 |
+
protected function can_save_post_data( $post_id, $post, $update ) {
|
223 |
// does nothing except on post types which are filterable
|
224 |
// also don't act on revisions
|
225 |
+
if ( ! $this->model->is_translated_post_type( $post->post_type ) || wp_is_post_revision( $post_id ) ) {
|
226 |
return false;
|
227 |
+
}
|
228 |
|
229 |
// capability check
|
230 |
// as 'wp_insert_post' can be called from outside WP admin
|
231 |
+
$post_type_object = get_post_type_object( $post->post_type );
|
232 |
+
if ( ( $update && ! current_user_can( $post_type_object->cap->edit_post, $post_id ) ) || ( ! $update && ! current_user_can( $post_type_object->cap->create_posts ) ) ) {
|
233 |
return false;
|
234 |
+
}
|
235 |
|
236 |
return true;
|
237 |
}
|
238 |
|
239 |
+
/**
|
240 |
* marks the post as edited if needed
|
241 |
*
|
242 |
* @since 0.1
|
243 |
*
|
244 |
+
* @param int $post_id
|
245 |
* @param object $post_after
|
246 |
* @param object $post_before
|
247 |
*/
|
248 |
+
public function post_updated( $post_id, $post_after, $post_before ) {
|
249 |
}
|
250 |
|
251 |
+
/**
|
252 |
* get translations ids to sync for delete / trash / untrash
|
253 |
* since we can't sync all translations as we get conflicts when attempting to act two times on the same
|
254 |
*
|
257 |
* @param int $post_id
|
258 |
* @return array
|
259 |
*/
|
260 |
+
protected function get_translations_to_sync( $post_id ) {
|
261 |
// don't synchronize disassociated posts
|
262 |
+
$group = $this->lgtm->get_group( 'post', $post_id );
|
263 |
+
if ( empty( $group->source ) ) {
|
264 |
+
return array( $post_id );
|
265 |
+
}
|
266 |
|
267 |
+
if ( isset( $_REQUEST['media'] ) && is_array( $_REQUEST['media'] ) ) {
|
268 |
+
$post_ids = array_map( 'intval', $_REQUEST['media'] );
|
269 |
+
} elseif ( ! empty( $_REQUEST['post'] ) && is_array( $_REQUEST['post'] ) ) {
|
270 |
+
$post_ids = array_map( 'intval', $_REQUEST['post'] );
|
271 |
+
}
|
272 |
|
273 |
$post_ids[] = $post_id;
|
274 |
+
return array_diff( PLL()->model->post->get_translations( $post_id ), $post_ids );
|
275 |
}
|
276 |
|
277 |
+
/**
|
278 |
* sync trash
|
279 |
*
|
280 |
* @since 0.1
|
281 |
*
|
282 |
* @param int $post_id
|
283 |
*/
|
284 |
+
public function trash_post( $post_id ) {
|
285 |
+
if ( get_option( 'ignore_delete_pref', false ) ) {
|
286 |
return;
|
287 |
}
|
288 |
+
$group = $this->lgtm->get_group( 'post', $post_id );
|
289 |
|
290 |
+
if ( isset( $this->lingotek_prefs['trash_linked_content']['enabled'] ) ) {
|
291 |
+
foreach ( $this->get_translations_to_sync( $post_id ) as $tr_id ) {
|
292 |
+
wp_trash_post( $tr_id );
|
293 |
+
}
|
294 |
+
if ( isset( $group->source ) ) {
|
295 |
+
$group->cancel();
|
296 |
+
}
|
297 |
+
} else {
|
298 |
+
wp_trash_post( $post_id );
|
299 |
+
if ( isset( $group->source ) ) {
|
300 |
+
$this->lgtm->cancel_post( $post_id );
|
301 |
}
|
302 |
}
|
|
|
303 |
}
|
304 |
|
305 |
+
/**
|
306 |
* sync untrash
|
307 |
*
|
308 |
* @since 0.1
|
309 |
*
|
310 |
* @param int $post_id
|
311 |
*/
|
312 |
+
public function untrash_post( $post_id ) {
|
313 |
+
foreach ( $this->get_translations_to_sync( $post_id ) as $tr_id ) {
|
314 |
+
wp_untrash_post( $tr_id );
|
315 |
+
}
|
316 |
}
|
317 |
|
318 |
+
/**
|
319 |
* checks stored hash against current hash to report change
|
320 |
*
|
321 |
* @since 1.0
|
322 |
*
|
323 |
* @param wp_post $post_after
|
324 |
*/
|
325 |
+
protected function post_hash_has_changed( $post_after ) {
|
326 |
+
if ( 'trash' === $post_after->post_status ) {
|
327 |
return false;
|
328 |
}
|
329 |
$document_id = 'lingotek_hash_' . $post_after->ID;
|
330 |
+
$new_hash = md5( Lingotek_Group_Post::get_content( $post_after ) );
|
331 |
+
$old_term = $this->get_post_hash( $post_after->ID );
|
332 |
+
$old_hash = $old_term->description;
|
333 |
|
334 |
// new or updated page
|
335 |
+
if ( null === $old_hash || strcmp( $new_hash, $old_hash ) ) {
|
336 |
+
if ( empty( $old_term ) ) {
|
337 |
+
wp_insert_term( $document_id, 'lingotek_hash', array( 'description' => $new_hash ) );
|
338 |
}
|
339 |
+
wp_set_object_terms( $post_after->ID, $document_id, 'lingotek_hash' );
|
340 |
return true;
|
341 |
+
} else {
|
|
|
342 |
return false;
|
343 |
}
|
344 |
}
|
345 |
|
346 |
+
/**
|
347 |
+
* Returns a lingotek post hash if it exists.
|
348 |
*
|
349 |
* @since 1.0
|
350 |
*
|
351 |
* @param int $post_id
|
352 |
*/
|
353 |
+
protected function get_post_hash( $post_id ) {
|
354 |
+
if ( taxonomy_exists( 'lingotek_hash' ) ) {
|
355 |
+
$terms = wp_get_object_terms( $post_id, 'lingotek_hash' );
|
356 |
+
$term = array_pop( $terms );
|
357 |
return $term;
|
358 |
+
} else {
|
|
|
359 |
return null;
|
360 |
}
|
361 |
}
|
admin/filters-term.php
CHANGED
@@ -60,17 +60,16 @@ class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
|
|
60 |
* @param string $taxonomy taxonomy.
|
61 |
*/
|
62 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
63 |
-
$document = $this->lgtm->get_group('term', $term_id);
|
64 |
-
if ($document) {
|
65 |
-
$document->pre_save_terms($term_id, $taxonomy, PLL()->model->term->get_language( $term_id ));
|
66 |
}
|
67 |
|
68 |
-
|
69 |
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
70 |
return;
|
71 |
}
|
72 |
|
73 |
-
$import_get
|
74 |
$import_post = filter_input( INPUT_POST, 'import' );
|
75 |
if ( empty( $import ) && empty( $import_post ) ) {
|
76 |
parent::save_term( $term_id, $tt_id, $taxonomy );
|
@@ -135,8 +134,8 @@ class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
|
|
135 |
return array();
|
136 |
}
|
137 |
|
138 |
-
$delete_tags
|
139 |
-
$delete_tags_get
|
140 |
$delete_tags_post = filter_input( INPUT_POST, 'delete_tags' );
|
141 |
if ( ! empty( $delete_tags_get ) ) {
|
142 |
$delete_tags = filter_input( INPUT_GET, 'delete_tags' );
|
@@ -162,16 +161,17 @@ class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
|
|
162 |
public function delete_term( $term_id ) {
|
163 |
$taxonomy = substr( current_filter(), 7 );
|
164 |
foreach ( $this->get_translations_to_sync( $term_id ) as $tr_id ) {
|
165 |
-
|
|
|
166 |
}
|
167 |
$this->lgtm->delete_term( $term_id );
|
168 |
}
|
169 |
|
170 |
-
public function cancel_term($term_id){
|
171 |
-
$taxonomy = substr(current_filter(), 7);
|
172 |
-
foreach($this->get_translations_to_sync($term_id) as $tr_id) {
|
173 |
-
wp_delete_term($tr_id, $taxonomy);
|
174 |
}
|
175 |
-
$this->lgtm->cancel_term($term_id);
|
176 |
}
|
177 |
}
|
60 |
* @param string $taxonomy taxonomy.
|
61 |
*/
|
62 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
63 |
+
$document = $this->lgtm->get_group( 'term', $term_id );
|
64 |
+
if ( $document ) {
|
65 |
+
$document->pre_save_terms( $term_id, $taxonomy, PLL()->model->term->get_language( $term_id ) );
|
66 |
}
|
67 |
|
|
|
68 |
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
69 |
return;
|
70 |
}
|
71 |
|
72 |
+
$import_get = filter_input( INPUT_GET, 'import' );
|
73 |
$import_post = filter_input( INPUT_POST, 'import' );
|
74 |
if ( empty( $import ) && empty( $import_post ) ) {
|
75 |
parent::save_term( $term_id, $tt_id, $taxonomy );
|
134 |
return array();
|
135 |
}
|
136 |
|
137 |
+
$delete_tags = null;
|
138 |
+
$delete_tags_get = filter_input( INPUT_GET, 'delete_tags' );
|
139 |
$delete_tags_post = filter_input( INPUT_POST, 'delete_tags' );
|
140 |
if ( ! empty( $delete_tags_get ) ) {
|
141 |
$delete_tags = filter_input( INPUT_GET, 'delete_tags' );
|
161 |
public function delete_term( $term_id ) {
|
162 |
$taxonomy = substr( current_filter(), 7 );
|
163 |
foreach ( $this->get_translations_to_sync( $term_id ) as $tr_id ) {
|
164 |
+
// Forces deletion for the translations which are not already in the list.
|
165 |
+
wp_delete_term( $tr_id, $taxonomy );
|
166 |
}
|
167 |
$this->lgtm->delete_term( $term_id );
|
168 |
}
|
169 |
|
170 |
+
public function cancel_term( $term_id ) {
|
171 |
+
$taxonomy = substr( current_filter(), 7 );
|
172 |
+
foreach ( $this->get_translations_to_sync( $term_id ) as $tr_id ) {
|
173 |
+
wp_delete_term( $tr_id, $taxonomy );
|
174 |
}
|
175 |
+
$this->lgtm->cancel_term( $term_id );
|
176 |
}
|
177 |
}
|
admin/import.php
CHANGED
@@ -1,44 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="wrap">
|
2 |
-
|
3 |
-
|
4 |
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
43 |
|
44 |
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
+
|
8 |
+
// phpcs:disable
|
9 |
+
?>
|
10 |
<div class="wrap">
|
11 |
+
<h2><?php esc_html_e( 'Import', 'lingotek-translation' ); ?></h2>
|
12 |
+
<p class="description"><?php printf(__( 'Import your posts from another WordPress blog through Lingotek', 'lingotek-translation' ), 'admin.php?page=lingotek-translation_import' ); ?></p>
|
13 |
|
14 |
|
15 |
+
<?php
|
16 |
+
$menu_items = array(
|
17 |
+
'content' => __( 'Content', 'wp-lingotek' ),
|
18 |
+
'settings' => __( 'Settings', 'wp-lingotek' ),
|
19 |
+
);
|
20 |
+
?>
|
21 |
|
22 |
+
<h3 class="nav-tab-wrapper">
|
23 |
+
<?php
|
24 |
+
$menu_item_index = 0;
|
25 |
+
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
26 |
+
$use_as_default = ( $menu_item_index === 0 && ! isset( $_GET['sm'] ) ) ? true : false;
|
27 |
+
$alias = null;
|
28 |
+
// custom sub sub-menus
|
29 |
+
if ( isset( $_GET['sm'] ) && $_GET['sm'] == 'edit-profile' ) {
|
30 |
+
$alias = 'profiles';
|
31 |
+
}
|
32 |
+
?>
|
33 |
|
34 |
+
<a class="nav-tab
|
35 |
+
<?php
|
36 |
+
if ( $use_as_default || ( isset( $_GET['sm'] ) && $_GET['sm'] == $menu_item_key ) || $alias == $menu_item_key ) :
|
37 |
+
?>
|
38 |
+
nav-tab-active<?php endif; ?>"
|
39 |
+
href="admin.php?page=<?php echo esc_url( $_GET['page'] ); ?>&sm=<?php echo esc_url( $menu_item_key ); ?>"><?php echo $menu_item_label; ?></a>
|
40 |
+
<?php
|
41 |
+
$menu_item_index++;
|
42 |
+
}
|
43 |
+
?>
|
44 |
+
</h3>
|
45 |
|
46 |
+
<?php
|
47 |
+
settings_errors();
|
48 |
+
$submenu = isset( $_GET['sm'] ) ? $_GET['sm'] : 'content';
|
49 |
+
$dir = dirname( __FILE__ ) . '/import/';
|
50 |
+
$filename = $dir . 'view-' . $submenu . '.php';
|
51 |
+
if ( file_exists( $filename ) ) {
|
52 |
+
require $filename;
|
53 |
+
} else {
|
54 |
+
echo 'TO-DO: create <i>' . 'import/view-' . $submenu . '.php</i>';
|
55 |
+
}
|
56 |
+
?>
|
57 |
|
58 |
</div>
|
admin/import/FormatConverter.php
CHANGED
@@ -1,237 +1,261 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
3 |
require_once 'StandardImportObject.php';
|
4 |
|
5 |
/**
|
6 |
-
*This class exists to convert other content (e.g. JSON--Drupal 7, Drupal 8, Middleware--
|
7 |
-
*HTML, XML, Text, Plaintext) into content compatible with WP
|
8 |
-
*
|
9 |
-
*@author Unkown
|
10 |
-
*@uses StandardImportObject.php|StandardImportObject
|
11 |
-
*@return StandardImportObject returns an object that is in the format and has the
|
12 |
-
*content to be imported into WordPress
|
13 |
*
|
|
|
|
|
|
|
|
|
14 |
*/
|
15 |
-
class FormatConverter
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
$decoded_json = json_decode($content);
|
94 |
-
|
95 |
-
$content = __(
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
110 |
$content = $decoded_json->post->post_content;
|
111 |
}
|
112 |
-
|
|
|
113 |
$content = $decoded_json->body[0]->value;
|
114 |
-
}
|
115 |
-
else if (isset($decoded_json->args->description)){
|
116 |
$content = $decoded_json->args->description;
|
117 |
}
|
118 |
-
|
|
|
119 |
$content = $decoded_json->content->body;
|
120 |
}
|
121 |
-
|
|
|
122 |
$content = $decoded_json->body;
|
123 |
}
|
124 |
-
|
|
|
125 |
$content = $decoded_json->email_body;
|
126 |
}
|
127 |
-
|
|
|
128 |
$content = $decoded_json->post_summary;
|
129 |
}
|
130 |
-
|
|
|
131 |
$content = $decoded_json->description;
|
|
|
|
|
132 |
}
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
if (isset($decoded_json->title[0]->value)){ // Drupal 8
|
145 |
$title = $decoded_json->title[0]->value;
|
146 |
}
|
147 |
-
|
|
|
148 |
$title = $decoded_json->post->post_title;
|
149 |
}
|
150 |
-
|
|
|
151 |
$title = $decoded_json->content->title;
|
152 |
}
|
153 |
-
|
|
|
154 |
$title = $decoded_json->title;
|
155 |
}
|
156 |
-
|
|
|
157 |
$title = $decoded_json->name;
|
158 |
-
}
|
159 |
-
else {
|
160 |
$error = true;
|
161 |
}
|
162 |
|
163 |
-
return new StandardImportObject($title, $content, $error);
|
164 |
}
|
165 |
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
182 |
echo $error_message_xml;
|
183 |
$error = true;
|
184 |
}
|
185 |
|
186 |
-
$found_content = (array) $xml->xpath('//element');
|
187 |
-
if ($found_content){
|
188 |
$content = (string) $found_content[0];
|
189 |
-
$title
|
190 |
-
}
|
191 |
-
else {
|
192 |
$error = true;
|
193 |
}
|
194 |
|
195 |
-
return new StandardImportObject($title, $content, $error);
|
196 |
}
|
197 |
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
207 |
$title = $source_doc->properties->title;
|
208 |
-
return new StandardImportObject($title, $content);
|
209 |
}
|
210 |
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
|
|
220 |
$title = $source_doc->properties->title;
|
221 |
-
return new StandardImportObject($title, $content);
|
222 |
}
|
223 |
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
233 |
$title = $source_doc->properties->title;
|
234 |
-
return new StandardImportObject($title, $content);
|
235 |
}
|
236 |
}
|
237 |
-
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
|
8 |
+
// phpcs:disable
|
9 |
require_once 'StandardImportObject.php';
|
10 |
|
11 |
/**
|
12 |
+
* This class exists to convert other content (e.g. JSON--Drupal 7, Drupal 8, Middleware--
|
13 |
+
* HTML, XML, Text, Plaintext) into content compatible with WP
|
|
|
|
|
|
|
|
|
|
|
14 |
*
|
15 |
+
* @author Unkown
|
16 |
+
* @uses StandardImportObject.php|StandardImportObject
|
17 |
+
* @return StandardImportObject returns an object that is in the format and has the
|
18 |
+
* content to be imported into WordPress
|
19 |
*/
|
20 |
+
class FormatConverter {
|
21 |
+
/**
|
22 |
+
* The document that is used to determine information about the import. It is
|
23 |
+
* the source document that can be accessed.
|
24 |
+
*/
|
25 |
+
private $source_doc;
|
26 |
+
/**
|
27 |
+
* The content is the bulk of the information without format, source, etc. This
|
28 |
+
* is what is converted into the title and body of the wp import.
|
29 |
+
*/
|
30 |
+
private $content;
|
31 |
+
/**
|
32 |
+
* The format is the format of the source upload document so that it can be handled
|
33 |
+
* by the right conversion function (e.g. JSON, HTML, TXT, etc.)
|
34 |
+
*/
|
35 |
+
private $format;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Constructor
|
39 |
+
* Sets up the FormatConverter object so it can be converted
|
40 |
+
*
|
41 |
+
* @author Unkown
|
42 |
+
*
|
43 |
+
* @param object $source_doc The document that needs to be converted and then imported
|
44 |
+
* @param string $content The content portion of the document -- This is what becomes
|
45 |
+
* the body of the WP post/page
|
46 |
+
* @param string $format The format of the file. The extension of the document
|
47 |
+
* is used to choose the right function to convert to standard
|
48 |
+
* @return void This builds an object that is then converted to wp import
|
49 |
+
*/
|
50 |
+
function __construct( $source_doc, $content, $format ) {
|
51 |
+
$this->source_doc = $source_doc;
|
52 |
+
$this->content = $content;
|
53 |
+
$this->format = $format;
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* This function determines which converter function is needed. If there is not
|
59 |
+
* a converter function for the selected document then it defaults to
|
60 |
+
* JSON (in the else statement) and attempts the conversion with the assumption
|
61 |
+
* of working with a JSON file.
|
62 |
+
*
|
63 |
+
* @author Unkown
|
64 |
+
* @return StandardImportObject $importObject An object that can be imported into WP
|
65 |
+
*/
|
66 |
+
public function convert_to_standard() {
|
67 |
+
if ( method_exists( $this, $this->format . '_to_standard' ) ) {
|
68 |
+
$importObject = call_user_func( array( $this, $this->format . '_to_standard' ), $this->source_doc, $this->content );
|
69 |
+
return $importObject;
|
70 |
+
} else {
|
71 |
+
$importObject = call_user_func( array( $this, 'json_to_standard' ), $this->source_doc, $this->content );
|
72 |
+
return $importObject;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Converts source JSON into a StandardImportObject that can be imported into WP
|
79 |
+
*
|
80 |
+
* @author Unkown
|
81 |
+
* @param object $source_doc source document
|
82 |
+
* @param string $content JSON string that is then parsed to get the relevant
|
83 |
+
* information for the title and body
|
84 |
+
* @return StandardImportObject That can be imported into WP
|
85 |
+
*/
|
86 |
+
public function json_to_standard( $source_doc, $content ) {
|
87 |
+
|
88 |
+
/**
|
89 |
+
*These string replaces are to make it so that we can access the json objects
|
90 |
+
*with these titles. They were being imported with @ before the key and that
|
91 |
+
*made them inaccessible. This is specific to Middleware json strings.
|
92 |
+
*
|
93 |
+
*@author Matt Smith and TJ Murphy
|
94 |
+
*/
|
95 |
+
$content = str_replace( '"@title"', '"title"', $content );
|
96 |
+
$content = str_replace( '"@type"', '"type"', $content );
|
97 |
+
|
98 |
+
$decoded_json = json_decode( $content );
|
99 |
+
|
100 |
+
$content = __(
|
101 |
+
'We could not parse the data from this document.
|
102 |
+
Are you sure that it is in a recognizable format, such as JSON, XML, HTML, or plain text?',
|
103 |
+
'wp-lingotek'
|
104 |
+
);
|
105 |
+
$title = __( 'No title found', 'wp-lingotek' );
|
106 |
+
$error = false;
|
107 |
+
|
108 |
+
/**
|
109 |
+
*An if statement to check for the different json patterns to find the content
|
110 |
+
*that will be the body of the WP imported post/page
|
111 |
+
*
|
112 |
+
*@author Unkown and TJ Murphy
|
113 |
+
*@return string $content is set -- if nothing matches then $content remains
|
114 |
+
*with a warning
|
115 |
+
*@see $content
|
116 |
+
*/
|
117 |
+
// Drupal 7
|
118 |
+
if ( isset( $decoded_json->post->post_content ) ) {
|
119 |
$content = $decoded_json->post->post_content;
|
120 |
}
|
121 |
+
// Drupal 8
|
122 |
+
elseif ( isset( $decoded_json->body[0]->value ) ) {
|
123 |
$content = $decoded_json->body[0]->value;
|
124 |
+
} elseif ( isset( $decoded_json->args->description ) ) {
|
|
|
125 |
$content = $decoded_json->args->description;
|
126 |
}
|
127 |
+
// Middleware - MindTouch
|
128 |
+
elseif ( isset( $decoded_json->content->body ) ) {
|
129 |
$content = $decoded_json->content->body;
|
130 |
}
|
131 |
+
// Middleware - Zendesk and HubSpot
|
132 |
+
elseif ( isset( $decoded_json->body ) ) {
|
133 |
$content = $decoded_json->body;
|
134 |
}
|
135 |
+
// Middleware - Email HubSpot
|
136 |
+
elseif ( isset( $decoded_json->email_body ) ) {
|
137 |
$content = $decoded_json->email_body;
|
138 |
}
|
139 |
+
// Middleware
|
140 |
+
elseif ( isset( $decoded_json->post_summary ) ) {
|
141 |
$content = $decoded_json->post_summary;
|
142 |
}
|
143 |
+
// Middleware
|
144 |
+
elseif ( isset( $decoded_json->description ) ) {
|
145 |
$content = $decoded_json->description;
|
146 |
+
} else {
|
147 |
+
$error = true;
|
148 |
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
*An if statement to check for the different json patterns to find the title
|
152 |
+
*that will be the title of the WP imported post/page
|
153 |
+
*
|
154 |
+
*@author Unkown and TJ Murphy
|
155 |
+
*@return string $title is set -- if nothing matches then $error is set to TRUE
|
156 |
+
*@see $title
|
157 |
+
*/
|
158 |
+
// Drupal 8
|
159 |
+
if ( isset( $decoded_json->title[0]->value ) ) {
|
|
|
160 |
$title = $decoded_json->title[0]->value;
|
161 |
}
|
162 |
+
// Drupal 7
|
163 |
+
elseif ( isset( $decoded_json->post->post_title ) ) {
|
164 |
$title = $decoded_json->post->post_title;
|
165 |
}
|
166 |
+
// Middleware - MindTouch
|
167 |
+
elseif ( isset( $decoded_json->content->title ) ) {
|
168 |
$title = $decoded_json->content->title;
|
169 |
}
|
170 |
+
// Middleware - Zendesk and HubSpot
|
171 |
+
elseif ( isset( $decoded_json->title ) ) {
|
172 |
$title = $decoded_json->title;
|
173 |
}
|
174 |
+
// Middleware - Email HubSpot
|
175 |
+
elseif ( isset( $decoded_json->name ) ) {
|
176 |
$title = $decoded_json->name;
|
177 |
+
} else {
|
|
|
178 |
$error = true;
|
179 |
}
|
180 |
|
181 |
+
return new StandardImportObject( $title, $content, $error );
|
182 |
}
|
183 |
|
184 |
+
/**
|
185 |
+
* Converts source XML into a StandardImportObject that can be imported into WP
|
186 |
+
*
|
187 |
+
* @author Unkown
|
188 |
+
* @param object $source_doc source document
|
189 |
+
* @param string $xml_string XML string that is then parsed to get the relevant
|
190 |
+
* information for the title and body
|
191 |
+
* @return StandardImportObject That can be imported into WP
|
192 |
+
*/
|
193 |
+
public function xml_to_standard( $source_doc, $xml_string ) {
|
194 |
+
$content = __(
|
195 |
+
'We could not parse the data from this document.
|
196 |
+
Are you sure that it is in a recognizable format, such as JSON, XML, HTML, or plain text?',
|
197 |
+
'wp-lingotek'
|
198 |
+
);
|
199 |
+
$title = __( 'No title found', 'wp-lingotek' );
|
200 |
+
$error_message_xml = __( 'Failed to load XML', 'wp-lingotek' );
|
201 |
+
$error = false;
|
202 |
+
$xml = new SimpleXMLElement( $xml_string );
|
203 |
+
if ( $xml === false ) {
|
204 |
echo $error_message_xml;
|
205 |
$error = true;
|
206 |
}
|
207 |
|
208 |
+
$found_content = (array) $xml->xpath( '//element' );
|
209 |
+
if ( $found_content ) {
|
210 |
$content = (string) $found_content[0];
|
211 |
+
$title = (string) $source_doc->properties->title;
|
212 |
+
} else {
|
|
|
213 |
$error = true;
|
214 |
}
|
215 |
|
216 |
+
return new StandardImportObject( $title, $content, $error );
|
217 |
}
|
218 |
|
219 |
+
/**
|
220 |
+
* Converts source TXT into a StandardImportObject that can be imported into WP
|
221 |
+
*
|
222 |
+
* @author Unkown
|
223 |
+
* @param object $source_doc source document
|
224 |
+
* @param string $content TXT string that is then parsed to get the relevant
|
225 |
+
* information for the title and body
|
226 |
+
* @return StandardImportObject That can be imported into WP
|
227 |
+
*/
|
228 |
+
public function txt_to_standard( $source_doc, $content ) {
|
229 |
$title = $source_doc->properties->title;
|
230 |
+
return new StandardImportObject( $title, $content );
|
231 |
}
|
232 |
|
233 |
+
/**
|
234 |
+
* Converts source PLAINTEXT into a StandardImportObject that can be imported into WP
|
235 |
+
*
|
236 |
+
* @author Unkown
|
237 |
+
* @param object $source_doc source document
|
238 |
+
* @param string $content PLAINTEXT string that is then parsed to get the relevant
|
239 |
+
* information for the title and body
|
240 |
+
* @return StandardImportObject That can be imported into WP
|
241 |
+
*/
|
242 |
+
public function plaintext_to_standard( $source_doc, $content ) {
|
243 |
$title = $source_doc->properties->title;
|
244 |
+
return new StandardImportObject( $title, $content );
|
245 |
}
|
246 |
|
247 |
+
/**
|
248 |
+
* Converts source HTML into a StandardImportObject that can be imported into WP
|
249 |
+
*
|
250 |
+
* @author Unkown
|
251 |
+
* @param object $source_doc source document
|
252 |
+
* @param string $content HTML string that is then parsed to get the relevant
|
253 |
+
* information for the title and body
|
254 |
+
* @return StandardImportObject That can be imported into WP
|
255 |
+
*/
|
256 |
+
public function html_to_standard( $source_doc, $content ) {
|
257 |
$title = $source_doc->properties->title;
|
258 |
+
return new StandardImportObject( $title, $content );
|
259 |
}
|
260 |
}
|
261 |
+
|
admin/import/StandardImportObject.php
CHANGED
@@ -1,95 +1,104 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
3 |
/**
|
4 |
* Used to hold all important information about a post or page to be imported
|
5 |
-
|
|
|
6 |
*/
|
7 |
-
class StandardImportObject
|
8 |
-
{
|
9 |
-
private $title;
|
10 |
-
private $content;
|
11 |
-
private $error;
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
*@param string $title This is what will become the title of the post/page
|
17 |
-
*when the document is imported into WP
|
18 |
-
*@param string $content This is what will become the body of the post/page
|
19 |
-
*when the document is imported into WP
|
20 |
-
*@param bool $error captures if there was an error in preparing the document
|
21 |
-
*@return void just sets the variables
|
22 |
-
*/
|
23 |
-
function __construct($title, $content, $error = false)
|
24 |
-
{
|
25 |
-
$this->title = $title;
|
26 |
-
$this->content = $content;
|
27 |
-
$this->error = $error;
|
28 |
-
}
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
return $this;
|
50 |
-
}
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
return $this;
|
72 |
-
}
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
}
|
95 |
-
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
|
8 |
+
// phpcs:disable
|
9 |
/**
|
10 |
* Used to hold all important information about a post or page to be imported
|
11 |
+
*
|
12 |
+
* @author Unknown
|
13 |
*/
|
14 |
+
class StandardImportObject {
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
private $title;
|
17 |
+
private $content;
|
18 |
+
private $error;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
+
/**
|
21 |
+
* Constructor
|
22 |
+
*
|
23 |
+
* @author Unknown
|
24 |
+
* @param string $title This is what will become the title of the post/page
|
25 |
+
* when the document is imported into WP
|
26 |
+
* @param string $content This is what will become the body of the post/page
|
27 |
+
* when the document is imported into WP
|
28 |
+
* @param bool $error captures if there was an error in preparing the document
|
29 |
+
* @return void just sets the variables
|
30 |
+
*/
|
31 |
+
function __construct( $title, $content, $error = false ) {
|
32 |
+
$this->title = $title;
|
33 |
+
$this->content = $content;
|
34 |
+
$this->error = $error;
|
35 |
+
}
|
36 |
|
37 |
+
/**
|
38 |
+
* Gets the title of the object
|
39 |
+
*
|
40 |
+
* @author Unknown
|
41 |
+
* @return string $this->title
|
42 |
+
*/
|
43 |
+
public function getTitle() {
|
44 |
+
return $this->title;
|
45 |
+
}
|
|
|
|
|
46 |
|
47 |
+
/**
|
48 |
+
* Sets the title of the object
|
49 |
+
*
|
50 |
+
* @author Unknown
|
51 |
+
* @param string $title What the title of the import should be
|
52 |
+
* @return self
|
53 |
+
*/
|
54 |
+
public function setTitle( $title ) {
|
55 |
+
$this->title = $title;
|
56 |
+
return $this;
|
57 |
+
}
|
58 |
|
59 |
+
/**
|
60 |
+
* Gets the Content of the object
|
61 |
+
*
|
62 |
+
* @author Unknown
|
63 |
+
* @return string $this->content
|
64 |
+
*/
|
65 |
+
public function getContent() {
|
66 |
+
return $this->content;
|
67 |
+
}
|
|
|
|
|
68 |
|
69 |
+
/**
|
70 |
+
* Sets the content of the object
|
71 |
+
*
|
72 |
+
* @author Unknown
|
73 |
+
* @param string $content What the body of the import should be
|
74 |
+
* @return self
|
75 |
+
*/
|
76 |
+
public function setContent( $content ) {
|
77 |
+
$this->content = $content;
|
78 |
+
return $this;
|
79 |
+
}
|
80 |
|
81 |
+
/**
|
82 |
+
* Sets the error for the object
|
83 |
+
*
|
84 |
+
* @author Unknown
|
85 |
+
* @param bool $trueOrFalse TRUE means there was an error, FALSE means there
|
86 |
+
* was not.
|
87 |
+
* @return void
|
88 |
+
*/
|
89 |
+
public function setError( $trueOrFalse ) {
|
90 |
+
$this->error = $trueOrFalse;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Checks to see if the object has an error.
|
95 |
+
*
|
96 |
+
* @author Unknown
|
97 |
+
* @return bool $this->error
|
98 |
+
*/
|
99 |
+
public function hasError() {
|
100 |
+
return $this->error;
|
101 |
+
}
|
102 |
|
103 |
}
|
104 |
+
|
admin/import/import-table.php
CHANGED
@@ -1,523 +1,576 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
}
|
6 |
|
7 |
/**
|
8 |
*Requires and evaluates the FormatConverter.php before continuing. If it is not
|
9 |
*found then a fatal error is thrown
|
|
|
10 |
*@author Unkown
|
11 |
*@link http://php.net/manual/en/function.include.php
|
12 |
*@see FormatConverter.php
|
13 |
-
*
|
14 |
*/
|
15 |
require_once 'FormatConverter.php';
|
16 |
settings_errors();
|
17 |
|
18 |
/**
|
19 |
-
|
20 |
-
*to manipulate their documents
|
21 |
-
|
22 |
-
|
23 |
-
*
|
24 |
-
|
|
|
25 |
//$client = new Lingotek_API();
|
26 |
//$docs = $client->get_documents(array('limit'=>5000));
|
27 |
//$communities = $client->get_communities();
|
28 |
|
29 |
|
30 |
/**
|
31 |
-
*This class is used to prepare the import table that is displayed when users go
|
32 |
-
*to the import tab.
|
33 |
-
|
34 |
-
*
|
35 |
-
*/
|
36 |
class Lingotek_Import_Table extends WP_List_Table {
|
37 |
|
38 |
-
var $client
|
39 |
-
var $doc_data
|
40 |
-
var $projects
|
41 |
-
var $import_status
|
42 |
-
var $supported_extentions = array('json', 'xml');
|
43 |
-
var $document_count
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
67 |
function __construct() {
|
68 |
$this->client = new Lingotek_API();
|
69 |
|
70 |
-
$this->projects
|
71 |
$this->document_count = $this->client->get_document_count();
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
|
|
95 |
|
96 |
global $status, $page;
|
97 |
-
parent::__construct(
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
$unsuccessful_imports_string = $unsuccessful_imports_string.'</ul></div>';
|
146 |
-
return $unsuccessful_imports_string;
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
*Calls the API to get all the projects from the TMS and show them for the end-user
|
151 |
-
*@author Unkown
|
152 |
-
*@uses wp-lingotek/include/api.php/Lingotek_API::get_projects()
|
153 |
-
*@param $communitites
|
154 |
-
*@return array $new_projects an array of projects with key/value of (project id, project title)
|
155 |
-
*/
|
156 |
-
function get_projects($communities){
|
157 |
$new_projects = array();
|
158 |
-
foreach ($communities->entities as $community){
|
159 |
-
$projects = $this->client->get_projects($community->properties->id)->entities;
|
160 |
-
foreach ($projects as $project){
|
161 |
-
$new_projects[$project->properties->id] = $project->properties->title;
|
162 |
}
|
163 |
}
|
164 |
|
165 |
return $new_projects;
|
166 |
}
|
167 |
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
$
|
181 |
-
$
|
|
|
182 |
$projectInfoArray = $resources['projects'];
|
183 |
|
184 |
-
foreach ($docs as $doc) {
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
189 |
$unix_upload_time = $doc->properties->upload_date / 1000;
|
190 |
-
$upload_date_str
|
191 |
|
192 |
$project_name = $doc->properties->project_id;
|
193 |
-
if (array_key_exists($doc->properties->project_id, $this->projects)){
|
194 |
-
$project_name = $this->projects[$doc->properties->project_id];
|
195 |
}
|
196 |
|
197 |
-
$doc_properties = array(
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
$count++;
|
202 |
-
}
|
203 |
return $result;
|
204 |
}
|
205 |
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
$limit = $per_page;
|
219 |
-
$docs
|
|
|
|
|
|
|
|
|
|
|
220 |
return $docs;
|
221 |
}
|
222 |
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
|
|
228 |
function get_columns() {
|
229 |
$columns = array(
|
230 |
-
'cb'
|
231 |
-
'title'
|
232 |
-
'extension'=>
|
233 |
-
'locale'
|
234 |
-
'upload_date'
|
235 |
-
'project_name' =>
|
236 |
-
'id'
|
237 |
);
|
238 |
return $columns;
|
239 |
}
|
240 |
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
|
|
254 |
function prepare_items() {
|
255 |
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
|
|
261 |
|
262 |
$columns = $this->get_columns();
|
263 |
$this->process_actions();
|
264 |
$hidden = array();
|
265 |
|
266 |
-
$sortable
|
267 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
|
|
|
|
|
|
|
|
289 |
}
|
290 |
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
|
|
301 |
case 'title':
|
302 |
case 'extension':
|
303 |
case 'locale':
|
304 |
case 'upload_date':
|
305 |
case 'project_name':
|
306 |
case 'id':
|
307 |
-
return $item[$column_name];
|
308 |
default:
|
309 |
-
return print_r($item, true);
|
310 |
}
|
311 |
}
|
312 |
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
|
|
318 |
function get_sortable_columns() {
|
319 |
$sortable_columns = array(
|
320 |
-
'title'
|
321 |
-
'extension'=>array('extension', false),
|
322 |
-
'locale'
|
323 |
-
'upload_date'
|
324 |
-
'project_name' => array('project_name', false),
|
325 |
-
'id'
|
326 |
);
|
327 |
return $sortable_columns;
|
328 |
}
|
329 |
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
$
|
343 |
-
$
|
344 |
-
|
345 |
-
|
346 |
-
$
|
|
|
347 |
$result = $date_a - $date_b;
|
348 |
-
}
|
349 |
-
|
350 |
-
$result = strcmp($a[$orderby], $b[$orderby]);
|
351 |
}
|
352 |
|
353 |
return ( $order === 'asc' ) ? $result : -$result;
|
354 |
}
|
355 |
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
|
|
364 |
$actions = array(
|
365 |
-
'import' => sprintf(
|
366 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
);
|
368 |
-
return sprintf('%1$s %2$s', $item['title'], $this->row_actions($actions));
|
369 |
}
|
370 |
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
|
|
376 |
function get_bulk_actions() {
|
377 |
$actions = array(
|
378 |
-
'import' => 'Import'
|
379 |
);
|
380 |
return $actions;
|
381 |
}
|
382 |
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
|
|
395 |
public function process_actions() {
|
396 |
$result = null;
|
397 |
-
if( 'import' === $this->current_action() ) {
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
}
|
408 |
-
}
|
409 |
-
|
410 |
-
if (isset($_GET['action']) && $_GET['action'] == 'import'){
|
411 |
$doc_id = $_GET['post'];
|
412 |
-
$result = $this->import($doc_id);
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
}
|
419 |
}
|
420 |
-
}
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
|
|
432 |
$this->import_status = 'success';
|
433 |
-
}
|
434 |
-
else {
|
435 |
$this->import_status = 'failure';
|
436 |
}
|
437 |
-
}
|
438 |
}
|
439 |
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
456 |
return 0;
|
457 |
}
|
458 |
|
459 |
-
$post_status = get_option('lingotek_import_prefs')['import_post_status'];
|
460 |
-
$post_type
|
461 |
-
if (!isset($post_status) ){
|
462 |
$post_status = 'draft';
|
463 |
}
|
464 |
-
if (!isset($post_type) ){
|
465 |
$post_type = 'post';
|
466 |
}
|
467 |
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
|
|
|
|
478 |
$result = wp_insert_post( $post_to_import );
|
479 |
return $result;
|
480 |
-
|
481 |
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
$source_doc = $this->client->get_document($doc_id);
|
493 |
-
|
494 |
-
$content
|
495 |
-
if ($content == null){
|
496 |
-
$content == __('There is no content to display', 'wp-lingotek');
|
497 |
}
|
498 |
|
499 |
-
$format
|
500 |
-
$formatConverter = new FormatConverter($source_doc, $content, $format);
|
501 |
-
$importObject
|
502 |
-
$response
|
503 |
return $response;
|
504 |
}
|
505 |
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
|
|
513 |
}
|
514 |
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
|
|
521 |
return $this->import_status;
|
522 |
}
|
523 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
+
|
8 |
+
// phpcs:disable
|
9 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
10 |
+
// since WP 3.1
|
11 |
+
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
*Requires and evaluates the FormatConverter.php before continuing. If it is not
|
16 |
*found then a fatal error is thrown
|
17 |
+
*
|
18 |
*@author Unkown
|
19 |
*@link http://php.net/manual/en/function.include.php
|
20 |
*@see FormatConverter.php
|
|
|
21 |
*/
|
22 |
require_once 'FormatConverter.php';
|
23 |
settings_errors();
|
24 |
|
25 |
/**
|
26 |
+
* $client is an API call for the client logged in. This gives the end-user the ability
|
27 |
+
* to manipulate their documents
|
28 |
+
*
|
29 |
+
* @uses wp-lingotek/include/api.php/Lingotek_API
|
30 |
+
* @deprecated since 24 May 2016 This was making an extra API call and making load
|
31 |
+
* time very slow.
|
32 |
+
*/
|
33 |
//$client = new Lingotek_API();
|
34 |
//$docs = $client->get_documents(array('limit'=>5000));
|
35 |
//$communities = $client->get_communities();
|
36 |
|
37 |
|
38 |
/**
|
39 |
+
* This class is used to prepare the import table that is displayed when users go
|
40 |
+
* to the import tab.
|
41 |
+
*
|
42 |
+
* @author Unkown
|
43 |
+
*/
|
44 |
class Lingotek_Import_Table extends WP_List_Table {
|
45 |
|
46 |
+
var $client = null;
|
47 |
+
var $doc_data = array();
|
48 |
+
var $projects = array();
|
49 |
+
var $import_status = null;
|
50 |
+
var $supported_extentions = array( 'json', 'xml' );
|
51 |
+
var $document_count = 0;
|
52 |
+
/**
|
53 |
+
* Used to mark the number of successful imports on a bulk import
|
54 |
+
*
|
55 |
+
* @author TJ Murphy
|
56 |
+
*/
|
57 |
+
var $import_success_count = 0;
|
58 |
+
/**
|
59 |
+
* Used to mark the number of failed imports on a bulk import
|
60 |
+
*
|
61 |
+
* @author TJ Murphy
|
62 |
+
*/
|
63 |
+
var $import_failure_count = 0;
|
64 |
+
/**
|
65 |
+
* Used to gather the doc ids for documents that did not import as expected
|
66 |
+
*
|
67 |
+
* @author TJ Murphy
|
68 |
+
*/
|
69 |
+
var $unsuccessful_imports = array();
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Constructor
|
73 |
+
*
|
74 |
+
* @author Unkown and TJ Murphy
|
75 |
+
* @uses wp-lingotek/include/api.php/Lingotek_API
|
76 |
+
* @see Lingotek_Import_Table::get_docs()
|
77 |
+
* @see Lingotek_Import_Table::format_docs()
|
78 |
+
*/
|
79 |
function __construct() {
|
80 |
$this->client = new Lingotek_API();
|
81 |
|
82 |
+
$this->projects = $this->get_projects( $this->client->get_communities() );
|
83 |
$this->document_count = $this->client->get_document_count();
|
84 |
+
/**
|
85 |
+
*Sets $import_success_count to ZERO
|
86 |
+
*
|
87 |
+
*@author TJ Murphy
|
88 |
+
*/
|
89 |
+
$this->import_success_count = 0;
|
90 |
+
/**
|
91 |
+
*Sets $import_failure_count to ZERO
|
92 |
+
*
|
93 |
+
*@author TJ Murphy
|
94 |
+
*/
|
95 |
+
$this->import_failure_count = 0;
|
96 |
+
/**
|
97 |
+
*Sets $unsuccessful_imports to a blank array
|
98 |
+
*
|
99 |
+
*@author TJ Murphy
|
100 |
+
*/
|
101 |
+
$this->unsuccessful_imports = array();
|
102 |
+
/**
|
103 |
+
*This will get ALL docs for the client
|
104 |
+
*
|
105 |
+
*@author TJ Murphy
|
106 |
+
*@see Lingotek_Import_Table::get_docs()
|
107 |
+
*@see Lingotek_Import_Table::format_docs()
|
108 |
+
*/
|
109 |
+
$docs = $this->get_docs( $this->client, $this->document_count );
|
110 |
+
$this->doc_data = $this->format_docs( $docs );
|
111 |
|
112 |
global $status, $page;
|
113 |
+
parent::__construct(
|
114 |
+
array(
|
115 |
+
'singular' => 'post',
|
116 |
+
'plural' => 'posts',
|
117 |
+
'ajax' => false,
|
118 |
+
)
|
119 |
+
);
|
120 |
+
}
|
121 |
+
/**
|
122 |
+
* This function is to access the count of successful imports. It is used for both
|
123 |
+
* bulk and single imports. This is used for a few checks and a few messages that
|
124 |
+
* get displayed to the end-user after imports occur
|
125 |
+
*
|
126 |
+
* @author TJ Murphy
|
127 |
+
* @uses Lingotek_Import_Table::$import_success_count
|
128 |
+
* @return void
|
129 |
+
*/
|
130 |
+
function add_one_import_success_count() {
|
131 |
+
$this->import_success_count++;
|
132 |
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* This function is to add the doc ids of the failed imports to an array so that
|
136 |
+
* they can be displayed to the end-user. This just gives them more information
|
137 |
+
* about the errors they may encounter. It also handles the counts for failed imports.
|
138 |
+
*
|
139 |
+
* @author TJ Murphy
|
140 |
+
* @param string $doc_id
|
141 |
+
* @return void
|
142 |
+
*/
|
143 |
+
function add_doc_id_to_unsuccessful_imports( $doc_id ) {
|
144 |
+
array_push( $this->unsuccessful_imports, $doc_id );
|
145 |
+
$this->import_failure_count++;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* This function is to list the captured doc ids in a string separated by commas
|
150 |
+
* so it can be displayed for the end-user in a message.
|
151 |
+
*
|
152 |
+
* @author TJ Murphy
|
153 |
+
* @uses Lingotek_Import_Table::$unsuccessful_imports
|
154 |
+
* @return string $unsuccessful_imports_string this creates an HTML string that
|
155 |
+
* creates an unordered list of doc ids that failed to import
|
156 |
+
*/
|
157 |
+
function to_string_unsuccessful_imports() {
|
158 |
+
$unsuccessful_imports_string = '<div><ul>';
|
159 |
+
foreach ( $this->unsuccessful_imports as $doc_id ) {
|
160 |
+
$unsuccessful_imports_string = $unsuccessful_imports_string . '<li>' . (string) $doc_id . '</li>';
|
161 |
+
}
|
162 |
+
$unsuccessful_imports_string = $unsuccessful_imports_string . '</ul></div>';
|
163 |
+
return $unsuccessful_imports_string;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Calls the API to get all the projects from the TMS and show them for the end-user
|
168 |
+
*
|
169 |
+
* @author Unkown
|
170 |
+
* @uses wp-lingotek/include/api.php/Lingotek_API::get_projects()
|
171 |
+
* @param $communitites
|
172 |
+
* @return array $new_projects an array of projects with key/value of (project id, project title)
|
173 |
+
*/
|
174 |
+
function get_projects( $communities ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
$new_projects = array();
|
176 |
+
foreach ( $communities->entities as $community ) {
|
177 |
+
$projects = $this->client->get_projects( $community->properties->id )->entities;
|
178 |
+
foreach ( $projects as $project ) {
|
179 |
+
$new_projects[ $project->properties->id ] = $project->properties->title;
|
180 |
}
|
181 |
}
|
182 |
|
183 |
return $new_projects;
|
184 |
}
|
185 |
|
186 |
+
/**
|
187 |
+
* Get a list of projects or use id to get the corresponding project
|
188 |
+
* extract doc data and insert into correct structure for rendering
|
189 |
+
*
|
190 |
+
* @author Unkown
|
191 |
+
* @uses Lingotek_Import_Table::get_option()
|
192 |
+
* @param object $docs list of files that need to be properly formatted to show
|
193 |
+
* in the table
|
194 |
+
* @return array $result an array of properly formatted objects to be put into
|
195 |
+
* the table
|
196 |
+
*/
|
197 |
+
function format_docs( $docs ) {
|
198 |
+
$result = array();
|
199 |
+
$count = 1;
|
200 |
+
$resources = get_option( 'lingotek_community_resources' );
|
201 |
$projectInfoArray = $resources['projects'];
|
202 |
|
203 |
+
foreach ( $docs as $doc ) {
|
204 |
+
/**
|
205 |
+
*Convert date from unix time and properly format it
|
206 |
+
*
|
207 |
+
*@author Unkown
|
208 |
+
*/
|
209 |
$unix_upload_time = $doc->properties->upload_date / 1000;
|
210 |
+
$upload_date_str = gmdate( 'm/j/Y', $unix_upload_time );
|
211 |
|
212 |
$project_name = $doc->properties->project_id;
|
213 |
+
if ( array_key_exists( $doc->properties->project_id, $this->projects ) ) {
|
214 |
+
$project_name = $this->projects[ $doc->properties->project_id ];
|
215 |
}
|
216 |
|
217 |
+
$doc_properties = array(
|
218 |
+
'ID' => $count,
|
219 |
+
'title' => $doc->properties->title,
|
220 |
+
'extension' => $doc->properties->extension,
|
221 |
+
'locale' => '<a title=' . $doc->entities[0]->properties->language . '>' . $doc->entities[0]->properties->code . '</a>',
|
222 |
+
'upload_date' => $upload_date_str,
|
223 |
+
'project_name' => $project_name,
|
224 |
+
'id' => $doc->properties->id,
|
225 |
+
);
|
226 |
+
$result[] = $doc_properties;
|
227 |
$count++;
|
228 |
+
}//end foreach
|
229 |
return $result;
|
230 |
}
|
231 |
|
232 |
+
/**
|
233 |
+
* This function makes a query to get the documents
|
234 |
+
*
|
235 |
+
* @author Unkown
|
236 |
+
* @uses wp-lingotek/include/api.php/Lingotek_API::get_documents()
|
237 |
+
* @param Lingotek_API $client used to make the API calls to get the docs
|
238 |
+
* @param int $per_page default = 10 limits the query to 10 results
|
239 |
+
* @param int $page_number default = 1 helps to determine the offset
|
240 |
+
* (so we get the right x amount of documents presented on the current page)
|
241 |
+
* @return array $docs list of documents returned from the API call get_documents()
|
242 |
+
*/
|
243 |
+
function get_docs( $client, $per_page = 10, $page_number = 1 ) {
|
244 |
$limit = $per_page;
|
245 |
+
$docs = $client->get_documents(
|
246 |
+
array(
|
247 |
+
'limit' => $limit,
|
248 |
+
'offset' => ( ( $page_number - 1 ) * $per_page ),
|
249 |
+
)
|
250 |
+
);
|
251 |
return $docs;
|
252 |
}
|
253 |
|
254 |
+
/**
|
255 |
+
* Gets the columns for the table to be displayed properly
|
256 |
+
*
|
257 |
+
* @author Unkown
|
258 |
+
* @return array $columns the appropriate columns i18n ready
|
259 |
+
*/
|
260 |
function get_columns() {
|
261 |
$columns = array(
|
262 |
+
'cb' => '<input type="checkbox" />',
|
263 |
+
'title' => __( 'Title', 'wp-lingotek' ),
|
264 |
+
'extension' => __( 'Extension', 'wp-lingotek' ),
|
265 |
+
'locale' => __( 'Locale', 'wp-lingotek' ),
|
266 |
+
'upload_date' => __( 'Upload Date', 'wp-lingotek' ),
|
267 |
+
'project_name' => __( 'Project Name', 'wp-lingotek' ),
|
268 |
+
'id' => __( 'ID', 'wp-lingotek' ),
|
269 |
);
|
270 |
return $columns;
|
271 |
}
|
272 |
|
273 |
+
/**
|
274 |
+
* This function prepares all the items to be displayed. It calls the get_columns()
|
275 |
+
* and other supporting funcitons.
|
276 |
+
*
|
277 |
+
* @author Unkown and TJ Murphy
|
278 |
+
* @uses Lingotek_Import_Table::get_columns()
|
279 |
+
* @uses Lingotek_Import_Table::process_actions()
|
280 |
+
* @uses Lingotek_Import_Table::get_sortable_columns()
|
281 |
+
* @uses Lingotek_Import_Table::usort_reorder()
|
282 |
+
* @see wp-admin/includes/class-wp-list-table.php/WP_List_Table::get_items_per_page()
|
283 |
+
* @see wp-admin/includes/class-wp-list-table.php/WP_List_Table::get_pagenum()
|
284 |
+
* @see wp-admin/includes/class-wp-list-table.php/WP_List_Table::set_pagination_args()
|
285 |
+
* @return void This just sets some variables within the object
|
286 |
+
*/
|
287 |
function prepare_items() {
|
288 |
|
289 |
+
/**
|
290 |
+
*Constant to define how many items per page will show up.
|
291 |
+
*
|
292 |
+
*@author TJ Murphy
|
293 |
+
*/
|
294 |
+
define( 'ITEMS_PER_PAGE', 10 );
|
295 |
|
296 |
$columns = $this->get_columns();
|
297 |
$this->process_actions();
|
298 |
$hidden = array();
|
299 |
|
300 |
+
$sortable = $this->get_sortable_columns();
|
301 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
302 |
+
|
303 |
+
/**
|
304 |
+
*Sets the total_items (total number of documents calculated by us) and
|
305 |
+
*the per_page (how many documents appear on a page dtermined by us)
|
306 |
+
*
|
307 |
+
*@see wp-admin/includes/class-wp-list-table.php/WP_List_Table::set_pagination_args()
|
308 |
+
*/
|
309 |
+
$this->set_pagination_args(
|
310 |
+
array(
|
311 |
+
'total_items' => $this->document_count,
|
312 |
+
'per_page' => ITEMS_PER_PAGE,
|
313 |
+
)
|
314 |
+
);
|
315 |
+
|
316 |
+
usort( $this->doc_data, array( &$this, 'usort_reorder' ) );
|
317 |
+
|
318 |
+
/**
|
319 |
+
*This slices the documents for the client and only shows the appropriate number
|
320 |
+
*of documents based on the constant ITEMS_PER_PAGE. array_slice takes three
|
321 |
+
*parameters ($array, $offset, $length)
|
322 |
+
*
|
323 |
+
*@author TJ Murphy
|
324 |
+
*@link http://php.net/manual/en/function.array-slice.php
|
325 |
+
*/
|
326 |
+
$this->items = array_slice( $this->doc_data, ( ( ITEMS_PER_PAGE * $this->get_pagenum() ) - ITEMS_PER_PAGE ), ITEMS_PER_PAGE );
|
327 |
}
|
328 |
|
329 |
+
/**
|
330 |
+
* This sets the column default. The default for the switch statement shows the
|
331 |
+
* whole array for troubleshooting purposes
|
332 |
+
*
|
333 |
+
* @author Unkown
|
334 |
+
* @param array $item
|
335 |
+
* @param string $column_name
|
336 |
+
* @return string $item[$column_name]
|
337 |
+
*/
|
338 |
+
function column_default( $item, $column_name ) {
|
339 |
+
switch ( $column_name ) {
|
340 |
case 'title':
|
341 |
case 'extension':
|
342 |
case 'locale':
|
343 |
case 'upload_date':
|
344 |
case 'project_name':
|
345 |
case 'id':
|
346 |
+
return $item[ $column_name ];
|
347 |
default:
|
348 |
+
return print_r( $item, true );
|
349 |
}
|
350 |
}
|
351 |
|
352 |
+
/**
|
353 |
+
* Gets the sortable columns and returns the list
|
354 |
+
*
|
355 |
+
* @author Unkown
|
356 |
+
* @return array $sortable_columns
|
357 |
+
*/
|
358 |
function get_sortable_columns() {
|
359 |
$sortable_columns = array(
|
360 |
+
'title' => array( 'title', false ),
|
361 |
+
'extension' => array( 'extension', false ),
|
362 |
+
'locale' => array( 'locale', false ),
|
363 |
+
'upload_date' => array( 'upload_date', false ),
|
364 |
+
'project_name' => array( 'project_name', false ),
|
365 |
+
'id' => array( 'id', false ),
|
366 |
);
|
367 |
return $sortable_columns;
|
368 |
}
|
369 |
|
370 |
+
/**
|
371 |
+
* Sorts the documents by one of the columns. The default sort is with the Title
|
372 |
+
* and ascending order. The date sort has its own method to sort, but all other
|
373 |
+
* columns are sorted the same way.
|
374 |
+
*
|
375 |
+
* @author Unknown
|
376 |
+
* @return int $result direction of sort
|
377 |
+
* @todo it would be great to make the query that gets the documents do an Order By
|
378 |
+
* and then this would not even be necessary. It appears this is a limitation in
|
379 |
+
* the API.
|
380 |
+
*/
|
381 |
+
function usort_reorder( $a, $b ) {
|
382 |
+
$orderby = ( ! empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'title';
|
383 |
+
$order = ( ! empty( $_GET['order'] ) ) ? $_GET['order'] : 'asc';
|
384 |
+
$result = 0;
|
385 |
+
if ( $orderby == 'upload_date' ) {
|
386 |
+
$date_a = strtotime( $a['upload_date'] );
|
387 |
+
$date_b = strtotime( $b['upload_date'] );
|
388 |
$result = $date_a - $date_b;
|
389 |
+
} else {
|
390 |
+
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
|
|
|
391 |
}
|
392 |
|
393 |
return ( $order === 'asc' ) ? $result : -$result;
|
394 |
}
|
395 |
|
396 |
+
/**
|
397 |
+
* Sets the column Title to have the right information in that column. This includes
|
398 |
+
* the popup link to import the file.
|
399 |
+
*
|
400 |
+
* @author Unknown
|
401 |
+
* @see wp-lingotek/admin/string-actions.php/Lingotek_String_actions::row_actions()
|
402 |
+
* @return string to be put in the column when displayed
|
403 |
+
*/
|
404 |
+
function column_title( $item ) {
|
405 |
$actions = array(
|
406 |
+
'import' => sprintf(
|
407 |
+
'<a href="?page=%s&action=%s&post=%s&count=%s&paged=%s">Import</a>',
|
408 |
+
$_REQUEST['page'],
|
409 |
+
'import',
|
410 |
+
$item['id'],
|
411 |
+
$this->importedCount,
|
412 |
+
$this->get_pagenum()
|
413 |
+
),
|
414 |
);
|
415 |
+
return sprintf( '%1$s %2$s', $item['title'], $this->row_actions( $actions ) );
|
416 |
}
|
417 |
|
418 |
+
/**
|
419 |
+
* This just gets the actions that are available for bulk actions
|
420 |
+
*
|
421 |
+
* @author Unknown
|
422 |
+
* @return array $actions available actions to be done on a bulk level
|
423 |
+
*/
|
424 |
function get_bulk_actions() {
|
425 |
$actions = array(
|
426 |
+
'import' => 'Import',
|
427 |
);
|
428 |
return $actions;
|
429 |
}
|
430 |
|
431 |
+
/**
|
432 |
+
* This function processes any actions (currently the only action is import).
|
433 |
+
* This includes bulk imports and individual imports. Then it sets the import as
|
434 |
+
* successful or unsuccessful.
|
435 |
+
*
|
436 |
+
* @author Unknown
|
437 |
+
* @uses Lingotek_Import_Table::add_one_import_success_count()
|
438 |
+
* @uses Lingotek_Import_Table::add_doc_id_to_unsuccessful_imports()
|
439 |
+
* @uses Lingotek_Import_Table::import()
|
440 |
+
* @uses Lingotek_Import_Table::$import_success_count
|
441 |
+
* @uses Lingotek_Import_Table::$import_status
|
442 |
+
* @return void this just sets certain variables in the object.
|
443 |
+
*/
|
444 |
public function process_actions() {
|
445 |
$result = null;
|
446 |
+
if ( 'import' === $this->current_action() ) {
|
447 |
+
// Bulk action.
|
448 |
+
if ( isset( $_POST['post'] ) ) {
|
449 |
+
foreach ( $_POST['post'] as $doc_id ) {
|
450 |
+
$result = $this->import( $doc_id );
|
451 |
+
if ( $result != 0 ) {
|
452 |
+
$this->add_one_import_success_count();
|
453 |
+
} else {
|
454 |
+
$this->add_doc_id_to_unsuccessful_imports( $doc_id );
|
455 |
+
}
|
456 |
}
|
457 |
+
} else {
|
458 |
+
// Single action.
|
459 |
+
if ( isset( $_GET['action'] ) && $_GET['action'] == 'import' ) {
|
460 |
$doc_id = $_GET['post'];
|
461 |
+
$result = $this->import( $doc_id );
|
462 |
+
if ( $result != 0 ) {
|
463 |
+
$this->add_one_import_success_count();
|
464 |
+
} else {
|
465 |
+
$this->add_doc_id_to_unsuccessful_imports( $doc_id );
|
466 |
+
}
|
|
|
467 |
}
|
468 |
+
}//end if
|
469 |
+
|
470 |
+
/**
|
471 |
+
*This checks the import_success_count to determine if the import status
|
472 |
+
*wassuccessful or not. It used to just check if the $result was 0 or not.
|
473 |
+
*This led to the last bulk import to determine the import status. Now if
|
474 |
+
*any imports are successful it will mark the import status as successful.
|
475 |
+
*
|
476 |
+
*@author TJ Murphy
|
477 |
+
*@uses Lingotek_Import_Table::$import_success_count
|
478 |
+
*@uses Lingotek_Import_Table::$import_status
|
479 |
+
*/
|
480 |
+
if ( $this->import_success_count > 0 ) {
|
481 |
$this->import_status = 'success';
|
482 |
+
} else {
|
|
|
483 |
$this->import_status = 'failure';
|
484 |
}
|
485 |
+
}//end if
|
486 |
}
|
487 |
|
488 |
+
/**
|
489 |
+
* This converts the many objects and strings that are documents into a format
|
490 |
+
* that can be imported into WP. If $post_status is not set it gets set to draft.
|
491 |
+
* If the $post_type is not set then it gets set to post.
|
492 |
+
*
|
493 |
+
* @author Unknown
|
494 |
+
* @uses wp-lingotek/admin/import/StandardImportObject.php/StandardImportObject
|
495 |
+
* @uses wp-lingotek/admin/import/StandardImportObject.php/StandardImportObject::getTitle()
|
496 |
+
* @uses wp-lingotek/admin/import/StandardImportObject.php/StandardImportObject::getContent()
|
497 |
+
* @see wp-admin/includes/class-wp-screen.php/WP_Screen::get_option()
|
498 |
+
* @link https://developer.wordpress.org/reference/functions/wp_insert_post/
|
499 |
+
* @param StandardImportObject $object a document that needs to be converted to
|
500 |
+
* a standard object that can be imported into WP
|
501 |
+
* @return int|bool $result 0 or 1 to show if it was successful or not
|
502 |
+
*/
|
503 |
+
public function import_standard_object( StandardImportObject $object ) {
|
504 |
+
if ( $object->hasError() ) {
|
505 |
return 0;
|
506 |
}
|
507 |
|
508 |
+
$post_status = get_option( 'lingotek_import_prefs' )['import_post_status'];
|
509 |
+
$post_type = get_option( 'lingotek_import_prefs' )['import_type'];
|
510 |
+
if ( ! isset( $post_status ) ) {
|
511 |
$post_status = 'draft';
|
512 |
}
|
513 |
+
if ( ! isset( $post_type ) ) {
|
514 |
$post_type = 'post';
|
515 |
}
|
516 |
|
517 |
+
$post_to_import = array(
|
518 |
+
'post_title' => $object->getTitle(),
|
519 |
+
'post_content' => $object->getContent(),
|
520 |
+
// draft, published, etc.
|
521 |
+
'post_status' => $post_status,
|
522 |
+
// page or post?
|
523 |
+
'post_type' => $post_type,
|
524 |
+
'post_category' => array( 8, 39 ),
|
525 |
+
);
|
526 |
+
/**
|
527 |
+
*@link https://developer.wordpress.org/reference/functions/wp_insert_post/
|
528 |
+
*/
|
529 |
$result = wp_insert_post( $post_to_import );
|
530 |
return $result;
|
531 |
+
}
|
532 |
|
533 |
+
/**
|
534 |
+
* This function makes the API calls that send a query and get the documents
|
535 |
+
*
|
536 |
+
* @author Unknown
|
537 |
+
* @uses Lingotek_Import_Table::$client
|
538 |
+
* @uses wp-lingotek/admin/import/FormatConverter.php/FormatConverter
|
539 |
+
* @uses wp-lingotek/admin/import/FormatConverter.php/FormatConverter::convert_to_standard()
|
540 |
+
* @uses wp-lingotek/admin/import/FormatConverter.php/FormatConverter::import_standard_object()
|
541 |
+
*/
|
542 |
+
public function import( $doc_id ) {
|
543 |
+
$source_doc = $this->client->get_document( $doc_id );
|
544 |
+
|
545 |
+
$content = $this->client->get_document_content( $doc_id );
|
546 |
+
if ( $content == null ) {
|
547 |
+
$content == __( 'There is no content to display', 'wp-lingotek' );
|
548 |
}
|
549 |
|
550 |
+
$format = $source_doc->properties->extension;
|
551 |
+
$formatConverter = new FormatConverter( $source_doc, $content, $format );
|
552 |
+
$importObject = $formatConverter->convert_to_standard();
|
553 |
+
$response = $this->import_standard_object( $importObject );
|
554 |
return $response;
|
555 |
}
|
556 |
|
557 |
+
/**
|
558 |
+
* Prints the Column Checkbox
|
559 |
+
*
|
560 |
+
* @author Unknown
|
561 |
+
* @return string the HTML necessary to show the Checkbox
|
562 |
+
*/
|
563 |
+
function column_cb( $item ) {
|
564 |
+
return sprintf( '<input type="checkbox" name="post[]" value="%s" />', $item['id'] );
|
565 |
}
|
566 |
|
567 |
+
/**
|
568 |
+
* This gets the import status
|
569 |
+
*
|
570 |
+
* @author Unknown
|
571 |
+
* @return string $this->import_status
|
572 |
+
*/
|
573 |
+
function get_import_status() {
|
574 |
return $this->import_status;
|
575 |
}
|
576 |
}
|
admin/import/view-content.php
CHANGED
@@ -1,139 +1,152 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
-
*
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*/
|
7 |
|
8 |
|
9 |
-
|
10 |
|
11 |
-
$profile = Lingotek_Model::get_profile('string', $this->pllm->get_language($this->pllm->options['default_lang']));
|
12 |
|
13 |
/**
|
14 |
*Tests to see if the profile is disabled or not.
|
|
|
15 |
*@author Unknown
|
16 |
*/
|
17 |
-
if ('disabled' == $profile['profile']) {
|
18 |
-
printf(
|
19 |
-
|
20 |
-
|
|
|
|
|
21 |
'</a>'
|
22 |
)
|
23 |
);
|
24 |
-
}
|
25 |
-
|
26 |
-
$table = new Lingotek_Import_Table();
|
27 |
|
28 |
$table->prepare_items();
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
39 |
$importedCount = 0;
|
40 |
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
47 |
}
|
48 |
-
|
49 |
-
|
|
|
50 |
}
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
else {
|
65 |
-
$plural_or_singular = sprintf( _n( 'Successfully imported %1$s of %2$s post', 'Successfully imported %1$s of %2$s posts', $table->import_success_count, 'wp-lingotek' ), $table->import_success_count, $importedCount );
|
66 |
-
}
|
67 |
-
|
68 |
-
add_settings_error($this->plugin_slug . '_import', '', $plural_or_singular, 'updated');
|
69 |
-
|
70 |
-
/**
|
71 |
-
*If not all the imports were successful this if statement adds a settings error
|
72 |
-
*that lists the ids of the documents that did not import
|
73 |
-
*
|
74 |
-
*@author TJ Murphy
|
75 |
-
*@uses Lingotek_Import_Table::$import_success_count
|
76 |
-
*@uses Lingotek_Import_Table::$import_failure_count
|
77 |
-
*@uses Lingotek_Import_Table::to_string_unsuccessful_imports()
|
78 |
-
*
|
79 |
-
*/
|
80 |
-
if ($table->import_success_count != $importedCount){
|
81 |
-
$document_plurality = sprintf(_n( 'The following document did not import: %s', 'The following documents did not import: %s', $table->import_failure_count, 'wp-lingotek' ), $table->to_string_unsuccessful_imports());
|
82 |
-
add_settings_error($this->plugin_slug . '_import', '',$document_plurality, 'error');
|
83 |
-
}
|
84 |
}
|
85 |
|
86 |
-
|
87 |
-
/**
|
88 |
-
*This determines if any files were attempted to be imported. If Zero were even
|
89 |
-
*attempted then it shows a message relating that. If >0 were attempted and 0
|
90 |
-
*passed then it displays an error message saying all imports failed.
|
91 |
-
*
|
92 |
-
*@author TJ Murphy
|
93 |
-
*@uses Lingotek_Import_Table::import_success_count
|
94 |
-
*@uses Lingotek_Import_Table::import_failure_count
|
95 |
-
*
|
96 |
-
*/
|
97 |
-
if ($table->import_success_count == $importedCount && $table->import_failure_count == $importedCount && $importedCount == 0){
|
98 |
-
add_settings_error(
|
99 |
-
$this->plugin_slug . '_import',
|
100 |
-
'',
|
101 |
-
__('No files were selected to import. Please check the desired documents to import.','wp-lingotek'),
|
102 |
-
'error'
|
103 |
-
);
|
104 |
-
}
|
105 |
-
else {
|
106 |
-
$file_plurality = sprintf( _n( 'There was an error importing your file. We currently only support Wordpress, Drupal, HTML, and Text files.',
|
107 |
-
'There was an error importing your files. We currently only support Wordpress, Drupal, HTML, and Text files.',
|
108 |
-
$table->import_failure_count,
|
109 |
-
'wp-lingotek' ),
|
110 |
-
$table->import_failure_count );
|
111 |
-
add_settings_error(
|
112 |
-
$this->plugin_slug . '_import',
|
113 |
-
'',
|
114 |
-
$file_plurality,
|
115 |
-
'error'
|
116 |
-
);
|
117 |
-
}
|
118 |
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
settings_errors();
|
121 |
|
122 |
-
|
123 |
-
|
124 |
|
125 |
-
|
126 |
|
127 |
<?php
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
|
1 |
<?php
|
2 |
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
+
|
8 |
+
// phpcs:disable
|
9 |
+
/**
|
10 |
+
* This file actually prepares the content to be viewed and calls the other files
|
11 |
+
* as needed so that everything appears as expected.
|
12 |
+
*
|
13 |
+
* @author Unknown
|
14 |
*/
|
15 |
|
16 |
|
17 |
+
require_once 'import-table.php';
|
18 |
|
19 |
+
$profile = Lingotek_Model::get_profile( 'string', $this->pllm->get_language( $this->pllm->options['default_lang'] ) );
|
20 |
|
21 |
/**
|
22 |
*Tests to see if the profile is disabled or not.
|
23 |
+
*
|
24 |
*@author Unknown
|
25 |
*/
|
26 |
+
if ( 'disabled' == $profile['profile'] ) {
|
27 |
+
printf(
|
28 |
+
'<div class="error" style="border-left: 4px solid #ffba00;"><p>%s</p></div>',
|
29 |
+
sprintf(
|
30 |
+
__( 'The strings translation is disabled in %1$sContent Type Configuration%2$s.', 'wp-lingotek' ),
|
31 |
+
'<a href="' . admin_url( 'admin.php?page=wp-lingotek_settings&sm=content' ) . '">',
|
32 |
'</a>'
|
33 |
)
|
34 |
);
|
35 |
+
} else {
|
36 |
+
$table = new Lingotek_Import_Table();
|
|
|
37 |
|
38 |
$table->prepare_items();
|
39 |
+
//Gets the import type (post or page)
|
40 |
+
$post_type = get_option( 'lingotek_import_prefs' )['import_type'];
|
41 |
+
$plural_or_singular = '';
|
42 |
|
43 |
+
/**
|
44 |
+
*This tests to see if the import was successful. If it was it runs the subsequent
|
45 |
+
*code.
|
46 |
+
*
|
47 |
+
*@author Unknown
|
48 |
+
*/
|
49 |
+
if ( $table->get_import_status() == 'success' ) {
|
50 |
$importedCount = 0;
|
51 |
|
52 |
+
/**
|
53 |
+
*Gets the import count based on if it is POST (Bulk import) or GET (indiviudal import)
|
54 |
+
*
|
55 |
+
*@author Unknown
|
56 |
+
*/
|
57 |
+
// Used for bulk import.
|
58 |
+
if ( isset( $_POST['post'] ) ) {
|
59 |
+
$importedCount = count( $_POST['post'] );
|
60 |
}
|
61 |
+
// Used for single import.
|
62 |
+
elseif ( isset( $_GET['post'] ) ) {
|
63 |
+
$importedCount = count( $_GET['post'] );
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
*This is to show the correct syntax in the message saying the import was Successful
|
68 |
+
*or not. It was always showing post even if it was imported as a page. Now it
|
69 |
+
*will show page if imported as page and post if imported as a post.
|
70 |
+
*
|
71 |
+
*@author TJ Murphy
|
72 |
+
*@uses Lingotek_Import_Table::$import_success_count
|
73 |
+
*/
|
74 |
+
if ( $post_type == 'page' ) {
|
75 |
+
$plural_or_singular = sprintf( _n( 'Successfully imported %1$s of %2$s page', 'Successfully imported %1$s of %2$s pages', $table->import_success_count, 'wp-lingotek' ), $table->import_success_count, $importedCount );
|
76 |
+
} else {
|
77 |
+
$plural_or_singular = sprintf( _n( 'Successfully imported %1$s of %2$s post', 'Successfully imported %1$s of %2$s posts', $table->import_success_count, 'wp-lingotek' ), $table->import_success_count, $importedCount );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
+
add_settings_error( $this->plugin_slug . '_import', '', $plural_or_singular, 'updated' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
+
/**
|
83 |
+
*If not all the imports were successful this if statement adds a settings error
|
84 |
+
*that lists the ids of the documents that did not import
|
85 |
+
*
|
86 |
+
*@author TJ Murphy
|
87 |
+
*@uses Lingotek_Import_Table::$import_success_count
|
88 |
+
*@uses Lingotek_Import_Table::$import_failure_count
|
89 |
+
*@uses Lingotek_Import_Table::to_string_unsuccessful_imports()
|
90 |
+
*/
|
91 |
+
if ( $table->import_success_count != $importedCount ) {
|
92 |
+
$document_plurality = sprintf( _n( 'The following document did not import: %s', 'The following documents did not import: %s', $table->import_failure_count, 'wp-lingotek' ), $table->to_string_unsuccessful_imports() );
|
93 |
+
add_settings_error( $this->plugin_slug . '_import', '', $document_plurality, 'error' );
|
94 |
+
}
|
95 |
+
} elseif ( $table->get_import_status() == 'failure' ) {
|
96 |
+
/**
|
97 |
+
*This determines if any files were attempted to be imported. If Zero were even
|
98 |
+
*attempted then it shows a message relating that. If >0 were attempted and 0
|
99 |
+
*passed then it displays an error message saying all imports failed.
|
100 |
+
*
|
101 |
+
*@author TJ Murphy
|
102 |
+
*@uses Lingotek_Import_Table::import_success_count
|
103 |
+
*@uses Lingotek_Import_Table::import_failure_count
|
104 |
+
*/
|
105 |
+
if ( $table->import_success_count == $importedCount && $table->import_failure_count == $importedCount && $importedCount == 0 ) {
|
106 |
+
add_settings_error(
|
107 |
+
$this->plugin_slug . '_import',
|
108 |
+
'',
|
109 |
+
__( 'No files were selected to import. Please check the desired documents to import.', 'wp-lingotek' ),
|
110 |
+
'error'
|
111 |
+
);
|
112 |
+
} else {
|
113 |
+
$file_plurality = sprintf(
|
114 |
+
_n(
|
115 |
+
'There was an error importing your file. We currently only support WordPress, Drupal, HTML, and Text files.',
|
116 |
+
'There was an error importing your files. We currently only support WordPress, Drupal, HTML, and Text files.',
|
117 |
+
$table->import_failure_count,
|
118 |
+
'wp-lingotek'
|
119 |
+
),
|
120 |
+
$table->import_failure_count
|
121 |
+
);
|
122 |
+
add_settings_error(
|
123 |
+
$this->plugin_slug . '_import',
|
124 |
+
'',
|
125 |
+
$file_plurality,
|
126 |
+
'error'
|
127 |
+
);
|
128 |
+
}//end if
|
129 |
+
}//end if
|
130 |
settings_errors();
|
131 |
|
132 |
+
$order = ( ! empty( $_GET['order'] ) ) ? $_GET['order'] : 'asc';
|
133 |
+
$orderby = ( ! empty( $_GET['orderby'] ) ) ? '&orderby=' . $_GET['orderby'] . '&order=' . $order : '';
|
134 |
|
135 |
+
?>
|
136 |
|
137 |
<?php
|
138 |
+
/**
|
139 |
+
* This creates the starting form tag for the import page and sets the page and
|
140 |
+
* action parameters.
|
141 |
+
*
|
142 |
+
* @author Unknown
|
143 |
+
*/
|
144 |
+
echo sprintf( '<form id="lingotek-import" method="post" action="admin.php?page=lingotek-translation_import&action=bulk_import' . (string) $orderby . '"' );
|
145 |
+
/**
|
146 |
+
*@see wp-admin/includes/class-wp-list-table.php/WP_List_Table::display()
|
147 |
+
*/
|
148 |
+
$table->display();
|
149 |
+
?>
|
150 |
+
</form>
|
151 |
+
<?php
|
152 |
+
}//end if
|
admin/import/view-settings.php
CHANGED
@@ -1,30 +1,39 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
3 |
|
4 |
/**
|
5 |
-
*Sets all of the setting details so they can appropriately be presented.
|
6 |
-
|
7 |
-
|
|
|
8 |
*/
|
9 |
$setting_details = array(
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
28 |
);
|
29 |
|
30 |
|
@@ -32,60 +41,65 @@ $page_key = $this->plugin_slug . '_import&sm=settings';
|
|
32 |
|
33 |
/**
|
34 |
*Sets the options
|
35 |
-
|
|
|
36 |
*/
|
37 |
-
if (!empty($_POST)) {
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
}
|
47 |
|
48 |
|
49 |
-
|
50 |
|
51 |
-
|
52 |
-
|
53 |
}
|
54 |
-
$selected_options = get_option('lingotek_import_prefs');
|
55 |
?>
|
56 |
|
57 |
-
<h3><?php _e('Settings', 'wp-lingotek'); ?></h3>
|
58 |
|
59 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate">
|
60 |
-
<?php wp_nonce_field($page_key, '_wpnonce_' . $page_key); ?>
|
61 |
|
62 |
-
<table class="form-table"><?php foreach ($setting_details as $key => $setting) { ?>
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
88 |
</table>
|
89 |
|
90 |
-
<?php submit_button(__('Save Changes', 'wp-lingotek'), 'primary', 'submit', false); ?>
|
91 |
</form>
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* I think this file is not used, and probably should be removed.
|
4 |
+
*
|
5 |
+
* @package lingotek-translation
|
6 |
+
*/
|
7 |
|
8 |
+
// phpcs:disable
|
9 |
|
10 |
/**
|
11 |
+
* Sets all of the setting details so they can appropriately be presented.
|
12 |
+
*
|
13 |
+
* @author Unknown
|
14 |
+
* @var array
|
15 |
*/
|
16 |
$setting_details = array(
|
17 |
+
'import_post_status' => array(
|
18 |
+
'type' => 'dropdown',
|
19 |
+
'label' => __( 'Import documents as', 'wp-lingotek' ),
|
20 |
+
'description' => __( 'The post status for newly imported documents', 'wp-lingotek' ),
|
21 |
+
'values' => array(
|
22 |
+
'draft' => __( 'Draft', 'wp-lingotek' ),
|
23 |
+
'pending' => __( 'Pending Review', 'wp-lingotek' ),
|
24 |
+
'publish' => __( 'Published', 'wp-lingotek' ),
|
25 |
+
'private' => __( 'Privately Published', 'wp-lingotek' ),
|
26 |
+
),
|
27 |
+
),
|
28 |
+
'import_type' => array(
|
29 |
+
'type' => 'dropdown',
|
30 |
+
'label' => __( 'Format', 'wp-lingotek' ),
|
31 |
+
'description' => __( 'In which format would you like your imports to be?', 'wp-lingotek' ),
|
32 |
+
'values' => array(
|
33 |
+
'page' => __( 'Page', 'wp-lingotek' ),
|
34 |
+
'post' => __( 'Post', 'wp-lingotek' ),
|
35 |
+
),
|
36 |
+
),
|
37 |
);
|
38 |
|
39 |
|
41 |
|
42 |
/**
|
43 |
*Sets the options
|
44 |
+
*
|
45 |
+
*@author Unknown
|
46 |
*/
|
47 |
+
if ( ! empty( $_POST ) ) {
|
48 |
+
$options = array();
|
49 |
+
foreach ( $setting_details as $key => $setting ) {
|
50 |
+
if ( isset( $_POST[ $key ] ) ) {
|
51 |
+
$options[ $key ] = $_POST[ $key ];
|
52 |
+
} else {
|
53 |
+
$options[ $key ] = null;
|
54 |
+
}
|
55 |
+
}
|
|
|
56 |
|
57 |
|
58 |
+
update_option( 'lingotek_import_prefs', $options, false );
|
59 |
|
60 |
+
add_settings_error( 'lingotek_prefs', 'prefs', __( 'Your preferences were successfully updated.', 'wp-lingotek' ), 'updated' );
|
61 |
+
settings_errors();
|
62 |
}
|
63 |
+
$selected_options = get_option( 'lingotek_import_prefs' );
|
64 |
?>
|
65 |
|
66 |
+
<h3><?php _e( 'Settings', 'wp-lingotek' ); ?></h3>
|
67 |
|
68 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate">
|
69 |
+
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
70 |
|
71 |
+
<table class="form-table"><?php foreach ( $setting_details as $key => $setting ) { ?>
|
72 |
|
73 |
+
<tr>
|
74 |
+
<th scope="row"><label for="<?php echo $key; ?>"><?php echo $setting['label']; ?></label></th>
|
75 |
+
<td>
|
76 |
+
<?php if ( $setting['type'] == 'dropdown' ) { ?>
|
77 |
+
<select name="<?php echo $key; ?>" id="<?php echo $key; ?>">
|
78 |
+
<?php
|
79 |
+
foreach ( $setting['values'] as $id => $title ) {
|
80 |
+
echo "\n\t" . '<option value="' . esc_attr( $id ) . '" ' . selected( $selected_options[ $key ], $id ) . '>' . $title . '</option>';
|
81 |
+
}
|
82 |
+
?>
|
83 |
+
</select>
|
84 |
+
<?php
|
85 |
+
} elseif ( $setting['type'] == 'checkboxes' ) {
|
86 |
+
echo '<ul class="pref-statuses">';
|
87 |
+
foreach ( $setting['values'] as $id => $title ) {
|
88 |
+
$cb_name = $key . '[' . esc_attr( $id ) . ']';
|
89 |
+
$checked = checked( '1', ( isset( $selected_options[ $key ][ $id ] ) && $selected_options[ $key ][ $id ] ), false );
|
90 |
+
echo '<li><input type="checkbox" id="' . $cb_name . '" name="' . $cb_name . '" value="1" ' . $checked . '><label for="' . $cb_name . '">' . $title . '</label></li>';
|
91 |
+
}
|
92 |
+
echo '</ul>';
|
93 |
+
}
|
94 |
+
?>
|
95 |
+
<p class="description">
|
96 |
+
<?php echo $setting['description']; ?>
|
97 |
+
</p>
|
98 |
+
</tr>
|
99 |
+
<?php
|
100 |
+
}//end foreach
|
101 |
+
?>
|
102 |
</table>
|
103 |
|
104 |
+
<?php submit_button( __( 'Save Changes', 'wp-lingotek' ), 'primary', 'submit', false ); ?>
|
105 |
</form>
|
admin/manage/view-content.php
CHANGED
@@ -2,99 +2,97 @@
|
|
2 |
|
3 |
global $polylang;
|
4 |
|
5 |
-
foreach ($polylang->model->get_translated_post_types() as $post_type) {
|
6 |
-
$post_type_object
|
7 |
-
$data[$post_type] = array(
|
8 |
-
'type'
|
9 |
-
'name'
|
10 |
-
'fields'
|
11 |
-
'label' => Lingotek_Group_Post::get_content_type_fields($post_type)
|
12 |
-
)
|
13 |
);
|
14 |
}
|
15 |
|
16 |
-
foreach ($polylang->model->get_translated_taxonomies() as $tax) {
|
17 |
-
$taxonomy
|
18 |
-
$data[$tax] = array(
|
19 |
-
'type'
|
20 |
-
'name'
|
21 |
-
'fields'
|
22 |
-
'label' => Lingotek_Group_Term::get_content_type_fields($tax)
|
23 |
-
)
|
24 |
);
|
25 |
}
|
26 |
|
27 |
$data['string'] = array(
|
28 |
-
'type'
|
29 |
-
'name'
|
30 |
);
|
31 |
|
32 |
-
if (empty($_POST)) {
|
33 |
-
$content_types = get_option('lingotek_content_type');
|
34 |
-
}
|
35 |
-
|
36 |
-
else {
|
37 |
-
check_admin_referer('lingotek-content-types', '_wpnonce_lingotek-content-types');
|
38 |
-
|
39 |
-
$profiles = array_keys(get_option('lingotek_profiles'));
|
40 |
-
$content_types = get_option('lingotek_content_type');
|
41 |
-
foreach ($data as $key => $item) {
|
42 |
-
if (isset($data[$key]['name']) && isset($_POST[$key])) {
|
43 |
-
if (in_array($_POST[$key]['profile'], $profiles))
|
44 |
-
$content_types[$key]['profile'] = $_POST[$key]['profile'];
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
49 |
}
|
50 |
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
-
if (isset($data[$key]['fields'])) {
|
53 |
-
foreach ($data[$key]['fields']['label'] as $key1 => $arr) {
|
54 |
-
if (is_array($arr)) {
|
55 |
-
foreach (array_keys($arr) as $key2) {
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
}
|
62 |
}
|
63 |
-
}
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
elseif (!empty($_POST[$key]['fields'][$key1])) {
|
68 |
-
$content_types[$key]['fields'][$key1] = 0;
|
69 |
}
|
70 |
}
|
71 |
}
|
72 |
-
}
|
73 |
|
74 |
-
update_option('lingotek_content_type', $content_types, false);
|
75 |
-
add_settings_error('lingotek_content_types', 'default', __('Your content types were sucessfully saved.', 'lingotek-translation'), 'updated');
|
76 |
settings_errors();
|
77 |
-
}
|
78 |
|
79 |
-
foreach ($data as $key => $item) {
|
80 |
// default profile is manual except for post
|
81 |
-
$data[$key]['profile'] = empty($content_types[$key]['profile']) ? ('post' === $key || 'page' === $key ? 'manual' : 'disabled') : $content_types[$key]['profile'];
|
82 |
-
$data[$key]['sources'] = empty($content_types[$key]['sources']) ? array() : $content_types[$key]['sources'];
|
83 |
-
if (!empty($content_types[$key]['fields']))
|
84 |
-
$data[$key]['fields']['value'] = $content_types[$key]['fields'];
|
|
|
85 |
}
|
86 |
|
87 |
?>
|
88 |
-
<h3><?php _e('Content Type Configuration', 'lingotek-translation'); ?></h3>
|
89 |
-
<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.', 'lingotek-translation'); ?></p>
|
90 |
|
91 |
-
<form id="lingotek-content-types" method="post" action="admin.php?page=lingotek-translation_manage&sm=content" class="validate"
|
92 |
-
|
|
|
93 |
|
94 |
-
$table = new Lingotek_Content_Table($content_types);
|
95 |
-
$table->prepare_items($data);
|
96 |
$table->display();
|
97 |
|
98 |
-
submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false);
|
99 |
?>
|
100 |
</form>
|
2 |
|
3 |
global $polylang;
|
4 |
|
5 |
+
foreach ( $polylang->model->get_translated_post_types() as $post_type ) {
|
6 |
+
$post_type_object = get_post_type_object( $post_type );
|
7 |
+
$data[ $post_type ] = array(
|
8 |
+
'type' => $post_type,
|
9 |
+
'name' => $post_type_object->labels->name,
|
10 |
+
'fields' => array(
|
11 |
+
'label' => Lingotek_Group_Post::get_content_type_fields( $post_type ),
|
12 |
+
),
|
13 |
);
|
14 |
}
|
15 |
|
16 |
+
foreach ( $polylang->model->get_translated_taxonomies() as $tax ) {
|
17 |
+
$taxonomy = get_taxonomy( $tax );
|
18 |
+
$data[ $tax ] = array(
|
19 |
+
'type' => $tax,
|
20 |
+
'name' => $taxonomy->labels->name,
|
21 |
+
'fields' => array(
|
22 |
+
'label' => Lingotek_Group_Term::get_content_type_fields( $tax ),
|
23 |
+
),
|
24 |
);
|
25 |
}
|
26 |
|
27 |
$data['string'] = array(
|
28 |
+
'type' => 'string',
|
29 |
+
'name' => __( 'Strings', 'lingotek-translation' ),
|
30 |
);
|
31 |
|
32 |
+
if ( empty( $_POST ) ) {
|
33 |
+
$content_types = get_option( 'lingotek_content_type' );
|
34 |
+
} else {
|
35 |
+
check_admin_referer( 'lingotek-content-types', '_wpnonce_lingotek-content-types' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
+
$profiles = array_keys( get_option( 'lingotek_profiles' ) );
|
38 |
+
$content_types = get_option( 'lingotek_content_type' );
|
39 |
+
foreach ( $data as $key => $item ) {
|
40 |
+
if ( isset( $data[ $key ]['name'] ) && isset( $_POST[ $key ] ) ) {
|
41 |
+
if ( in_array( $_POST[ $key ]['profile'], $profiles ) ) {
|
42 |
+
$content_types[ $key ]['profile'] = $_POST[ $key ]['profile'];
|
43 |
}
|
44 |
|
45 |
+
foreach ( $polylang->model->get_languages_list() as $language ) {
|
46 |
+
if ( isset( $_POST[ $key ]['sources'][ $language->slug ] ) && in_array( $_POST[ $key ]['sources'][ $language->slug ], $profiles ) ) {
|
47 |
+
$content_types[ $key ]['sources'][ $language->slug ] = $_POST[ $key ]['sources'][ $language->slug ];
|
48 |
+
}
|
49 |
+
}
|
50 |
}
|
51 |
+
if ( isset( $data[ $key ]['fields'] ) ) {
|
52 |
+
foreach ( $data[ $key ]['fields']['label'] as $key1 => $arr ) {
|
53 |
+
if ( is_array( $arr ) ) {
|
54 |
+
foreach ( array_keys( $arr ) as $key2 ) {
|
55 |
+
if ( ! isset( $_POST[ $key ]['fields'][ $key1 ][ $key2 ] ) ) {
|
56 |
+
$content_types[ $key ]['fields'][ $key1 ][ $key2 ] = 1;
|
57 |
+
} else {
|
58 |
+
$content_types[ $key ]['fields'][ $key1 ][ $key2 ] = 0;
|
59 |
+
}
|
|
|
60 |
}
|
61 |
+
} elseif ( isset( $_POST[ $key ] ) && empty( $_POST[ $key ]['fields'][ $key1 ] ) ) {
|
62 |
+
$content_types[ $key ]['fields'][ $key1 ] = 1;
|
63 |
+
} elseif ( ! empty( $_POST[ $key ]['fields'][ $key1 ] ) ) {
|
64 |
+
$content_types[ $key ]['fields'][ $key1 ] = 0;
|
|
|
|
|
65 |
}
|
66 |
}
|
67 |
}
|
68 |
+
}//end foreach
|
69 |
|
70 |
+
update_option( 'lingotek_content_type', $content_types, false );
|
71 |
+
add_settings_error( 'lingotek_content_types', 'default', __( 'Your content types were sucessfully saved.', 'lingotek-translation' ), 'updated' );
|
72 |
settings_errors();
|
73 |
+
}//end if
|
74 |
|
75 |
+
foreach ( $data as $key => $item ) {
|
76 |
// default profile is manual except for post
|
77 |
+
$data[ $key ]['profile'] = empty( $content_types[ $key ]['profile'] ) ? ( 'post' === $key || 'page' === $key ? 'manual' : 'disabled' ) : $content_types[ $key ]['profile'];
|
78 |
+
$data[ $key ]['sources'] = empty( $content_types[ $key ]['sources'] ) ? array() : $content_types[ $key ]['sources'];
|
79 |
+
if ( ! empty( $content_types[ $key ]['fields'] ) ) {
|
80 |
+
$data[ $key ]['fields']['value'] = $content_types[ $key ]['fields'];
|
81 |
+
}
|
82 |
}
|
83 |
|
84 |
?>
|
85 |
+
<h3><?php _e( 'Content Type Configuration', 'lingotek-translation' ); ?></h3>
|
86 |
+
<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.', 'lingotek-translation' ); ?></p>
|
87 |
|
88 |
+
<form id="lingotek-content-types" method="post" action="admin.php?page=lingotek-translation_manage&sm=content" class="validate">
|
89 |
+
<?php
|
90 |
+
wp_nonce_field( 'lingotek-content-types', '_wpnonce_lingotek-content-types' );
|
91 |
|
92 |
+
$table = new Lingotek_Content_Table( $content_types );
|
93 |
+
$table->prepare_items( $data );
|
94 |
$table->display();
|
95 |
|
96 |
+
submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false );
|
97 |
?>
|
98 |
</form>
|
admin/manage/view-custom-fields.php
CHANGED
@@ -2,102 +2,112 @@
|
|
2 |
|
3 |
global $polylang;
|
4 |
|
5 |
-
$items
|
6 |
-
$default_setting
|
|
|
|
|
|
|
|
|
7 |
$default_custom_fields = '';
|
8 |
|
9 |
-
if (!empty($_POST)) {
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
$
|
|
|
60 |
|
61 |
?>
|
62 |
|
63 |
-
<h3><?php _e('Custom Field Configuration', 'lingotek-translation'); ?></h3>
|
64 |
<p class="description">
|
65 |
-
|
66 |
</p>
|
67 |
|
68 |
<form id="lingotek-custom-fields" method="post" action="admin.php?page=lingotek-translation_manage&sm=custom-fields"
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
101 |
</form>
|
102 |
|
103 |
|
@@ -131,4 +141,4 @@ function toggle(source) {
|
|
131 |
checkboxes[i].checked = source.checked;
|
132 |
}
|
133 |
|
134 |
-
</script>" ?>
|
2 |
|
3 |
global $polylang;
|
4 |
|
5 |
+
$items = array();
|
6 |
+
$default_setting = array(
|
7 |
+
'ignore' => 'Ignore',
|
8 |
+
'translate' => 'Translate',
|
9 |
+
'copy' => 'Copy',
|
10 |
+
);
|
11 |
$default_custom_fields = '';
|
12 |
|
13 |
+
if ( ! empty( $_POST ) ) {
|
14 |
+
check_admin_referer( 'lingotek-custom-fields', '_wpnonce_lingotek-custom-fields' );
|
15 |
+
|
16 |
+
if ( ! empty( $_POST['submit'] ) ) {
|
17 |
+
$arr = empty( $_POST['settings'] ) ? array() : $_POST['settings'];
|
18 |
+
|
19 |
+
if ( isset( $_POST['default_custom_fields'] ) ) {
|
20 |
+
$default_custom_fields = $_POST['default_custom_fields'];
|
21 |
+
update_option( 'lingotek_default_custom_fields', $default_custom_fields, false );
|
22 |
+
}
|
23 |
+
update_option( 'lingotek_custom_fields', $arr, false );
|
24 |
+
$post_types = get_post_types();
|
25 |
+
foreach ( $post_types as $post_type ) {
|
26 |
+
$cache_key = 'content_type_fields_' . $post_type;
|
27 |
+
wp_cache_delete( $cache_key, 'lingotek' );
|
28 |
+
}
|
29 |
+
add_settings_error( 'lingotek_custom_fields_save', 'custom_fields', __( 'Your <i>Custom Fields</i> were sucessfully saved.', 'lingotek-translation' ), 'updated' );
|
30 |
+
}
|
31 |
+
|
32 |
+
// Bulk Change.
|
33 |
+
if ( ! empty( $_POST['submit2'] ) ) {
|
34 |
+
$arr = empty( $_POST['settings'] ) ? array() : $_POST['settings'];
|
35 |
+
|
36 |
+
if ( isset( $_POST['custom_fields'] ) ) {
|
37 |
+
$custom_fields = $_POST['custom_fields'];
|
38 |
+
}
|
39 |
+
foreach ( $_POST as $post => $value ) {
|
40 |
+
if ( $value == 'value1' ) {
|
41 |
+
$temp = explode( '_', $post );
|
42 |
+
$temp = implode( ' ', $temp );
|
43 |
+
|
44 |
+
foreach ( $arr as $item => $val ) {
|
45 |
+
$temp2 = explode( '_', $item );
|
46 |
+
$temp2 = implode( ' ', $temp2 );
|
47 |
+
if ( $temp == $temp2 ) {
|
48 |
+
$arr[ $item ] = $custom_fields;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
52 |
+
}
|
53 |
+
update_option( 'lingotek_custom_fields', $arr, false );
|
54 |
+
}//end if
|
55 |
+
|
56 |
+
if ( ! empty( $_POST['refresh'] ) ) {
|
57 |
+
Lingotek_Group_Post::get_updated_meta_values();
|
58 |
+
add_settings_error( 'lingotek_custom_fields_refresh', 'custom_fields', __( 'Your <i>Custom Fields</i> were sucessfully identified.', 'lingotek-translation' ), 'updated' );
|
59 |
+
}
|
60 |
+
settings_errors();
|
61 |
+
}//end if
|
62 |
+
|
63 |
+
$items = Lingotek_Group_Post::get_cached_meta_values();
|
64 |
+
$default_custom_fields = get_option( 'lingotek_default_custom_fields' );
|
65 |
|
66 |
?>
|
67 |
|
68 |
+
<h3><?php _e( 'Custom Field Configuration', 'lingotek-translation' ); ?></h3>
|
69 |
<p class="description">
|
70 |
+
<?php _e( 'Custom Fields can be translated, copied, or ignored. Click "Refresh Custom Fields" to identify and enable your custom fields.', 'lingotek-translation' ); ?>
|
71 |
</p>
|
72 |
|
73 |
<form id="lingotek-custom-fields" method="post" action="admin.php?page=lingotek-translation_manage&sm=custom-fields"
|
74 |
+
class="validate">
|
75 |
+
<?php
|
76 |
+
wp_nonce_field( 'lingotek-custom-fields', '_wpnonce_lingotek-custom-fields' );
|
77 |
+
?>
|
78 |
+
|
79 |
+
<br>
|
80 |
+
<label for="default_custom_fields">Default configuration for new Custom Fields</label>
|
81 |
+
<select name="default_custom_fields">
|
82 |
+
<?php
|
83 |
+
foreach ( $default_setting as $key => $title ) {
|
84 |
+
$selected = $key == $default_custom_fields ? 'selected="selected"' : '';
|
85 |
+
echo "\n\t<option value='" . $key . "' $selected>" . $title . '</option>';
|
86 |
+
}
|
87 |
+
?>
|
88 |
+
</select>
|
89 |
+
</br>
|
90 |
+
<div id="d1" style="display: none;">
|
91 |
+
<select name="custom_fields">
|
92 |
+
<?php
|
93 |
+
foreach ( $default_setting as $key => $title ) {
|
94 |
+
$selected = $key == $default_custom_fields ? 'selected="selected"' : '';
|
95 |
+
echo "\n\t<option value='" . $key . "' $selected>" . $title . '</option>';
|
96 |
+
}
|
97 |
+
?>
|
98 |
+
</select>
|
99 |
+
<?php
|
100 |
+
submit_button( __( 'Bulk Change', 'lingotek-translation' ), 'primary', 'submit2', false );
|
101 |
+
echo '</div>';
|
102 |
+
$table = new Lingotek_Custom_Fields_Table();
|
103 |
+
$table->prepare_items( $items );
|
104 |
+
$table->display();
|
105 |
+
?>
|
106 |
+
|
107 |
+
<p>
|
108 |
+
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
109 |
+
<?php submit_button( __( 'Refresh Custom Fields', 'lingotek-translation' ), 'secondary', 'refresh', false ); ?>
|
110 |
+
</p>
|
111 |
</form>
|
112 |
|
113 |
|
141 |
checkboxes[i].checked = source.checked;
|
142 |
}
|
143 |
|
144 |
+
</script>" ?>
|
admin/manage/view-edit-profile.php
CHANGED
@@ -2,136 +2,164 @@
|
|
2 |
|
3 |
$settings = $this->get_profiles_settings();
|
4 |
|
5 |
-
$defaults = get_option('lingotek_defaults');
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
$
|
|
|
11 |
}
|
12 |
}
|
13 |
|
14 |
$target_settings = array(
|
15 |
-
'default' => __('Use default settings', 'lingotek-translation'),
|
16 |
-
'custom' => __('Use custom settings', 'lingotek-translation'),
|
17 |
-
'copy'
|
18 |
-
'disabled' => __('Disabled', 'lingotek-translation')
|
19 |
);
|
20 |
|
21 |
-
$profiles = $this->get_profiles_usage(get_option('lingotek_profiles'));
|
22 |
|
23 |
-
$profile
|
24 |
-
$disabled = isset($profile['profile']) && in_array($profile['profile'], array('automatic', 'manual')) ? 'disabled="disabled"' : '';
|
25 |
// Code to determine which filter scenario will be displayed. (Not configured, defaults, custom filters)
|
26 |
-
$primary_filter_id
|
27 |
-
$secondary_filter_id
|
28 |
-
$default_filters
|
29 |
-
$
|
30 |
-
$
|
31 |
-
|
|
|
|
|
|
|
32 |
|
33 |
-
if (array_key_exists('default', array_diff_assoc($settings['primary_filter_id']['options'], $default_filters)) && count(array_diff_assoc($settings['primary_filter_id']['options'], $default_filters))
|
34 |
-
unset($settings['primary_filter_id']['options']['default']);
|
35 |
-
}
|
36 |
-
if ($settings['primary_filter_id']['options'] == $default_filters) {
|
37 |
-
$default_filters_exist = TRUE;
|
38 |
-
$defaults['primary_filter_id'] = $primary_filter_id;
|
39 |
-
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
40 |
-
update_option('lingotek_defaults', $defaults, false);
|
41 |
}
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
53 |
}
|
54 |
-
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=lingotek-translation_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 |
|
62 |
<table class="form-table">
|
63 |
<tr>
|
64 |
-
<th scope="row"><?php printf('<label for="%s">%s</label>', 'name'
|
65 |
-
<td
|
66 |
-
|
67 |
-
|
|
|
|
|
68 |
}
|
69 |
-
printf(
|
70 |
-
|
71 |
-
$
|
72 |
-
|
|
|
|
|
73 |
</td>
|
74 |
</tr>
|
75 |
</table>
|
76 |
|
77 |
-
<h3><?php
|
78 |
|
79 |
-
<table class="form-table"
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
-
if ('project_id' == $key) {
|
|
|
92 |
<input type="checkbox" name="update_callback" id="update_callback"/>
|
93 |
-
<label for="update_callback"><?php _e('Update the callback url for this project.', 'lingotek-translation') ?></label
|
|
|
94 |
}
|
95 |
|
96 |
-
if (isset($setting['description']))
|
97 |
-
printf('<p class="description">%s</p>', $setting['description'])
|
|
|
|
|
98 |
|
99 |
<!-- Code to handle displaying of Primary and Secondary Filters -->
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
112 |
</td>
|
113 |
-
</tr
|
114 |
-
|
|
|
|
|
|
|
115 |
</table>
|
116 |
|
117 |
-
<h3><?php _e('Target languages', 'lingotek-translation'); ?></h3>
|
118 |
|
119 |
-
<table class="form-table target-table"
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
122 |
// Filters not needed for target languages
|
123 |
-
unset($settings['primary_filter_id']);
|
124 |
-
unset($settings['secondary_filter_id']);
|
125 |
-
|
126 |
<?php
|
127 |
$custom_profile_chosen = false;
|
128 |
-
foreach ($this->pllm->get_languages_list() as $language) {
|
|
|
129 |
<tr>
|
130 |
-
<th scope="row"><?php printf('<label for="%s">%s (%s)</label>', esc_attr($language->slug)
|
|
|
131 |
|
132 |
-
printf(
|
133 |
-
|
134 |
-
|
|
|
135 |
"
|
136 |
d = document.getElementById('{$language->slug}_details');
|
137 |
if ('none' == d.style.display) {
|
@@ -142,12 +170,15 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
142 |
d.style.display = 'none';
|
143 |
this.className = 'dashicons dashicons-arrow-right';
|
144 |
}",
|
145 |
-
''
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
151 |
"
|
152 |
dl = document.getElementById('{$language->slug}_details_link');
|
153 |
d = document.getElementById('{$language->slug}_details');
|
@@ -183,65 +214,74 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
183 |
}
|
184 |
"
|
185 |
);
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
|
|
190 |
</select>
|
191 |
|
192 |
</td>
|
193 |
<?php
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
$checked = empty($profile['target_locales'][$language->slug]) ? '' : 'checked="checked"';
|
198 |
$display = '';
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
?>
|
203 |
<td><input
|
204 |
<?php echo $checked; ?>
|
205 |
<?php echo $display; ?>
|
206 |
type="checkbox"
|
207 |
class="ltk-target-checkbox"
|
208 |
-
value="<?php echo esc_attr($language->lingotek_locale); ?>"
|
209 |
-
id="target_locales[<?php echo esc_attr($language->slug); ?>]"
|
210 |
-
name="target_locales[<?php echo esc_attr($language->slug); ?>]"
|
211 |
>
|
212 |
<label
|
213 |
<?php echo $display; ?>
|
214 |
-
for="target_locales[<?php echo esc_attr($language->slug); ?>]"
|
215 |
-
id="target_locales_label[<?php echo esc_attr($language->slug); ?>]">Auto-request with document upload
|
216 |
</label>
|
217 |
</td>
|
218 |
</tr>
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
|
|
224 |
<tr>
|
225 |
-
<th scope="row"
|
226 |
-
<td
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
|
|
|
|
235 |
</select>
|
236 |
</td>
|
237 |
-
</tr
|
238 |
-
|
|
|
|
|
239 |
</table>
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
}
|
244 |
-
|
|
|
|
|
245 |
<td></td>
|
246 |
<td class="target-table-td"></td>
|
247 |
<td>
|
@@ -256,67 +296,70 @@ unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
|
256 |
}
|
257 |
";
|
258 |
?>
|
259 |
-
<input type="checkbox" name="target_select_all" id="target_select_all" onchange="<?php echo $select_all_on_change; ?>">
|
260 |
-
<label for="target_select_all"
|
261 |
-
|
262 |
-
|
263 |
$target_warning = $custom_profile_chosen ? '' : 'style="display:none"';
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
</table>
|
270 |
|
271 |
-
<?php
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
|
|
|
|
289 |
<table class="form-table">
|
290 |
-
<?php
|
291 |
-
foreach ($metadata as $key => $data){
|
292 |
-
$index = array_search($key,array_keys($metadata));
|
293 |
-
if ($index
|
294 |
-
printf('<tr>');
|
295 |
-
}
|
296 |
-
if ($index %3 == 0){
|
297 |
-
printf('</tr>');
|
298 |
-
printf('<tr>');
|
299 |
}
|
300 |
-
if (
|
301 |
-
printf('
|
|
|
302 |
}
|
303 |
-
|
304 |
-
|
|
|
|
|
305 |
}
|
306 |
}
|
307 |
?>
|
308 |
-
</table>
|
309 |
|
310 |
-
<?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
|
311 |
<?php
|
312 |
-
if (!empty($profile['profile']) && !in_array($profile['profile'], array('automatic', 'manual', 'disabled')) && empty($profile['usage']))
|
313 |
printf(
|
314 |
'<a href="%s" class="button" onclick = "return confirm(\'%s\');">%s</a>',
|
315 |
-
esc_url(wp_nonce_url('admin.php?page=lingotek-translation_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile='
|
316 |
-
|
317 |
-
|
318 |
);
|
319 |
-
|
|
|
|
|
320 |
</form>
|
321 |
|
322 |
-
<?php Lingotek_Workflow_Factory::
|
2 |
|
3 |
$settings = $this->get_profiles_settings();
|
4 |
|
5 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
6 |
+
/* translators: %s: The global default value. */
|
7 |
+
$default = __( 'Use global default (%s)', 'lingotek-translation' );
|
8 |
+
foreach ( $settings as $key => $setting ) {
|
9 |
+
if ( isset( $defaults[ $key ] ) && array_key_exists( $defaults[ $key ], $settings[ $key ]['options'] ) ) {
|
10 |
+
$default_arr = array( 'default' => sprintf( $default, $settings[ $key ]['options'][ $defaults[ $key ] ] ) );
|
11 |
+
$settings[ $key ]['options'] = array_merge( $default_arr, $settings[ $key ]['options'] );
|
12 |
}
|
13 |
}
|
14 |
|
15 |
$target_settings = array(
|
16 |
+
'default' => __( 'Use default settings', 'lingotek-translation' ),
|
17 |
+
'custom' => __( 'Use custom settings', 'lingotek-translation' ),
|
18 |
+
'copy' => __( 'Copy source language', 'lingotek-translation' ),
|
19 |
+
'disabled' => __( 'Disabled', 'lingotek-translation' ),
|
20 |
);
|
21 |
|
22 |
+
$profiles = $this->get_profiles_usage( get_option( 'lingotek_profiles' ) );
|
23 |
|
24 |
+
$profile = isset( $_GET['profile'] ) && array_key_exists( sanitize_key( wp_unslash( $_GET['profile'] ) ), $profiles ) ? $profiles[ sanitize_key( wp_unslash( $_GET['profile'] ) ) ] : array();
|
25 |
+
$disabled = isset( $profile['profile'] ) && in_array( $profile['profile'], array( 'automatic', 'manual' ), true ) ? 'disabled="disabled"' : '';
|
26 |
// Code to determine which filter scenario will be displayed. (Not configured, defaults, custom filters)
|
27 |
+
$primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options'], true );
|
28 |
+
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $settings['secondary_filter_id']['options'], true );
|
29 |
+
$default_filters = array(
|
30 |
+
$primary_filter_id => 'okf_json@with-html-subfilter.fprm',
|
31 |
+
$secondary_filter_id => 'okf_html@wordpress.fprm',
|
32 |
+
);
|
33 |
+
$default_filters_exist = false;
|
34 |
+
$extra_filters_exist = false;
|
35 |
+
$no_filters_exist = false;
|
36 |
|
37 |
+
if ( array_key_exists( 'default', array_diff_assoc( $settings['primary_filter_id']['options'], $default_filters ) ) && 1 === count( array_diff_assoc( $settings['primary_filter_id']['options'], $default_filters ) ) ) {
|
38 |
+
unset( $settings['primary_filter_id']['options']['default'] );
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
+
if ( $settings['primary_filter_id']['options'] === $default_filters ) {
|
41 |
+
$default_filters_exist = true;
|
42 |
+
$defaults['primary_filter_id'] = $primary_filter_id;
|
43 |
+
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
44 |
+
update_option( 'lingotek_defaults', $defaults, false );
|
45 |
+
} else {
|
46 |
+
$num = count( array_diff_assoc( $settings['primary_filter_id']['options'], $default_filters ) );
|
47 |
+
if ( $num > 0 ) {
|
48 |
+
$extra_filters_exist = true;
|
49 |
+
} else {
|
50 |
+
$defaults['primary_filter_id'] = '';
|
51 |
+
$defaults['secondary_filter_id'] = '';
|
52 |
+
update_option( 'lingotek_defaults', $defaults, false );
|
53 |
+
$no_filters_exist = true;
|
54 |
+
}
|
55 |
}
|
56 |
+
unset( $settings['primary_filter_id']['options'][ $secondary_filter_id ] );
|
57 |
+
unset( $settings['secondary_filter_id']['options'][ $primary_filter_id ] );
|
58 |
?>
|
59 |
|
60 |
<form id="lingotek-edit-profile" method="post" action="admin.php?page=lingotek-translation_manage&sm=profiles" class="validate">
|
61 |
+
<?php wp_nonce_field( 'lingotek-edit-profile', '_wpnonce_lingotek-edit-profile' ); ?>
|
62 |
+
<input name="profile" type="hidden" value="<?php echo empty( $profile['profile'] ) ? '' : esc_attr( $profile['profile'] ); ?>">
|
63 |
|
64 |
<table class="form-table">
|
65 |
<tr>
|
66 |
+
<th scope="row"><?php printf( '<label for="%s">%s</label>', 'name', esc_attr__( 'Profile name', 'lingotek-translation' ) ); ?></th>
|
67 |
+
<td>
|
68 |
+
<?php
|
69 |
+
if ( ! empty( $profile ) ) {
|
70 |
+
// localize canned profile names
|
71 |
+
$profile_name = $disabled ? __( 'Disabled', 'lingotek-translation' ) : $profile['name'];
|
72 |
}
|
73 |
+
printf(
|
74 |
+
'<input name="name" id="name" type="text" value="%s" %s>',
|
75 |
+
empty( $profile['name'] ) ? '' : esc_attr( $profile_name ),
|
76 |
+
esc_html( $disabled )
|
77 |
+
);
|
78 |
+
?>
|
79 |
</td>
|
80 |
</tr>
|
81 |
</table>
|
82 |
|
83 |
+
<h3><?php esc_html_e( 'Default settings', 'lingotek-translation' ); ?></h3>
|
84 |
|
85 |
+
<table class="form-table">
|
86 |
+
<?php
|
87 |
+
foreach ( $settings as $key => $setting ) {
|
88 |
+
?>
|
89 |
+
<tr id="<?php echo $key . '_row'; ?>">
|
90 |
+
<th scope="row"><?php printf( '<label for="%s">%s</label>', $key, $setting['label'] ); ?></th>
|
91 |
+
<td>
|
92 |
+
<?php
|
93 |
+
printf( '<select name="%1$s" id="%1$s" %2$s>', $key, in_array( $key, array( 'upload', 'download' ) ) ? $disabled : '' );
|
94 |
+
foreach ( $setting['options'] as $option_id => $option_title ) {
|
95 |
+
$selected = isset( $profile[ $key ] ) && $profile[ $key ] == $option_id ? 'selected="selected"' : '';
|
96 |
+
echo "\n\t<option value='" . esc_attr( $option_id ) . "' $selected>" . esc_html( $option_title ) . '</option>';
|
97 |
+
}
|
98 |
+
?>
|
99 |
+
</select>
|
100 |
+
<?php
|
101 |
|
102 |
+
if ( 'project_id' == $key ) {
|
103 |
+
?>
|
104 |
<input type="checkbox" name="update_callback" id="update_callback"/>
|
105 |
+
<label for="update_callback"><?php _e( 'Update the callback url for this project.', 'lingotek-translation' ); ?></label>
|
106 |
+
<?php
|
107 |
}
|
108 |
|
109 |
+
if ( isset( $setting['description'] ) ) {
|
110 |
+
printf( '<p class="description">%s</p>', $setting['description'] );
|
111 |
+
}
|
112 |
+
?>
|
113 |
|
114 |
<!-- Code to handle displaying of Primary and Secondary Filters -->
|
115 |
+
<?php if ( $no_filters_exist ) { ?>
|
116 |
+
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
117 |
+
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
118 |
+
<?php
|
119 |
+
if ( 'primary_filter_id' == $key ) {
|
120 |
+
?>
|
121 |
+
<tr id="filters_row"><th><?php _e( 'Filters', 'lingotek-translation' ); ?></th><td><i><?php _e( 'Not configured', 'lingotek-translation' ); ?></i></td></tr>
|
122 |
+
<?php
|
123 |
+
}
|
124 |
+
}
|
125 |
+
if ( $default_filters_exist ) {
|
126 |
+
?>
|
127 |
+
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
128 |
+
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
129 |
+
<?php } ?>
|
130 |
+
<!-- End of filter code -->
|
131 |
</td>
|
132 |
+
</tr>
|
133 |
+
<?php
|
134 |
+
}//end foreach
|
135 |
+
|
136 |
+
?>
|
137 |
</table>
|
138 |
|
139 |
+
<h3><?php _e( 'Target languages', 'lingotek-translation' ); ?></h3>
|
140 |
|
141 |
+
<table class="form-table target-table">
|
142 |
+
<?php
|
143 |
+
// we don't want this for target languages
|
144 |
+
unset( $settings['upload'] );
|
145 |
+
// FIXME disable the possibility to have a different project per target language for now
|
146 |
+
unset( $settings['project_id'] );
|
147 |
// Filters not needed for target languages
|
148 |
+
unset( $settings['primary_filter_id'] );
|
149 |
+
unset( $settings['secondary_filter_id'] );
|
150 |
+
?>
|
151 |
<?php
|
152 |
$custom_profile_chosen = false;
|
153 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
154 |
+
?>
|
155 |
<tr>
|
156 |
+
<th scope="row"><?php printf( '<label for="%s">%s (%s)</label>', esc_attr( $language->slug ), esc_html( $language->name ), esc_attr( $language->locale ) ); ?>
|
157 |
+
<?php
|
158 |
|
159 |
+
printf(
|
160 |
+
'<a id="%1$s_details_link" %2$s class="dashicons dashicons-arrow-right" onclick="%3$s">%4$s</a>',
|
161 |
+
esc_attr( $language->slug ),
|
162 |
+
isset( $profile['targets'][ $language->slug ] ) && 'custom' == $profile['targets'][ $language->slug ] ? '' : 'style="display:none;"',
|
163 |
"
|
164 |
d = document.getElementById('{$language->slug}_details');
|
165 |
if ('none' == d.style.display) {
|
170 |
d.style.display = 'none';
|
171 |
this.className = 'dashicons dashicons-arrow-right';
|
172 |
}",
|
173 |
+
''
|
174 |
+
);
|
175 |
+
?>
|
176 |
+
</th>
|
177 |
+
<td class="target-table-td">
|
178 |
+
<?php
|
179 |
+
printf(
|
180 |
+
'<select name="targets[%1$s]" id="targets[%1$s]" onchange="%2$s">',
|
181 |
+
esc_attr( $language->slug ),
|
182 |
"
|
183 |
dl = document.getElementById('{$language->slug}_details_link');
|
184 |
d = document.getElementById('{$language->slug}_details');
|
214 |
}
|
215 |
"
|
216 |
);
|
217 |
+
foreach ( $target_settings as $target_id => $target_title ) {
|
218 |
+
$selected = ( empty( $profile['targets'][ $language->slug ] ) && 'default' === $target_id ) || ( isset( $profile['targets'][ $language->slug ] ) && $profile['targets'][ $language->slug ] === $target_id ) ? 'selected="selected"' : '';
|
219 |
+
echo "\n\t<option value='" . esc_attr( $target_id ) . "' $selected>" . esc_html( $target_title ) . '</option>';
|
220 |
+
}
|
221 |
+
?>
|
222 |
</select>
|
223 |
|
224 |
</td>
|
225 |
<?php
|
226 |
+
if ( isset( $profile['targets'][ $language->slug ] ) && 'custom' === $profile['targets'][ $language->slug ] ) {
|
227 |
+
$custom_profile_chosen = true;
|
228 |
+
}
|
229 |
+
$checked = empty( $profile['target_locales'][ $language->slug ] ) ? '' : 'checked="checked"';
|
230 |
$display = '';
|
231 |
+
if ( isset( $profile['targets'][ $language->slug ] ) && ( 'disabled' === $profile['targets'][ $language->slug ] || 'copy' === $profile['targets'][ $language->slug ] ) ) {
|
232 |
+
$display = 'style="display:none;"';
|
233 |
+
}
|
234 |
?>
|
235 |
<td><input
|
236 |
<?php echo $checked; ?>
|
237 |
<?php echo $display; ?>
|
238 |
type="checkbox"
|
239 |
class="ltk-target-checkbox"
|
240 |
+
value="<?php echo esc_attr( $language->lingotek_locale ); ?>"
|
241 |
+
id="target_locales[<?php echo esc_attr( $language->slug ); ?>]"
|
242 |
+
name="target_locales[<?php echo esc_attr( $language->slug ); ?>]"
|
243 |
>
|
244 |
<label
|
245 |
<?php echo $display; ?>
|
246 |
+
for="target_locales[<?php echo esc_attr( $language->slug ); ?>]"
|
247 |
+
id="target_locales_label[<?php echo esc_attr( $language->slug ); ?>]">Auto-request with document upload
|
248 |
</label>
|
249 |
</td>
|
250 |
</tr>
|
251 |
+
<tr id="<?php echo esc_attr( $language->slug ); ?>_details" style="display:none;">
|
252 |
+
<td colspan="2" style="padding:0;">
|
253 |
+
<table class="form-table" style="background: #ffffff; margin:0; padding: 10px;">
|
254 |
+
<?php
|
255 |
+
foreach ( $settings as $key => $setting ) {
|
256 |
+
$custom_key = 'custom[' . $key . '][' . esc_attr( $language->slug ) . ']';
|
257 |
+
?>
|
258 |
<tr>
|
259 |
+
<th scope="row"><?php printf( '<label for="%s">%s</label>', esc_attr( $custom_key ), esc_attr( $setting['label'] ) ); ?></th>
|
260 |
+
<td>
|
261 |
+
<?php
|
262 |
+
printf( '<select name="%1$s" id="%1$s" %2$s>', $custom_key, in_array( $key, array( 'upload', 'download' ) ) ? $disabled : '' );
|
263 |
+
foreach ( $setting['options'] as $option_id => $option_title ) {
|
264 |
+
if ( 'default' === $option_id && 'workflow_id' === $key ) {
|
265 |
+
$option_id = $defaults['workflow_id'];
|
266 |
+
}
|
267 |
+
$selected = isset( $profile['custom'][ $key ][ $language->slug ] ) && $profile['custom'][ $key ][ $language->slug ] == $option_id ? 'selected="selected"' : '';
|
268 |
+
echo "\n\t<option value='" . esc_attr( $option_id ) . "' $selected>" . esc_html( $option_title ) . '</option>';
|
269 |
+
}
|
270 |
+
?>
|
271 |
</select>
|
272 |
</td>
|
273 |
+
</tr>
|
274 |
+
<?php
|
275 |
+
}//end foreach
|
276 |
+
?>
|
277 |
</table>
|
278 |
+
</td>
|
279 |
+
</tr>
|
280 |
+
<?php
|
281 |
+
}//end foreach
|
282 |
+
|
283 |
+
?>
|
284 |
+
<tr>
|
285 |
<td></td>
|
286 |
<td class="target-table-td"></td>
|
287 |
<td>
|
296 |
}
|
297 |
";
|
298 |
?>
|
299 |
+
<input type="checkbox" name="target_select_all" id="target_select_all" onchange="<?php echo esc_attr( $select_all_on_change ); ?>">
|
300 |
+
<label for="target_select_all"><?php esc_html_e( 'Select All', 'lingotek-translation' ); ?></label></td>
|
301 |
+
</tr>
|
302 |
+
<?php
|
303 |
$target_warning = $custom_profile_chosen ? '' : 'style="display:none"';
|
304 |
+
?>
|
305 |
+
<tr>
|
306 |
+
<td colspan="3"><span id='target_warning' <?php echo $target_warning; ?>><b>Note:</b> If any targets are selected to be uploaded and at the same time a custom workflow is selected
|
307 |
+
for any of them, all targets to be uploaded must have a non-project-default workflow selected.</span></td>
|
308 |
+
</tr>
|
309 |
</table>
|
310 |
|
311 |
+
<?php
|
312 |
+
$metadata = array(
|
313 |
+
'author_email' => 'Author Email',
|
314 |
+
'author_name' => 'Author Name',
|
315 |
+
'division' => 'Business Division',
|
316 |
+
'unit' => 'Business Unit',
|
317 |
+
'campaign_id' => 'Campaign ID',
|
318 |
+
'channel' => 'Channel',
|
319 |
+
'contact_email' => 'Contact Email',
|
320 |
+
'contact_name' => 'Contact Name',
|
321 |
+
'description' => 'Content Description',
|
322 |
+
'domain' => 'Domain',
|
323 |
+
'style_id' => 'External Style ID',
|
324 |
+
'purchase_order' => 'Purchase Order',
|
325 |
+
'reference_url' => 'Reference URL',
|
326 |
+
'region' => 'Region',
|
327 |
+
'require_review' => 'Require Review',
|
328 |
+
)
|
329 |
+
?>
|
330 |
+
<h3><?php esc_html_e( 'Document Metadata', 'lingotek-translation' ); ?></h3>
|
331 |
<table class="form-table">
|
332 |
+
<?php
|
333 |
+
foreach ( $metadata as $key => $data ) {
|
334 |
+
$index = array_search( $key, array_keys( $metadata ), true );
|
335 |
+
if ( 0 === $index ) {
|
336 |
+
printf( '<tr>' );
|
|
|
|
|
|
|
|
|
337 |
}
|
338 |
+
if ( 0 === $index % 3 ) {
|
339 |
+
printf( '</tr>' );
|
340 |
+
printf( '<tr>' );
|
341 |
}
|
342 |
+
if ( isset( $profile[ $key ] ) ) {
|
343 |
+
printf( '<th> %s <br><input type="text" name="%s" value="%s"></th>', esc_html( $data ), esc_attr( $key ), esc_attr( $profile[ $key ] ) );
|
344 |
+
} else {
|
345 |
+
printf( '<th> %s <br><input type="text" name="%s"></th>', esc_html( $data ), esc_attr( $key ) );
|
346 |
}
|
347 |
}
|
348 |
?>
|
349 |
+
</table>
|
350 |
|
351 |
+
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
352 |
<?php
|
353 |
+
if ( ! empty( $profile['profile'] ) && ! in_array( $profile['profile'], array( 'automatic', 'manual', 'disabled' ), true ) && empty( $profile['usage'] ) ) {
|
354 |
printf(
|
355 |
'<a href="%s" class="button" onclick = "return confirm(\'%s\');">%s</a>',
|
356 |
+
esc_url( wp_nonce_url( 'admin.php?page=lingotek-translation_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile=' . $profile['profile'], 'delete-profile' ) ),
|
357 |
+
esc_html__( 'You are about to permanently delete this profile. Are you sure?', 'lingotek-translation' ),
|
358 |
+
esc_html__( 'Delete', 'lingotek-translation' )
|
359 |
);
|
360 |
+
}
|
361 |
+
?>
|
362 |
+
<a href="admin.php?page=lingotek-translation_manage&sm=profiles" class="button"> <?php esc_html_e( 'Cancel', 'lingotek-translation' ); ?></a>
|
363 |
</form>
|
364 |
|
365 |
+
<?php Lingotek_Workflow_Factory::lingotek_translation_professional_translation_info_modals(); ?>
|
admin/manage/view-profiles.php
CHANGED
@@ -2,125 +2,139 @@
|
|
2 |
global $polylang;
|
3 |
|
4 |
$profiles = Lingotek::get_profiles();
|
5 |
-
$profiles = $this->get_profiles_usage($profiles);
|
6 |
$settings = $this->get_profiles_settings();
|
7 |
|
8 |
-
if (isset($_GET['lingotek_action']) && 'delete-profile' == $_GET['lingotek_action']) {
|
9 |
-
check_admin_referer('delete-profile');
|
10 |
|
11 |
// check again that usage empty
|
12 |
-
if (!empty($profiles[$_GET['profile']]) && empty($profiles[$_GET['profile']]['usage'])) {
|
13 |
-
unset($profiles[$_GET['profile']]);
|
14 |
-
update_option('lingotek_profiles', $profiles, false);
|
15 |
-
add_settings_error('lingotek_profile', 'default', __('Your translation profile was sucessfully deleted.', 'lingotek-translation'), 'updated');
|
16 |
-
set_transient('settings_errors', get_settings_errors(), 30);
|
17 |
-
wp_redirect(admin_url('admin.php?page=lingotek-translation_manage&sm=profiles&settings-updated=1'));
|
18 |
exit;
|
19 |
}
|
20 |
}
|
21 |
|
22 |
-
if (!empty($_POST)) {
|
23 |
-
check_admin_referer('lingotek-edit-profile', '_wpnonce_lingotek-edit-profile');
|
24 |
|
25 |
-
$defaults = get_option('lingotek_defaults');
|
26 |
|
27 |
-
if (empty($_POST['name']) && empty($_POST['profile'])) {
|
28 |
-
add_settings_error('lingotek_profile', 'default', __('You must provide a name for your translation profile.', 'lingotek-translation'), 'error');
|
29 |
-
}
|
30 |
-
|
31 |
-
$profile_id
|
32 |
-
$
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
foreach (array('upload', 'download', 'project_id', 'workflow_id', 'primary_filter_id', 'secondary_filter_id','author_email', 'author_name','division','unit','campaign_id','channel','contact_email','contact_name','description','domain','style_id','purchase_order','reference_url','region','require_review') as $key) {
|
37 |
-
if (isset($_POST[$key]) )
|
38 |
-
$profiles[$profile_id][$key] = $_POST[$key];
|
39 |
-
|
40 |
-
|
41 |
-
|
|
|
|
|
42 |
}
|
43 |
|
44 |
-
$custom_profile_keys = array('download', 'project_id', 'workflow_id');
|
45 |
|
46 |
-
foreach ($this->pllm->get_languages_list() as $language) {
|
47 |
-
switch($_POST['targets'][$language->slug]) {
|
48 |
case 'custom':
|
49 |
-
foreach ($custom_profile_keys as $key) {
|
50 |
-
if (isset($_POST['custom'][$key][$language->slug]) && in_array($_POST['custom'][$key][$language->slug], array_keys($settings[$key]['options']))) {
|
51 |
-
$profiles[$profile_id]['custom'][$key][$language->slug] = $_POST['custom'][$key][$language->slug];
|
52 |
}
|
53 |
|
54 |
-
if ($key != 'workflow_id' && (empty($_POST['custom'][$key][$language->slug]) || 'default' == $_POST['custom'][$key][$language->slug])) {
|
55 |
-
unset($profiles[$profile_id]['custom'][$key][$language->slug]);
|
56 |
}
|
57 |
}
|
58 |
-
$profiles[$profile_id]['targets'][$language->slug] = $_POST['targets'][$language->slug];
|
59 |
break;
|
60 |
|
61 |
case 'disabled':
|
62 |
case 'copy':
|
63 |
-
$profiles[$profile_id]['targets'][$language->slug] = $_POST['targets'][$language->slug];
|
64 |
-
foreach ($custom_profile_keys as $key) {
|
65 |
-
unset($profiles[$profile_id]['custom'][$key][$language->slug]);
|
66 |
}
|
67 |
break;
|
68 |
|
69 |
case 'default':
|
70 |
-
unset($profiles[$profile_id]['targets'][$language->slug]);
|
71 |
-
foreach ($custom_profile_keys as $key) {
|
72 |
-
if ($key !== 'workflow_id') {
|
73 |
-
unset($profiles[$profile_id]['custom'][$key][$language->slug]);
|
74 |
}
|
75 |
}
|
|
|
|
|
|
|
76 |
}
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
79 |
}
|
80 |
-
}
|
81 |
-
if (!isset($_POST['custom']['workflow_id'])) {
|
82 |
-
unset($profiles[$profile_id]['custom']['workflow_id']);
|
83 |
}
|
84 |
|
85 |
// Add target locales to request
|
86 |
-
$profiles[$profile_id]['target_locales'] = empty($_POST['target_locales']) ? array() : $_POST['target_locales'];
|
87 |
|
88 |
-
//
|
89 |
$profiles['automatic']['upload'] = $profiles['automatic']['download'] = 'automatic';
|
90 |
-
$profiles['manual']['upload']
|
91 |
-
|
|
|
|
|
|
|
|
|
92 |
|
93 |
-
update_option('lingotek_profiles', $profiles, false);
|
94 |
-
add_settings_error('lingotek_profile', 'default', __('Your translation profile was sucessfully saved.', 'lingotek-translation'), 'updated');
|
95 |
|
96 |
-
if (isset($_POST['update_callback'])) {
|
97 |
-
$project_id = isset($profiles[$profile_id]['project_id']) ? $profiles[$profile_id]['project_id'] : $defaults['project_id'];
|
98 |
-
$client
|
99 |
-
if ($client->update_callback_url($project_id))
|
100 |
-
add_settings_error('lingotek_profile', 'default', __('Your callback url was successfully updated.', 'lingotek-translation'), 'updated');
|
|
|
101 |
}
|
102 |
-
}
|
103 |
settings_errors();
|
104 |
-
}
|
105 |
|
106 |
?>
|
107 |
-
<h3><?php _e('Translation Profiles', 'lingotek-translation'); ?></h3>
|
108 |
<p class="description">
|
109 |
-
|
110 |
-
</p
|
|
|
111 |
|
112 |
$table = new Lingotek_Profiles_Table();
|
113 |
-
$table->prepare_items($profiles);
|
114 |
?>
|
115 |
<style>
|
116 |
.tablenav {
|
117 |
-
|
118 |
}
|
119 |
</style>
|
120 |
<?php
|
121 |
$table->display();
|
122 |
printf(
|
123 |
'<a href="%s" class="button button-primary">%s</a>',
|
124 |
-
admin_url('admin.php?page=lingotek-translation_manage&sm=edit-profile'),
|
125 |
-
__('Add New Profile', 'lingotek-translation')
|
126 |
-
);
|
2 |
global $polylang;
|
3 |
|
4 |
$profiles = Lingotek::get_profiles();
|
5 |
+
$profiles = $this->get_profiles_usage( $profiles );
|
6 |
$settings = $this->get_profiles_settings();
|
7 |
|
8 |
+
if ( isset( $_GET['lingotek_action'] ) && 'delete-profile' == $_GET['lingotek_action'] ) {
|
9 |
+
check_admin_referer( 'delete-profile' );
|
10 |
|
11 |
// check again that usage empty
|
12 |
+
if ( ! empty( $profiles[ $_GET['profile'] ] ) && empty( $profiles[ $_GET['profile'] ]['usage'] ) ) {
|
13 |
+
unset( $profiles[ $_GET['profile'] ] );
|
14 |
+
update_option( 'lingotek_profiles', $profiles, false );
|
15 |
+
add_settings_error( 'lingotek_profile', 'default', __( 'Your translation profile was sucessfully deleted.', 'lingotek-translation' ), 'updated' );
|
16 |
+
set_transient( 'settings_errors', get_settings_errors(), 30 );
|
17 |
+
wp_redirect( admin_url( 'admin.php?page=lingotek-translation_manage&sm=profiles&settings-updated=1' ) );
|
18 |
exit;
|
19 |
}
|
20 |
}
|
21 |
|
22 |
+
if ( ! empty( $_POST ) ) {
|
23 |
+
check_admin_referer( 'lingotek-edit-profile', '_wpnonce_lingotek-edit-profile' );
|
24 |
|
25 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
26 |
|
27 |
+
if ( empty( $_POST['name'] ) && empty( $_POST['profile'] ) ) {
|
28 |
+
add_settings_error( 'lingotek_profile', 'default', __( 'You must provide a name for your translation profile.', 'lingotek-translation' ), 'error' );
|
29 |
+
} else {
|
30 |
+
$profile_id = empty( $_POST['profile'] ) ? uniqid( rand() ) : $_POST['profile'];
|
31 |
+
$profiles[ $profile_id ]['profile'] = $profile_id;
|
32 |
+
if ( ! empty( $_POST['name'] ) ) {
|
33 |
+
$profiles[ $profile_id ]['name'] = strip_tags( $_POST['name'] );
|
34 |
+
}
|
35 |
+
|
36 |
+
foreach ( array( 'upload', 'download', 'project_id', 'workflow_id', 'primary_filter_id', 'secondary_filter_id', 'author_email', 'author_name', 'division', 'unit', 'campaign_id', 'channel', 'contact_email', 'contact_name', 'description', 'domain', 'style_id', 'purchase_order', 'reference_url', 'region', 'require_review' ) as $key ) {
|
37 |
+
if ( isset( $_POST[ $key ] ) ) {
|
38 |
+
$profiles[ $profile_id ][ $key ] = $_POST[ $key ];
|
39 |
+
}
|
40 |
+
|
41 |
+
if ( empty( $_POST[ $key ] ) || 'default' == $_POST[ $key ] ) {
|
42 |
+
unset( $profiles[ $profile_id ][ $key ] );
|
43 |
+
}
|
44 |
}
|
45 |
|
46 |
+
$custom_profile_keys = array( 'download', 'project_id', 'workflow_id' );
|
47 |
|
48 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
49 |
+
switch ( $_POST['targets'][ $language->slug ] ) {
|
50 |
case 'custom':
|
51 |
+
foreach ( $custom_profile_keys as $key ) {
|
52 |
+
if ( isset( $_POST['custom'][ $key ][ $language->slug ] ) && in_array( $_POST['custom'][ $key ][ $language->slug ], array_keys( $settings[ $key ]['options'] ) ) ) {
|
53 |
+
$profiles[ $profile_id ]['custom'][ $key ][ $language->slug ] = $_POST['custom'][ $key ][ $language->slug ];
|
54 |
}
|
55 |
|
56 |
+
if ( $key != 'workflow_id' && ( empty( $_POST['custom'][ $key ][ $language->slug ] ) || 'default' == $_POST['custom'][ $key ][ $language->slug ] ) ) {
|
57 |
+
unset( $profiles[ $profile_id ]['custom'][ $key ][ $language->slug ] );
|
58 |
}
|
59 |
}
|
60 |
+
$profiles[ $profile_id ]['targets'][ $language->slug ] = $_POST['targets'][ $language->slug ];
|
61 |
break;
|
62 |
|
63 |
case 'disabled':
|
64 |
case 'copy':
|
65 |
+
$profiles[ $profile_id ]['targets'][ $language->slug ] = $_POST['targets'][ $language->slug ];
|
66 |
+
foreach ( $custom_profile_keys as $key ) {
|
67 |
+
unset( $profiles[ $profile_id ]['custom'][ $key ][ $language->slug ] );
|
68 |
}
|
69 |
break;
|
70 |
|
71 |
case 'default':
|
72 |
+
unset( $profiles[ $profile_id ]['targets'][ $language->slug ] );
|
73 |
+
foreach ( $custom_profile_keys as $key ) {
|
74 |
+
if ( $key !== 'workflow_id' ) {
|
75 |
+
unset( $profiles[ $profile_id ]['custom'][ $key ][ $language->slug ] );
|
76 |
}
|
77 |
}
|
78 |
+
}//end switch
|
79 |
+
if ( $_POST['targets'][ $language->slug ] != 'disabled' && isset( $_POST['custom']['workflow_id'][ $language->slug ] ) ) {
|
80 |
+
$profiles[ $profile_id ]['custom']['workflow_id'][ $language->slug ] = $_POST['custom']['workflow_id'][ $language->slug ];
|
81 |
}
|
82 |
+
// If target workflow is set to default, and there is another target with a custom workflow, set default workflow id
|
83 |
+
if ( $_POST['targets'][ $language->slug ] === 'default' && in_array( 'custom', $_POST['targets'] ) && isset( $_POST['custom']['workflow_id'][ $language->slug ] ) ) {
|
84 |
+
$profiles[ $profile_id ]['custom']['workflow_id'][ $language->slug ] = $_POST['workflow_id'];
|
85 |
+
} elseif ( $_POST['targets'][ $language->slug ] != 'disabled' && isset( $_POST['custom']['workflow_id'][ $language->slug ] ) ) {
|
86 |
+
$profiles[ $profile_id ]['custom']['workflow_id'][ $language->slug ] = $_POST['custom']['workflow_id'][ $language->slug ];
|
87 |
}
|
88 |
+
}//end foreach
|
89 |
+
if ( ! isset( $_POST['custom']['workflow_id'] ) ) {
|
90 |
+
unset( $profiles[ $profile_id ]['custom']['workflow_id'] );
|
91 |
}
|
92 |
|
93 |
// Add target locales to request
|
94 |
+
$profiles[ $profile_id ]['target_locales'] = empty( $_POST['target_locales'] ) ? array() : $_POST['target_locales'];
|
95 |
|
96 |
+
// Hardcode default values for automatic and manual profiles as the process above emptied them.
|
97 |
$profiles['automatic']['upload'] = $profiles['automatic']['download'] = 'automatic';
|
98 |
+
$profiles['manual']['upload'] = $profiles['manual']['download'] = 'manual';
|
99 |
+
|
100 |
+
// Do not localize names here.
|
101 |
+
$profiles['automatic']['name'] = 'Automatic';
|
102 |
+
$profiles['manual']['name'] = 'Manual';
|
103 |
+
$profiles['disabled']['name'] = 'Disabled';
|
104 |
|
105 |
+
update_option( 'lingotek_profiles', $profiles, false );
|
106 |
+
add_settings_error( 'lingotek_profile', 'default', __( 'Your translation profile was sucessfully saved.', 'lingotek-translation' ), 'updated' );
|
107 |
|
108 |
+
if ( isset( $_POST['update_callback'] ) ) {
|
109 |
+
$project_id = isset( $profiles[ $profile_id ]['project_id'] ) ? $profiles[ $profile_id ]['project_id'] : $defaults['project_id'];
|
110 |
+
$client = new Lingotek_API();
|
111 |
+
if ( $client->update_callback_url( $project_id ) ) {
|
112 |
+
add_settings_error( 'lingotek_profile', 'default', __( 'Your callback url was successfully updated.', 'lingotek-translation' ), 'updated' );
|
113 |
+
}
|
114 |
}
|
115 |
+
}//end if
|
116 |
settings_errors();
|
117 |
+
}//end if
|
118 |
|
119 |
?>
|
120 |
+
<h3><?php _e( 'Translation Profiles', 'lingotek-translation' ); ?></h3>
|
121 |
<p class="description">
|
122 |
+
<?php _e( 'Translation profiles allow you to quickly configure and re-use translation settings.', 'lingotek-translation' ); ?>
|
123 |
+
</p>
|
124 |
+
<?php
|
125 |
|
126 |
$table = new Lingotek_Profiles_Table();
|
127 |
+
$table->prepare_items( $profiles );
|
128 |
?>
|
129 |
<style>
|
130 |
.tablenav {
|
131 |
+
clear: none !important;
|
132 |
}
|
133 |
</style>
|
134 |
<?php
|
135 |
$table->display();
|
136 |
printf(
|
137 |
'<a href="%s" class="button button-primary">%s</a>',
|
138 |
+
admin_url( 'admin.php?page=lingotek-translation_manage&sm=edit-profile' ),
|
139 |
+
__( 'Add New Profile', 'lingotek-translation' )
|
140 |
+
);
|
admin/manage/view-string-groups.php
CHANGED
@@ -1,41 +1,49 @@
|
|
1 |
-
<h3><?php _e('String Groups', 'lingotek-translation'); ?></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.', 'lingotek-translation'), 'admin.php?page=lingotek-translation_manage&sm=strings'); ?></p>
|
4 |
<?php
|
5 |
|
6 |
-
$profile = Lingotek_Model::get_profile('string', $this->pllm->get_language($this->pllm->options['default_lang']));
|
7 |
|
8 |
-
if ('disabled' == $profile['profile']) {
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
12 |
'</a>'
|
13 |
)
|
14 |
);
|
15 |
-
}
|
16 |
-
else {
|
17 |
$string_actions = $GLOBALS['wp_lingotek']->string_actions;
|
18 |
-
$table
|
19 |
-
$action
|
20 |
-
if (!empty($action)) {
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
24 |
|
25 |
$data = Lingotek_Model::get_strings();
|
26 |
-
foreach ($data as $key => $row) {
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
31 |
|
32 |
-
<form id="lingotek-strings" method="post" action="admin.php?page=lingotek-translation_manage&noheader=true&sm=string-groups"
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
35 |
|
36 |
-
foreach (Lingotek_String_actions::$actions as $action => $strings) {
|
37 |
-
if (!empty($_GET['bulk-lingotek-' . $action])) {
|
38 |
-
printf('<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', $strings['progress']);
|
39 |
-
|
40 |
}
|
41 |
-
}
|
1 |
+
<h3><?php _e( 'String Groups', 'lingotek-translation' ); ?></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.', 'lingotek-translation' ), 'admin.php?page=lingotek-translation_manage&sm=strings' ); ?></p>
|
4 |
<?php
|
5 |
|
6 |
+
$profile = Lingotek_Model::get_profile( 'string', $this->pllm->get_language( $this->pllm->options['default_lang'] ) );
|
7 |
|
8 |
+
if ( 'disabled' == $profile['profile'] ) {
|
9 |
+
// no warning class in WP 4.0, color form .update-nag
|
10 |
+
printf(
|
11 |
+
'<div class="error" style="border-left: 4px solid #ffba00;"><p>%s</p></div>',
|
12 |
+
sprintf(
|
13 |
+
__( 'The strings translation is disabled in %1$sContent Type Configuration%2$s.', 'lingotek-translation' ),
|
14 |
+
'<a href="' . admin_url( 'admin.php?page=lingotek-translation_settings&sm=content' ) . '">',
|
15 |
'</a>'
|
16 |
)
|
17 |
);
|
18 |
+
} else {
|
|
|
19 |
$string_actions = $GLOBALS['wp_lingotek']->string_actions;
|
20 |
+
$table = new Lingotek_Strings_Table( $string_actions );
|
21 |
+
$action = $table->current_action();
|
22 |
+
if ( ! empty( $action ) ) {
|
23 |
+
// flush the output buffer.
|
24 |
+
ob_end_clean();
|
25 |
+
$string_actions->manage_actions( $action );
|
26 |
+
}
|
27 |
|
28 |
$data = Lingotek_Model::get_strings();
|
29 |
+
foreach ( $data as $key => $row ) {
|
30 |
+
// Store the row number for convenience.
|
31 |
+
$data[ $key ]['row'] = $key;
|
32 |
+
}
|
33 |
+
|
34 |
+
$table->prepare_items( $data );
|
35 |
+
?>
|
36 |
|
37 |
+
<form id="lingotek-strings" method="post" action="admin.php?page=lingotek-translation_manage&noheader=true&sm=string-groups">
|
38 |
+
<?php
|
39 |
+
$table->display();
|
40 |
+
?>
|
41 |
+
</form>
|
42 |
+
<?php
|
43 |
|
44 |
+
foreach ( Lingotek_String_actions::$actions as $action => $strings ) {
|
45 |
+
if ( ! empty( $_GET[ 'bulk-lingotek-' . $action ] ) ) {
|
46 |
+
printf( '<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', $strings['progress'] );
|
47 |
+
}
|
48 |
}
|
49 |
+
}//end if
|
admin/manage/view-strings.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<h3 style="padding-top:10px; margin-top:10px; margin-bottom:-25px;"><?php _e('Strings', 'lingotek-translation'); ?> <a href="admin.php?page=mlang_strings" title="<?php _e('Edit on Polylang Strings Translation page', 'lingotek-translation'); ?>" class="dashicons dashicons-edit"></a></h3>
|
2 |
|
3 |
<?php
|
4 |
$listlanguages = $GLOBALS['polylang']->model->get_languages_list();
|
@@ -8,42 +8,49 @@ $listlanguages = $GLOBALS['polylang']->model->get_languages_list();
|
|
8 |
// get the strings to translate
|
9 |
$data = PLL_Admin_Strings::get_strings();
|
10 |
|
11 |
-
$selected = empty($_REQUEST['group']) ? -1 : $_REQUEST['group'];
|
12 |
-
foreach ($data as $key
|
13 |
-
|
|
|
14 |
|
15 |
// filter for search string
|
16 |
-
if (($selected
|
17 |
-
unset
|
|
|
18 |
}
|
19 |
|
20 |
-
$groups = array_unique($groups);
|
21 |
|
22 |
// load translations
|
23 |
-
foreach ($listlanguages as $language) {
|
24 |
// filters by language if requested
|
25 |
-
if (($lg = get_user_meta(get_current_user_id(), 'pll_filter_content', true)) && $language->slug != $lg)
|
26 |
continue;
|
|
|
27 |
|
28 |
$mo = new PLL_MO();
|
29 |
-
$mo->import_from_db($language);
|
30 |
-
foreach ($data as $key
|
31 |
-
$data[$key]['translations'][$language->slug] = $mo->translate($row['string']);
|
32 |
-
|
|
|
33 |
}
|
34 |
}
|
35 |
|
36 |
// get an array with language slugs as keys, names as values
|
37 |
-
$languages = array_combine(wp_list_pluck($listlanguages, 'slug'), wp_list_pluck($listlanguages, 'name'));
|
38 |
|
39 |
-
$string_table = new Lingotek_Table_String(compact('languages', 'groups', 'selected'));
|
40 |
-
$string_table->prepare_items($data);
|
|
|
41 |
|
42 |
<div class="form-wrap">
|
43 |
<form id="string-translation" method="post" action="admin.php?page=mlang_strings&noheader=true">
|
44 |
-
<input type="hidden" name="pll_action" value="string-translation"
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
</form>
|
49 |
</div>
|
1 |
+
<h3 style="padding-top:10px; margin-top:10px; margin-bottom:-25px;"><?php _e( 'Strings', 'lingotek-translation' ); ?> <a href="admin.php?page=mlang_strings" title="<?php _e( 'Edit on Polylang Strings Translation page', 'lingotek-translation' ); ?>" class="dashicons dashicons-edit"></a></h3>
|
2 |
|
3 |
<?php
|
4 |
$listlanguages = $GLOBALS['polylang']->model->get_languages_list();
|
8 |
// get the strings to translate
|
9 |
$data = PLL_Admin_Strings::get_strings();
|
10 |
|
11 |
+
$selected = empty( $_REQUEST['group'] ) ? -1 : $_REQUEST['group'];
|
12 |
+
foreach ( $data as $key => $row ) {
|
13 |
+
// get the groups
|
14 |
+
$groups[] = $row['context'];
|
15 |
|
16 |
// filter for search string
|
17 |
+
if ( ( $selected != -1 && $row['context'] != $selected ) || ( ! empty( $_REQUEST['s'] ) && stripos( $row['name'], $_REQUEST['s'] ) === false && stripos( $row['string'], $_REQUEST['s'] ) === false ) ) {
|
18 |
+
unset( $data[ $key ] );
|
19 |
+
}
|
20 |
}
|
21 |
|
22 |
+
$groups = array_unique( $groups );
|
23 |
|
24 |
// load translations
|
25 |
+
foreach ( $listlanguages as $language ) {
|
26 |
// filters by language if requested
|
27 |
+
if ( ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) && $language->slug != $lg ) {
|
28 |
continue;
|
29 |
+
}
|
30 |
|
31 |
$mo = new PLL_MO();
|
32 |
+
$mo->import_from_db( $language );
|
33 |
+
foreach ( $data as $key => $row ) {
|
34 |
+
$data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
|
35 |
+
// Store the row number for convenience.
|
36 |
+
$data[ $key ]['row'] = $key;
|
37 |
}
|
38 |
}
|
39 |
|
40 |
// get an array with language slugs as keys, names as values
|
41 |
+
$languages = array_combine( wp_list_pluck( $listlanguages, 'slug' ), wp_list_pluck( $listlanguages, 'name' ) );
|
42 |
|
43 |
+
$string_table = new Lingotek_Table_String( compact( 'languages', 'groups', 'selected' ) );
|
44 |
+
$string_table->prepare_items( $data );
|
45 |
+
?>
|
46 |
|
47 |
<div class="form-wrap">
|
48 |
<form id="string-translation" method="post" action="admin.php?page=mlang_strings&noheader=true">
|
49 |
+
<input type="hidden" name="pll_action" value="string-translation" />
|
50 |
+
<?php
|
51 |
+
$string_table->search_box( __( 'Search translations', 'lingotek-translation' ), 'translations' );
|
52 |
+
wp_nonce_field( 'string-translation', '_wpnonce_string-translation' );
|
53 |
+
$string_table->display();
|
54 |
+
?>
|
55 |
</form>
|
56 |
</div>
|
admin/post-actions.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
-
class
|
10 |
|
11 |
/**
|
12 |
* Constructor
|
@@ -16,30 +16,26 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
16 |
public function __construct() {
|
17 |
parent::__construct( 'post' );
|
18 |
|
19 |
-
//
|
20 |
add_filter( 'post_row_actions', array( &$this, 'post_row_actions' ), 10, 2 );
|
21 |
-
|
|
|
22 |
add_filter( 'media_row_actions', array( &$this, 'post_row_actions' ), 10, 2 );
|
23 |
|
24 |
// add bulk actions.
|
25 |
add_filter( 'bulk_actions-edit-post', array( &$this, 'add_bulk_actions' ) );
|
26 |
add_filter( 'bulk_actions-edit-page', array( &$this, 'add_bulk_actions' ) );
|
27 |
|
28 |
-
foreach(PLL()->model->get_translated_taxonomies() as $taxonomy) {
|
29 |
add_filter( "bulk_actions-edit-$taxonomy", array( &$this, 'add_bulk_actions' ) );
|
30 |
}
|
31 |
-
// add_filter( 'bulk_actions-edit-category', array( &$this, 'add_bulk_actions' ) );
|
32 |
|
33 |
$polylang_enabled = PLL()->model->get_translated_post_types();
|
34 |
-
|
35 |
-
|
36 |
|
37 |
-
foreach ( $
|
38 |
-
|
39 |
-
if (isset($polylang_enabled[$type]))
|
40 |
-
{
|
41 |
-
add_filter( "bulk_actions-edit-$type", array( &$this, 'add_bulk_actions' ) );
|
42 |
-
}
|
43 |
}
|
44 |
|
45 |
// manage bulk actions, row actions and icon actions.
|
@@ -113,22 +109,23 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
113 |
}
|
114 |
|
115 |
public function manage_promotions() {
|
116 |
-
if (null !== filter_input(INPUT_GET, 'ltk-promotion') && 'dismiss' === filter_input(INPUT_GET, 'ltk-promotion')) {
|
117 |
-
update_option('lingotek_professional_promotion_shown', true, false);
|
118 |
-
}
|
119 |
-
update_option('lingotek_professional_promotion_shown', true, false);
|
120 |
wp_safe_redirect( 'admin.php?page=lingotek-translation_tutorial&sm=content&tutorial=ltk-prof#ltk-prof-trans-header' );
|
121 |
die();
|
122 |
}
|
123 |
function lingotek_professional_translation_notice() {
|
124 |
-
echo sprintf(
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
|
|
128 |
);
|
129 |
}
|
130 |
-
|
131 |
-
if (!get_option('lingotek_professional_promotion_shown')) {
|
132 |
add_action( 'admin_notices', 'lingotek_professional_translation_notice' );
|
133 |
}
|
134 |
}
|
@@ -149,7 +146,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
149 |
// get the action.
|
150 |
// $typenow is empty for media.
|
151 |
$wp_list_table = _get_list_table( empty( $typenow ) ? 'WP_Media_List_Table' : 'WP_Posts_List_Table' );
|
152 |
-
$action
|
153 |
|
154 |
if ( empty( $action ) ) {
|
155 |
return;
|
@@ -162,7 +159,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
162 |
|
163 |
switch ( $action ) {
|
164 |
case 'bulk-lingotek-upload':
|
165 |
-
$type
|
166 |
$filtered_get = filter_input_array( INPUT_GET );
|
167 |
if ( ! isset( $filtered_get[ $type ] ) ) {
|
168 |
return;
|
@@ -174,13 +171,13 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
174 |
// safe upload.
|
175 |
if ( $this->lgtm->can_upload( 'post', $post_id ) ) {
|
176 |
$post_ids[] = $post_id;
|
177 |
-
|
178 |
-
elseif ( ($document = $this->lgtm->get_group( 'post', $post_id )) && empty( $document->source ) ) {
|
179 |
// take care to upload only one post in a translation group.
|
180 |
$intersect = array_intersect( $post_ids, PLL()->model->post->get_translations( $post_id ) );
|
181 |
if ( empty( $intersect ) ) {
|
182 |
$post_ids[] = $post_id;
|
183 |
-
$redirect
|
184 |
}
|
185 |
}
|
186 |
}
|
@@ -189,7 +186,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
189 |
if ( ! empty( $post_ids ) ) {
|
190 |
foreach ( $post_ids as $key => $post_id ) {
|
191 |
$language = PLL()->model->post->get_language( $post_id );
|
192 |
-
$profile
|
193 |
if ( 'disabled' === $profile['profile'] ) {
|
194 |
unset( $post_ids[ $key ] );
|
195 |
}
|
@@ -202,7 +199,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
202 |
case 'bulk-lingotek-delete':
|
203 |
case 'bulk-lingotek-cancel':
|
204 |
if ( empty( $post_ids ) ) {
|
205 |
-
$type
|
206 |
$filtered_get = filter_input_array( INPUT_GET );
|
207 |
if ( ! isset( $filtered_get[ $type ] ) ) {
|
208 |
return;
|
@@ -210,41 +207,41 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
210 |
|
211 |
$post_ids = array_map( 'intval', $filtered_get[ $type ] );
|
212 |
}
|
213 |
-
|
214 |
empty( $typenow ) ? check_admin_referer( 'bulk-media' ) : check_admin_referer( 'bulk-posts' );
|
215 |
-
if( $action
|
216 |
$redirect = add_query_arg( 'lingotek_remove', 1, $redirect );
|
217 |
}
|
218 |
$redirect = add_query_arg( $action, 1, $redirect );
|
219 |
$redirect = add_query_arg( 'ids', implode( ',', $post_ids ), $redirect );
|
220 |
break;
|
221 |
-
|
222 |
case 'lingotek-upload':
|
223 |
check_admin_referer( 'lingotek-upload' );
|
224 |
-
$id
|
225 |
-
$document = $this->lgtm->get_group('post', $id);
|
226 |
-
$this->lgtm->upload_post($id);
|
227 |
-
$redirect = add_query_arg( 'id', $id, $redirect);
|
228 |
-
$redirect = add_query_arg( 'type', 'post', $redirect);
|
229 |
-
$redirect = add_query_arg( 'source', $this->pllm->post->get_language($id)->locale, $redirect);
|
230 |
break;
|
231 |
|
232 |
case 'lingotek-copy':
|
233 |
check_admin_referer( 'lingotek-copy' );
|
234 |
$post_to_copy = get_post( (int) filter_input( INPUT_GET, 'post' ) );
|
235 |
-
$target
|
236 |
$this->lgtm->copy_post( $post_to_copy, $target );
|
237 |
break;
|
238 |
-
|
239 |
default:
|
240 |
if ( ! $this->_manage_actions( $action ) ) {
|
241 |
-
|
|
|
242 |
}
|
243 |
-
}
|
244 |
|
245 |
wp_safe_redirect( $redirect );
|
246 |
exit();
|
247 |
-
|
248 |
}
|
249 |
|
250 |
/**
|
@@ -254,15 +251,15 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
254 |
*/
|
255 |
public function ajax_upload() {
|
256 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
257 |
-
$id
|
258 |
-
$wp_locales =
|
259 |
-
if (isset($wp_locales)) {
|
260 |
-
$lingotek_locales = array_map('Lingotek::map_to_lingotek_locale', $wp_locales);
|
261 |
-
$lingotek_locales = array('translation_locale_code' => $lingotek_locales);
|
262 |
-
$wp_locales
|
263 |
-
$wp_locales
|
264 |
}
|
265 |
-
$this->lgtm->upload_post($id);
|
266 |
die();
|
267 |
}
|
268 |
|
@@ -273,33 +270,31 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
273 |
*/
|
274 |
public function lingotek_add_meta_boxes() {
|
275 |
global $post;
|
276 |
-
$lgtm
|
277 |
$group = $lgtm->get_group( $post->post_type, $post->ID );
|
278 |
|
279 |
// if it's a new page, $group will be null, so don't check if it's a source page.
|
280 |
if ( $group ) {
|
281 |
$desc_array = $group->desc_array;
|
282 |
-
$source_id
|
283 |
// only display the meta box if it's a source.
|
284 |
if ( isset( $desc_array['lingotek']['source'] ) && $post->ID !== $source_id ) {
|
285 |
return;
|
286 |
}
|
287 |
}
|
288 |
|
289 |
-
$polylang_enabled
|
290 |
$custom_post_types = get_post_types( array( '_builtin' => false ) );
|
291 |
-
unset( $custom_post_types[
|
292 |
|
293 |
-
foreach ( $custom_post_types as $type )
|
294 |
-
|
295 |
-
|
296 |
-
{
|
297 |
-
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), $type, 'side', 'default');
|
298 |
}
|
299 |
}
|
300 |
|
301 |
-
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'post', 'side', 'default');
|
302 |
-
add_meta_box('lingotek_page_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'page', 'side', 'default');
|
303 |
}
|
304 |
|
305 |
/**
|
@@ -308,61 +303,64 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
308 |
* @since 0.1
|
309 |
*/
|
310 |
public static function lingotek_edit_meta_box_html() {
|
311 |
-
wp_enqueue_script( 'lingotek_defaults', LINGOTEK_URL . '/js/defaults.js' );
|
312 |
|
313 |
global $post;
|
314 |
-
$post_type
|
315 |
-
$lgtm
|
316 |
-
$group
|
317 |
-
$profiles
|
318 |
-
$content_profiles
|
319 |
-
$language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
|
320 |
-
$default_name
|
321 |
-
if ( ! isset( $default_name ) || 'disabled' === $default_name )
|
322 |
-
|
323 |
-
echo esc_html( __('You must enable translation for this content type in Lingotek\'s Content Type Configuration to enable Translation Profiles.', 'lingotek-translation') );
|
324 |
return;
|
325 |
}
|
326 |
-
$content_default_profile = array(
|
327 |
-
'
|
328 |
-
|
|
|
|
|
|
|
329 |
|
330 |
$language_profiles['defaults'] = array(
|
331 |
'content_default' => $default_name,
|
332 |
-
'title'
|
333 |
);
|
334 |
-
$profiles
|
335 |
-
$post_profile
|
336 |
if ( isset( $post_profile ) ) {
|
337 |
$selected[ $post_profile->description ] = $profiles[ $post_profile->description ];
|
338 |
unset( $profiles[ $post_profile->description ] );
|
339 |
$profiles = array_merge( $selected, $profiles );
|
340 |
}
|
341 |
|
342 |
-
|
|
|
343 |
$args = array(
|
344 |
'document_id' => $group->document_id,
|
345 |
-
'action'
|
346 |
-
'noheader'
|
347 |
);
|
348 |
-
if (
|
349 |
$args['lingotek_redirect'] = true;
|
350 |
}
|
351 |
-
$site_id
|
352 |
-
$url
|
353 |
$disassociate_url = wp_nonce_url( add_query_arg( $args, $url ), 'lingotek-delete' );
|
354 |
-
$remove_post
|
355 |
$disassociate_url = str_replace( $remove_post, '', $disassociate_url );
|
356 |
-
$confirm_message
|
357 |
-
$confirm_message
|
358 |
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
359 |
printf( '<em>%s</em><br>', esc_html( __( 'Delete this content from your Lingotek community to change the Translation Profile', 'lingotek-translation' ) ) );
|
360 |
-
printf( ('<a class="button button-small" href="%s" %s>%s</a><br><br>'), esc_url( $disassociate_url ), esc_html( $confirm_message ), esc_html( __( 'Delete', 'lingotek-translation' ) ) );
|
361 |
printf( '<select disabled class="lingotek-profile-setting" name="%1$s" id="%1$s">', esc_html( 'lingotek_profile_meta' ) );
|
362 |
} else {
|
363 |
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
364 |
printf( '<select class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta' );
|
365 |
-
}
|
366 |
|
367 |
foreach ( $profiles as $key => $profile ) {
|
368 |
echo "\n\t<option value=" . esc_attr( $key ) . '>' . esc_attr( $profile['name'] ) . '</option>';
|
@@ -377,15 +375,15 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
377 |
}
|
378 |
|
379 |
global $post;
|
380 |
-
$profile_choice
|
381 |
-
$document_id
|
382 |
-
$term
|
383 |
-
$post_language
|
384 |
$content_profiles = get_option( 'lingotek_content_type' );
|
385 |
|
386 |
-
if (
|
387 |
wp_delete_term( (int) $term->term_id, 'lingotek_profile' );
|
388 |
-
} elseif (
|
389 |
if ( empty( $term ) ) {
|
390 |
wp_insert_term( $document_id, 'lingotek_profile', array( 'description' => $profile_choice ) );
|
391 |
} else {
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
+
class Lingotek_Post_Actions extends Lingotek_Actions {
|
10 |
|
11 |
/**
|
12 |
* Constructor
|
16 |
public function __construct() {
|
17 |
parent::__construct( 'post' );
|
18 |
|
19 |
+
// Row actions.
|
20 |
add_filter( 'post_row_actions', array( &$this, 'post_row_actions' ), 10, 2 );
|
21 |
+
// Hierarchical post types.
|
22 |
+
add_filter( 'page_row_actions', array( &$this, 'post_row_actions' ), 10, 2 );
|
23 |
add_filter( 'media_row_actions', array( &$this, 'post_row_actions' ), 10, 2 );
|
24 |
|
25 |
// add bulk actions.
|
26 |
add_filter( 'bulk_actions-edit-post', array( &$this, 'add_bulk_actions' ) );
|
27 |
add_filter( 'bulk_actions-edit-page', array( &$this, 'add_bulk_actions' ) );
|
28 |
|
29 |
+
foreach ( PLL()->model->get_translated_taxonomies() as $taxonomy ) {
|
30 |
add_filter( "bulk_actions-edit-$taxonomy", array( &$this, 'add_bulk_actions' ) );
|
31 |
}
|
|
|
32 |
|
33 |
$polylang_enabled = PLL()->model->get_translated_post_types();
|
34 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
35 |
+
$polylang_enabled = apply_filters( 'pll_get_post_types', $polylang_enabled, false );
|
36 |
|
37 |
+
foreach ( $polylang_enabled as $type ) {
|
38 |
+
add_filter( "bulk_actions-edit-$type", array( &$this, 'add_bulk_actions' ) );
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
// manage bulk actions, row actions and icon actions.
|
109 |
}
|
110 |
|
111 |
public function manage_promotions() {
|
112 |
+
if ( null !== filter_input( INPUT_GET, 'ltk-promotion' ) && 'dismiss' === filter_input( INPUT_GET, 'ltk-promotion' ) ) {
|
113 |
+
update_option( 'lingotek_professional_promotion_shown', true, false );
|
114 |
+
} elseif ( null !== filter_input( INPUT_GET, 'ltk-promotion' ) && 'view' === filter_input( INPUT_GET, 'ltk-promotion' ) ) {
|
115 |
+
update_option( 'lingotek_professional_promotion_shown', true, false );
|
116 |
wp_safe_redirect( 'admin.php?page=lingotek-translation_tutorial&sm=content&tutorial=ltk-prof#ltk-prof-trans-header' );
|
117 |
die();
|
118 |
}
|
119 |
function lingotek_professional_translation_notice() {
|
120 |
+
echo sprintf(
|
121 |
+
'<div style="height: 45px;" class="notice notice-success"><p><b>%s</b>%s <a style="float:right;" class="button" href="%s" >Dismiss</a><a style="float:right; margin-right: 6px;" class="button button-primary" href="%s" >Learn More</a></p></div>',
|
122 |
+
esc_html__( 'NEW FEATURE!', 'lingotek-translation' ),
|
123 |
+
esc_html__( 'Lingotek Professional Translation is now available.', 'lingotek-translation' ),
|
124 |
+
esc_url( admin_url( 'edit.php?ltk-promotion=dismiss' ) ),
|
125 |
+
esc_url( admin_url( 'edit.php?ltk-promotion=view' ) )
|
126 |
);
|
127 |
}
|
128 |
+
if ( ! get_option( 'lingotek_professional_promotion_shown' ) ) {
|
|
|
129 |
add_action( 'admin_notices', 'lingotek_professional_translation_notice' );
|
130 |
}
|
131 |
}
|
146 |
// get the action.
|
147 |
// $typenow is empty for media.
|
148 |
$wp_list_table = _get_list_table( empty( $typenow ) ? 'WP_Media_List_Table' : 'WP_Posts_List_Table' );
|
149 |
+
$action = $wp_list_table->current_action();
|
150 |
|
151 |
if ( empty( $action ) ) {
|
152 |
return;
|
159 |
|
160 |
switch ( $action ) {
|
161 |
case 'bulk-lingotek-upload':
|
162 |
+
$type = empty( $typenow ) ? 'media' : 'post';
|
163 |
$filtered_get = filter_input_array( INPUT_GET );
|
164 |
if ( ! isset( $filtered_get[ $type ] ) ) {
|
165 |
return;
|
171 |
// safe upload.
|
172 |
if ( $this->lgtm->can_upload( 'post', $post_id ) ) {
|
173 |
$post_ids[] = $post_id;
|
174 |
+
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found,Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
|
175 |
+
} elseif ( ( $document = $this->lgtm->get_group( 'post', $post_id ) ) && empty( $document->source ) ) {
|
176 |
// take care to upload only one post in a translation group.
|
177 |
$intersect = array_intersect( $post_ids, PLL()->model->post->get_translations( $post_id ) );
|
178 |
if ( empty( $intersect ) ) {
|
179 |
$post_ids[] = $post_id;
|
180 |
+
$redirect = add_query_arg( 'lingotek_warning', 1, $redirect );
|
181 |
}
|
182 |
}
|
183 |
}
|
186 |
if ( ! empty( $post_ids ) ) {
|
187 |
foreach ( $post_ids as $key => $post_id ) {
|
188 |
$language = PLL()->model->post->get_language( $post_id );
|
189 |
+
$profile = Lingotek_Model::get_profile( $post_type, $language );
|
190 |
if ( 'disabled' === $profile['profile'] ) {
|
191 |
unset( $post_ids[ $key ] );
|
192 |
}
|
199 |
case 'bulk-lingotek-delete':
|
200 |
case 'bulk-lingotek-cancel':
|
201 |
if ( empty( $post_ids ) ) {
|
202 |
+
$type = empty( $typenow ) ? 'media' : 'post';
|
203 |
$filtered_get = filter_input_array( INPUT_GET );
|
204 |
if ( ! isset( $filtered_get[ $type ] ) ) {
|
205 |
return;
|
207 |
|
208 |
$post_ids = array_map( 'intval', $filtered_get[ $type ] );
|
209 |
}
|
210 |
+
|
211 |
empty( $typenow ) ? check_admin_referer( 'bulk-media' ) : check_admin_referer( 'bulk-posts' );
|
212 |
+
if ( in_array( $action, array( 'bulk-lingotek-cancel', 'bulk-lingotek-delete' ), true ) ) {
|
213 |
$redirect = add_query_arg( 'lingotek_remove', 1, $redirect );
|
214 |
}
|
215 |
$redirect = add_query_arg( $action, 1, $redirect );
|
216 |
$redirect = add_query_arg( 'ids', implode( ',', $post_ids ), $redirect );
|
217 |
break;
|
218 |
+
|
219 |
case 'lingotek-upload':
|
220 |
check_admin_referer( 'lingotek-upload' );
|
221 |
+
$id = filter_input( INPUT_GET, 'post' );
|
222 |
+
$document = $this->lgtm->get_group( 'post', $id );
|
223 |
+
$this->lgtm->upload_post( $id );
|
224 |
+
$redirect = add_query_arg( 'id', $id, $redirect );
|
225 |
+
$redirect = add_query_arg( 'type', 'post', $redirect );
|
226 |
+
$redirect = add_query_arg( 'source', $this->pllm->post->get_language( $id )->locale, $redirect );
|
227 |
break;
|
228 |
|
229 |
case 'lingotek-copy':
|
230 |
check_admin_referer( 'lingotek-copy' );
|
231 |
$post_to_copy = get_post( (int) filter_input( INPUT_GET, 'post' ) );
|
232 |
+
$target = filter_input( INPUT_GET, 'target' );
|
233 |
$this->lgtm->copy_post( $post_to_copy, $target );
|
234 |
break;
|
235 |
+
|
236 |
default:
|
237 |
if ( ! $this->_manage_actions( $action ) ) {
|
238 |
+
// Do not redirect if this is not one of our actions.
|
239 |
+
return;
|
240 |
}
|
241 |
+
}//end switch
|
242 |
|
243 |
wp_safe_redirect( $redirect );
|
244 |
exit();
|
|
|
245 |
}
|
246 |
|
247 |
/**
|
251 |
*/
|
252 |
public function ajax_upload() {
|
253 |
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
254 |
+
$id = (int) filter_input( INPUT_POST, 'id' );
|
255 |
+
$wp_locales = json_decode( filter_input( INPUT_POST, 'locales' ) );
|
256 |
+
if ( isset( $wp_locales ) ) {
|
257 |
+
$lingotek_locales = array_map( 'Lingotek::map_to_lingotek_locale', $wp_locales );
|
258 |
+
$lingotek_locales = array( 'translation_locale_code' => $lingotek_locales );
|
259 |
+
$wp_locales = array_map( array( $this->pllm, 'get_language' ), $wp_locales );
|
260 |
+
$wp_locales = array_column( $wp_locales, 'locale' );
|
261 |
}
|
262 |
+
$this->lgtm->upload_post( $id );
|
263 |
die();
|
264 |
}
|
265 |
|
270 |
*/
|
271 |
public function lingotek_add_meta_boxes() {
|
272 |
global $post;
|
273 |
+
$lgtm = new Lingotek_Model();
|
274 |
$group = $lgtm->get_group( $post->post_type, $post->ID );
|
275 |
|
276 |
// if it's a new page, $group will be null, so don't check if it's a source page.
|
277 |
if ( $group ) {
|
278 |
$desc_array = $group->desc_array;
|
279 |
+
$source_id = $desc_array['lingotek']['source'];
|
280 |
// only display the meta box if it's a source.
|
281 |
if ( isset( $desc_array['lingotek']['source'] ) && $post->ID !== $source_id ) {
|
282 |
return;
|
283 |
}
|
284 |
}
|
285 |
|
286 |
+
$polylang_enabled = PLL()->model->get_translated_post_types();
|
287 |
$custom_post_types = get_post_types( array( '_builtin' => false ) );
|
288 |
+
unset( $custom_post_types['polylang_mo'] );
|
289 |
|
290 |
+
foreach ( $custom_post_types as $type ) {
|
291 |
+
if ( isset( $polylang_enabled[ $type ] ) ) {
|
292 |
+
add_meta_box( 'lingotek_post_meta_box', __( 'Lingotek Translation', 'lingotek-translation' ), array( __CLASS__, 'lingotek_edit_meta_box_html' ), $type, 'side', 'default' );
|
|
|
|
|
293 |
}
|
294 |
}
|
295 |
|
296 |
+
add_meta_box( 'lingotek_post_meta_box', __( 'Lingotek Translation', 'lingotek-translation' ), array( __CLASS__, 'lingotek_edit_meta_box_html' ), 'post', 'side', 'default' );
|
297 |
+
add_meta_box( 'lingotek_page_meta_box', __( 'Lingotek Translation', 'lingotek-translation' ), array( __CLASS__, 'lingotek_edit_meta_box_html' ), 'page', 'side', 'default' );
|
298 |
}
|
299 |
|
300 |
/**
|
303 |
* @since 0.1
|
304 |
*/
|
305 |
public static function lingotek_edit_meta_box_html() {
|
306 |
+
wp_enqueue_script( 'lingotek_defaults', LINGOTEK_URL . '/js/defaults.js', array(), LINGOTEK_VERSION, false );
|
307 |
|
308 |
global $post;
|
309 |
+
$post_type = get_post_type( $post->ID );
|
310 |
+
$lgtm = new Lingotek_Model();
|
311 |
+
$group = $lgtm->get_group( 'post', $post->ID );
|
312 |
+
$profiles = Lingotek::get_profiles();
|
313 |
+
$content_profiles = get_option( 'lingotek_content_type' );
|
314 |
+
$language_profiles = self::retrieve_lang_Profiles( $post_type, $profiles, $content_profiles );
|
315 |
+
$default_name = ! empty( $content_profiles ) ? $profiles[ $content_profiles[ $post->post_type ]['profile'] ]['name'] : __( 'Manual', 'lingotek-translation' );
|
316 |
+
if ( ! isset( $default_name ) || 'disabled' === $default_name ) {
|
317 |
+
echo esc_html( __( 'You must enable translation for this content type in Lingotek\'s Content Type Configuration to enable Translation Profiles.', 'lingotek-translation' ) );
|
|
|
318 |
return;
|
319 |
}
|
320 |
+
$content_default_profile = array(
|
321 |
+
'default' => array(
|
322 |
+
// Adds in the name of the content type default profile.
|
323 |
+
'name' => __( 'Content Default', 'lingotek-translation' ) . ' (' . $default_name . ')',
|
324 |
+
),
|
325 |
+
);
|
326 |
|
327 |
$language_profiles['defaults'] = array(
|
328 |
'content_default' => $default_name,
|
329 |
+
'title' => __( 'Content Default', 'lingotek-translation' ),
|
330 |
);
|
331 |
+
$profiles = array_merge( $content_default_profile, $profiles );
|
332 |
+
$post_profile = self::get_post_profile( $post->ID );
|
333 |
if ( isset( $post_profile ) ) {
|
334 |
$selected[ $post_profile->description ] = $profiles[ $post_profile->description ];
|
335 |
unset( $profiles[ $post_profile->description ] );
|
336 |
$profiles = array_merge( $selected, $profiles );
|
337 |
}
|
338 |
|
339 |
+
// Disables selection of a different profile if content has been uploaded to Lingotek.
|
340 |
+
if ( isset( $group->source ) ) {
|
341 |
$args = array(
|
342 |
'document_id' => $group->document_id,
|
343 |
+
'action' => 'lingotek-delete',
|
344 |
+
'noheader' => true,
|
345 |
);
|
346 |
+
if ( 'page' === $post_type ) {
|
347 |
$args['lingotek_redirect'] = true;
|
348 |
}
|
349 |
+
$site_id = get_current_blog_id();
|
350 |
+
$url = 'page' === $post_type ? get_site_url( $site_id, '/wp-admin/edit.php?post_type=page' ) : get_site_url( $site_id, '/wp-admin/edit.php' );
|
351 |
$disassociate_url = wp_nonce_url( add_query_arg( $args, $url ), 'lingotek-delete' );
|
352 |
+
$remove_post = 'post=' . $post->ID;
|
353 |
$disassociate_url = str_replace( $remove_post, '', $disassociate_url );
|
354 |
+
$confirm_message = __( 'Are you sure you want to do this?', 'lingotek-translation' );
|
355 |
+
$confirm_message = sprintf( ' onclick = "return confirm(\'%s\');"', esc_html( $confirm_message ) );
|
356 |
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
357 |
printf( '<em>%s</em><br>', esc_html( __( 'Delete this content from your Lingotek community to change the Translation Profile', 'lingotek-translation' ) ) );
|
358 |
+
printf( ( '<a class="button button-small" href="%s" %s>%s</a><br><br>' ), esc_url( $disassociate_url ), esc_html( $confirm_message ), esc_html( __( 'Delete', 'lingotek-translation' ) ) );
|
359 |
printf( '<select disabled class="lingotek-profile-setting" name="%1$s" id="%1$s">', esc_html( 'lingotek_profile_meta' ) );
|
360 |
} else {
|
361 |
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
362 |
printf( '<select class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta' );
|
363 |
+
}//end if
|
364 |
|
365 |
foreach ( $profiles as $key => $profile ) {
|
366 |
echo "\n\t<option value=" . esc_attr( $key ) . '>' . esc_attr( $profile['name'] ) . '</option>';
|
375 |
}
|
376 |
|
377 |
global $post;
|
378 |
+
$profile_choice = filter_input( INPUT_POST, 'lingotek_profile_meta' );
|
379 |
+
$document_id = 'lingotek_profile_' . $post->ID;
|
380 |
+
$term = self::get_post_profile( $post->ID );
|
381 |
+
$post_language = $this->get_language( $post->ID );
|
382 |
$content_profiles = get_option( 'lingotek_content_type' );
|
383 |
|
384 |
+
if ( 'default' === $profile_choice && ! empty( $term ) ) {
|
385 |
wp_delete_term( (int) $term->term_id, 'lingotek_profile' );
|
386 |
+
} elseif ( 'default' !== $profile_choice ) {
|
387 |
if ( empty( $term ) ) {
|
388 |
wp_insert_term( $document_id, 'lingotek_profile', array( 'description' => $profile_choice ) );
|
389 |
} else {
|
admin/profiles-table.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
-
|
|
|
5 |
}
|
6 |
|
7 |
/**
|
@@ -14,11 +15,14 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
14 |
*
|
15 |
* @since 0.2
|
16 |
*/
|
17 |
-
function __construct() {
|
18 |
-
parent::__construct(
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
22 |
}
|
23 |
|
24 |
/**
|
@@ -30,7 +34,7 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
30 |
* @param string $column_name column.
|
31 |
* @return string
|
32 |
*/
|
33 |
-
function column_default( $item, $column_name ) {
|
34 |
return isset( $item[ $column_name ] ) ? esc_html( $item[ $column_name ] ) : '';
|
35 |
}
|
36 |
|
@@ -42,9 +46,10 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
42 |
* @param array $item item.
|
43 |
* @return string
|
44 |
*/
|
45 |
-
function column_usage( $item ) {
|
46 |
return empty( $item['usage'] ) ?
|
47 |
__( 'No content types', 'lingotek-translation' ) :
|
|
|
48 |
sprintf( _n( '%d content type', '%d content types', $item['usage'], 'lingotek-translation' ), number_format_i18n( $item['usage'] ) );
|
49 |
}
|
50 |
|
@@ -56,7 +61,7 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
56 |
* @param array $item item.
|
57 |
* @return string
|
58 |
*/
|
59 |
-
function column_actions( $item ) {
|
60 |
$actions = array();
|
61 |
|
62 |
if ( 'disabled' !== $item['profile'] ) {
|
@@ -86,9 +91,9 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
86 |
*
|
87 |
* @return array the list of column titles
|
88 |
*/
|
89 |
-
function get_columns() {
|
90 |
return array(
|
91 |
-
'name'
|
92 |
'usage' => __( 'Usage', 'lingotek-translation' ),
|
93 |
'actions' => __( 'Actions', 'lingotek-translation' ),
|
94 |
);
|
@@ -101,7 +106,7 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
101 |
*
|
102 |
* @return array
|
103 |
*/
|
104 |
-
function get_sortable_columns() {
|
105 |
return array(
|
106 |
'name' => array( 'name', false ),
|
107 |
);
|
@@ -114,8 +119,8 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
114 |
*
|
115 |
* @param array $data data.
|
116 |
*/
|
117 |
-
function prepare_items( $data = array() ) {
|
118 |
-
$per_page
|
119 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
120 |
|
121 |
/**
|
@@ -126,23 +131,28 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
126 |
* @return int sort direction.
|
127 |
*/
|
128 |
function usort_reorder( $a, $b ) {
|
129 |
-
$order
|
130 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
131 |
-
|
132 |
-
|
|
|
|
|
133 |
};
|
134 |
|
135 |
-
|
|
|
136 |
usort( $data, 'usort_reorder' );
|
137 |
}
|
138 |
|
139 |
$total_items = count( $data );
|
140 |
-
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
141 |
-
|
142 |
-
$this->set_pagination_args(
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
147 |
}
|
148 |
}
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
// since WP 3.1.
|
5 |
+
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
6 |
}
|
7 |
|
8 |
/**
|
15 |
*
|
16 |
* @since 0.2
|
17 |
*/
|
18 |
+
public function __construct() {
|
19 |
+
parent::__construct(
|
20 |
+
array(
|
21 |
+
// do not translate (used for css class).
|
22 |
+
'plural' => 'lingotek-profiles',
|
23 |
+
'ajax' => false,
|
24 |
+
)
|
25 |
+
);
|
26 |
}
|
27 |
|
28 |
/**
|
34 |
* @param string $column_name column.
|
35 |
* @return string
|
36 |
*/
|
37 |
+
public function column_default( $item, $column_name ) {
|
38 |
return isset( $item[ $column_name ] ) ? esc_html( $item[ $column_name ] ) : '';
|
39 |
}
|
40 |
|
46 |
* @param array $item item.
|
47 |
* @return string
|
48 |
*/
|
49 |
+
protected function column_usage( $item ) {
|
50 |
return empty( $item['usage'] ) ?
|
51 |
__( 'No content types', 'lingotek-translation' ) :
|
52 |
+
/* translators: %d: Number of content types. */
|
53 |
sprintf( _n( '%d content type', '%d content types', $item['usage'], 'lingotek-translation' ), number_format_i18n( $item['usage'] ) );
|
54 |
}
|
55 |
|
61 |
* @param array $item item.
|
62 |
* @return string
|
63 |
*/
|
64 |
+
public function column_actions( $item ) {
|
65 |
$actions = array();
|
66 |
|
67 |
if ( 'disabled' !== $item['profile'] ) {
|
91 |
*
|
92 |
* @return array the list of column titles
|
93 |
*/
|
94 |
+
public function get_columns() {
|
95 |
return array(
|
96 |
+
'name' => __( 'Profile name', 'lingotek-translation' ),
|
97 |
'usage' => __( 'Usage', 'lingotek-translation' ),
|
98 |
'actions' => __( 'Actions', 'lingotek-translation' ),
|
99 |
);
|
106 |
*
|
107 |
* @return array
|
108 |
*/
|
109 |
+
public function get_sortable_columns() {
|
110 |
return array(
|
111 |
'name' => array( 'name', false ),
|
112 |
);
|
119 |
*
|
120 |
* @param array $data data.
|
121 |
*/
|
122 |
+
public function prepare_items( $data = array() ) {
|
123 |
+
$per_page = $this->get_items_per_page( 'lingotek_profiles_per_page' );
|
124 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
125 |
|
126 |
/**
|
131 |
* @return int sort direction.
|
132 |
*/
|
133 |
function usort_reorder( $a, $b ) {
|
134 |
+
$order = filter_input( INPUT_GET, 'order' );
|
135 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
136 |
+
// Determine sort order.
|
137 |
+
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
|
138 |
+
// Send final sort direction to usort.
|
139 |
+
return ( empty( $order ) || 'asc' === $order ) ? $result : -$result;
|
140 |
};
|
141 |
|
142 |
+
// No sort by default.
|
143 |
+
if ( ! empty( $orderby ) ) {
|
144 |
usort( $data, 'usort_reorder' );
|
145 |
}
|
146 |
|
147 |
$total_items = count( $data );
|
148 |
+
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
149 |
+
|
150 |
+
$this->set_pagination_args(
|
151 |
+
array(
|
152 |
+
'total_items' => $total_items,
|
153 |
+
'per_page' => $per_page,
|
154 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
155 |
+
)
|
156 |
+
);
|
157 |
}
|
158 |
}
|
admin/settings.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wrap">
|
2 |
-
|
3 |
|
4 |
<?php
|
5 |
if ( strlen( $access_token ) ) {
|
@@ -9,13 +9,13 @@
|
|
9 |
<?php
|
10 |
|
11 |
$menu_items = array(
|
12 |
-
|
13 |
);
|
14 |
|
15 |
$community_required_menu_items = array(
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
);
|
20 |
|
21 |
if ( false !== $community_id ) {
|
@@ -28,35 +28,39 @@
|
|
28 |
<?php
|
29 |
$menu_item_index = 0;
|
30 |
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
31 |
-
$use_as_default = (0 === $menu_item_index
|
32 |
-
$alias
|
33 |
// custom sub sub-menus.
|
34 |
if ( ! empty( $sm ) && 'edit-profile' === $sm ) {
|
35 |
$alias = 'profiles';
|
36 |
}
|
37 |
?>
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
41 |
<?php
|
42 |
-
|
43 |
}
|
44 |
-
|
45 |
</h3>
|
46 |
|
47 |
<?php
|
48 |
settings_errors();
|
49 |
-
$submenu
|
50 |
-
$dir
|
51 |
$filename = $dir . 'view-' . $submenu . '.php';
|
52 |
if ( file_exists( $filename ) ) {
|
53 |
include $filename;
|
54 |
-
} else {
|
|
|
55 |
}
|
56 |
?>
|
57 |
|
58 |
<?php
|
59 |
-
}
|
60 |
?>
|
61 |
</div>
|
62 |
<script>jQuery(document).ready(function($) { $('#wpfooter').remove(); } );</script>
|
1 |
<div class="wrap">
|
2 |
+
<h2><?php esc_html_e( 'Settings', 'lingotek-translation' ); ?></h2>
|
3 |
|
4 |
<?php
|
5 |
if ( strlen( $access_token ) ) {
|
9 |
<?php
|
10 |
|
11 |
$menu_items = array(
|
12 |
+
'account' => __( 'Account', 'lingotek-translation' ),
|
13 |
);
|
14 |
|
15 |
$community_required_menu_items = array(
|
16 |
+
'defaults' => __( 'Defaults', 'lingotek-translation' ),
|
17 |
+
'preferences' => __( 'Preferences', 'lingotek-translation' ),
|
18 |
+
'utilities' => __( 'Utilities', 'lingotek-translation' ),
|
19 |
);
|
20 |
|
21 |
if ( false !== $community_id ) {
|
28 |
<?php
|
29 |
$menu_item_index = 0;
|
30 |
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
31 |
+
$use_as_default = ( 0 === $menu_item_index && empty( $sm ) ) ? true : false;
|
32 |
+
$alias = null;
|
33 |
// custom sub sub-menus.
|
34 |
if ( ! empty( $sm ) && 'edit-profile' === $sm ) {
|
35 |
$alias = 'profiles';
|
36 |
}
|
37 |
?>
|
38 |
+
<a class="nav-tab
|
39 |
+
<?php
|
40 |
+
if ( $use_as_default || ( ! empty( $sm ) && $sm === $menu_item_key ) || $alias === $menu_item_key ) :
|
41 |
+
?>
|
42 |
+
nav-tab-active<?php endif; ?>"
|
43 |
+
href="admin.php?page=<?php echo filter_input( INPUT_GET, 'page' ); ?>&sm=<?php echo esc_html( $menu_item_key ); ?>"><?php echo esc_html( $menu_item_label ); ?></a>
|
44 |
<?php
|
45 |
+
$menu_item_index++;
|
46 |
}
|
47 |
+
?>
|
48 |
</h3>
|
49 |
|
50 |
<?php
|
51 |
settings_errors();
|
52 |
+
$submenu = ! empty( $sm ) ? sanitize_text_field( $sm ) : 'account';
|
53 |
+
$dir = dirname( __FILE__ ) . '/settings/';
|
54 |
$filename = $dir . 'view-' . $submenu . '.php';
|
55 |
if ( file_exists( $filename ) ) {
|
56 |
include $filename;
|
57 |
+
} else {
|
58 |
+
echo 'TO-DO: create <i>settings/view-' . esc_html( $submenu ) . '.php</i>';
|
59 |
}
|
60 |
?>
|
61 |
|
62 |
<?php
|
63 |
+
}//end if
|
64 |
?>
|
65 |
</div>
|
66 |
<script>jQuery(document).ready(function($) { $('#wpfooter').remove(); } );</script>
|
admin/settings/connect-account.php
CHANGED
@@ -30,52 +30,52 @@ jQuery(document).ready(function ($){
|
|
30 |
})
|
31 |
}
|
32 |
} else if (window.location.search.includes("connect")) {
|
33 |
-
window.location.href = "<?php echo esc_url_raw( $connect_url ) ?>";
|
34 |
}
|
35 |
});
|
36 |
</script>
|
37 |
<!-- Connect Your Account Button -->
|
38 |
<div class="loader content" hidden></div>
|
39 |
<div class="wrap content">
|
40 |
-
<h2><?php esc_html_e( 'Connect Your Account', 'lingotek-translation' ) ?></h2>
|
41 |
<div>
|
42 |
<p class="description">
|
43 |
-
<?php esc_html_e( 'Get started by clicking the button below to connect your Lingotek account to this
|
44 |
</p>
|
45 |
<hr/>
|
46 |
<p>
|
47 |
-
<a class="button button-large button-hero" href="<?php echo esc_url_raw( $connect_account_cloak_url_new ) ?>">
|
48 |
-
|
49 |
</a>
|
50 |
</p>
|
51 |
<hr/>
|
52 |
<p class="description">
|
53 |
<?php
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
);
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
</p>
|
63 |
</div>
|
64 |
</div>
|
65 |
<style>
|
66 |
.loader {
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
}
|
76 |
|
77 |
@keyframes spin {
|
78 |
-
|
79 |
-
|
80 |
}
|
81 |
</style>
|
30 |
})
|
31 |
}
|
32 |
} else if (window.location.search.includes("connect")) {
|
33 |
+
window.location.href = "<?php echo esc_url_raw( $connect_url ); ?>";
|
34 |
}
|
35 |
});
|
36 |
</script>
|
37 |
<!-- Connect Your Account Button -->
|
38 |
<div class="loader content" hidden></div>
|
39 |
<div class="wrap content">
|
40 |
+
<h2><?php esc_html_e( 'Connect Your Account', 'lingotek-translation' ); ?></h2>
|
41 |
<div>
|
42 |
<p class="description">
|
43 |
+
<?php esc_html_e( 'Get started by clicking the button below to connect your Lingotek account to this WordPress installation.', 'lingotek-translation' ); ?>
|
44 |
</p>
|
45 |
<hr/>
|
46 |
<p>
|
47 |
+
<a class="button button-large button-hero" href="<?php echo esc_url_raw( $connect_account_cloak_url_new ); ?>">
|
48 |
+
<img src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/lingotek-icon.png" style="padding: 0 4px 2px 0;" align="absmiddle"/> <?php esc_html_e( 'Connect New Account', 'lingotek-translation' ); ?>
|
49 |
</a>
|
50 |
</p>
|
51 |
<hr/>
|
52 |
<p class="description">
|
53 |
<?php
|
54 |
+
$allowed_html = array(
|
55 |
+
'a' => array(
|
56 |
+
'href' => array(),
|
57 |
+
),
|
58 |
);
|
59 |
+
/* translators: %s: Connect to Lingotek url. */
|
60 |
+
echo sprintf( wp_kses( __( 'Do you already have a Lingotek account? <a href="%s">Connect Lingotek Account</a>', 'lingotek-translation' ), $allowed_html ), esc_attr( $connect_account_cloak_url_prod ) )
|
61 |
+
?>
|
62 |
</p>
|
63 |
</div>
|
64 |
</div>
|
65 |
<style>
|
66 |
.loader {
|
67 |
+
border: 16px solid #dedede;
|
68 |
+
border-top: 16px solid #3498db;
|
69 |
+
border-radius: 50%;
|
70 |
+
width: 100px;
|
71 |
+
height: 100px;
|
72 |
+
animation: spin 1.5s linear infinite;
|
73 |
+
animation-direction: reverse;
|
74 |
+
margin: 7em;
|
75 |
}
|
76 |
|
77 |
@keyframes spin {
|
78 |
+
0% { transform: rotate(0deg); }
|
79 |
+
100% { transform: rotate(360deg); }
|
80 |
}
|
81 |
</style>
|
admin/settings/view-account.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
<?php
|
2 |
-
$client
|
3 |
$api_communities = $client->get_communities();
|
4 |
if ( ! isset( $api_communities->entities ) ) {
|
5 |
add_settings_error( 'lingotek_community_resources', 'error', __( 'The Lingotek TMS is currently unavailable. Please try again later. If the problem persists, contact Lingotek Support.', 'lingotek-translation' ), 'error' );
|
6 |
settings_errors();
|
7 |
}
|
8 |
if ( ! $community_id ) {
|
9 |
-
$ltk_client
|
10 |
-
$ltk_communities
|
11 |
$ltk_num_communities = $ltk_communities->properties->total;
|
12 |
if ( 1 === $ltk_num_communities ) {
|
13 |
$ltk_community_id = $ltk_communities->entities[0]->properties->id;
|
@@ -23,52 +23,60 @@ if ( ! $community_id ) {
|
|
23 |
<table class="form-table">
|
24 |
<tr>
|
25 |
<th scope="row">
|
26 |
-
<?php esc_html_e( 'Connected', 'lingotek-translation' ) ?>
|
27 |
-
|
28 |
-
|
29 |
</th>
|
30 |
<td>
|
31 |
-
<?php esc_html_e( 'Yes', 'lingotek-translation' ) ?><span title="<?php esc_html_e( 'Connected', 'lingotek-translation' ) ?>" class="dashicons dashicons-yes" style="color: green;"></span>
|
32 |
</td>
|
33 |
</tr>
|
34 |
<tbody id="connection-details" style="display: none;">
|
35 |
<tr>
|
36 |
-
<th scope="row"><?php echo esc_html( __( 'Login ID', 'lingotek-translation' ) ) ?></th>
|
37 |
<td>
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
45 |
</td>
|
46 |
</tr>
|
47 |
<tr>
|
48 |
-
<th scope="row"><?php echo esc_html( __( 'Access Token', 'lingotek-translation' ) ) ?></th>
|
49 |
<td>
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
</td>
|
61 |
</tr>
|
62 |
<tr>
|
63 |
-
<th scope="row"><?php echo
|
64 |
<td>
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
</td>
|
73 |
</tr>
|
74 |
<tr>
|
@@ -90,73 +98,73 @@ if ( ! $community_id ) {
|
|
90 |
|
91 |
<table class="form-table">
|
92 |
<tr>
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
112 |
}
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
}
|
117 |
-
}
|
118 |
-
?>
|
119 |
-
</select>
|
120 |
-
</td>
|
121 |
</tr>
|
122 |
<tr>
|
123 |
-
<th scope="row"><?php esc_html_e( 'Payment Method', 'lingotek-translation' ) ?></th>
|
124 |
<td>
|
125 |
-
|
126 |
<?php
|
127 |
add_thickbox();
|
128 |
-
wp_enqueue_script( 'lingotek_professional_workflow_account', LINGOTEK_URL . '/js/workflow/professional-workflow-account.js' );
|
129 |
$vars = array(
|
130 |
-
'modal_id'
|
131 |
-
'bridge_payment' => BRIDGE_URL . '/#/payment/portal'
|
132 |
);
|
133 |
wp_localize_script( 'lingotek_professional_workflow_account', 'account_vars', $vars );
|
134 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
135 |
-
$ltk_client
|
136 |
-
$payment_info
|
137 |
-
$cc
|
138 |
-
$cc_type
|
139 |
-
|
|
|
140 |
$cc = $payment_info['payment_info']['payment_profile']['cc'];
|
141 |
-
$cc = str_replace('X','', $cc);
|
142 |
|
143 |
$cc_type = $payment_info['payment_info']['payment_profile']['cc_type'];
|
144 |
}
|
145 |
-
|
146 |
<div id='modal-window-id-payment-portal-screen' style='display:none;' >
|
147 |
<div id='payment-portal-wrapper' class='payment-portal-element'>
|
148 |
-
<img class='payment-portal-element payment-portal-image' src="<?php echo esc_url_raw( LINGOTEK_URL )
|
149 |
-
<img class='payment-portal-element payment-portal-loading' src="<?php echo esc_url_raw( LINGOTEK_URL ) ?>/img/loading.gif"/>
|
150 |
<span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
|
151 |
</div>
|
152 |
</div>
|
153 |
-
<div class='payment-method-setup professional-card-border' style="<?php echo ($payment_method_set) ? 'display:inline-block;' : 'display:none';
|
154 |
<div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/blue-radio-button.svg"/></div>
|
155 |
<div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/credit-dots.svg" /></div>
|
156 |
-
<div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'><?php echo $cc; ?></span></div>
|
157 |
-
<div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src="<?php echo Lingotek_Credit_Card_To_Path::get_cc_type_asset_url($cc_type) ?>"/></div>
|
158 |
</div>
|
159 |
-
<div style="height:37px; display:inline-block;padding-left: 10px;"><a id="professional-payment-info-link" href="<?php echo esc_url_raw( BRIDGE_URL ); ?>/#/payment/portal?redirect_url=<?php echo
|
160 |
</td>
|
161 |
</tr>
|
162 |
</table>
|
1 |
<?php
|
2 |
+
$client = new Lingotek_API();
|
3 |
$api_communities = $client->get_communities();
|
4 |
if ( ! isset( $api_communities->entities ) ) {
|
5 |
add_settings_error( 'lingotek_community_resources', 'error', __( 'The Lingotek TMS is currently unavailable. Please try again later. If the problem persists, contact Lingotek Support.', 'lingotek-translation' ), 'error' );
|
6 |
settings_errors();
|
7 |
}
|
8 |
if ( ! $community_id ) {
|
9 |
+
$ltk_client = new Lingotek_API();
|
10 |
+
$ltk_communities = $ltk_client->get_communities();
|
11 |
$ltk_num_communities = $ltk_communities->properties->total;
|
12 |
if ( 1 === $ltk_num_communities ) {
|
13 |
$ltk_community_id = $ltk_communities->entities[0]->properties->id;
|
23 |
<table class="form-table">
|
24 |
<tr>
|
25 |
<th scope="row">
|
26 |
+
<?php esc_html_e( 'Connected', 'lingotek-translation' ); ?>
|
27 |
+
<a id="cd-show-link" class="dashicons dashicons-arrow-right" onclick="document.getElementById('connection-details').style.display = ''; document.getElementById('cd-hide-link').style.display = ''; this.style.display = 'none'; return false;"></a>
|
28 |
+
<a id="cd-hide-link" class="dashicons dashicons-arrow-down" onclick="document.getElementById('connection-details').style.display = 'none'; document.getElementById('cd-show-link').style.display = ''; this.style.display = 'none'; return false;" style="display: none;"></a>
|
29 |
</th>
|
30 |
<td>
|
31 |
+
<?php esc_html_e( 'Yes', 'lingotek-translation' ); ?><span title="<?php esc_html_e( 'Connected', 'lingotek-translation' ); ?>" class="dashicons dashicons-yes" style="color: green;"></span>
|
32 |
</td>
|
33 |
</tr>
|
34 |
<tbody id="connection-details" style="display: none;">
|
35 |
<tr>
|
36 |
+
<th scope="row"><?php echo esc_html( __( 'Login ID', 'lingotek-translation' ) ); ?></th>
|
37 |
<td>
|
38 |
+
<label>
|
39 |
+
<?php
|
40 |
+
printf(
|
41 |
+
'<input name="%s" class="regular-text" type="text" value="%s" disabled="disabled" />',
|
42 |
+
'login_id',
|
43 |
+
esc_html( $token_details['login_id'] )
|
44 |
+
);
|
45 |
+
?>
|
46 |
+
</label>
|
47 |
</td>
|
48 |
</tr>
|
49 |
<tr>
|
50 |
+
<th scope="row"><?php echo esc_html( __( 'Access Token', 'lingotek-translation' ) ); ?></th>
|
51 |
<td>
|
52 |
+
<label>
|
53 |
+
<?php
|
54 |
+
printf(
|
55 |
+
'<input name="%s" class="regular-text" type="password" value="%s" disabled="disabled" style="display: none;" />',
|
56 |
+
'access_token',
|
57 |
+
esc_html( $token_details['access_token'] )
|
58 |
+
);
|
59 |
+
printf(
|
60 |
+
'<input name="%s" class="regular-text" type="text" value="%s" disabled="disabled" />',
|
61 |
+
'access_token',
|
62 |
+
esc_html( $token_details['access_token'] )
|
63 |
+
);
|
64 |
+
?>
|
65 |
+
</label>
|
66 |
</td>
|
67 |
</tr>
|
68 |
<tr>
|
69 |
+
<th scope="row"><?php echo esc_html( __( 'API Endpoint', 'lingotek-translation' ) ); ?></th>
|
70 |
<td>
|
71 |
+
<label>
|
72 |
+
<?php
|
73 |
+
printf(
|
74 |
+
'<input name="%s" class="regular-text" type="text" value="%s" disabled="disabled" />',
|
75 |
+
'base_url',
|
76 |
+
esc_html( $base_url )
|
77 |
+
);
|
78 |
+
?>
|
79 |
+
</label>
|
80 |
</td>
|
81 |
</tr>
|
82 |
<tr>
|
98 |
|
99 |
<table class="form-table">
|
100 |
<tr>
|
101 |
+
<th scope="row"><label for="lingotek_community"><?php esc_html_e( 'Community', 'lingotek-translation' ); ?></label></th>
|
102 |
+
<td>
|
103 |
+
<select name="lingotek_community" id="lingotek_community">
|
104 |
+
<?php
|
105 |
+
$default_community_id = $community_id;
|
106 |
|
107 |
+
// Community.
|
108 |
+
$communities = array();
|
109 |
+
if ( isset( $api_communities->entities ) ) {
|
110 |
+
foreach ( $api_communities->entities as $community ) {
|
111 |
+
$communities[ $community->properties->id ] = $community->properties->title;
|
112 |
+
}
|
113 |
|
114 |
+
$num_communities = count( $communities );
|
115 |
+
if ( 1 === $num_communities && ! $community_id ) {
|
116 |
+
update_option( 'lingotek_community', current( array_keys( $communities ) ) );
|
117 |
+
}
|
118 |
+
if ( ! $community_id && $num_communities > 1 ) {
|
119 |
+
echo "\n\t" . '<option value="">' . esc_html( __( 'Select', 'lingotek-translation' ) ) . '...</option>';
|
120 |
+
}
|
121 |
+
foreach ( $communities as $community_id_option => $community_title ) {
|
122 |
+
$selected = ( $default_community_id === $community_id_option ) ? 'selected="selected"' : '';
|
123 |
+
echo "\n\t" . '<option value="' . esc_attr( $community_id_option ) . '" ' . esc_html( $selected ) . '>' . esc_html( $community_title ) . '</option>';
|
124 |
+
}
|
125 |
}
|
126 |
+
?>
|
127 |
+
</select>
|
128 |
+
</td>
|
|
|
|
|
|
|
|
|
|
|
129 |
</tr>
|
130 |
<tr>
|
131 |
+
<th scope="row"><?php esc_html_e( 'Payment Method', 'lingotek-translation' ); ?></th>
|
132 |
<td>
|
|
|
133 |
<?php
|
134 |
add_thickbox();
|
135 |
+
wp_enqueue_script( 'lingotek_professional_workflow_account', LINGOTEK_URL . '/js/workflow/professional-workflow-account.js', array(), LINGOTEK_VERSION, false );
|
136 |
$vars = array(
|
137 |
+
'modal_id' => 'payment-portal-screen',
|
138 |
+
'bridge_payment' => BRIDGE_URL . '/#/payment/portal',
|
139 |
);
|
140 |
wp_localize_script( 'lingotek_professional_workflow_account', 'account_vars', $vars );
|
141 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
142 |
+
$ltk_client = new Lingotek_API();
|
143 |
+
$payment_info = $ltk_client->get_user_payment_information();
|
144 |
+
$cc = '';
|
145 |
+
$cc_type = '';
|
146 |
+
$payment_method_set = isset( $payment_info['payment_info']['payment_profile']['cc'] );
|
147 |
+
if ( $payment_method_set ) {
|
148 |
$cc = $payment_info['payment_info']['payment_profile']['cc'];
|
149 |
+
$cc = str_replace( 'X', '', $cc );
|
150 |
|
151 |
$cc_type = $payment_info['payment_info']['payment_profile']['cc_type'];
|
152 |
}
|
153 |
+
?>
|
154 |
<div id='modal-window-id-payment-portal-screen' style='display:none;' >
|
155 |
<div id='payment-portal-wrapper' class='payment-portal-element'>
|
156 |
+
<img class='payment-portal-element payment-portal-image' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/translation-logo.png"/>
|
157 |
+
<img class='payment-portal-element payment-portal-loading' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/loading.gif"/>
|
158 |
<span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
|
159 |
</div>
|
160 |
</div>
|
161 |
+
<div class='payment-method-setup professional-card-border' style="<?php echo ( $payment_method_set ) ? 'display:inline-block;' : 'display:none'; ?>">
|
162 |
<div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/blue-radio-button.svg"/></div>
|
163 |
<div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/credit-dots.svg" /></div>
|
164 |
+
<div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'><?php echo esc_html( $cc ); ?></span></div>
|
165 |
+
<div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src="<?php echo esc_html( Lingotek_Credit_Card_To_Path::get_cc_type_asset_url( $cc_type ) ); ?>"/></div>
|
166 |
</div>
|
167 |
+
<div style="height:37px; display:inline-block;padding-left: 10px;"><a id="professional-payment-info-link" href="<?php echo esc_url_raw( BRIDGE_URL ); ?>/#/payment/portal?redirect_url=<?php echo rawurlencode( home_url( add_query_arg( null, null ) ) ); ?>" style="display: table-cell;padding-top: 7%;"><?php echo ( $payment_method_set ) ? 'Edit Payment Method' : 'Set Up Payment Method'; ?></a></div>
|
168 |
</td>
|
169 |
</tr>
|
170 |
</table>
|
admin/settings/view-defaults.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
$page_key = $this->plugin_slug . '_settings&sm=defaults';
|
4 |
|
5 |
-
wp_enqueue_script( 'defaults', LINGOTEK_URL . '/js/defaults.js' );
|
6 |
|
7 |
if ( ! empty( $_POST ) ) {
|
8 |
check_admin_referer( $page_key, '_wpnonce_' . $page_key );
|
@@ -19,7 +19,7 @@ if ( ! empty( $_POST ) ) {
|
|
19 |
add_settings_error( 'lingotek_community_resources', 'error', __( 'The Lingotek TMS is currently unavailable. Please try again later. If the problem persists, contact Lingotek Support.', 'lingotek-translation' ), 'error' );
|
20 |
}
|
21 |
} else {
|
22 |
-
$options
|
23 |
$settings = $this->get_profiles_settings( true );
|
24 |
foreach ( $settings as $key => $setting ) {
|
25 |
$key_input = filter_input( INPUT_POST, $key );
|
@@ -41,33 +41,38 @@ if ( ! empty( $_POST ) ) {
|
|
41 |
// adds new project if text box is filled out.
|
42 |
$new_project = filter_input( INPUT_POST, 'new_project' );
|
43 |
if ( ! empty( $new_project ) ) {
|
44 |
-
$client
|
45 |
-
$
|
46 |
|
47 |
-
|
|
|
48 |
add_settings_error( 'lingotek_defaults', 'defaultgs', __( 'Your new project was successfully created.', 'lingotek-translation' ), 'updated' );
|
49 |
-
|
|
|
50 |
$options['project_id'] = $new_id;
|
51 |
update_option( 'lingotek_defaults', $options );
|
52 |
}
|
53 |
}
|
54 |
-
}
|
55 |
settings_errors();
|
56 |
-
}
|
57 |
$settings = $this->get_profiles_settings( true );
|
58 |
-
$options
|
59 |
|
60 |
// Code to determine which filter scenario will be displayed (Not configured, defaults, custom filters).
|
61 |
-
$primary_filter_id
|
62 |
-
$secondary_filter_id
|
63 |
-
$default_filters
|
|
|
|
|
|
|
64 |
$default_filters_exist = false;
|
65 |
-
$extra_filters_exist
|
66 |
-
$no_filters_exist
|
67 |
|
68 |
if ( $settings['primary_filter_id']['options'] === $default_filters ) {
|
69 |
-
$default_filters_exist
|
70 |
-
$options['primary_filter_id']
|
71 |
$options['secondary_filter_id'] = $secondary_filter_id;
|
72 |
update_option( 'lingotek_defaults', $options );
|
73 |
} else {
|
@@ -75,7 +80,7 @@ if ( $settings['primary_filter_id']['options'] === $default_filters ) {
|
|
75 |
if ( $num > 0 ) {
|
76 |
$extra_filters_exist = true;
|
77 |
} else {
|
78 |
-
$options['primary_filter_id']
|
79 |
$options['secondary_filter_id'] = '';
|
80 |
update_option( 'lingotek_defaults', $options );
|
81 |
$no_filters_exist = true;
|
@@ -92,45 +97,58 @@ unset( $settings['secondary_filter_id']['options'][ $primary_filter_id ] );
|
|
92 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
93 |
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
94 |
|
95 |
-
<table class="form-table"
|
96 |
-
|
97 |
-
|
|
|
98 |
<td>
|
99 |
-
<select name="<?php echo esc_html( $key ) ?>" id="<?php echo esc_html( $key ) ?>"
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
106 |
<?php
|
107 |
|
108 |
-
if ( empty( $setting['options'] ) ) {
|
|
|
109 |
<script> document.getElementById('project_id').style.display = 'none';</script>
|
110 |
-
<input type="text" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ) ?>" />
|
111 |
<?php } else { ?>
|
112 |
|
113 |
-
<input type="text" style="display:none" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ) ?>" />
|
114 |
<input type="checkbox" name="update_callback" id="update_callback"/>
|
115 |
-
<label for="update_callback" id="callback_label"><?php esc_html_e( 'Update the callback url for this project.', 'lingotek-translation' ) ?></label>
|
116 |
|
117 |
-
<br/><a href="#" id="create" onclick="toggleTextbox()" style="padding-left:3px; color:#999; font-size:80%; text-decoration:none"><b>+</b> <?php echo esc_html_e( 'Create New Project', 'lingotek-translation' ) ?></a>
|
118 |
<?php } ?>
|
119 |
<?php } ?>
|
120 |
<!-- Code to handle displaying of Primary and Secondary Filters. -->
|
121 |
-
<?php
|
122 |
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
123 |
-
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
|
|
|
|
|
|
|
|
129 |
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
130 |
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
131 |
-
|
132 |
<!-- End of filter code. -->
|
133 |
-
</tr
|
|
|
|
|
|
|
134 |
</table>
|
135 |
|
136 |
<p>
|
@@ -139,4 +157,4 @@ if ( $default_filters_exist ) { ?>
|
|
139 |
</p>
|
140 |
</form>
|
141 |
|
142 |
-
<?php Lingotek_Workflow_Factory::
|
2 |
|
3 |
$page_key = $this->plugin_slug . '_settings&sm=defaults';
|
4 |
|
5 |
+
wp_enqueue_script( 'defaults', LINGOTEK_URL . '/js/defaults.js', array(), LINGOTEK_VERSION, false );
|
6 |
|
7 |
if ( ! empty( $_POST ) ) {
|
8 |
check_admin_referer( $page_key, '_wpnonce_' . $page_key );
|
19 |
add_settings_error( 'lingotek_community_resources', 'error', __( 'The Lingotek TMS is currently unavailable. Please try again later. If the problem persists, contact Lingotek Support.', 'lingotek-translation' ), 'error' );
|
20 |
}
|
21 |
} else {
|
22 |
+
$options = array();
|
23 |
$settings = $this->get_profiles_settings( true );
|
24 |
foreach ( $settings as $key => $setting ) {
|
25 |
$key_input = filter_input( INPUT_POST, $key );
|
41 |
// adds new project if text box is filled out.
|
42 |
$new_project = filter_input( INPUT_POST, 'new_project' );
|
43 |
if ( ! empty( $new_project ) ) {
|
44 |
+
$client = new Lingotek_API();
|
45 |
+
$project_title = stripslashes( filter_input( INPUT_POST, 'new_project' ) );
|
46 |
|
47 |
+
$new_id = $client->create_project( $project_title, $community_id );
|
48 |
+
if ( $new_id ) {
|
49 |
add_settings_error( 'lingotek_defaults', 'defaultgs', __( 'Your new project was successfully created.', 'lingotek-translation' ), 'updated' );
|
50 |
+
// Updates the cache to include the newly created project.
|
51 |
+
$this->set_community_resources( $community_id );
|
52 |
$options['project_id'] = $new_id;
|
53 |
update_option( 'lingotek_defaults', $options );
|
54 |
}
|
55 |
}
|
56 |
+
}//end if
|
57 |
settings_errors();
|
58 |
+
}//end if
|
59 |
$settings = $this->get_profiles_settings( true );
|
60 |
+
$options = get_option( 'lingotek_defaults', array() );
|
61 |
|
62 |
// Code to determine which filter scenario will be displayed (Not configured, defaults, custom filters).
|
63 |
+
$primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options'], true );
|
64 |
+
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $settings['secondary_filter_id']['options'], true );
|
65 |
+
$default_filters = array(
|
66 |
+
$primary_filter_id => 'okf_json@with-html-subfilter.fprm',
|
67 |
+
$secondary_filter_id => 'okf_html@wordpress.fprm',
|
68 |
+
);
|
69 |
$default_filters_exist = false;
|
70 |
+
$extra_filters_exist = false;
|
71 |
+
$no_filters_exist = false;
|
72 |
|
73 |
if ( $settings['primary_filter_id']['options'] === $default_filters ) {
|
74 |
+
$default_filters_exist = true;
|
75 |
+
$options['primary_filter_id'] = $primary_filter_id;
|
76 |
$options['secondary_filter_id'] = $secondary_filter_id;
|
77 |
update_option( 'lingotek_defaults', $options );
|
78 |
} else {
|
80 |
if ( $num > 0 ) {
|
81 |
$extra_filters_exist = true;
|
82 |
} else {
|
83 |
+
$options['primary_filter_id'] = '';
|
84 |
$options['secondary_filter_id'] = '';
|
85 |
update_option( 'lingotek_defaults', $options );
|
86 |
$no_filters_exist = true;
|
97 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
98 |
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
99 |
|
100 |
+
<table class="form-table">
|
101 |
+
<?php foreach ( $settings as $key => $setting ) { ?>
|
102 |
+
<tr id="<?php echo esc_html( $key ) . '_row'; ?>">
|
103 |
+
<th scope="row"><label for="<?php echo esc_html( $key ); ?>"><?php echo esc_html( $setting['label'] ); ?></label></th>
|
104 |
<td>
|
105 |
+
<select name="<?php echo esc_html( $key ); ?>" id="<?php echo esc_html( $key ); ?>">
|
106 |
+
<?php
|
107 |
+
foreach ( $setting['options'] as $option_id => $option_title ) {
|
108 |
+
$selected = array_key_exists( $key, $options ) && ( $options[ $key ] === $option_id ) ? 'selected="selected"' : '';
|
109 |
+
echo "\n\t<option value='" . esc_attr( $option_id ) . "' " . esc_html( $selected ) . '>' . esc_html( $option_title ) . '</option>';
|
110 |
+
}
|
111 |
+
?>
|
112 |
+
</select>
|
113 |
+
<?php
|
114 |
+
if ( 'project_id' === $key ) {
|
115 |
+
?>
|
116 |
<?php
|
117 |
|
118 |
+
if ( empty( $setting['options'] ) ) {
|
119 |
+
?>
|
120 |
<script> document.getElementById('project_id').style.display = 'none';</script>
|
121 |
+
<input type="text" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ); ?>" />
|
122 |
<?php } else { ?>
|
123 |
|
124 |
+
<input type="text" style="display:none" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ); ?>" />
|
125 |
<input type="checkbox" name="update_callback" id="update_callback"/>
|
126 |
+
<label for="update_callback" id="callback_label"><?php esc_html_e( 'Update the callback url for this project.', 'lingotek-translation' ); ?></label>
|
127 |
|
128 |
+
<br/><a href="#" id="create" onclick="toggleTextbox()" style="padding-left:3px; color:#999; font-size:80%; text-decoration:none"><b>+</b> <?php echo esc_html_e( 'Create New Project', 'lingotek-translation' ); ?></a>
|
129 |
<?php } ?>
|
130 |
<?php } ?>
|
131 |
<!-- Code to handle displaying of Primary and Secondary Filters. -->
|
132 |
+
<?php if ( $no_filters_exist ) { ?>
|
133 |
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
134 |
+
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
135 |
+
<?php
|
136 |
+
if ( 'primary_filter_id' === $key ) {
|
137 |
+
?>
|
138 |
+
<tr id="filters_row"><th><?php esc_html_e( 'Filters', 'lingotek-translation' ); ?></th><td><i><?php esc_html_e( 'Not configured', 'lingotek-translation' ); ?></i></td></tr>
|
139 |
+
<?php
|
140 |
+
}
|
141 |
+
}
|
142 |
+
if ( $default_filters_exist ) {
|
143 |
+
?>
|
144 |
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
145 |
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
146 |
+
<?php } ?>
|
147 |
<!-- End of filter code. -->
|
148 |
+
</tr>
|
149 |
+
<?php
|
150 |
+
}//end foreach
|
151 |
+
?>
|
152 |
</table>
|
153 |
|
154 |
<p>
|
157 |
</p>
|
158 |
</form>
|
159 |
|
160 |
+
<?php Lingotek_Workflow_Factory::lingotek_translation_professional_translation_info_modals(); ?>
|
admin/settings/view-preferences.php
CHANGED
@@ -1,72 +1,75 @@
|
|
1 |
<?php
|
2 |
global $wp_post_statuses;
|
3 |
$setting_details = array(
|
4 |
-
'download_post_status'
|
5 |
-
'type'
|
6 |
-
'label'
|
7 |
'description' => __( 'The post status for newly downloaded translations', 'lingotek-translation' ),
|
8 |
-
'values'
|
9 |
-
Lingotek_Group_Post::SAME_AS_SOURCE => __( 'Same as source post', 'lingotek-translation' )
|
10 |
),
|
11 |
),
|
12 |
-
'auto_upload_post_statuses' => array(
|
13 |
-
'type'
|
14 |
-
'label'
|
15 |
'description' => __( 'The post statuses checked above are enabled for automatic upload (when using automatic uploading translation profiles).', 'lingotek-translation' ),
|
16 |
-
'values'
|
17 |
),
|
18 |
-
'trash_linked_content'
|
19 |
-
'type'
|
20 |
-
'label'
|
21 |
-
'description' => __( 'When enabled, sending source or target content to the trash will also send all linked content to the trash. ', '
|
22 |
-
'values'
|
23 |
-
'enabled' => __( 'Sync trashed content', '
|
24 |
),
|
25 |
),
|
26 |
-
'import_enabled'
|
27 |
-
'type'
|
28 |
-
'label'
|
29 |
-
'description' => __( 'When checked, an "Import" submenu will appear.', '
|
30 |
-
'values'
|
31 |
-
'enabled' => __( 'Enable importing from Lingotek Content Cloud. (beta)', '
|
32 |
),
|
33 |
),
|
34 |
-
'auto_update_status'
|
35 |
-
'type'
|
36 |
-
'label' => __( 'Automatic Status Update Interval', '
|
37 |
-
'description' => __( 'Changes the rate at which content statuses update automatically.', '
|
38 |
-
'values'
|
39 |
-
'10' => '10 seconds',
|
|
|
|
|
|
|
40 |
),
|
41 |
),
|
42 |
-
'enable_lingotek_logs'
|
43 |
-
'type'
|
44 |
-
'label'
|
45 |
-
'description' => __( 'Enables Lingotek\'s logs for debugging purposes.'
|
46 |
-
'values'
|
47 |
-
'enabled' => __( 'Enable Lingotek Logs', '
|
48 |
),
|
49 |
),
|
50 |
);
|
51 |
|
52 |
-
function
|
53 |
return __( $status->label, 'lingotek-translation' );
|
54 |
}
|
55 |
|
56 |
-
function
|
57 |
-
$statuses_to_filter = array('auto-draft', 'trash', 'inactive', 'inherit');
|
58 |
-
$ret
|
59 |
-
foreach ($statuses as $status => $value) {
|
60 |
-
if (!in_array($status
|
61 |
-
$ret[$status] = $value;
|
62 |
}
|
63 |
}
|
64 |
return $ret;
|
65 |
}
|
66 |
|
67 |
-
$post_statuses =
|
68 |
-
$setting_details[
|
69 |
-
$setting_details[
|
70 |
|
71 |
$page_key = $this->plugin_slug . '_settings&sm=preferences';
|
72 |
|
@@ -79,10 +82,9 @@ if ( ! empty( $_POST ) ) {
|
|
79 |
$options[ $key ] = $key_input;
|
80 |
} else {
|
81 |
$key_input = filter_input_array( INPUT_POST );
|
82 |
-
if (!empty($key_input[$key])) {
|
83 |
-
$options[ $key ] = $key_input[$key];
|
84 |
-
}
|
85 |
-
else {
|
86 |
$options[ $key ] = null;
|
87 |
}
|
88 |
}
|
@@ -91,7 +93,7 @@ if ( ! empty( $_POST ) ) {
|
|
91 |
|
92 |
add_settings_error( 'lingotek_prefs', 'prefs', __( 'Your preferences were successfully updated.', 'lingotek-translation' ), 'updated' );
|
93 |
settings_errors();
|
94 |
-
}
|
95 |
$selected_options = Lingotek_Model::get_prefs();
|
96 |
|
97 |
?>
|
@@ -103,32 +105,37 @@ $selected_options = Lingotek_Model::get_prefs();
|
|
103 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
104 |
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
105 |
|
106 |
-
<table class="form-table"
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
<?php
|
114 |
-
|
115 |
-
|
116 |
-
}
|
117 |
-
?>
|
118 |
-
</select>
|
119 |
-
<?php } elseif ( 'checkboxes' === $setting['type'] ) {
|
120 |
-
echo '<ul class="pref-statuses">';
|
121 |
-
foreach ( $setting['values'] as $id => $title ) {
|
122 |
-
$cb_name = $key . '[' . esc_attr( $id ) . ']';
|
123 |
-
$checked = checked( '1', (isset( $selected_options[ $key ][ $id ] ) && $selected_options[ $key ][ $id ]), false );
|
124 |
-
echo '<li><input type="checkbox" id="' . esc_attr( $cb_name ) . '" name="' . esc_attr( $cb_name ) . '" value="1" ' . esc_attr( $checked ) . '><label for="' . esc_attr( $cb_name ) . '">' . esc_html( $title ) . '</label></li>';
|
125 |
-
}
|
126 |
-
echo '</ul>';
|
127 |
-
} ?>
|
128 |
-
<p class="description">
|
129 |
-
<?php echo esc_html( $setting['description'] ); ?>
|
130 |
-
</p>
|
131 |
-
</tr><?php } ?>
|
132 |
</table>
|
133 |
|
134 |
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
1 |
<?php
|
2 |
global $wp_post_statuses;
|
3 |
$setting_details = array(
|
4 |
+
'download_post_status' => array(
|
5 |
+
'type' => 'dropdown',
|
6 |
+
'label' => __( 'Download translation status', 'lingotek-translation' ),
|
7 |
'description' => __( 'The post status for newly downloaded translations', 'lingotek-translation' ),
|
8 |
+
'values' => array(
|
9 |
+
Lingotek_Group_Post::SAME_AS_SOURCE => __( 'Same as source post', 'lingotek-translation' ),
|
10 |
),
|
11 |
),
|
12 |
+
'auto_upload_post_statuses' => array(
|
13 |
+
'type' => 'checkboxes',
|
14 |
+
'label' => __( 'Auto upload statuses', 'lingotek-translation' ),
|
15 |
'description' => __( 'The post statuses checked above are enabled for automatic upload (when using automatic uploading translation profiles).', 'lingotek-translation' ),
|
16 |
+
'values' => array(),
|
17 |
),
|
18 |
+
'trash_linked_content' => array(
|
19 |
+
'type' => 'checkboxes',
|
20 |
+
'label' => __( 'Trashed Content', 'lingotek-translation' ),
|
21 |
+
'description' => __( 'When enabled, sending source or target content to the trash will also send all linked content to the trash. ', 'lingotek-translation' ),
|
22 |
+
'values' => array(
|
23 |
+
'enabled' => __( 'Sync trashed content', 'lingotek-translation' ),
|
24 |
),
|
25 |
),
|
26 |
+
'import_enabled' => array(
|
27 |
+
'type' => 'checkboxes',
|
28 |
+
'label' => __( 'Import', 'lingotek-translation' ),
|
29 |
+
'description' => __( 'When checked, an "Import" submenu will appear.', 'lingotek-translation' ),
|
30 |
+
'values' => array(
|
31 |
+
'enabled' => __( 'Enable importing from Lingotek Content Cloud. (beta)', 'lingotek-translation' ),
|
32 |
),
|
33 |
),
|
34 |
+
'auto_update_status' => array(
|
35 |
+
'type' => 'dropdown',
|
36 |
+
'label' => __( 'Automatic Status Update Interval', 'lingotek-translation' ),
|
37 |
+
'description' => __( 'Changes the rate at which content statuses update automatically.', 'lingotek-translation' ),
|
38 |
+
'values' => array(
|
39 |
+
'10' => '10 seconds',
|
40 |
+
'30' => '30 seconds',
|
41 |
+
'60' => '60 seconds',
|
42 |
+
'-1' => 'Do not update automatically',
|
43 |
),
|
44 |
),
|
45 |
+
'enable_lingotek_logs' => array(
|
46 |
+
'type' => 'checkboxes',
|
47 |
+
'label' => __( 'Enable Lingotek Debug Logs', 'lingotek-translation' ),
|
48 |
+
'description' => __( 'Enables Lingotek\'s logs for debugging purposes.', 'lingotek-translation' ),
|
49 |
+
'values' => array(
|
50 |
+
'enabled' => __( 'Enable Lingotek Logs', 'lingotek-translation' ),
|
51 |
),
|
52 |
),
|
53 |
);
|
54 |
|
55 |
+
function lingotek_translation_preferences_map_wp_post_status( $status ) {
|
56 |
return __( $status->label, 'lingotek-translation' );
|
57 |
}
|
58 |
|
59 |
+
function lingotek_translation_preferences_filter_statuses( $statuses ) {
|
60 |
+
$statuses_to_filter = array( 'auto-draft', 'trash', 'inactive', 'inherit' );
|
61 |
+
$ret = array();
|
62 |
+
foreach ( $statuses as $status => $value ) {
|
63 |
+
if ( ! in_array( $status, $statuses_to_filter, true ) ) {
|
64 |
+
$ret[ $status ] = $value;
|
65 |
}
|
66 |
}
|
67 |
return $ret;
|
68 |
}
|
69 |
|
70 |
+
$post_statuses = lingotek_translation_preferences_filter_statuses( array_map( 'lingotek_translation_preferences_map_wp_post_status', $wp_post_statuses ) );
|
71 |
+
$setting_details['auto_upload_post_statuses']['values'] = array_merge( $post_statuses, $setting_details['auto_upload_post_statuses']['values'] );
|
72 |
+
$setting_details['download_post_status']['values'] = array_merge( $post_statuses, $setting_details['download_post_status']['values'] );
|
73 |
|
74 |
$page_key = $this->plugin_slug . '_settings&sm=preferences';
|
75 |
|
82 |
$options[ $key ] = $key_input;
|
83 |
} else {
|
84 |
$key_input = filter_input_array( INPUT_POST );
|
85 |
+
if ( ! empty( $key_input[ $key ] ) ) {
|
86 |
+
$options[ $key ] = $key_input[ $key ];
|
87 |
+
} else {
|
|
|
88 |
$options[ $key ] = null;
|
89 |
}
|
90 |
}
|
93 |
|
94 |
add_settings_error( 'lingotek_prefs', 'prefs', __( 'Your preferences were successfully updated.', 'lingotek-translation' ), 'updated' );
|
95 |
settings_errors();
|
96 |
+
}//end if
|
97 |
$selected_options = Lingotek_Model::get_prefs();
|
98 |
|
99 |
?>
|
105 |
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
106 |
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
107 |
|
108 |
+
<table class="form-table">
|
109 |
+
<?php foreach ( $setting_details as $key => $setting ) { ?>
|
110 |
+
<tr>
|
111 |
+
<th scope="row"><label for="<?php echo esc_html( $key ); ?>"><?php echo esc_html( $setting['label'] ); ?></label></th>
|
112 |
+
<td>
|
113 |
+
<?php if ( 'dropdown' === $setting['type'] ) { ?>
|
114 |
+
<select name="<?php echo esc_html( $key ); ?>" id="<?php echo esc_html( $key ); ?>">
|
115 |
+
<?php
|
116 |
+
foreach ( $setting['values'] as $setting_id => $setting_title ) {
|
117 |
+
echo "\n\t" . '<option value="' . esc_attr( $setting_id ) . '" ' . selected( $selected_options[ $key ], $setting_id ) . '>' . esc_html( $setting_title ) . '</option>';
|
118 |
+
}
|
119 |
+
?>
|
120 |
+
</select>
|
121 |
+
<?php
|
122 |
+
} elseif ( 'checkboxes' === $setting['type'] ) {
|
123 |
+
echo '<ul class="pref-statuses">';
|
124 |
+
foreach ( $setting['values'] as $setting_id => $setting_title ) {
|
125 |
+
$cb_name = $key . '[' . esc_attr( $setting_id ) . ']';
|
126 |
+
$checked = checked( '1', ( isset( $selected_options[ $key ][ $setting_id ] ) && $selected_options[ $key ][ $setting_id ] ), false );
|
127 |
+
echo '<li><input type="checkbox" id="' . esc_attr( $cb_name ) . '" name="' . esc_attr( $cb_name ) . '" value="1" ' . esc_attr( $checked ) . '><label for="' . esc_attr( $cb_name ) . '">' . esc_html( $setting_title ) . '</label></li>';
|
128 |
+
}
|
129 |
+
echo '</ul>';
|
130 |
+
}
|
131 |
+
?>
|
132 |
+
<p class="description">
|
133 |
+
<?php echo esc_html( $setting['description'] ); ?>
|
134 |
+
</p>
|
135 |
+
</tr>
|
136 |
<?php
|
137 |
+
}//end foreach
|
138 |
+
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
</table>
|
140 |
|
141 |
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
admin/settings/view-utilities.php
CHANGED
@@ -13,11 +13,11 @@ if ( ! empty( $_POST ) ) {
|
|
13 |
}
|
14 |
}
|
15 |
|
16 |
-
$utility_cancel = filter_input(INPUT_POST, 'utility_cancel');
|
17 |
-
if(!empty($utility_cancel)){
|
18 |
$ids = Lingotek_Utilities::get_all_document_ids();
|
19 |
-
if(!empty($ids)){
|
20 |
-
printf('<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', esc_html(__('Cancelling content...', 'lingotek-translation')));
|
21 |
}
|
22 |
}
|
23 |
|
@@ -29,14 +29,15 @@ if ( ! empty( $_POST ) ) {
|
|
29 |
$GLOBALS['wp_lingotek']->utilities->run_utilities( $utilities );
|
30 |
|
31 |
settings_errors();
|
32 |
-
}
|
33 |
|
34 |
?>
|
35 |
<h3><?php esc_html_e( 'Utilities', 'lingotek-translation' ); ?></h3>
|
36 |
<p class="description"><?php esc_html_e( 'These utilities are designed to help you prepare and maintain your multilingual content.', 'lingotek-translation' ); ?></p>
|
37 |
|
38 |
<h4><?php esc_html_e( 'Language', 'lingotek-translation' ); ?></h4>
|
39 |
-
<form id="lingotek-utilities" method="post" action="admin.php?page=<?php echo esc_attr( $page_key ); ?>" class="validate"
|
|
|
40 |
wp_nonce_field( $page_key, '_wpnonce_' . $page_key );
|
41 |
|
42 |
$allowed_html = array(
|
@@ -50,28 +51,28 @@ if ( ! empty( $_POST ) ) {
|
|
50 |
|
51 |
?>
|
52 |
|
53 |
-
<h4><?php esc_html_e('Cancellation', 'lingotek-translation')
|
54 |
<?php
|
55 |
|
56 |
printf(
|
57 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
58 |
'utility_cancel',
|
59 |
-
esc_html(__('Cancel any existing content from your Lingotek community', 'lingotek-translation'))
|
60 |
);
|
61 |
?>
|
62 |
-
|
63 |
<h4><?php esc_html_e( 'Deletion', 'lingotek-translation' ); ?></h4>
|
64 |
<?php
|
65 |
|
66 |
printf(
|
67 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
68 |
'utility_disassociate',
|
69 |
-
esc_html( __( 'Delete all unfinished documents from WordPress and cancel corresponding documents from your Lingotek Community.', 'lingotek-translation' ) ) .
|
70 |
-
);
|
71 |
|
72 |
$confirm_delete = __( 'You are about to delete all your content from your Lingotek community. Are you sure ?', 'lingotek-translation' );
|
73 |
|
74 |
-
$confirm_cancel = __('You are about to cancel all of your content from your Lingotek community. Are you sure ?', 'lingotek-translation');
|
75 |
|
76 |
$confirm_js = "
|
77 |
d = document.getElementById('utility_disassociate');
|
@@ -82,5 +83,7 @@ if ( ! empty( $_POST ) ) {
|
|
82 |
return confirm('$confirm_cancel');
|
83 |
}";
|
84 |
|
85 |
-
submit_button( __( 'Run Utilities', 'lingotek-translation' ), 'primary', 'submit', true, sprintf( 'onclick="%s"', $confirm_js ) );
|
86 |
-
|
|
|
|
13 |
}
|
14 |
}
|
15 |
|
16 |
+
$utility_cancel = filter_input( INPUT_POST, 'utility_cancel' );
|
17 |
+
if ( ! empty( $utility_cancel ) ) {
|
18 |
$ids = Lingotek_Utilities::get_all_document_ids();
|
19 |
+
if ( ! empty( $ids ) ) {
|
20 |
+
printf( '<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', esc_html( __( 'Cancelling content...', 'lingotek-translation' ) ) );
|
21 |
}
|
22 |
}
|
23 |
|
29 |
$GLOBALS['wp_lingotek']->utilities->run_utilities( $utilities );
|
30 |
|
31 |
settings_errors();
|
32 |
+
}//end if
|
33 |
|
34 |
?>
|
35 |
<h3><?php esc_html_e( 'Utilities', 'lingotek-translation' ); ?></h3>
|
36 |
<p class="description"><?php esc_html_e( 'These utilities are designed to help you prepare and maintain your multilingual content.', 'lingotek-translation' ); ?></p>
|
37 |
|
38 |
<h4><?php esc_html_e( 'Language', 'lingotek-translation' ); ?></h4>
|
39 |
+
<form id="lingotek-utilities" method="post" action="admin.php?page=<?php echo esc_attr( $page_key ); ?>" class="validate">
|
40 |
+
<?php
|
41 |
wp_nonce_field( $page_key, '_wpnonce_' . $page_key );
|
42 |
|
43 |
$allowed_html = array(
|
51 |
|
52 |
?>
|
53 |
|
54 |
+
<h4><?php esc_html_e( 'Cancellation', 'lingotek-translation' ); ?></h4>
|
55 |
<?php
|
56 |
|
57 |
printf(
|
58 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
59 |
'utility_cancel',
|
60 |
+
esc_html( __( 'Cancel any existing content from your Lingotek community', 'lingotek-translation' ) )
|
61 |
);
|
62 |
?>
|
63 |
+
|
64 |
<h4><?php esc_html_e( 'Deletion', 'lingotek-translation' ); ?></h4>
|
65 |
<?php
|
66 |
|
67 |
printf(
|
68 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
69 |
'utility_disassociate',
|
70 |
+
esc_html( __( 'Delete all unfinished documents from WordPress and cancel corresponding documents from your Lingotek Community.', 'lingotek-translation' ) ) . ' <b>Use with caution.</b>'
|
71 |
+
);
|
72 |
|
73 |
$confirm_delete = __( 'You are about to delete all your content from your Lingotek community. Are you sure ?', 'lingotek-translation' );
|
74 |
|
75 |
+
$confirm_cancel = __( 'You are about to cancel all of your content from your Lingotek community. Are you sure ?', 'lingotek-translation' );
|
76 |
|
77 |
$confirm_js = "
|
78 |
d = document.getElementById('utility_disassociate');
|
83 |
return confirm('$confirm_cancel');
|
84 |
}";
|
85 |
|
86 |
+
submit_button( __( 'Run Utilities', 'lingotek-translation' ), 'primary', 'submit', true, sprintf( 'onclick="%s"', $confirm_js ) );
|
87 |
+
?>
|
88 |
+
</form>
|
89 |
+
<?php
|
admin/string-actions.php
CHANGED
@@ -28,7 +28,6 @@ class Lingotek_String_actions extends Lingotek_Actions {
|
|
28 |
*/
|
29 |
protected function get_language( $name ) {
|
30 |
return $this->pllm->get_language( $this->pllm->options['default_lang'] );
|
31 |
-
;
|
32 |
}
|
33 |
|
34 |
|
@@ -53,7 +52,7 @@ class Lingotek_String_actions extends Lingotek_Actions {
|
|
53 |
* @return string
|
54 |
*/
|
55 |
protected function get_action_link( $args, $warning = false ) {
|
56 |
-
$args['page']
|
57 |
$args['noheader'] = true;
|
58 |
return parent::get_action_link( $args, $warning );
|
59 |
}
|
@@ -78,7 +77,6 @@ class Lingotek_String_actions extends Lingotek_Actions {
|
|
78 |
* @param string $action action.
|
79 |
*/
|
80 |
public function manage_actions( $action ) {
|
81 |
-
|
82 |
$redirect = remove_query_arg( array( 'action', 'action2' ), wp_get_referer() );
|
83 |
if ( ! $redirect ) {
|
84 |
$redirect = admin_url( 'admin.php?page=lingotek-translation_manage&sm=strings' );
|
@@ -120,13 +118,13 @@ class Lingotek_String_actions extends Lingotek_Actions {
|
|
120 |
|
121 |
default:
|
122 |
if ( ! $this->_manage_actions( $action ) ) {
|
123 |
-
|
|
|
124 |
}
|
125 |
-
}
|
126 |
|
127 |
wp_redirect( $redirect );
|
128 |
exit();
|
129 |
-
|
130 |
}
|
131 |
|
132 |
/**
|
28 |
*/
|
29 |
protected function get_language( $name ) {
|
30 |
return $this->pllm->get_language( $this->pllm->options['default_lang'] );
|
|
|
31 |
}
|
32 |
|
33 |
|
52 |
* @return string
|
53 |
*/
|
54 |
protected function get_action_link( $args, $warning = false ) {
|
55 |
+
$args['page'] = 'lingotek-translation_manage';
|
56 |
$args['noheader'] = true;
|
57 |
return parent::get_action_link( $args, $warning );
|
58 |
}
|
77 |
* @param string $action action.
|
78 |
*/
|
79 |
public function manage_actions( $action ) {
|
|
|
80 |
$redirect = remove_query_arg( array( 'action', 'action2' ), wp_get_referer() );
|
81 |
if ( ! $redirect ) {
|
82 |
$redirect = admin_url( 'admin.php?page=lingotek-translation_manage&sm=strings' );
|
118 |
|
119 |
default:
|
120 |
if ( ! $this->_manage_actions( $action ) ) {
|
121 |
+
// Do not redirect if this is not one of our actions.
|
122 |
+
return;
|
123 |
}
|
124 |
+
}//end switch
|
125 |
|
126 |
wp_redirect( $redirect );
|
127 |
exit();
|
|
|
128 |
}
|
129 |
|
130 |
/**
|
admin/strings-table.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
-
|
|
|
5 |
}
|
6 |
|
7 |
/**
|
@@ -34,12 +35,15 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
34 |
* @param string $string_actions string actions.
|
35 |
*/
|
36 |
function __construct( $string_actions ) {
|
37 |
-
parent::__construct(
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
43 |
$this->string_actions = $string_actions;
|
44 |
}
|
45 |
|
@@ -59,49 +63,51 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
59 |
|
60 |
// language column.
|
61 |
$language = $this->pllm->get_language( substr( $column_name, 9 ) );
|
62 |
-
|
63 |
-
|
64 |
|
65 |
-
$workflow_id = Lingotek_Model::get_profile_option('workflow_id', 'string', $language);
|
66 |
-
|
67 |
-
$workflow
|
|
|
68 |
|
69 |
$allowed_html = array(
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
);
|
83 |
// post ready for upload.
|
84 |
if ( $this->lgtm->can_upload( 'string', $item['context'] ) && $language->slug === $this->pllm->options['default_lang'] ) {
|
85 |
echo wp_kses( $this->string_actions->upload_icon( $item['context'] ), $allowed_html );
|
86 |
-
} //
|
87 |
elseif ( isset( $document->source ) && $document->is_disabled_target( $language ) ) {
|
88 |
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
89 |
} // source post is uploaded.
|
90 |
elseif ( isset( $document->source ) && $document->source === $language->mo_id ) {
|
91 |
echo wp_kses( 'importing' === $document->status ? Lingotek_Actions::importing_icon( $document ) : Lingotek_String_actions::uploaded_icon( $item['context'] ), $allowed_html );
|
92 |
} // translations.
|
93 |
-
elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) && Lingotek::is_allowed_tms_locale($language->lingotek_locale)) {
|
94 |
echo wp_kses( Lingotek_Actions::translation_icon( $document, $language ), $allowed_html );
|
95 |
} // no translation.
|
96 |
-
else {
|
|
|
97 |
}
|
98 |
|
99 |
$language_only = 'language_' . $language->slug;
|
100 |
-
$errors
|
101 |
if ( $language_only === $this->get_first_language_column() ) {
|
102 |
if ( isset( $errors[ $item['context'] ] ) ) {
|
103 |
$api_error = Lingotek_Actions::retrieve_api_error( $errors[ $item['context'] ] );
|
104 |
-
echo
|
105 |
}
|
106 |
}
|
107 |
}
|
@@ -140,9 +146,9 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
140 |
*/
|
141 |
function get_columns() {
|
142 |
$columns = array(
|
143 |
-
'cb'
|
144 |
-
'context'
|
145 |
-
'count'
|
146 |
);
|
147 |
|
148 |
foreach ( $GLOBALS['polylang']->model->get_languages_list() as $lang ) {
|
@@ -178,7 +184,7 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
178 |
* @param array $data data.
|
179 |
*/
|
180 |
function prepare_items( $data = array() ) {
|
181 |
-
$per_page
|
182 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
183 |
|
184 |
/**
|
@@ -189,24 +195,29 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
189 |
* @return int sort direction.
|
190 |
*/
|
191 |
function usort_reorder( $a, $b ) {
|
192 |
-
$order
|
193 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
194 |
-
|
195 |
-
|
|
|
|
|
196 |
};
|
197 |
|
198 |
-
|
|
|
199 |
usort( $data, 'usort_reorder' );
|
200 |
}
|
201 |
|
202 |
$total_items = count( $data );
|
203 |
-
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
204 |
-
|
205 |
-
$this->set_pagination_args(
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
|
|
210 |
}
|
211 |
|
212 |
/**
|
1 |
<?php
|
2 |
|
3 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
// since WP 3.1.
|
5 |
+
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
6 |
}
|
7 |
|
8 |
/**
|
35 |
* @param string $string_actions string actions.
|
36 |
*/
|
37 |
function __construct( $string_actions ) {
|
38 |
+
parent::__construct(
|
39 |
+
array(
|
40 |
+
// Do not translate (used for css class).
|
41 |
+
'plural' => 'lingotek-strings-translations',
|
42 |
+
'ajax' => false,
|
43 |
+
)
|
44 |
+
);
|
45 |
+
$this->pllm = $GLOBALS['polylang']->model;
|
46 |
+
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
47 |
$this->string_actions = $string_actions;
|
48 |
}
|
49 |
|
63 |
|
64 |
// language column.
|
65 |
$language = $this->pllm->get_language( substr( $column_name, 9 ) );
|
66 |
+
// FIXME.
|
67 |
+
$document = $this->lgtm->get_group( 'string', $item['context'] );
|
68 |
|
69 |
+
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', 'string', $language );
|
70 |
+
// TODO: put workflow_id here. It is currently not set up.
|
71 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
|
72 |
+
$workflow->echo_strings_modal( $item['row'], $language->locale );
|
73 |
|
74 |
$allowed_html = array(
|
75 |
+
'a' => array(
|
76 |
+
'class' => array(),
|
77 |
+
'title' => array(),
|
78 |
+
'href' => array(),
|
79 |
+
),
|
80 |
+
'img' => array(
|
81 |
+
'src' => array(),
|
82 |
+
),
|
83 |
+
'div' => array(
|
84 |
+
'title' => array(),
|
85 |
+
'class' => array(),
|
86 |
+
),
|
87 |
);
|
88 |
// post ready for upload.
|
89 |
if ( $this->lgtm->can_upload( 'string', $item['context'] ) && $language->slug === $this->pllm->options['default_lang'] ) {
|
90 |
echo wp_kses( $this->string_actions->upload_icon( $item['context'] ), $allowed_html );
|
91 |
+
} //end if
|
92 |
elseif ( isset( $document->source ) && $document->is_disabled_target( $language ) ) {
|
93 |
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
94 |
} // source post is uploaded.
|
95 |
elseif ( isset( $document->source ) && $document->source === $language->mo_id ) {
|
96 |
echo wp_kses( 'importing' === $document->status ? Lingotek_Actions::importing_icon( $document ) : Lingotek_String_actions::uploaded_icon( $item['context'] ), $allowed_html );
|
97 |
} // translations.
|
98 |
+
elseif ( isset( $document->translations[ $language->locale ] ) || ( isset( $document->source ) && 'current' === $document->status ) && Lingotek::is_allowed_tms_locale( $language->lingotek_locale ) ) {
|
99 |
echo wp_kses( Lingotek_Actions::translation_icon( $document, $language ), $allowed_html );
|
100 |
} // no translation.
|
101 |
+
else {
|
102 |
+
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
103 |
}
|
104 |
|
105 |
$language_only = 'language_' . $language->slug;
|
106 |
+
$errors = get_option( 'lingotek_log_errors' );
|
107 |
if ( $language_only === $this->get_first_language_column() ) {
|
108 |
if ( isset( $errors[ $item['context'] ] ) ) {
|
109 |
$api_error = Lingotek_Actions::retrieve_api_error( $errors[ $item['context'] ] );
|
110 |
+
echo Lingotek_Actions::display_error_icon( 'error', $api_error );
|
111 |
}
|
112 |
}
|
113 |
}
|
146 |
*/
|
147 |
function get_columns() {
|
148 |
$columns = array(
|
149 |
+
'cb' => '<input type="checkbox" />',
|
150 |
+
'context' => __( 'Group', 'lingotek-translation' ),
|
151 |
+
'count' => __( 'Count', 'lingotek-translation' ),
|
152 |
);
|
153 |
|
154 |
foreach ( $GLOBALS['polylang']->model->get_languages_list() as $lang ) {
|
184 |
* @param array $data data.
|
185 |
*/
|
186 |
function prepare_items( $data = array() ) {
|
187 |
+
$per_page = $this->get_items_per_page( 'lingotek_strings_per_page' );
|
188 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
189 |
|
190 |
/**
|
195 |
* @return int sort direction.
|
196 |
*/
|
197 |
function usort_reorder( $a, $b ) {
|
198 |
+
$order = filter_input( INPUT_GET, 'order' );
|
199 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
200 |
+
// Determine sort order.
|
201 |
+
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
|
202 |
+
// Send final sort direction to usort.
|
203 |
+
return ( empty( $order ) || 'asc' === $order ) ? $result : -$result;
|
204 |
};
|
205 |
|
206 |
+
// no sort by default.
|
207 |
+
if ( ! empty( $orderby ) ) {
|
208 |
usort( $data, 'usort_reorder' );
|
209 |
}
|
210 |
|
211 |
$total_items = count( $data );
|
212 |
+
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
213 |
+
|
214 |
+
$this->set_pagination_args(
|
215 |
+
array(
|
216 |
+
'total_items' => $total_items,
|
217 |
+
'per_page' => $per_page,
|
218 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
219 |
+
)
|
220 |
+
);
|
221 |
}
|
222 |
|
223 |
/**
|
admin/table-string.php
CHANGED
@@ -20,11 +20,14 @@ class Lingotek_Table_String extends PLL_Table_String {
|
|
20 |
$input_type = $item['multiline'] ?
|
21 |
'<textarea name="translation[%1$s][%2$s]" id="%1$s-%2$s" disabled="disabled">%4$s</textarea>' :
|
22 |
'<input type="text" name="translation[%1$s][%2$s]" id="%1$s-%2$s" value="%4$s" disabled="disabled" />';
|
23 |
-
$out
|
|
|
24 |
esc_attr( $key ),
|
25 |
esc_attr( $item['row'] ),
|
26 |
esc_html( $this->languages['languages'][ $key ] ),
|
27 |
-
|
|
|
|
|
28 |
}
|
29 |
return $out;
|
30 |
}
|
@@ -49,7 +52,7 @@ class Lingotek_Table_String extends PLL_Table_String {
|
|
49 |
// Load translations.
|
50 |
foreach ( $listlanguages as $language ) {
|
51 |
// filters by language if requested.
|
52 |
-
if ( ($lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true )) && $language->slug !== $lg ) {
|
53 |
continue;
|
54 |
}
|
55 |
|
@@ -57,25 +60,29 @@ class Lingotek_Table_String extends PLL_Table_String {
|
|
57 |
$mo->import_from_db( $language );
|
58 |
foreach ( $data as $key => $row ) {
|
59 |
$data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
|
60 |
-
|
|
|
61 |
}
|
62 |
}
|
63 |
|
64 |
-
$per_page
|
65 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
66 |
|
67 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
68 |
-
|
|
|
69 |
usort( $data, array( $this, 'usort_reorder' ) );
|
70 |
}
|
71 |
|
72 |
$total_items = count( $data );
|
73 |
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
74 |
|
75 |
-
$this->set_pagination_args(
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
80 |
}
|
81 |
}
|
20 |
$input_type = $item['multiline'] ?
|
21 |
'<textarea name="translation[%1$s][%2$s]" id="%1$s-%2$s" disabled="disabled">%4$s</textarea>' :
|
22 |
'<input type="text" name="translation[%1$s][%2$s]" id="%1$s-%2$s" value="%4$s" disabled="disabled" />';
|
23 |
+
$out .= sprintf(
|
24 |
+
'<div class="translation"><label for="%1$s-%2$s">%3$s</label>' . $input_type . '</div>' . "\n",
|
25 |
esc_attr( $key ),
|
26 |
esc_attr( $item['row'] ),
|
27 |
esc_html( $this->languages['languages'][ $key ] ),
|
28 |
+
// Don't interpret special chars.
|
29 |
+
format_to_edit( $translation )
|
30 |
+
);
|
31 |
}
|
32 |
return $out;
|
33 |
}
|
52 |
// Load translations.
|
53 |
foreach ( $listlanguages as $language ) {
|
54 |
// filters by language if requested.
|
55 |
+
if ( ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) && $language->slug !== $lg ) {
|
56 |
continue;
|
57 |
}
|
58 |
|
60 |
$mo->import_from_db( $language );
|
61 |
foreach ( $data as $key => $row ) {
|
62 |
$data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
|
63 |
+
// Store the row number for convenience.
|
64 |
+
$data[ $key ]['row'] = $key;
|
65 |
}
|
66 |
}
|
67 |
|
68 |
+
$per_page = $this->get_items_per_page( 'pll_strings_per_page' );
|
69 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
70 |
|
71 |
$orderby = filter_input( INPUT_GET, 'orderby' );
|
72 |
+
// No sort by default.
|
73 |
+
if ( ! empty( $orderby ) ) {
|
74 |
usort( $data, array( $this, 'usort_reorder' ) );
|
75 |
}
|
76 |
|
77 |
$total_items = count( $data );
|
78 |
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
79 |
|
80 |
+
$this->set_pagination_args(
|
81 |
+
array(
|
82 |
+
'total_items' => $total_items,
|
83 |
+
'per_page' => $per_page,
|
84 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
85 |
+
)
|
86 |
+
);
|
87 |
}
|
88 |
}
|
admin/term-actions.php
CHANGED
@@ -14,13 +14,14 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
14 |
* @since 0.2
|
15 |
*/
|
16 |
public function __construct() {
|
17 |
-
parent::__construct('term');
|
18 |
|
19 |
-
foreach ($this->pllm->get_translated_taxonomies() as $taxonomy)
|
20 |
-
add_filter( $taxonomy . '_row_actions', array(&$this, 'term_row_actions'), 10, 2);
|
|
|
21 |
|
22 |
// add_action('admin_footer-edit-tags.php', array(&$this, 'add_bulk_actions')); // FIXME admin_print_footer_scripts instead?
|
23 |
-
add_action('load-edit-tags.php', array(&$this, 'manage_actions'));
|
24 |
}
|
25 |
|
26 |
/*
|
@@ -31,8 +32,8 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
31 |
* @param int $term_id
|
32 |
* @return object
|
33 |
*/
|
34 |
-
protected function get_language($term_id) {
|
35 |
-
return PLL()->model->term->get_language($term_id);
|
36 |
}
|
37 |
|
38 |
/*
|
@@ -42,11 +43,12 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
42 |
*
|
43 |
* @param int $id
|
44 |
*/
|
45 |
-
public static function uploaded_icon($id) {
|
46 |
-
|
47 |
-
$
|
48 |
-
$
|
49 |
-
|
|
|
50 |
}
|
51 |
|
52 |
/*
|
@@ -58,15 +60,16 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
58 |
* @param object $term
|
59 |
* @return array
|
60 |
*/
|
61 |
-
public function term_row_actions($actions, $term) {
|
62 |
-
if ($this->pllm->is_translated_taxonomy($term->taxonomy)) {
|
63 |
-
$actions = $this->_row_actions($actions, $term->term_id);
|
64 |
-
|
65 |
-
$language = PLL()->model->term->get_language($term->term_id);
|
66 |
-
if (!empty($language)) {
|
67 |
-
$profile = Lingotek_Model::get_profile($term->taxonomy, $language);
|
68 |
-
if ('disabled' == $profile['profile'])
|
69 |
-
unset($actions['lingotek-upload']);
|
|
|
70 |
}
|
71 |
}
|
72 |
return $actions;
|
@@ -90,95 +93,103 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
90 |
public function manage_actions() {
|
91 |
global $taxnow, $post_type;
|
92 |
|
93 |
-
if (
|
94 |
return;
|
|
|
95 |
|
96 |
// get the action
|
97 |
-
$wp_list_table = _get_list_table('WP_Terms_List_Table');
|
98 |
-
$action
|
99 |
|
100 |
-
if (empty($action))
|
101 |
return;
|
|
|
102 |
|
103 |
-
$redirect = remove_query_arg( array('action', 'action2', 'delete_tags'), wp_get_referer() );
|
104 |
-
if (
|
105 |
-
$redirect = admin_url("edit-tags.php?taxonomy=$taxnow&post_type=$post_type");
|
|
|
106 |
|
107 |
-
switch($action) {
|
108 |
case 'bulk-lingotek-upload':
|
109 |
-
if (empty($_REQUEST['delete_tags']))
|
110 |
return;
|
|
|
111 |
|
112 |
$term_ids = array();
|
113 |
|
114 |
-
foreach (array_map('intval', $_REQUEST['delete_tags']) as $term_id) {
|
115 |
// safe upload
|
116 |
-
if ($this->lgtm->can_upload('term', $term_id))
|
117 |
$term_ids[] = $term_id;
|
|
|
118 |
|
119 |
// the document is already translated so will be overwritten
|
120 |
-
elseif(($document = $this->lgtm->get_group('term', $term_id)) && empty($document->source)) {
|
121 |
// take care to upload only one post in a translation group
|
122 |
-
$intersect = array_intersect($term_ids, PLL()->model->term->get_translations($term_id));
|
123 |
-
if (empty($intersect)) {
|
124 |
$term_ids[] = $term_id;
|
125 |
-
$redirect
|
126 |
}
|
127 |
}
|
128 |
}
|
129 |
|
130 |
// check if translation is disabled
|
131 |
-
if (!empty($term_ids)) {
|
132 |
-
foreach ($term_ids as $key => $term_id) {
|
133 |
-
$language = PLL()->model->term->get_language($term_id);
|
134 |
-
$profile
|
135 |
-
if ('disabled' == $profile['profile'])
|
136 |
-
unset($term_ids[$key]);
|
|
|
137 |
}
|
138 |
}
|
139 |
case 'bulk-lingotek-request':
|
140 |
case 'bulk-lingotek-download':
|
141 |
case 'bulk-lingotek-status':
|
142 |
case 'bulk-lingotek-delete':
|
143 |
-
if (empty($_REQUEST['delete_tags']))
|
144 |
return;
|
|
|
145 |
|
146 |
-
if (empty($term_ids))
|
147 |
-
$term_ids = array_map('intval', $_REQUEST['delete_tags']);
|
|
|
148 |
|
149 |
-
check_admin_referer('bulk-tags');
|
150 |
|
151 |
-
$redirect = add_query_arg($action, 1, $redirect);
|
152 |
-
$redirect = add_query_arg('ids', implode(',', $term_ids), $redirect);
|
153 |
|
154 |
break;
|
155 |
|
156 |
case 'lingotek-upload':
|
157 |
-
check_admin_referer('lingotek-upload');
|
158 |
-
$id
|
159 |
-
$document = $this->lgtm->get_group('term', $id);
|
160 |
-
$this->lgtm->upload_post($id);
|
161 |
-
$redirect = add_query_arg( 'id', filter_input( INPUT_GET, 'term'), $redirect);
|
162 |
-
$redirect = add_query_arg( 'type', 'term', $redirect);
|
163 |
-
$redirect = add_query_arg( 'source', $this->pllm->term->get_language($id)->locale, $redirect);
|
164 |
break;
|
165 |
|
166 |
-
case 'lingotek-copy':
|
167 |
check_admin_referer( 'lingotek-copy' );
|
168 |
$term_to_copy = get_term( (int) filter_input( INPUT_GET, 'term' ) );
|
169 |
-
$target
|
170 |
-
$this->lgtm->copy_term( $term_to_copy, $target, $taxnow);
|
171 |
break;
|
172 |
|
173 |
default:
|
174 |
-
if (
|
175 |
-
|
176 |
-
|
177 |
-
|
|
|
178 |
|
179 |
-
wp_redirect($redirect);
|
180 |
exit();
|
181 |
-
|
182 |
}
|
183 |
|
184 |
/*
|
@@ -187,11 +198,12 @@ class Lingotek_Term_actions extends Lingotek_Actions {
|
|
187 |
* @since 0.1
|
188 |
*/
|
189 |
public function ajax_upload() {
|
190 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
191 |
-
$id
|
192 |
-
$taxonomy = filter_input( INPUT_POST, 'taxonomy');
|
193 |
-
if (taxonomy_exists($_POST['taxonomy']))
|
194 |
-
$this->lgtm->upload_term($id, $taxonomy);
|
|
|
195 |
die();
|
196 |
}
|
197 |
}
|
14 |
* @since 0.2
|
15 |
*/
|
16 |
public function __construct() {
|
17 |
+
parent::__construct( 'term' );
|
18 |
|
19 |
+
foreach ( $this->pllm->get_translated_taxonomies() as $taxonomy ) {
|
20 |
+
add_filter( $taxonomy . '_row_actions', array( &$this, 'term_row_actions' ), 10, 2 );
|
21 |
+
}
|
22 |
|
23 |
// add_action('admin_footer-edit-tags.php', array(&$this, 'add_bulk_actions')); // FIXME admin_print_footer_scripts instead?
|
24 |
+
add_action( 'load-edit-tags.php', array( &$this, 'manage_actions' ) );
|
25 |
}
|
26 |
|
27 |
/*
|
32 |
* @param int $term_id
|
33 |
* @return object
|
34 |
*/
|
35 |
+
protected function get_language( $term_id ) {
|
36 |
+
return PLL()->model->term->get_language( $term_id );
|
37 |
}
|
38 |
|
39 |
/*
|
43 |
*
|
44 |
* @param int $id
|
45 |
*/
|
46 |
+
public static function uploaded_icon( $id ) {
|
47 |
+
// 2nd case for quick edit
|
48 |
+
$post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
49 |
+
$taxonomy = isset( $GLOBALS['taxonomy'] ) ? $GLOBALS['taxonomy'] : $_REQUEST['taxonomy'];
|
50 |
+
$link = get_edit_term_link( $id, $taxonomy, $post_type );
|
51 |
+
return self::display_icon( 'uploaded', $link );
|
52 |
}
|
53 |
|
54 |
/*
|
60 |
* @param object $term
|
61 |
* @return array
|
62 |
*/
|
63 |
+
public function term_row_actions( $actions, $term ) {
|
64 |
+
if ( $this->pllm->is_translated_taxonomy( $term->taxonomy ) ) {
|
65 |
+
$actions = $this->_row_actions( $actions, $term->term_id );
|
66 |
+
|
67 |
+
$language = PLL()->model->term->get_language( $term->term_id );
|
68 |
+
if ( ! empty( $language ) ) {
|
69 |
+
$profile = Lingotek_Model::get_profile( $term->taxonomy, $language );
|
70 |
+
if ( 'disabled' == $profile['profile'] ) {
|
71 |
+
unset( $actions['lingotek-upload'] );
|
72 |
+
}
|
73 |
}
|
74 |
}
|
75 |
return $actions;
|
93 |
public function manage_actions() {
|
94 |
global $taxnow, $post_type;
|
95 |
|
96 |
+
if ( ! $this->pllm->is_translated_taxonomy( $taxnow ) ) {
|
97 |
return;
|
98 |
+
}
|
99 |
|
100 |
// get the action
|
101 |
+
$wp_list_table = _get_list_table( 'WP_Terms_List_Table' );
|
102 |
+
$action = $wp_list_table->current_action();
|
103 |
|
104 |
+
if ( empty( $action ) ) {
|
105 |
return;
|
106 |
+
}
|
107 |
|
108 |
+
$redirect = remove_query_arg( array( 'action', 'action2', 'delete_tags' ), wp_get_referer() );
|
109 |
+
if ( ! $redirect ) {
|
110 |
+
$redirect = admin_url( "edit-tags.php?taxonomy=$taxnow&post_type=$post_type" );
|
111 |
+
}
|
112 |
|
113 |
+
switch ( $action ) {
|
114 |
case 'bulk-lingotek-upload':
|
115 |
+
if ( empty( $_REQUEST['delete_tags'] ) ) {
|
116 |
return;
|
117 |
+
}
|
118 |
|
119 |
$term_ids = array();
|
120 |
|
121 |
+
foreach ( array_map( 'intval', $_REQUEST['delete_tags'] ) as $term_id ) {
|
122 |
// safe upload
|
123 |
+
if ( $this->lgtm->can_upload( 'term', $term_id ) ) {
|
124 |
$term_ids[] = $term_id;
|
125 |
+
}
|
126 |
|
127 |
// the document is already translated so will be overwritten
|
128 |
+
elseif ( ( $document = $this->lgtm->get_group( 'term', $term_id ) ) && empty( $document->source ) ) {
|
129 |
// take care to upload only one post in a translation group
|
130 |
+
$intersect = array_intersect( $term_ids, PLL()->model->term->get_translations( $term_id ) );
|
131 |
+
if ( empty( $intersect ) ) {
|
132 |
$term_ids[] = $term_id;
|
133 |
+
$redirect = add_query_arg( 'lingotek_warning', 1, $redirect );
|
134 |
}
|
135 |
}
|
136 |
}
|
137 |
|
138 |
// check if translation is disabled
|
139 |
+
if ( ! empty( $term_ids ) ) {
|
140 |
+
foreach ( $term_ids as $key => $term_id ) {
|
141 |
+
$language = PLL()->model->term->get_language( $term_id );
|
142 |
+
$profile = Lingotek_Model::get_profile( $taxnow, $language );
|
143 |
+
if ( 'disabled' == $profile['profile'] ) {
|
144 |
+
unset( $term_ids[ $key ] );
|
145 |
+
}
|
146 |
}
|
147 |
}
|
148 |
case 'bulk-lingotek-request':
|
149 |
case 'bulk-lingotek-download':
|
150 |
case 'bulk-lingotek-status':
|
151 |
case 'bulk-lingotek-delete':
|
152 |
+
if ( empty( $_REQUEST['delete_tags'] ) ) {
|
153 |
return;
|
154 |
+
}
|
155 |
|
156 |
+
if ( empty( $term_ids ) ) {
|
157 |
+
$term_ids = array_map( 'intval', $_REQUEST['delete_tags'] );
|
158 |
+
}
|
159 |
|
160 |
+
check_admin_referer( 'bulk-tags' );
|
161 |
|
162 |
+
$redirect = add_query_arg( $action, 1, $redirect );
|
163 |
+
$redirect = add_query_arg( 'ids', implode( ',', $term_ids ), $redirect );
|
164 |
|
165 |
break;
|
166 |
|
167 |
case 'lingotek-upload':
|
168 |
+
check_admin_referer( 'lingotek-upload' );
|
169 |
+
$id = filter_input( INPUT_GET, 'term' );
|
170 |
+
$document = $this->lgtm->get_group( 'term', $id );
|
171 |
+
$this->lgtm->upload_post( $id );
|
172 |
+
$redirect = add_query_arg( 'id', filter_input( INPUT_GET, 'term' ), $redirect );
|
173 |
+
$redirect = add_query_arg( 'type', 'term', $redirect );
|
174 |
+
$redirect = add_query_arg( 'source', $this->pllm->term->get_language( $id )->locale, $redirect );
|
175 |
break;
|
176 |
|
177 |
+
case 'lingotek-copy':
|
178 |
check_admin_referer( 'lingotek-copy' );
|
179 |
$term_to_copy = get_term( (int) filter_input( INPUT_GET, 'term' ) );
|
180 |
+
$target = filter_input( INPUT_GET, 'target' );
|
181 |
+
$this->lgtm->copy_term( $term_to_copy, $target, $taxnow );
|
182 |
break;
|
183 |
|
184 |
default:
|
185 |
+
if ( ! $this->_manage_actions( $action ) ) {
|
186 |
+
// do not redirect if this is not one of our actions.
|
187 |
+
return;
|
188 |
+
}
|
189 |
+
}//end switch
|
190 |
|
191 |
+
wp_redirect( $redirect );
|
192 |
exit();
|
|
|
193 |
}
|
194 |
|
195 |
/*
|
198 |
* @since 0.1
|
199 |
*/
|
200 |
public function ajax_upload() {
|
201 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
202 |
+
$id = (int) filter_input( INPUT_POST, 'id' );
|
203 |
+
$taxonomy = filter_input( INPUT_POST, 'taxonomy' );
|
204 |
+
if ( taxonomy_exists( $_POST['taxonomy'] ) ) {
|
205 |
+
$this->lgtm->upload_term( $id, $taxonomy );
|
206 |
+
}
|
207 |
die();
|
208 |
}
|
209 |
}
|
admin/tutorial/content.php
CHANGED
@@ -19,132 +19,147 @@
|
|
19 |
}
|
20 |
</style>
|
21 |
<h4>
|
22 |
-
<?php _e('What Does The Lingotek Translation Plugin Do?', 'lingotek-translation') ?>
|
23 |
<a id="cd-show-link-summary" class="dashicons dashicons-arrow-right" onclick="document.getElementById('ltk-summary').style.display = ''; document.getElementById('cd-hide-link-summary').style.display = ''; this.style.display = 'none'; return false;"></a>
|
24 |
<a id="cd-hide-link-summary" class="dashicons dashicons-arrow-down" onclick="document.getElementById('ltk-summary').style.display = 'none'; document.getElementById('cd-show-link-summary').style.display = ''; this.style.display = 'none'; return false;" style="display: none;"></a>
|
25 |
</h4>
|
26 |
-
<p id="ltk-summary" style="display:none; margin-left: 25px;"><?php _e('Lingotek works in conjunction with the Polylang plugin (the plumbing to make WordPress multilingual ready) simplifying the process of creating and maintaining your multilingual website. You write posts, pages, and create categories and post tags as usual, and then define the language for each of them.', 'lingotek-translation') ?></p>
|
27 |
|
28 |
<h4>
|
29 |
-
<?php _e('Lingotek Translation General Overview', 'lingotek-translation') ?>
|
30 |
<a id="cd-show-link-gen" class="dashicons dashicons-arrow-right" onclick="document.getElementById('gen-overview-tut').style.display = ''; document.getElementById('cd-hide-link-gen').style.display = ''; this.style.display = 'none'; return false;"></a>
|
31 |
<a id="cd-hide-link-gen" class="dashicons dashicons-arrow-down" onclick="document.getElementById('gen-overview-tut').style.display = 'none'; document.getElementById('cd-show-link-gen').style.display = ''; this.style.display = 'none'; return false;" style="display: none;"></a>
|
32 |
</h4>
|
33 |
<div id="gen-overview-tut" style="display:none;margin-left: 25px;">
|
34 |
<div>
|
35 |
-
<h4><?php _e('1. Create content', 'lingotek-translation') ?></h4>
|
36 |
-
<p><?php _e('Whether you write a blog post, create a page for your site, or have existing posts and pages, any of your
|
37 |
-
<?php _e('The examples shown below are for Pages but translation for other content types works the same way!', 'lingotek-translation') ?></p>
|
38 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/add-page.png'; ?>">
|
39 |
-
<p class="img-caption"><?php _e('Create a new page for translation.', 'lingotek-translation') ?></p>
|
40 |
</div>
|
41 |
<div>
|
42 |
-
<h4><?php _e('2. Upload content to Lingotek', 'lingotek-translation') ?></h4>
|
43 |
-
<p><?php _e('Your
|
44 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/ready-to-upload.png'; ?>">
|
45 |
-
<p class="img-caption"><?php _e('Content has been created and is ready for upload to Lingotek.', 'lingotek-translation') ?></p>
|
46 |
</div>
|
47 |
<div>
|
48 |
-
<h4><?php _e('3. Request translations for target languages', 'lingotek-translation') ?></h4>
|
49 |
-
<p><?php _e('Request translation for a specific language by clicking on the orange plus icon, for all languages at once, or in bulk by using the <i>Bulk Actions</i> dropdown.', 'lingotek-translation') ?></p>
|
50 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/request-translations.png'; ?>">
|
51 |
-
<p class="img-caption"><?php _e('The source content is uploaded and ready for target languages.', 'lingotek-translation') ?></p>
|
52 |
</div>
|
53 |
<div>
|
54 |
-
<h4><?php _e('4. Translate your content', 'lingotek-translation') ?></h4>
|
55 |
-
<p><?php _e('Your content will now be translated into your selected target languages by free machine translation or, if you contract with <i>Lingotek</i>, professional translation services.', 'lingotek-translation') ?></p>
|
56 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-underway.png'; ?>">
|
57 |
-
<p class="img-caption"><?php _e('Your translations are underway.', 'lingotek-translation') ?></p>
|
58 |
</div>
|
59 |
<div>
|
60 |
-
<h4><?php _e('5. Download translations', 'lingotek-translation') ?></h4>
|
61 |
-
<p><?php _e('Once your translations are complete they will be marked ready for download. You can download translations for all languages, each language individually, or in bulk (using the <i>Bulk Actions</i> dropdown).', 'lingotek-translation') ?></p>
|
62 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-ready-for-download.png'; ?>">
|
63 |
-
<p class="img-caption"><?php _e('Your translations are ready for download.', 'lingotek-translation') ?></p>
|
64 |
</div>
|
65 |
<div>
|
66 |
-
<h4><?php _e('6. Your content is translated!', 'lingotek-translation') ?></h4>
|
67 |
-
<p><?php _e('The orange pencil icons indicate that your translations are finished, downloaded, and current within your
|
68 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-downloaded.png'; ?>">
|
69 |
-
<p class="img-caption"><?php _e('Your content has been translated.', 'lingotek-translation') ?></p>
|
70 |
</div>
|
71 |
|
72 |
-
<h2><?php _e('What do all the icons mean?', 'lingotek-translation') ?></h2>
|
73 |
|
74 |
<table>
|
75 |
<tr>
|
76 |
<td><span class="lingotek-color dashicons dashicons-upload"></span></td>
|
77 |
-
<th><?php _e('Upload Source', 'lingotek-translation') ?></th>
|
78 |
-
<td><?php _e('There is content ready to be uploaded to Lingotek.', 'lingotek-translation') ?></td>
|
79 |
</tr>
|
80 |
<tr>
|
81 |
<td><span class="lingotek-color dashicons dashicons-clock"></span></td>
|
82 |
-
<th><?php _e('In Progress', 'lingotek-translation') ?></th>
|
83 |
-
<td><?php _e('Content is importing to Lingotek or a target language is being added to source content.', 'lingotek-translation') ?></td>
|
84 |
</tr>
|
85 |
<tr>
|
86 |
<td><span class="lingotek-color dashicons dashicons-yes"></span></td>
|
87 |
-
<th><?php _e('Source Uploaded', 'lingotek-translation') ?></th>
|
88 |
-
<td><?php _e('The source content has been uploaded to Lingotek.', 'lingotek-translation') ?></td>
|
89 |
</tr>
|
90 |
<tr>
|
91 |
<td><span class="lingotek-color dashicons dashicons-plus"></span></td>
|
92 |
-
<th><?php _e('Request Translation', 'lingotek-translation') ?></th>
|
93 |
-
<td><?php _e('Request a translation of the source content. (Add a target language)', 'lingotek-translation') ?></td>
|
94 |
</tr>
|
95 |
<tr>
|
96 |
<td><span class="lingotek-color dashicons dashicons-download"></span></td>
|
97 |
-
<th><?php _e('Download Translation', 'lingotek-translation') ?></th>
|
98 |
-
<td><?php _e('Download the translated content to
|
99 |
</tr>
|
100 |
<tr>
|
101 |
<td><span class="lingotek-color dashicons dashicons-edit"></span></td>
|
102 |
-
<th><?php _e('Translation Current', 'lingotek-translation') ?></th>
|
103 |
-
<td><?php _e('The translation is complete. (Clicking on this icon will allow you to edit translations in the Lingotek Workbench)', 'lingotek-translation') ?></td>
|
104 |
</tr>
|
105 |
<tr>
|
106 |
<td><span class="lingotek-color dashicons dashicons-warning"></span></td>
|
107 |
-
<th><?php _e('Translation Cancelled', 'lingotek-translation') ?></th>
|
108 |
-
<td><?php _e('The translation is cancelled. The source cannot be translated into this language again.', 'lingotek-translation') ?></td>
|
109 |
</tr>
|
110 |
-
|
111 |
<td><span class="lingotek-color dashicons dashicons-no"></span></td>
|
112 |
-
<th><?php _e('Out of Sync', 'lingotek-translation') ?></th>
|
113 |
-
<td><?php _e('You have made changes to source content. The source must be sent to Lingotek again for additional translation.', 'lingotek-translation') ?></td>
|
114 |
</tr>
|
115 |
</table>
|
116 |
</div>
|
117 |
<h4 id="ltk-prof-trans-header">
|
118 |
-
<?php _e('Lingotek Professional Translation Overview', 'lingotek-translation') ?>
|
119 |
-
<a id="cd-show-link" class="dashicons dashicons-arrow-right" onclick="document.getElementById('pro-translation-tut').style.display = ''; document.getElementById('cd-hide-link').style.display = ''; this.style.display = 'none'; return false;" style="
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
</h4>
|
122 |
-
<div id="pro-translation-tut" style="
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
127 |
<ul>
|
128 |
-
<li><strong><?php _e('Translation > Manage > Translation Profiles', 'lingotek-translation') ?></strong></li>
|
129 |
-
<li><strong><?php _e('Translation > Settings > Defaults', 'lingotek-translation') ?></strong></li>
|
130 |
</ul>
|
131 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/combined-selection.png'; ?>">
|
132 |
-
<p><?php _e('After selecting this workflow a dialog box will pop up prompting you to enter a payment method. Clicking LATER will close the dialog box and allow you to come back later to add a payment method.', 'lingotek-translation') ?></p>
|
133 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/selection-workflow-from-list.png'; ?>">
|
134 |
-
<p><?php _e('Clicking the ADD PAYMENT METHOD button will redirect you to the Lingotek Secure Payment Portal.', 'lingotek-translation') ?></p>
|
135 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/redirected-to-payment-portal-screen.png'; ?>">
|
136 |
-
<p><?php _e('From the Payment Portal you will enter your payment information. Then you will be redirected back to your WordPress site.', 'lingotek-translation') ?></p>
|
137 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/redirected-to-payment-portal.png'; ?>">
|
138 |
-
<p><?php _e('After the workflow has been set you can access the professional translation request menu by clicking on the orange plus icon located on any page that contains your posts.', 'lingotek-translation') ?></p>
|
139 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/request-translations.png'; ?>">
|
140 |
-
<p><?php _e('When requesting a document for translation with the Lingotek Professional Translation workflow enabled you will see one of two dialog boxes. If you don\'t have a payment method set up you will see the following dialog box allowing you to view translation quotes on your selected documents.'
|
141 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/quote-calculator.png'; ?>">
|
142 |
-
<p><?php _e('If you do have a payment method enabled you will see the following dialog box that will allow you to purchase your professional translations.', 'lingotek-translation') ?></p>
|
143 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/higher-res-buy-now.png'; ?>">
|
144 |
-
<p><?php _e('After purchasing one or more professional translations you will see a success message and will receive a payment confirmation email.', 'lingotek-translation') ?></p>
|
145 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/purchased.png'; ?>">
|
146 |
-
<p><?php _e('The status of your translation will change to the Translator icon while your document is being processed and translated.', 'lingotek-translation') ?></p>
|
147 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation-icon.png'; ?>">
|
148 |
-
<p><?php _e('You can set up or edit your payment method from the Translation > Settings > Account page.', 'lingotek-translation') ?></p>
|
149 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/change-account-settings.png'; ?>">
|
150 |
</div>
|
19 |
}
|
20 |
</style>
|
21 |
<h4>
|
22 |
+
<?php _e( 'What Does The Lingotek Translation Plugin Do?', 'lingotek-translation' ); ?>
|
23 |
<a id="cd-show-link-summary" class="dashicons dashicons-arrow-right" onclick="document.getElementById('ltk-summary').style.display = ''; document.getElementById('cd-hide-link-summary').style.display = ''; this.style.display = 'none'; return false;"></a>
|
24 |
<a id="cd-hide-link-summary" class="dashicons dashicons-arrow-down" onclick="document.getElementById('ltk-summary').style.display = 'none'; document.getElementById('cd-show-link-summary').style.display = ''; this.style.display = 'none'; return false;" style="display: none;"></a>
|
25 |
</h4>
|
26 |
+
<p id="ltk-summary" style="display:none; margin-left: 25px;"><?php _e( 'Lingotek works in conjunction with the Polylang plugin (the plumbing to make WordPress multilingual ready) simplifying the process of creating and maintaining your multilingual website. You write posts, pages, and create categories and post tags as usual, and then define the language for each of them.', 'lingotek-translation' ); ?></p>
|
27 |
|
28 |
<h4>
|
29 |
+
<?php _e( 'Lingotek Translation General Overview', 'lingotek-translation' ); ?>
|
30 |
<a id="cd-show-link-gen" class="dashicons dashicons-arrow-right" onclick="document.getElementById('gen-overview-tut').style.display = ''; document.getElementById('cd-hide-link-gen').style.display = ''; this.style.display = 'none'; return false;"></a>
|
31 |
<a id="cd-hide-link-gen" class="dashicons dashicons-arrow-down" onclick="document.getElementById('gen-overview-tut').style.display = 'none'; document.getElementById('cd-show-link-gen').style.display = ''; this.style.display = 'none'; return false;" style="display: none;"></a>
|
32 |
</h4>
|
33 |
<div id="gen-overview-tut" style="display:none;margin-left: 25px;">
|
34 |
<div>
|
35 |
+
<h4><?php _e( '1. Create content', 'lingotek-translation' ); ?></h4>
|
36 |
+
<p><?php _e( 'Whether you write a blog post, create a page for your site, or have existing posts and pages, any of your WordPress content can be uploaded to <i>Lingotek</i>.', 'lingotek-translation' ); ?>
|
37 |
+
<?php _e( 'The examples shown below are for Pages but translation for other content types works the same way!', 'lingotek-translation' ); ?></p>
|
38 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/add-page.png'; ?>">
|
39 |
+
<p class="img-caption"><?php _e( 'Create a new page for translation.', 'lingotek-translation' ); ?></p>
|
40 |
</div>
|
41 |
<div>
|
42 |
+
<h4><?php _e( '2. Upload content to Lingotek', 'lingotek-translation' ); ?></h4>
|
43 |
+
<p><?php _e( 'Your WordPress content can be uploaded to <i>Lingotek</i> with the simple push of a button.', 'lingotek-translation' ); ?></p>
|
44 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/ready-to-upload.png'; ?>">
|
45 |
+
<p class="img-caption"><?php _e( 'Content has been created and is ready for upload to Lingotek.', 'lingotek-translation' ); ?></p>
|
46 |
</div>
|
47 |
<div>
|
48 |
+
<h4><?php _e( '3. Request translations for target languages', 'lingotek-translation' ); ?></h4>
|
49 |
+
<p><?php _e( 'Request translation for a specific language by clicking on the orange plus icon, for all languages at once, or in bulk by using the <i>Bulk Actions</i> dropdown.', 'lingotek-translation' ); ?></p>
|
50 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/request-translations.png'; ?>">
|
51 |
+
<p class="img-caption"><?php _e( 'The source content is uploaded and ready for target languages.', 'lingotek-translation' ); ?></p>
|
52 |
</div>
|
53 |
<div>
|
54 |
+
<h4><?php _e( '4. Translate your content', 'lingotek-translation' ); ?></h4>
|
55 |
+
<p><?php _e( 'Your content will now be translated into your selected target languages by free machine translation or, if you contract with <i>Lingotek</i>, professional translation services.', 'lingotek-translation' ); ?></p>
|
56 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-underway.png'; ?>">
|
57 |
+
<p class="img-caption"><?php _e( 'Your translations are underway.', 'lingotek-translation' ); ?></p>
|
58 |
</div>
|
59 |
<div>
|
60 |
+
<h4><?php _e( '5. Download translations', 'lingotek-translation' ); ?></h4>
|
61 |
+
<p><?php _e( 'Once your translations are complete they will be marked ready for download. You can download translations for all languages, each language individually, or in bulk (using the <i>Bulk Actions</i> dropdown).', 'lingotek-translation' ); ?></p>
|
62 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-ready-for-download.png'; ?>">
|
63 |
+
<p class="img-caption"><?php _e( 'Your translations are ready for download.', 'lingotek-translation' ); ?></p>
|
64 |
</div>
|
65 |
<div>
|
66 |
+
<h4><?php _e( '6. Your content is translated!', 'lingotek-translation' ); ?></h4>
|
67 |
+
<p><?php _e( 'The orange pencil icons indicate that your translations are finished, downloaded, and current within your WordPress site. Clicking on any one of the pencils will direct you to the Lingotek Workbench for that specific language. Here you can make updates and changes to your translations if necessary.', 'lingotek-translation' ); ?></p>
|
68 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translations-downloaded.png'; ?>">
|
69 |
+
<p class="img-caption"><?php _e( 'Your content has been translated.', 'lingotek-translation' ); ?></p>
|
70 |
</div>
|
71 |
|
72 |
+
<h2><?php _e( 'What do all the icons mean?', 'lingotek-translation' ); ?></h2>
|
73 |
|
74 |
<table>
|
75 |
<tr>
|
76 |
<td><span class="lingotek-color dashicons dashicons-upload"></span></td>
|
77 |
+
<th><?php _e( 'Upload Source', 'lingotek-translation' ); ?></th>
|
78 |
+
<td><?php _e( 'There is content ready to be uploaded to Lingotek.', 'lingotek-translation' ); ?></td>
|
79 |
</tr>
|
80 |
<tr>
|
81 |
<td><span class="lingotek-color dashicons dashicons-clock"></span></td>
|
82 |
+
<th><?php _e( 'In Progress', 'lingotek-translation' ); ?></th>
|
83 |
+
<td><?php _e( 'Content is importing to Lingotek or a target language is being added to source content.', 'lingotek-translation' ); ?></td>
|
84 |
</tr>
|
85 |
<tr>
|
86 |
<td><span class="lingotek-color dashicons dashicons-yes"></span></td>
|
87 |
+
<th><?php _e( 'Source Uploaded', 'lingotek-translation' ); ?></th>
|
88 |
+
<td><?php _e( 'The source content has been uploaded to Lingotek.', 'lingotek-translation' ); ?></td>
|
89 |
</tr>
|
90 |
<tr>
|
91 |
<td><span class="lingotek-color dashicons dashicons-plus"></span></td>
|
92 |
+
<th><?php _e( 'Request Translation', 'lingotek-translation' ); ?></th>
|
93 |
+
<td><?php _e( 'Request a translation of the source content. (Add a target language)', 'lingotek-translation' ); ?></td>
|
94 |
</tr>
|
95 |
<tr>
|
96 |
<td><span class="lingotek-color dashicons dashicons-download"></span></td>
|
97 |
+
<th><?php _e( 'Download Translation', 'lingotek-translation' ); ?></th>
|
98 |
+
<td><?php _e( 'Download the translated content to WordPress.', 'lingotek-translation' ); ?></td>
|
99 |
</tr>
|
100 |
<tr>
|
101 |
<td><span class="lingotek-color dashicons dashicons-edit"></span></td>
|
102 |
+
<th><?php _e( 'Translation Current', 'lingotek-translation' ); ?></th>
|
103 |
+
<td><?php _e( 'The translation is complete. (Clicking on this icon will allow you to edit translations in the Lingotek Workbench)', 'lingotek-translation' ); ?></td>
|
104 |
</tr>
|
105 |
<tr>
|
106 |
<td><span class="lingotek-color dashicons dashicons-warning"></span></td>
|
107 |
+
<th><?php _e( 'Translation Cancelled', 'lingotek-translation' ); ?></th>
|
108 |
+
<td><?php _e( 'The translation is cancelled. The source cannot be translated into this language again.', 'lingotek-translation' ); ?></td>
|
109 |
</tr>
|
110 |
+
<tr>
|
111 |
<td><span class="lingotek-color dashicons dashicons-no"></span></td>
|
112 |
+
<th><?php _e( 'Out of Sync', 'lingotek-translation' ); ?></th>
|
113 |
+
<td><?php _e( 'You have made changes to source content. The source must be sent to Lingotek again for additional translation.', 'lingotek-translation' ); ?></td>
|
114 |
</tr>
|
115 |
</table>
|
116 |
</div>
|
117 |
<h4 id="ltk-prof-trans-header">
|
118 |
+
<?php _e( 'Lingotek Professional Translation Overview', 'lingotek-translation' ); ?>
|
119 |
+
<a id="cd-show-link" class="dashicons dashicons-arrow-right" onclick="document.getElementById('pro-translation-tut').style.display = ''; document.getElementById('cd-hide-link').style.display = ''; this.style.display = 'none'; return false;" style="
|
120 |
+
<?php
|
121 |
+
if ( 'ltk-prof' === filter_input( INPUT_GET, 'tutorial' ) ) {
|
122 |
+
echo 'display: none;'; }
|
123 |
+
?>
|
124 |
+
"></a>
|
125 |
+
<a id="cd-hide-link" class="dashicons dashicons-arrow-down" onclick="document.getElementById('pro-translation-tut').style.display = 'none'; document.getElementById('cd-show-link').style.display = ''; this.style.display = 'none'; return false;" style="
|
126 |
+
<?php
|
127 |
+
if ( 'ltk-prof' !== filter_input( INPUT_GET, 'tutorial' ) ) {
|
128 |
+
echo 'display: none;'; }
|
129 |
+
?>
|
130 |
+
"></a>
|
131 |
</h4>
|
132 |
+
<div id="pro-translation-tut" style="
|
133 |
+
<?php
|
134 |
+
if ( 'ltk-prof' != filter_input( INPUT_GET, 'tutorial' ) ) {
|
135 |
+
echo 'display: none;'; }
|
136 |
+
?>
|
137 |
+
margin-left: 25px;">
|
138 |
+
<h4><?php _e( 'What Is Lingotek Professional Translation?', 'lingotek-translation' ); ?></h4>
|
139 |
+
<p><?php _e( 'Lingotek Professional Translation is a workflow that allows you to connect with audiences around the globe using Lingotek\'s network of 5000+ professional, in-country, translators. Professional Translation ensures that your audiences will feel the sentiment of your content.', 'lingotek-translation' ); ?></p>
|
140 |
+
<h4><?php _e( 'How To Use', 'lingotek-translation' ); ?></h4>
|
141 |
+
<p><?php _e( 'Use the "Lingotek Professional Translation" workflow to enable this feature. This can be done from any of the following area in the Lingotek plugin settings:', 'lingotek-translation' ); ?></p>
|
142 |
<ul>
|
143 |
+
<li><strong><?php _e( 'Translation > Manage > Translation Profiles', 'lingotek-translation' ); ?></strong></li>
|
144 |
+
<li><strong><?php _e( 'Translation > Settings > Defaults', 'lingotek-translation' ); ?></strong></li>
|
145 |
</ul>
|
146 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/combined-selection.png'; ?>">
|
147 |
+
<p><?php _e( 'After selecting this workflow a dialog box will pop up prompting you to enter a payment method. Clicking LATER will close the dialog box and allow you to come back later to add a payment method.', 'lingotek-translation' ); ?></p>
|
148 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/selection-workflow-from-list.png'; ?>">
|
149 |
+
<p><?php _e( 'Clicking the ADD PAYMENT METHOD button will redirect you to the Lingotek Secure Payment Portal.', 'lingotek-translation' ); ?></p>
|
150 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/redirected-to-payment-portal-screen.png'; ?>">
|
151 |
+
<p><?php _e( 'From the Payment Portal you will enter your payment information. Then you will be redirected back to your WordPress site.', 'lingotek-translation' ); ?></p>
|
152 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/redirected-to-payment-portal.png'; ?>">
|
153 |
+
<p><?php _e( 'After the workflow has been set you can access the professional translation request menu by clicking on the orange plus icon located on any page that contains your posts.', 'lingotek-translation' ); ?></p>
|
154 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/request-translations.png'; ?>">
|
155 |
+
<p><?php _e( 'When requesting a document for translation with the Lingotek Professional Translation workflow enabled you will see one of two dialog boxes. If you don\'t have a payment method set up you will see the following dialog box allowing you to view translation quotes on your selected documents.', 'lingotek-translation' ); ?></p>
|
156 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/quote-calculator.png'; ?>">
|
157 |
+
<p><?php _e( 'If you do have a payment method enabled you will see the following dialog box that will allow you to purchase your professional translations.', 'lingotek-translation' ); ?></p>
|
158 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/higher-res-buy-now.png'; ?>">
|
159 |
+
<p><?php _e( 'After purchasing one or more professional translations you will see a success message and will receive a payment confirmation email.', 'lingotek-translation' ); ?></p>
|
160 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/purchased.png'; ?>">
|
161 |
+
<p><?php _e( 'The status of your translation will change to the Translator icon while your document is being processed and translated.', 'lingotek-translation' ); ?></p>
|
162 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation-icon.png'; ?>">
|
163 |
+
<p><?php _e( 'You can set up or edit your payment method from the Translation > Settings > Account page.', 'lingotek-translation' ); ?></p>
|
164 |
<img class="lingotek-bordered" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/change-account-settings.png'; ?>">
|
165 |
</div>
|
admin/tutorial/credits.php
CHANGED
@@ -1,123 +1,166 @@
|
|
1 |
<?php
|
2 |
|
3 |
$team = array(
|
4 |
-
'fred'=>array(
|
5 |
-
'name'=>'Frédéric Demarle',
|
6 |
-
'title'=>'Lead Polylang Developer',
|
7 |
-
'image_url'=>'https://www.gravatar.com/avatar/132157ff7a533c8e9a272795a1b5c2b9',
|
8 |
-
'url'=>'https://profiles.wordpress.org/chouby'
|
9 |
-
|
10 |
-
|
11 |
-
'
|
12 |
-
'
|
13 |
-
'
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
'
|
18 |
-
'
|
19 |
-
|
20 |
-
'
|
21 |
-
|
22 |
-
|
23 |
-
'
|
|
|
|
|
|
|
|
|
24 |
);
|
25 |
|
26 |
$team_contributors = array(
|
27 |
-
'calvin'=>array(
|
28 |
-
'name'=>'Calvin Scharffs',
|
29 |
-
'title'=>'Marketing Guru',
|
30 |
-
'image_url'=>'https://www.gravatar.com/avatar/d18e8bf783f63bf893e143cf04e0034d',
|
31 |
-
'url'=>'https://profiles.wordpress.org/cscharffs'
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
'
|
41 |
-
'
|
42 |
-
|
43 |
-
'
|
44 |
-
|
45 |
-
|
46 |
-
'
|
47 |
-
|
48 |
-
'
|
49 |
-
'
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
'
|
54 |
-
'
|
55 |
-
'
|
56 |
-
|
57 |
-
'
|
58 |
-
'name'=>'
|
59 |
-
'title'=>'Support',
|
60 |
-
'image_url'=>'https://www.gravatar.com/avatar/
|
61 |
-
'url'=>'https://profiles.wordpress.org/
|
62 |
-
|
63 |
-
|
64 |
-
'
|
65 |
-
'
|
66 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
);
|
68 |
|
69 |
$contributors = array(
|
70 |
-
'larry'=>array(
|
71 |
-
'name'=>'Larry Furr',
|
72 |
-
'title'=>'',
|
73 |
-
'image_url'=>'https://www.gravatar.com/avatar/77447d8ad56b4ba5ea8f3900b3245c41',
|
74 |
-
'url'=>'https://profiles.wordpress.org/furrever'
|
|
|
75 |
);
|
76 |
|
77 |
-
shuffle($team);
|
78 |
-
shuffle($team_contributors);
|
79 |
-
shuffle($contributors);
|
80 |
|
81 |
?>
|
82 |
|
83 |
-
<p class="about-description"><?php _e('The Lingotek plugin for WordPress is created with love.', 'lingotek-translation'); ?></p>
|
84 |
|
85 |
-
<h4 class="wp-people-group"><?php _e('Project Leaders', 'lingotek-translation'); ?></h4>
|
86 |
|
87 |
<ul class="wp-people-group">
|
88 |
<?php
|
89 |
|
90 |
-
foreach($team as $person_key
|
91 |
-
printf(
|
|
|
92 |
<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>
|
93 |
<a class="web" href="%s" target="_blank">%s</a>
|
94 |
<span class="title">%s</span>
|
95 |
-
</li>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
?>
|
99 |
</ul>
|
100 |
|
101 |
-
<h4 class="wp-people-group"><?php _e('Contributors', 'lingotek-translation'); ?></h4>
|
102 |
|
103 |
<ul class="wp-people-group">
|
104 |
<?php
|
105 |
|
106 |
-
foreach($team_contributors as $person_key
|
107 |
-
printf(
|
|
|
108 |
<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>
|
109 |
<a class="web" href="%s" target="_blank">%s</a>
|
110 |
<span class="title">%s</span>
|
111 |
-
</li>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
}
|
113 |
|
114 |
-
foreach($contributors as $person_key
|
115 |
-
printf(
|
|
|
116 |
<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>
|
117 |
<a class="web" href="%s" target="_blank">%s</a>
|
118 |
<span class="title">%s</span>
|
119 |
-
</li>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
?>
|
123 |
-
</ul>
|
1 |
<?php
|
2 |
|
3 |
$team = array(
|
4 |
+
'fred' => array(
|
5 |
+
'name' => 'Frédéric Demarle',
|
6 |
+
'title' => 'Lead Polylang Developer',
|
7 |
+
'image_url' => 'https://www.gravatar.com/avatar/132157ff7a533c8e9a272795a1b5c2b9',
|
8 |
+
'url' => 'https://profiles.wordpress.org/chouby',
|
9 |
+
),
|
10 |
+
'matt' => array(
|
11 |
+
'name' => 'Matt Smith',
|
12 |
+
'title' => 'Lead Developer',
|
13 |
+
'image_url' => 'https://www.gravatar.com/avatar/d79b46c94a52b4679c308986ef05eac2',
|
14 |
+
'url' => 'https://profiles.wordpress.org/smithworx',
|
15 |
+
),
|
16 |
+
'edward' => array(
|
17 |
+
'name' => 'Edward Richards',
|
18 |
+
'title' => 'Lead Developer',
|
19 |
+
'image_url' => 'https://www.gravatar.com/avatar/a0ab415173b16d2ac476077d587bea96',
|
20 |
+
'url' => 'https://profiles.wordpress.org/erichie',
|
21 |
+
),
|
22 |
+
'robert' => array(
|
23 |
+
'name' => 'Robert Hanna',
|
24 |
+
'title' => 'Software Engineer',
|
25 |
+
'image_url' => 'https://www.gravatar.com/avatar/0583e77b41cefd00203ec0737cd38891',
|
26 |
+
'url' => 'https://profiles.wordpress.org/robertdhanna/',
|
27 |
+
),
|
28 |
);
|
29 |
|
30 |
$team_contributors = array(
|
31 |
+
'calvin' => array(
|
32 |
+
'name' => 'Calvin Scharffs',
|
33 |
+
'title' => 'Marketing Guru',
|
34 |
+
'image_url' => 'https://www.gravatar.com/avatar/d18e8bf783f63bf893e143cf04e0034d',
|
35 |
+
'url' => 'https://profiles.wordpress.org/cscharffs',
|
36 |
+
),
|
37 |
+
'joey' => array(
|
38 |
+
'name' => 'Joseph Hovik',
|
39 |
+
'title' => 'Developer',
|
40 |
+
'image_url' => 'https://www.gravatar.com/avatar/171f66a729d063bb6ee4e0e51135a120',
|
41 |
+
'url' => 'https://profiles.wordpress.org/jbhovik',
|
42 |
+
),
|
43 |
+
'seth' => array(
|
44 |
+
'name' => 'Seth White',
|
45 |
+
'title' => 'Developer',
|
46 |
+
'image_url' => 'https://www.gravatar.com/avatar/53706ce5472909827db3e582bb4bccf2',
|
47 |
+
'url' => 'https://profiles.wordpress.org/sethwhite',
|
48 |
+
),
|
49 |
+
'brian' => array(
|
50 |
+
'name' => 'Brian Isle',
|
51 |
+
'title' => 'Quality Assurance',
|
52 |
+
'image_url' => 'https://www.gravatar.com/avatar/5f43658c382412d8f120cb5595d9bf03',
|
53 |
+
'url' => 'https://profiles.wordpress.org/bisle',
|
54 |
+
),
|
55 |
+
'brad' => array(
|
56 |
+
'name' => 'Brad Ross',
|
57 |
+
'title' => 'Product Management',
|
58 |
+
'image_url' => 'https://www.gravatar.com/avatar/477601d2c0c8c8dd31c021e3bae3841c',
|
59 |
+
'url' => 'https://profiles.wordpress.org/bradross12/',
|
60 |
+
),
|
61 |
+
'clark' => array(
|
62 |
+
'name' => 'Clark Fuller',
|
63 |
+
'title' => 'Support',
|
64 |
+
'image_url' => 'https://www.gravatar.com/avatar/622c9cece3cd4ff8245e93892e1ea1cc',
|
65 |
+
'url' => 'https://profiles.wordpress.org/clarticus',
|
66 |
+
),
|
67 |
+
'nathan' => array(
|
68 |
+
'name' => 'Nathan Overlin',
|
69 |
+
'title' => 'Support',
|
70 |
+
'image_url' => 'https://www.gravatar.com/avatar/602038ac19d5295415269aedc8d6ebf4',
|
71 |
+
'url' => 'https://profiles.wordpress.org/noverlin',
|
72 |
+
),
|
73 |
+
'laura' => array(
|
74 |
+
'name' => 'Laura White',
|
75 |
+
'title' => 'Tech Writer',
|
76 |
+
'image_url' => 'https://www.gravatar.com/avatar/56c44e12c3431aca766d06c6019201ff',
|
77 |
+
'url' => 'https://profiles.wordpress.org/laurakaysc',
|
78 |
+
),
|
79 |
);
|
80 |
|
81 |
$contributors = array(
|
82 |
+
'larry' => array(
|
83 |
+
'name' => 'Larry Furr',
|
84 |
+
'title' => '',
|
85 |
+
'image_url' => 'https://www.gravatar.com/avatar/77447d8ad56b4ba5ea8f3900b3245c41',
|
86 |
+
'url' => 'https://profiles.wordpress.org/furrever',
|
87 |
+
),
|
88 |
);
|
89 |
|
90 |
+
shuffle( $team );
|
91 |
+
shuffle( $team_contributors );
|
92 |
+
shuffle( $contributors );
|
93 |
|
94 |
?>
|
95 |
|
96 |
+
<p class="about-description"><?php _e( 'The Lingotek plugin for WordPress is created with love.', 'lingotek-translation' ); ?></p>
|
97 |
|
98 |
+
<h4 class="wp-people-group"><?php _e( 'Project Leaders', 'lingotek-translation' ); ?></h4>
|
99 |
|
100 |
<ul class="wp-people-group">
|
101 |
<?php
|
102 |
|
103 |
+
foreach ( $team as $person_key => $person ) {
|
104 |
+
printf(
|
105 |
+
'<li class="wp-person" id="wp-person-%s">
|
106 |
<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>
|
107 |
<a class="web" href="%s" target="_blank">%s</a>
|
108 |
<span class="title">%s</span>
|
109 |
+
</li>',
|
110 |
+
$person_key,
|
111 |
+
$person['url'],
|
112 |
+
$person['image_url'],
|
113 |
+
$person['image_url'],
|
114 |
+
$person['name'],
|
115 |
+
$person['url'],
|
116 |
+
$person['name'],
|
117 |
+
$person['title']
|
118 |
+
);
|
119 |
}
|
120 |
|
121 |
?>
|
122 |
</ul>
|
123 |
|
124 |
+
<h4 class="wp-people-group"><?php _e( 'Contributors', 'lingotek-translation' ); ?></h4>
|
125 |
|
126 |
<ul class="wp-people-group">
|
127 |
<?php
|
128 |
|
129 |
+
foreach ( $team_contributors as $person_key => $person ) {
|
130 |
+
printf(
|
131 |
+
'<li class="wp-person" id="wp-person-%s">
|
132 |
<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>
|
133 |
<a class="web" href="%s" target="_blank">%s</a>
|
134 |
<span class="title">%s</span>
|
135 |
+
</li>',
|
136 |
+
$person_key,
|
137 |
+
$person['url'],
|
138 |
+
$person['image_url'],
|
139 |
+
$person['image_url'],
|
140 |
+
$person['name'],
|
141 |
+
$person['url'],
|
142 |
+
$person['name'],
|
143 |
+
$person['title']
|
144 |
+
);
|
145 |
}
|
146 |
|
147 |
+
foreach ( $contributors as $person_key => $person ) {
|
148 |
+
printf(
|
149 |
+
'<li class="wp-person" id="wp-person-%s">
|
150 |
<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>
|
151 |
<a class="web" href="%s" target="_blank">%s</a>
|
152 |
<span class="title">%s</span>
|
153 |
+
</li>',
|
154 |
+
$person_key,
|
155 |
+
$person['url'],
|
156 |
+
$person['image_url'],
|
157 |
+
$person['image_url'],
|
158 |
+
$person['name'],
|
159 |
+
$person['url'],
|
160 |
+
$person['name'],
|
161 |
+
$person['title']
|
162 |
+
);
|
163 |
}
|
164 |
|
165 |
?>
|
166 |
+
</ul>
|
admin/tutorial/faq.php
CHANGED
@@ -7,59 +7,59 @@
|
|
7 |
}
|
8 |
</style>
|
9 |
|
10 |
-
<p class="about-description"><?php _e('Questions and answers...', 'lingotek-translation'); ?></p>
|
11 |
|
12 |
-
<b><?php _e('How does this really work?', 'lingotek-translation') ?></b>
|
13 |
-
<p><?php _e('<i>Polylang</i> puts in the framework to make WordPress multilingual and <i>Lingotek</i> leverages that framework to provide localization through machine translation and professional translation services.', 'lingotek-translation') ?></p>
|
14 |
|
15 |
-
<b><?php _e('What does the Lingotek plugin do?', 'lingotek-translation') ?></b>
|
16 |
-
<p><?php _e('<i>Lingotek</i> has teamed up with <i>Polylang</i> to offer a simple way to make your WordPress site truly multilingual. Manage all your multilingual content in the same site. No need to have a different site for each language!', 'lingotek-translation') ?></p>
|
17 |
|
18 |
-
<b><?php _e('How can I add a language?', 'lingotek-translation') ?></b>
|
19 |
-
<p><?php _e('On the <i>translation dashboard</i>, click on the <i>Translate my site into...</i> textbox and choose from the list or start typing to quickly find a language.', 'lingotek-translation') ?></p>
|
20 |
|
21 |
-
<b><?php _e('How can I remove a language?', 'lingotek-translation') ?></b>
|
22 |
<p>
|
23 |
-
<?php _e('On the <i>translation dashboard</i>, click on the blue check mark for the language you would like to remove.', 'lingotek-translation') ?>
|
24 |
-
<i><?php _e('Note: If you have translated content in a language you will not be able to remove that language until that content has been deleted.', 'lingotek-translation') ?></i>
|
25 |
</p>
|
26 |
|
27 |
-
<b><?php _e("Why can't I upload my existing content to Lingotek?", 'lingotek-translation') ?></b>
|
28 |
-
<p><?php printf(__("You must assign a language to content that existed before you installed the <i>Polylang</i> and <i>Lingotek</i> plugins. You can do this manually or use the <a href='%s'><i>Lingotek Language Utility</i></a> to set all content that doesn't have an assigned language to the default language. This will allow you to upload your existing content to Lingotek.", 'lingotek-translation'), 'admin.php?page=lingotek-translation_settings&sm=utilities'); ?></p>
|
29 |
|
30 |
-
<b><?php _e(
|
31 |
-
<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."
|
32 |
|
33 |
-
<b><?php _e('How can I check the overall translation progress of my site?', 'lingotek-translation') ?></b>
|
34 |
-
<p><?php _e('On the <i>translation dashboard</i>, the bars under <i>Completed Percentage</i> show the translation progress of content for each language. You can filter by content type or show progress for all content.', 'lingotek-translation') ?></p>
|
35 |
<ul>
|
36 |
<li>
|
37 |
-
<b><?php _e('Why are there two different shades of blue in the progress bar?', 'lingotek-translation') ?></b>
|
38 |
-
<p><?php _e('The <i>translation dashboard</i> not only shows how much of your content is translated, but also indicates the language that your source content was authored in.', 'lingotek-translation') ?></p>
|
39 |
</li>
|
40 |
<ul style="list-style-type:disc; padding-left:30px">
|
41 |
-
<li><?php _e('<i>Dark Blue:</i> Indicates that this is a source language that the content was authored in.', 'lingotek-translation') ?></li>
|
42 |
-
<li><?php _e('<i>Light Blue:</i> Indicates that this is a target language that the content was translated into.', 'lingotek-translation') ?></li>
|
43 |
</ul>
|
44 |
</ul>
|
45 |
|
46 |
-
<b><?php _e('What happens when I <i>Disassociate Translations</i>?', 'lingotek-translation') ?></b>
|
47 |
-
<p><?php _e('When content is disassociated, the connection between WordPress and <i>Lingotek</i> is safely removed so that translations can be solely managed inside of WordPress.', 'lingotek-translation') ?></p>
|
48 |
|
49 |
-
<b><?php _e(
|
50 |
-
<p><?php
|
51 |
|
52 |
|
53 |
<div class="changelog feature-section two-col">
|
54 |
<div>
|
55 |
<img class="workbench-image" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/workbench-full.png'; ?>">
|
56 |
-
<h3><?php _e( 'Lingotek Workbench', 'lingotek-translation'); ?></h3>
|
57 |
-
<p><?php _e( 'Lingotek Translation is the only WordPress plugin to integrate a Translation Management System directly into WordPress, thus allowing the WordPress community to use professional-grade translation technologies (e.g. machine translation, translation memory, CAT tool) without ever having to leave the comfort of the WordPress environment.', 'lingotek-translation'); ?></p>
|
58 |
</div>
|
59 |
<div class="last-feature">
|
60 |
<a href="admin.php?page=lingotek-translation"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/dashboard.png'; ?>"></a>
|
61 |
-
<h3><?php _e( 'Translation Dashboard', 'lingotek-translation'); ?></h3>
|
62 |
-
<p><?php _e(
|
63 |
</div>
|
64 |
</div>
|
65 |
|
7 |
}
|
8 |
</style>
|
9 |
|
10 |
+
<p class="about-description"><?php _e( 'Questions and answers...', 'lingotek-translation' ); ?></p>
|
11 |
|
12 |
+
<b><?php _e( 'How does this really work?', 'lingotek-translation' ); ?></b>
|
13 |
+
<p><?php _e( '<i>Polylang</i> puts in the framework to make WordPress multilingual and <i>Lingotek</i> leverages that framework to provide localization through machine translation and professional translation services.', 'lingotek-translation' ); ?></p>
|
14 |
|
15 |
+
<b><?php _e( 'What does the Lingotek plugin do?', 'lingotek-translation' ); ?></b>
|
16 |
+
<p><?php _e( '<i>Lingotek</i> has teamed up with <i>Polylang</i> to offer a simple way to make your WordPress site truly multilingual. Manage all your multilingual content in the same site. No need to have a different site for each language!', 'lingotek-translation' ); ?></p>
|
17 |
|
18 |
+
<b><?php _e( 'How can I add a language?', 'lingotek-translation' ); ?></b>
|
19 |
+
<p><?php _e( 'On the <i>translation dashboard</i>, click on the <i>Translate my site into...</i> textbox and choose from the list or start typing to quickly find a language.', 'lingotek-translation' ); ?></p>
|
20 |
|
21 |
+
<b><?php _e( 'How can I remove a language?', 'lingotek-translation' ); ?></b>
|
22 |
<p>
|
23 |
+
<?php _e( 'On the <i>translation dashboard</i>, click on the blue check mark for the language you would like to remove.', 'lingotek-translation' ); ?>
|
24 |
+
<i><?php _e( 'Note: If you have translated content in a language you will not be able to remove that language until that content has been deleted.', 'lingotek-translation' ); ?></i>
|
25 |
</p>
|
26 |
|
27 |
+
<b><?php _e( "Why can't I upload my existing content to Lingotek?", 'lingotek-translation' ); ?></b>
|
28 |
+
<p><?php printf( __( "You must assign a language to content that existed before you installed the <i>Polylang</i> and <i>Lingotek</i> plugins. You can do this manually or use the <a href='%s'><i>Lingotek Language Utility</i></a> to set all content that doesn't have an assigned language to the default language. This will allow you to upload your existing content to Lingotek.", 'lingotek-translation' ), 'admin.php?page=lingotek-translation_settings&sm=utilities' ); ?></p>
|
29 |
|
30 |
+
<b><?php _e( 'Can I use my own translation agency with Lingotek?', 'lingotek-translation' ); ?></b>
|
31 |
+
<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.", 'lingotek-translation' ); ?></p>
|
32 |
|
33 |
+
<b><?php _e( 'How can I check the overall translation progress of my site?', 'lingotek-translation' ); ?></b>
|
34 |
+
<p><?php _e( 'On the <i>translation dashboard</i>, the bars under <i>Completed Percentage</i> show the translation progress of content for each language. You can filter by content type or show progress for all content.', 'lingotek-translation' ); ?></p>
|
35 |
<ul>
|
36 |
<li>
|
37 |
+
<b><?php _e( 'Why are there two different shades of blue in the progress bar?', 'lingotek-translation' ); ?></b>
|
38 |
+
<p><?php _e( 'The <i>translation dashboard</i> not only shows how much of your content is translated, but also indicates the language that your source content was authored in.', 'lingotek-translation' ); ?></p>
|
39 |
</li>
|
40 |
<ul style="list-style-type:disc; padding-left:30px">
|
41 |
+
<li><?php _e( '<i>Dark Blue:</i> Indicates that this is a source language that the content was authored in.', 'lingotek-translation' ); ?></li>
|
42 |
+
<li><?php _e( '<i>Light Blue:</i> Indicates that this is a target language that the content was translated into.', 'lingotek-translation' ); ?></li>
|
43 |
</ul>
|
44 |
</ul>
|
45 |
|
46 |
+
<b><?php _e( 'What happens when I <i>Disassociate Translations</i>?', 'lingotek-translation' ); ?></b>
|
47 |
+
<p><?php _e( 'When content is disassociated, the connection between WordPress and <i>Lingotek</i> is safely removed so that translations can be solely managed inside of WordPress.', 'lingotek-translation' ); ?></p>
|
48 |
|
49 |
+
<b><?php _e( 'How do I translate strings within widgets or general WordPress settings (e.g., Site Title, Tagline)?', 'lingotek-translation' ); ?></b>
|
50 |
+
<p><?php printf( __( "Groups of strings can be sent for translation and managed using the <a href='%1\$s'>String Groups</a> page. Individual strings may be viewed on the <a href='%2\$s'>Strings</a> page.", 'lingotek-translation' ), 'admin.php?page=lingotek-translation_manage&sm=string-groups', 'admin.php?page=lingotek-translation_manage&sm=strings' ); ?></p>
|
51 |
|
52 |
|
53 |
<div class="changelog feature-section two-col">
|
54 |
<div>
|
55 |
<img class="workbench-image" src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/workbench-full.png'; ?>">
|
56 |
+
<h3><?php _e( 'Lingotek Workbench', 'lingotek-translation' ); ?></h3>
|
57 |
+
<p><?php _e( 'Lingotek Translation is the only WordPress plugin to integrate a Translation Management System directly into WordPress, thus allowing the WordPress community to use professional-grade translation technologies (e.g. machine translation, translation memory, CAT tool) without ever having to leave the comfort of the WordPress environment.', 'lingotek-translation' ); ?></p>
|
58 |
</div>
|
59 |
<div class="last-feature">
|
60 |
<a href="admin.php?page=lingotek-translation"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/dashboard.png'; ?>"></a>
|
61 |
+
<h3><?php _e( 'Translation Dashboard', 'lingotek-translation' ); ?></h3>
|
62 |
+
<p><?php _e( 'The <i>translation dashboard</i> allows you to view your site languages, add and remove new languages, check the overall translation progress of your site, see site analytics, and connect with Lingotek support.', 'lingotek-translation' ); ?></p>
|
63 |
</div>
|
64 |
</div>
|
65 |
|
admin/tutorial/features.php
CHANGED
@@ -8,13 +8,13 @@
|
|
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', 'lingotek-translation' ); ?></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).", 'lingotek-translation'); ?></p>
|
12 |
</div>
|
13 |
<div class="col">
|
14 |
<img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation.png'; ?>">
|
15 |
-
<h3><?php _e( 'Request professional translation', 'lingotek-translation'); ?></h3>
|
16 |
-
<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.", 'lingotek-translation'); ?></p>
|
17 |
-
<a href="<?php echo admin_url( 'admin.php?page=lingotek-translation_tutorial&sm=content&tutorial=ltk-prof#ltk-prof-trans-header' ) ?>" class="button button-primary"><?php _e('Learn More', 'lingotek-translation'); ?></a>
|
18 |
</div>
|
19 |
</div>
|
20 |
|
@@ -23,17 +23,17 @@
|
|
23 |
<div class="col">
|
24 |
<img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/polylang-compatible.png'; ?>">
|
25 |
<h3><?php _e( 'Fully compatible with Polylang', 'lingotek-translation' ); ?></h3>
|
26 |
-
<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.', 'lingotek-translation' ), 'darkorange', '#0473a8' ); ?></p>
|
27 |
</div>
|
28 |
<div class="col">
|
29 |
<a href="admin.php?page=lingotek-translation_manage&sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-profiles.png'; ?>"></a>
|
30 |
-
<h3><?php _e( 'Use translation profiles', 'lingotek-translation'); ?></h3>
|
31 |
-
<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.', 'lingotek-translation'); ?></p>
|
32 |
</div>
|
33 |
<div class="col">
|
34 |
<a href="admin.php?page=lingotek-translation_manage&sm=content"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/content-types.png'; ?>"></a>
|
35 |
-
<h3><?php _e( 'Content type profiles', 'lingotek-translation'); ?></h3>
|
36 |
-
<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.', 'lingotek-translation'); ?></p>
|
37 |
</div>
|
38 |
|
39 |
</div>
|
@@ -42,18 +42,18 @@
|
|
42 |
<div class="feature-section three-col">
|
43 |
<div class="col">
|
44 |
<a href="admin.php?page=lingotek-translation_manage&sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-services.png'; ?>"></a>
|
45 |
-
<h3><?php _e( 'Need Extra Services?', 'lingotek-translation'); ?></h3>
|
46 |
-
<p><?php _e( 'Start the process of getting extra services.', 'lingotek-translation'); ?></p>
|
47 |
<ul style="list-style-type: circle;">
|
48 |
-
<li><?php _e('Do you need someone to run your localization project?', 'lingotek-translation'); ?></li>
|
49 |
-
<li><?php _e('Do you need customized workflows?', 'lingotek-translation'); ?></li>
|
50 |
-
<li><?php _e('Do you you have existing Translation Memories you would like to use?', 'lingotek-translation'); ?></li>
|
51 |
-
<li><?php _e('Do you need help creating glossaries and terminologies?', 'lingotek-translation'); ?></li>
|
52 |
</ul>
|
53 |
-
<a href="http://www.lingotek.com/wordpress/extra_services" class="button button-primary" target="_blank"><?php _e('Request Services', 'lingotek-translation'); ?></a>
|
54 |
</div>
|
55 |
<div class="col">
|
56 |
</div>
|
57 |
<div class="col">
|
58 |
</div>
|
59 |
-
</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', 'lingotek-translation' ); ?></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).", 'lingotek-translation' ); ?></p>
|
12 |
</div>
|
13 |
<div class="col">
|
14 |
<img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/professional-translation.png'; ?>">
|
15 |
+
<h3><?php _e( 'Request professional translation', 'lingotek-translation' ); ?></h3>
|
16 |
+
<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.", 'lingotek-translation' ); ?></p>
|
17 |
+
<a href="<?php echo admin_url( 'admin.php?page=lingotek-translation_tutorial&sm=content&tutorial=ltk-prof#ltk-prof-trans-header' ); ?>" class="button button-primary"><?php _e( 'Learn More', 'lingotek-translation' ); ?></a>
|
18 |
</div>
|
19 |
</div>
|
20 |
|
23 |
<div class="col">
|
24 |
<img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/polylang-compatible.png'; ?>">
|
25 |
<h3><?php _e( 'Fully compatible with Polylang', 'lingotek-translation' ); ?></h3>
|
26 |
+
<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: %1$s">orange</b> icons indicate Lingotek statuses/actions while the <b style="color: %2$s">blue</b> icons continue to represent Polylang actions.', 'lingotek-translation' ), 'darkorange', '#0473a8' ); ?></p>
|
27 |
</div>
|
28 |
<div class="col">
|
29 |
<a href="admin.php?page=lingotek-translation_manage&sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-profiles.png'; ?>"></a>
|
30 |
+
<h3><?php _e( 'Use translation profiles', 'lingotek-translation' ); ?></h3>
|
31 |
+
<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.', 'lingotek-translation' ); ?></p>
|
32 |
</div>
|
33 |
<div class="col">
|
34 |
<a href="admin.php?page=lingotek-translation_manage&sm=content"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/content-types.png'; ?>"></a>
|
35 |
+
<h3><?php _e( 'Content type profiles', 'lingotek-translation' ); ?></h3>
|
36 |
+
<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.', 'lingotek-translation' ); ?></p>
|
37 |
</div>
|
38 |
|
39 |
</div>
|
42 |
<div class="feature-section three-col">
|
43 |
<div class="col">
|
44 |
<a href="admin.php?page=lingotek-translation_manage&sm=profiles"><img src="<?php echo LINGOTEK_URL . '/admin/tutorial/img/translation-services.png'; ?>"></a>
|
45 |
+
<h3><?php _e( 'Need Extra Services?', 'lingotek-translation' ); ?></h3>
|
46 |
+
<p><?php _e( 'Start the process of getting extra services.', 'lingotek-translation' ); ?></p>
|
47 |
<ul style="list-style-type: circle;">
|
48 |
+
<li><?php _e( 'Do you need someone to run your localization project?', 'lingotek-translation' ); ?></li>
|
49 |
+
<li><?php _e( 'Do you need customized workflows?', 'lingotek-translation' ); ?></li>
|
50 |
+
<li><?php _e( 'Do you you have existing Translation Memories you would like to use?', 'lingotek-translation' ); ?></li>
|
51 |
+
<li><?php _e( 'Do you need help creating glossaries and terminologies?', 'lingotek-translation' ); ?></li>
|
52 |
</ul>
|
53 |
+
<a href="http://www.lingotek.com/wordpress/extra_services" class="button button-primary" target="_blank"><?php _e( 'Request Services', 'lingotek-translation' ); ?></a>
|
54 |
</div>
|
55 |
<div class="col">
|
56 |
</div>
|
57 |
<div class="col">
|
58 |
</div>
|
59 |
+
</div>
|
admin/utilities.php
CHANGED
@@ -6,7 +6,8 @@
|
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
class Lingotek_Utilities {
|
9 |
-
|
|
|
10 |
|
11 |
/*
|
12 |
* Constructor
|
@@ -17,10 +18,10 @@ class Lingotek_Utilities {
|
|
17 |
$this->pllm = $GLOBALS['polylang']->model;
|
18 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
19 |
|
20 |
-
add_action('admin_enqueue_scripts', array(&$this, 'admin_enqueue_scripts'));
|
21 |
-
add_action('wp_ajax_lingotek_progress_disassociate'
|
22 |
-
add_action('wp_ajax_lingotek_progress_disassociate_and_delete'
|
23 |
-
add_action('wp_ajax_lingotek_progress_cancel', array(&$this, 'ajax_utility_cancel'));
|
24 |
}
|
25 |
|
26 |
/*
|
@@ -31,11 +32,11 @@ class Lingotek_Utilities {
|
|
31 |
* @param array $utilities array of utility names to run
|
32 |
* @return array
|
33 |
*/
|
34 |
-
public function run_utilities($utilities){
|
35 |
$results = array();
|
36 |
-
if(!empty($utilities) && is_array($utilities)){
|
37 |
-
foreach($utilities as $utility_name) {
|
38 |
-
$results[] = $this->run_utility($utility_name);
|
39 |
}
|
40 |
}
|
41 |
return $results;
|
@@ -49,11 +50,11 @@ class Lingotek_Utilities {
|
|
49 |
* @param string $utilty_name
|
50 |
* @return boolean $result
|
51 |
*/
|
52 |
-
public function run_utility($utility_name) {
|
53 |
$result = 0;
|
54 |
-
switch ($utility_name) {
|
55 |
-
case
|
56 |
-
case
|
57 |
$result = $this->utility_set_default_language();
|
58 |
break;
|
59 |
default:
|
@@ -70,13 +71,15 @@ class Lingotek_Utilities {
|
|
70 |
* @since 0.2
|
71 |
*/
|
72 |
public function utility_set_default_language() {
|
73 |
-
if ($nolang = $this->pllm->get_objects_with_no_lang()) {
|
74 |
-
if (!empty($nolang['posts']))
|
75 |
-
$this->pllm->set_language_in_mass('post', $nolang['posts'], $this->pllm->options['default_lang']);
|
76 |
-
|
77 |
-
|
|
|
|
|
78 |
}
|
79 |
-
add_settings_error('lingotek_utilities', 'utilities', __('The language update utility ran successfully.', 'lingotek-translation'), 'updated');
|
80 |
return 0;
|
81 |
}
|
82 |
|
@@ -87,15 +90,16 @@ class Lingotek_Utilities {
|
|
87 |
*
|
88 |
* @return array
|
89 |
*/
|
90 |
-
static
|
91 |
-
$terms = get_terms(array('post_translations', 'term_translations'));
|
92 |
-
foreach ($terms as $term) {
|
93 |
-
$desc_arr = unserialize($term->description);
|
94 |
-
if (!empty($desc_arr['lingotek']))
|
95 |
$ids[] = $term->slug;
|
|
|
96 |
}
|
97 |
|
98 |
-
return empty($ids) ? array() : $ids;
|
99 |
}
|
100 |
|
101 |
/*
|
@@ -104,31 +108,41 @@ class Lingotek_Utilities {
|
|
104 |
* @since 0.2
|
105 |
*/
|
106 |
public function admin_enqueue_scripts() {
|
107 |
-
if (!empty($_POST['utility_disassociate'])) {
|
108 |
$ids = self::get_all_document_ids();
|
109 |
-
if (!empty($ids)) {
|
110 |
-
wp_localize_script(
|
111 |
-
'
|
112 |
-
'
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
-
}
|
120 |
$ids = self::get_all_document_ids();
|
121 |
-
if(!empty($ids)){
|
122 |
-
wp_localize_script(
|
123 |
-
'
|
124 |
-
'
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
130 |
}
|
131 |
-
}
|
132 |
}
|
133 |
|
134 |
/*
|
@@ -137,16 +151,17 @@ class Lingotek_Utilities {
|
|
137 |
* @since 0.2
|
138 |
*/
|
139 |
public function ajax_utility_disassociate() {
|
140 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
141 |
-
if ($group = $this->lgtm->get_group_by_id($_POST['id']))
|
142 |
-
$group->delete('lingotek_progress_disassociate_and_delete' == $_POST['action']);
|
|
|
143 |
die();
|
144 |
}
|
145 |
|
146 |
public function ajax_utility_cancel() {
|
147 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
148 |
-
if ($group = $this->lgtm->get_group_by_id($_POST['id'])){
|
149 |
-
$group->cancel('lingotek_progress_cancel' == $_POST['action']);
|
150 |
}
|
151 |
die();
|
152 |
}
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
class Lingotek_Utilities {
|
9 |
+
// Polylang and Lingotek models.
|
10 |
+
public $pllm, $lgtm;
|
11 |
|
12 |
/*
|
13 |
* Constructor
|
18 |
$this->pllm = $GLOBALS['polylang']->model;
|
19 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
20 |
|
21 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
|
22 |
+
add_action( 'wp_ajax_lingotek_progress_disassociate', array( &$this, 'ajax_utility_disassociate' ) );
|
23 |
+
add_action( 'wp_ajax_lingotek_progress_disassociate_and_delete', array( &$this, 'ajax_utility_disassociate' ) );
|
24 |
+
add_action( 'wp_ajax_lingotek_progress_cancel', array( &$this, 'ajax_utility_cancel' ) );
|
25 |
}
|
26 |
|
27 |
/*
|
32 |
* @param array $utilities array of utility names to run
|
33 |
* @return array
|
34 |
*/
|
35 |
+
public function run_utilities( $utilities ) {
|
36 |
$results = array();
|
37 |
+
if ( ! empty( $utilities ) && is_array( $utilities ) ) {
|
38 |
+
foreach ( $utilities as $utility_name ) {
|
39 |
+
$results[] = $this->run_utility( $utility_name );
|
40 |
}
|
41 |
}
|
42 |
return $results;
|
50 |
* @param string $utilty_name
|
51 |
* @return boolean $result
|
52 |
*/
|
53 |
+
public function run_utility( $utility_name ) {
|
54 |
$result = 0;
|
55 |
+
switch ( $utility_name ) {
|
56 |
+
case 'set_default_language':
|
57 |
+
case 'utility_set_default_language':
|
58 |
$result = $this->utility_set_default_language();
|
59 |
break;
|
60 |
default:
|
71 |
* @since 0.2
|
72 |
*/
|
73 |
public function utility_set_default_language() {
|
74 |
+
if ( $nolang = $this->pllm->get_objects_with_no_lang() ) {
|
75 |
+
if ( ! empty( $nolang['posts'] ) ) {
|
76 |
+
$this->pllm->set_language_in_mass( 'post', $nolang['posts'], $this->pllm->options['default_lang'] );
|
77 |
+
}
|
78 |
+
if ( ! empty( $nolang['terms'] ) ) {
|
79 |
+
$this->pllm->set_language_in_mass( 'term', $nolang['terms'], $this->pllm->options['default_lang'] );
|
80 |
+
}
|
81 |
}
|
82 |
+
add_settings_error( 'lingotek_utilities', 'utilities', __( 'The language update utility ran successfully.', 'lingotek-translation' ), 'updated' );
|
83 |
return 0;
|
84 |
}
|
85 |
|
90 |
*
|
91 |
* @return array
|
92 |
*/
|
93 |
+
public static function get_all_document_ids() {
|
94 |
+
$terms = get_terms( array( 'post_translations', 'term_translations' ) );
|
95 |
+
foreach ( $terms as $term ) {
|
96 |
+
$desc_arr = unserialize( $term->description );
|
97 |
+
if ( ! empty( $desc_arr['lingotek'] ) ) {
|
98 |
$ids[] = $term->slug;
|
99 |
+
}
|
100 |
}
|
101 |
|
102 |
+
return empty( $ids ) ? array() : $ids;
|
103 |
}
|
104 |
|
105 |
/*
|
108 |
* @since 0.2
|
109 |
*/
|
110 |
public function admin_enqueue_scripts() {
|
111 |
+
if ( ! empty( $_POST['utility_disassociate'] ) ) {
|
112 |
$ids = self::get_all_document_ids();
|
113 |
+
if ( ! empty( $ids ) ) {
|
114 |
+
wp_localize_script(
|
115 |
+
'lingotek_progress',
|
116 |
+
'lingotek_data',
|
117 |
+
array(
|
118 |
+
'action' => 'disassociate' . ( 'on' == $_POST['utility_delete_documents'] ? '_and_delete' : '' ),
|
119 |
+
'taxonomy' => '',
|
120 |
+
'sendback' => wp_get_referer(),
|
121 |
+
// Lingotek document ids.
|
122 |
+
'ids' => $ids,
|
123 |
+
'warning' => '',
|
124 |
+
'nonce' => wp_create_nonce( 'lingotek_progress' ),
|
125 |
+
)
|
126 |
+
);
|
127 |
}
|
128 |
+
} elseif ( ! empty( $_POST['utility_cancel'] ) ) {
|
129 |
$ids = self::get_all_document_ids();
|
130 |
+
if ( ! empty( $ids ) ) {
|
131 |
+
wp_localize_script(
|
132 |
+
'lingotek_progress',
|
133 |
+
'lingotek_data',
|
134 |
+
array(
|
135 |
+
'action' => 'cancel' . ( $_POST['utility_cancel_documents'] ),
|
136 |
+
'taxonomy' => '',
|
137 |
+
'sendback' => wp_get_referer(),
|
138 |
+
// Lingotek document ids.
|
139 |
+
'ids' => $ids,
|
140 |
+
'warning' => '',
|
141 |
+
'nonce' => wp_create_nonce( 'lingotek_progress' ),
|
142 |
+
)
|
143 |
+
);
|
144 |
}
|
145 |
+
}//end if
|
146 |
}
|
147 |
|
148 |
/*
|
151 |
* @since 0.2
|
152 |
*/
|
153 |
public function ajax_utility_disassociate() {
|
154 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
155 |
+
if ( $group = $this->lgtm->get_group_by_id( $_POST['id'] ) ) {
|
156 |
+
$group->delete( 'lingotek_progress_disassociate_and_delete' == $_POST['action'] );
|
157 |
+
}
|
158 |
die();
|
159 |
}
|
160 |
|
161 |
public function ajax_utility_cancel() {
|
162 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
163 |
+
if ( $group = $this->lgtm->get_group_by_id( $_POST['id'] ) ) {
|
164 |
+
$group->cancel( 'lingotek_progress_cancel' == $_POST['action'] );
|
165 |
}
|
166 |
die();
|
167 |
}
|
admin/view-dashboard.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<div class="wrap">
|
2 |
-
<h2><?php _e('Dashboard', 'lingotek-translation'); ?></h2>
|
3 |
<script>
|
4 |
-
|
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>
|
1 |
<div class="wrap">
|
2 |
+
<h2><?php _e( 'Dashboard', 'lingotek-translation' ); ?></h2>
|
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>
|
admin/view-manage.php
CHANGED
@@ -1,43 +1,48 @@
|
|
1 |
<div class="wrap">
|
2 |
-
<h2><?php _e('Manage', 'lingotek-translation'); ?></h2>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
</div>
|
43 |
|
1 |
<div class="wrap">
|
2 |
+
<h2><?php _e( 'Manage', 'lingotek-translation' ); ?></h2>
|
3 |
+
|
4 |
+
<?php
|
5 |
+
|
6 |
+
$menu_items = array(
|
7 |
+
'content' => __( 'Content Type Configuration', 'lingotek-translation' ),
|
8 |
+
'profiles' => __( 'Translation Profiles', 'lingotek-translation' ),
|
9 |
+
'custom-fields' => __( 'Custom Fields', 'lingotek-translation' ),
|
10 |
+
'string-groups' => __( 'String Groups', 'lingotek-translation' ),
|
11 |
+
'strings' => __( 'Strings', 'lingotek-translation' ),
|
12 |
+
);
|
13 |
+
|
14 |
+
?>
|
15 |
+
|
16 |
+
<h3 class="nav-tab-wrapper">
|
17 |
+
<?php
|
18 |
+
$menu_item_index = 0;
|
19 |
+
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
20 |
+
$use_as_default = ( $menu_item_index === 0 && ! isset( $_GET['sm'] ) ) ? true : false;
|
21 |
+
?>
|
22 |
+
|
23 |
+
<a class="nav-tab
|
24 |
+
<?php
|
25 |
+
if ( $use_as_default || ( isset( $_GET['sm'] ) && $_GET['sm'] == $menu_item_key ) ) :
|
26 |
+
?>
|
27 |
+
nav-tab-active<?php endif; ?>"
|
28 |
+
href="admin.php?page=<?php echo $_GET['page']; ?>&sm=<?php echo $menu_item_key; ?>"><?php echo $menu_item_label; ?></a>
|
29 |
+
<?php
|
30 |
+
$menu_item_index++;
|
31 |
+
}
|
32 |
+
?>
|
33 |
+
</h3>
|
34 |
+
|
35 |
+
<?php
|
36 |
+
settings_errors();
|
37 |
+
$submenu = isset( $_GET['sm'] ) ? sanitize_text_field( $_GET['sm'] ) : current( array_keys( $menu_items ) );
|
38 |
+
$dir = dirname( __FILE__ ) . '/manage/';
|
39 |
+
$filename = $dir . 'view-' . $submenu . '.php';
|
40 |
+
if ( file_exists( $filename ) ) {
|
41 |
+
require $filename;
|
42 |
+
} else {
|
43 |
+
echo 'TO-DO: create <i>' . 'manage/view-' . $submenu . '.php</i>';
|
44 |
+
}
|
45 |
+
?>
|
46 |
|
47 |
</div>
|
48 |
|
admin/view-network.php
CHANGED
@@ -1,105 +1,103 @@
|
|
1 |
<?php
|
2 |
-
$sites
|
3 |
$site_data = array();
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
if ($setting == 'token') {
|
30 |
-
$lingotek_option = 'lingotek_' . $setting;
|
31 |
|
32 |
-
|
33 |
-
|
|
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
}
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
$source_options = get_blog_option($source_site, $lingotek_option);
|
43 |
-
update_blog_option($destination, $lingotek_option, $source_options);
|
44 |
-
}
|
45 |
}
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
}
|
61 |
-
|
62 |
-
if (isset($_POST['preferences'])) {
|
63 |
-
switch_to_blog($source_site);
|
64 |
-
$preferences = Lingotek_Model::get_prefs();
|
65 |
-
update_blog_option($destination, 'lingotek_prefs', $preferences);
|
66 |
-
restore_current_blog();
|
67 |
}
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
}
|
76 |
|
77 |
-
if (isset($_POST['utility_set_default_language'])) {
|
78 |
-
|
|
|
|
|
79 |
}
|
80 |
-
|
|
|
|
|
|
|
81 |
}
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
$source_options = get_option('lingotek_community_resources');
|
91 |
-
update_blog_option($destination, 'lingotek_community_resources', $source_options);
|
92 |
-
}
|
93 |
-
$num = count($destination_site);
|
94 |
-
if ($num > 1) {
|
95 |
-
add_settings_error('network', 'projects', __('Your new projects were successfully created.', 'lingotek-translation'), 'updated');
|
96 |
-
}
|
97 |
-
else {
|
98 |
-
add_settings_error('network', 'projects', __('Your new project was successfully created.', 'lingotek-translation'), 'updated');
|
99 |
-
}
|
100 |
}
|
101 |
}
|
102 |
-
|
|
|
103 |
?>
|
104 |
|
105 |
<style>
|
@@ -109,59 +107,66 @@
|
|
109 |
</style>
|
110 |
|
111 |
<div class="wrap">
|
112 |
-
<h2><?php _e('Lingotek Network Settings', 'lingotek-translation'); ?></h2>
|
113 |
-
<p><?php _e('Copy Lingotek settings from the source site to multiple sites', 'lingotek-translation'); ?></p>
|
114 |
|
115 |
<form id="network-settings" method="post" action="admin.php?page=lingotek-translation_network" class="validate" onsubmit="return confirm('Are you sure you want to submit this request? It will overwrite any current settings you have for the destination sites.');">
|
116 |
|
117 |
<table class="form-table">
|
118 |
<tr>
|
119 |
-
<th><?php echo _e('Source Site', 'lingotek-translation'); ?></th>
|
120 |
<td>
|
121 |
-
<select name="source" id="source"
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
124 |
</select>
|
125 |
</td>
|
126 |
</tr>
|
127 |
<tr>
|
128 |
-
<th><?php echo _e('Destination Site', 'lingotek-translation'); ?></th>
|
129 |
<td>
|
130 |
-
<select multiple="multiple" name="destination[]" id="destination"
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
133 |
</select>
|
134 |
</td>
|
135 |
</tr>
|
136 |
<tr>
|
137 |
-
<th><?php echo _e('Settings to copy', 'lingotek-translation'); ?></th>
|
138 |
<td>
|
139 |
-
<input checked type="checkbox" id="account" name="settings[]" value="token"><label for="account"><?php echo _e('Account', 'lingotek-translation'); ?></label>
|
140 |
-
<input checked type="checkbox" id="community" name="settings[]" value="community"><label for="community"><?php echo _e('Community', 'lingotek-translation'); ?></label>
|
141 |
-
<input checked type="checkbox" id="defaults" name="settings[]" value="defaults"><label for="defaults"><?php echo _e('Defaults', 'lingotek-translation'); ?></label>
|
142 |
-
<input checked type="checkbox" id="resources" name="settings[]" value="community_resources"><label for="resources"><?php echo _e('Resources', 'lingotek-translation'); ?></label>
|
143 |
-
<input checked type="checkbox" id="profiles" name="settings[]" value="profiles"><label for="profiles"><?php echo _e('Profiles', 'lingotek-translation'); ?></label>
|
144 |
-
<input checked type="checkbox" id="content_types" name="settings[]" value="content_type"><label for="content_types"><?php echo _e('Content Types', 'lingotek-translation'); ?></label>
|
145 |
-
<input checked type="checkbox" id="preferences" name="preferences" value="preferences"><label for="preferences"><?php echo _e('Preferences', 'lingotek-translation'); ?></label>
|
146 |
</td>
|
147 |
</tr>
|
148 |
<tr>
|
149 |
-
<th><?php echo _e('New Project', 'lingotek-translation'); ?></th>
|
150 |
<td>
|
151 |
-
<input checked type="checkbox" name="new_project" id="new_project" ><label for="new_project"><?php echo _e('Create a new project using the name of the selected site (Recommended for a newly created site)', 'lingotek-translation'); ?></label>
|
152 |
</td>
|
153 |
</tr>
|
154 |
<tr>
|
155 |
-
<th><?php echo _e('Language', 'lingotek-translation'); ?></th>
|
156 |
<td>
|
157 |
-
<input checked type="checkbox" name="utility_set_default_language" id="utility_set_default_language" ><label for="utility_set_default_language"><?php echo _e('Set <i>default language</i> as the language for all existing content that has not been assigned a language.', 'lingotek-translation'); ?></label>
|
158 |
</td>
|
159 |
</tr>
|
160 |
</table>
|
161 |
|
162 |
<p>
|
163 |
-
<?php submit_button(__('Update Options', 'lingotek-translation'), 'primary', 'submit', false); ?>
|
164 |
</p>
|
165 |
|
166 |
</form>
|
167 |
-
</div>
|
1 |
<?php
|
2 |
+
$sites = wp_get_sites();
|
3 |
$site_data = array();
|
4 |
|
5 |
+
foreach ( $sites as $site ) {
|
6 |
+
switch_to_blog( $site['blog_id'] );
|
7 |
+
$details = get_blog_details( $site['blog_id'] )->blogname;
|
8 |
+
$temp = array(
|
9 |
+
'blog_id' => $site['blog_id'],
|
10 |
+
'blogname' => $details,
|
11 |
+
);
|
12 |
+
array_push( $site_data, $temp );
|
13 |
+
$ltk = new Lingotek();
|
14 |
+
$ltk->admin_init();
|
15 |
+
restore_current_blog();
|
16 |
+
}
|
17 |
+
|
18 |
+
if ( ! empty( $_POST ) ) {
|
19 |
+
$source_site = $_POST['source'];
|
20 |
+
|
21 |
+
if ( isset( $_POST['destination'] ) ) {
|
22 |
+
$destination_site = $_POST['destination'];
|
23 |
+
|
24 |
+
foreach ( $destination_site as $destination ) {
|
25 |
+
if ( ! empty( $_POST['settings'] ) ) {
|
26 |
+
$selected_settings = $_POST['settings'];
|
27 |
+
|
28 |
+
foreach ( $selected_settings as $setting ) {
|
29 |
+
//Updates account options for access token and the base url to connect to Lingotek
|
30 |
+
if ( $setting == 'token' ) {
|
31 |
+
$lingotek_option = 'lingotek_' . $setting;
|
32 |
|
33 |
+
$source_options = get_blog_option( $source_site, $lingotek_option );
|
34 |
+
update_blog_option( $destination, $lingotek_option, $source_options );
|
|
|
|
|
35 |
|
36 |
+
$source_options = get_blog_option( $source_site, 'lingotek_base_url' );
|
37 |
+
update_blog_option( $destination, 'lingotek_base_url', $source_options );
|
38 |
+
}
|
39 |
|
40 |
+
//Updates the chosen option
|
41 |
+
$lingotek_option = 'lingotek_' . $setting;
|
|
|
42 |
|
43 |
+
$source_options = get_blog_option( $source_site, $lingotek_option );
|
44 |
+
update_blog_option( $destination, $lingotek_option, $source_options );
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
+
}//end if
|
47 |
+
|
48 |
+
//Creates a new project based on the name of the selected site
|
49 |
+
if ( isset( $_POST['new_project'] ) ) {
|
50 |
+
$options = get_blog_option( $destination, 'lingotek_defaults', array() );
|
51 |
+
$client = new Lingotek_API();
|
52 |
+
$title = htmlspecialchars_decode( get_blog_details( $destination )->blogname, ENT_QUOTES );
|
53 |
+
|
54 |
+
if ( $new_id = $client->create_project( $title, $community_id = get_blog_option( $destination, 'lingotek_community' ) ) ) {
|
55 |
+
$options['project_id'] = $new_id;
|
56 |
+
// Adds correct callback URL for new project
|
57 |
+
$args = array( 'callback_url' => add_query_arg( 'lingotek', 1, get_blog_details( $destination )->siteurl ) );
|
58 |
+
$response = $client->patch( $client->get_api_url() . '/project/' . $new_id, $args );
|
59 |
+
update_blog_option( $destination, 'lingotek_defaults', $options );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
}
|
61 |
+
}
|
62 |
|
63 |
+
if ( isset( $_POST['preferences'] ) ) {
|
64 |
+
switch_to_blog( $source_site );
|
65 |
+
$preferences = Lingotek_Model::get_prefs();
|
66 |
+
update_blog_option( $destination, 'lingotek_prefs', $preferences );
|
67 |
+
restore_current_blog();
|
|
|
68 |
}
|
69 |
|
70 |
+
if ( isset( $_POST['utility_set_default_language'] ) ) {
|
71 |
+
switch_to_blog( $destination );
|
72 |
+
$GLOBALS['wp_lingotek']->utilities->run_utility( 'utility_set_default_language' );
|
73 |
+
restore_current_blog();
|
74 |
}
|
75 |
+
}//end foreach
|
76 |
+
|
77 |
+
if ( isset( $_POST['utility_set_default_language'] ) ) {
|
78 |
+
add_settings_error( 'network', 'utilities', __( 'The language utility ran successfully.', 'lingotek-translation' ), 'updated' );
|
79 |
}
|
80 |
+
add_settings_error( 'network', 'destination', __( 'Your chosen settings have updated successfully for all selected sites.', 'lingotek-translation' ), 'updated' );
|
81 |
+
} else {
|
82 |
+
add_settings_error( 'network', 'destination', __( 'Please choose at least one destination site.', 'lingotek-translation' ), 'error' );
|
83 |
+
}//end if
|
84 |
+
|
85 |
+
//Refreshes community resources so that the defaults are set when you visit the sites translation settings
|
86 |
+
if ( isset( $_POST['new_project'] ) && isset( $_POST['destination'] ) ) {
|
87 |
+
$this->set_community_resources( get_option( 'lingotek_community' ) );
|
88 |
+
foreach ( $destination_site as $destination ) {
|
89 |
+
$source_options = get_option( 'lingotek_community_resources' );
|
90 |
+
update_blog_option( $destination, 'lingotek_community_resources', $source_options );
|
91 |
}
|
92 |
+
$num = count( $destination_site );
|
93 |
+
if ( $num > 1 ) {
|
94 |
+
add_settings_error( 'network', 'projects', __( 'Your new projects were successfully created.', 'lingotek-translation' ), 'updated' );
|
95 |
+
} else {
|
96 |
+
add_settings_error( 'network', 'projects', __( 'Your new project was successfully created.', 'lingotek-translation' ), 'updated' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
}
|
99 |
+
}//end if
|
100 |
+
settings_errors( 'network' );
|
101 |
?>
|
102 |
|
103 |
<style>
|
107 |
</style>
|
108 |
|
109 |
<div class="wrap">
|
110 |
+
<h2><?php _e( 'Lingotek Network Settings', 'lingotek-translation' ); ?></h2>
|
111 |
+
<p><?php _e( 'Copy Lingotek settings from the source site to multiple sites', 'lingotek-translation' ); ?></p>
|
112 |
|
113 |
<form id="network-settings" method="post" action="admin.php?page=lingotek-translation_network" class="validate" onsubmit="return confirm('Are you sure you want to submit this request? It will overwrite any current settings you have for the destination sites.');">
|
114 |
|
115 |
<table class="form-table">
|
116 |
<tr>
|
117 |
+
<th><?php echo _e( 'Source Site', 'lingotek-translation' ); ?></th>
|
118 |
<td>
|
119 |
+
<select name="source" id="source">
|
120 |
+
<?php
|
121 |
+
foreach ( $site_data as $site ) {
|
122 |
+
echo "\n\t<option value='" . esc_attr( $site['blog_id'] ) . "'>" . $site['blogname'] . '</option>';
|
123 |
+
}
|
124 |
+
?>
|
125 |
+
|
126 |
</select>
|
127 |
</td>
|
128 |
</tr>
|
129 |
<tr>
|
130 |
+
<th><?php echo _e( 'Destination Site', 'lingotek-translation' ); ?></th>
|
131 |
<td>
|
132 |
+
<select multiple="multiple" name="destination[]" id="destination">
|
133 |
+
<?php
|
134 |
+
foreach ( $site_data as $site ) {
|
135 |
+
echo "\n\t<option value='" . esc_attr( $site['blog_id'] ) . "'>" . $site['blogname'] . '</option>';
|
136 |
+
}
|
137 |
+
?>
|
138 |
</select>
|
139 |
</td>
|
140 |
</tr>
|
141 |
<tr>
|
142 |
+
<th><?php echo _e( 'Settings to copy', 'lingotek-translation' ); ?></th>
|
143 |
<td>
|
144 |
+
<input checked type="checkbox" id="account" name="settings[]" value="token"><label for="account"><?php echo _e( 'Account', 'lingotek-translation' ); ?></label>
|
145 |
+
<input checked type="checkbox" id="community" name="settings[]" value="community"><label for="community"><?php echo _e( 'Community', 'lingotek-translation' ); ?></label>
|
146 |
+
<input checked type="checkbox" id="defaults" name="settings[]" value="defaults"><label for="defaults"><?php echo _e( 'Defaults', 'lingotek-translation' ); ?></label>
|
147 |
+
<input checked type="checkbox" id="resources" name="settings[]" value="community_resources"><label for="resources"><?php echo _e( 'Resources', 'lingotek-translation' ); ?></label>
|
148 |
+
<input checked type="checkbox" id="profiles" name="settings[]" value="profiles"><label for="profiles"><?php echo _e( 'Profiles', 'lingotek-translation' ); ?></label>
|
149 |
+
<input checked type="checkbox" id="content_types" name="settings[]" value="content_type"><label for="content_types"><?php echo _e( 'Content Types', 'lingotek-translation' ); ?></label>
|
150 |
+
<input checked type="checkbox" id="preferences" name="preferences" value="preferences"><label for="preferences"><?php echo _e( 'Preferences', 'lingotek-translation' ); ?></label>
|
151 |
</td>
|
152 |
</tr>
|
153 |
<tr>
|
154 |
+
<th><?php echo _e( 'New Project', 'lingotek-translation' ); ?></th>
|
155 |
<td>
|
156 |
+
<input checked type="checkbox" name="new_project" id="new_project" ><label for="new_project"><?php echo _e( 'Create a new project using the name of the selected site (Recommended for a newly created site)', 'lingotek-translation' ); ?></label>
|
157 |
</td>
|
158 |
</tr>
|
159 |
<tr>
|
160 |
+
<th><?php echo _e( 'Language', 'lingotek-translation' ); ?></th>
|
161 |
<td>
|
162 |
+
<input checked type="checkbox" name="utility_set_default_language" id="utility_set_default_language" ><label for="utility_set_default_language"><?php echo _e( 'Set <i>default language</i> as the language for all existing content that has not been assigned a language.', 'lingotek-translation' ); ?></label>
|
163 |
</td>
|
164 |
</tr>
|
165 |
</table>
|
166 |
|
167 |
<p>
|
168 |
+
<?php submit_button( __( 'Update Options', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
169 |
</p>
|
170 |
|
171 |
</form>
|
172 |
+
</div>
|
admin/view-tutorial.php
CHANGED
@@ -1,49 +1,54 @@
|
|
1 |
<?php
|
2 |
|
3 |
$menu_items = array(
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
);
|
9 |
|
10 |
-
?>
|
11 |
|
12 |
|
13 |
<div class="wrap about-wrap">
|
14 |
|
15 |
-
<h1><?php printf( __( 'Welcome to Lingotek'
|
16 |
|
17 |
-
<div class="about-text"><?php printf( __( 'Thank you for updating! Lingotek offers convenient cloud-based localization and translation.'
|
18 |
|
19 |
|
20 |
-
<div class="wp-badge" style="background: url(<?php echo LINGOTEK_URL ?>/img/lingotek-chevrons-blue.png) center 24px/85px 80px no-repeat #fff; color: #666;"><?php printf( __( 'Version %s'
|
21 |
|
22 |
<h2 class="nav-tab-wrapper">
|
23 |
<?php
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
35 |
</h2>
|
36 |
|
37 |
|
38 |
<?php
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
47 |
?>
|
48 |
|
49 |
</div>
|
1 |
<?php
|
2 |
|
3 |
$menu_items = array(
|
4 |
+
'features' => __( 'Features', 'lingotek-translation' ),
|
5 |
+
'content' => __( 'Tutorial', 'lingotek-translation' ),
|
6 |
+
'faq' => __( 'FAQ', 'lingotek-translation' ),
|
7 |
+
'credits' => __( 'Credits', 'lingotek-translation' ),
|
8 |
);
|
9 |
|
10 |
+
?>
|
11 |
|
12 |
|
13 |
<div class="wrap about-wrap">
|
14 |
|
15 |
+
<h1><?php printf( __( 'Welcome to Lingotek', 'lingotek-translation' ) ); ?></h1>
|
16 |
|
17 |
+
<div class="about-text"><?php printf( __( 'Thank you for updating! Lingotek offers convenient cloud-based localization and translation.', 'lingotek-translation' ), LINGOTEK_VERSION ); ?></div>
|
18 |
|
19 |
|
20 |
+
<div class="wp-badge" style="background: url(<?php echo LINGOTEK_URL; ?>/img/lingotek-chevrons-blue.png) center 24px/85px 80px no-repeat #fff; color: #666;"><?php printf( __( 'Version %s', 'lingotek-translation' ), LINGOTEK_VERSION ); ?></div>
|
21 |
|
22 |
<h2 class="nav-tab-wrapper">
|
23 |
<?php
|
24 |
+
$menu_item_index = 0;
|
25 |
+
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
26 |
+
$use_as_default = ( $menu_item_index === 0 && ! isset( $_GET['sm'] ) ) ? true : false;
|
27 |
+
?>
|
28 |
+
|
29 |
+
<a class="nav-tab
|
30 |
+
<?php
|
31 |
+
if ( $use_as_default || ( isset( $_GET['sm'] ) && $_GET['sm'] == $menu_item_key ) ) :
|
32 |
+
?>
|
33 |
+
nav-tab-active<?php endif; ?>"
|
34 |
+
href="admin.php?page=<?php echo $_GET['page']; ?>&sm=<?php echo $menu_item_key; ?>"><?php echo $menu_item_label; ?></a>
|
35 |
+
<?php
|
36 |
+
$menu_item_index++;
|
37 |
+
}
|
38 |
+
?>
|
39 |
</h2>
|
40 |
|
41 |
|
42 |
<?php
|
43 |
+
settings_errors();
|
44 |
+
$submenu = isset( $_GET['sm'] ) ? sanitize_text_field( $_GET['sm'] ) : current( array_keys( $menu_items ) );
|
45 |
+
$dir = dirname( __FILE__ ) . '/tutorial/';
|
46 |
+
$filename = $dir . $submenu . '.php';
|
47 |
+
if ( file_exists( $filename ) ) {
|
48 |
+
require $filename;
|
49 |
+
} else {
|
50 |
+
echo 'TO-DO: create <i>' . 'tutorial/' . $submenu . '.php</i>';
|
51 |
+
}
|
52 |
?>
|
53 |
|
54 |
</div>
|
admin/workflows/credit-card-to-path.php
CHANGED
@@ -2,47 +2,47 @@
|
|
2 |
|
3 |
class Lingotek_Credit_Card_To_Path {
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
'AmericanExpress' => LINGOTEK_URL .
|
35 |
-
'Discover'
|
36 |
-
'JCB'
|
37 |
-
'DinersClub'
|
38 |
-
'Visa'
|
39 |
-
$this->default_cc => LINGOTEK_URL .
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
}
|
2 |
|
3 |
class Lingotek_Credit_Card_To_Path {
|
4 |
|
5 |
+
private $cc_type_map = array();
|
6 |
+
private $default_cc = 'Default';
|
7 |
+
private static $instance = null;
|
8 |
+
|
9 |
+
|
10 |
+
public static function get_url( $cc_type ) {
|
11 |
+
self::check_instantiated();
|
12 |
+
return self::$instance->get_cc_type_asset_url( $cc_type );
|
13 |
+
}
|
14 |
+
|
15 |
+
public static function get_cc_map() {
|
16 |
+
self::check_instantiated();
|
17 |
+
return self::$instance->cc_type_map;
|
18 |
+
}
|
19 |
+
|
20 |
+
public static function get_cc_type_asset_url( $cc_type ) {
|
21 |
+
self::check_instantiated();
|
22 |
+
return isset( self::$instance->cc_type_map[ $cc_type ] ) ? self::$instance->cc_type_map[ $cc_type ] : self::$instance->cc_type_map[ self::$instance->default_cc ];
|
23 |
+
}
|
24 |
+
|
25 |
+
public static function get_default_cc_key() {
|
26 |
+
self::check_instantiated();
|
27 |
+
return self::$instance->default_cc;
|
28 |
+
}
|
29 |
+
|
30 |
+
|
31 |
+
private function __construct() {
|
32 |
+
$this->cc_type_map = array(
|
33 |
+
'MasterCard' => LINGOTEK_URL . '/img/credit-cards/mastercard.svg',
|
34 |
+
'AmericanExpress' => LINGOTEK_URL . '/img/credit-cards/amex.svg',
|
35 |
+
'Discover' => LINGOTEK_URL . '/img/credit-cards/discover.svg',
|
36 |
+
'JCB' => LINGOTEK_URL . '/img/credit-cards/jcb.svg',
|
37 |
+
'DinersClub' => LINGOTEK_URL . '/img/credit-cards/diners.svg',
|
38 |
+
'Visa' => LINGOTEK_URL . '/img/credit-cards/visa.svg',
|
39 |
+
$this->default_cc => LINGOTEK_URL . '/img/credit-cards/default.svg',
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
private static function check_instantiated() {
|
44 |
+
if ( ! self::$instance ) {
|
45 |
+
self::$instance = new Lingotek_Credit_Card_To_Path();
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
admin/workflows/professional-translation-workflow.php
CHANGED
@@ -1,8 +1,7 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* Overrides uploads for Posts, Pages and Terms in order to display a modal and handle redirecting to bridge for payment.
|
5 |
-
*
|
6 |
*/
|
7 |
class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
8 |
|
@@ -12,71 +11,70 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
12 |
/**
|
13 |
* Writes a modal to the output buffer that contains information about this workflow.
|
14 |
*
|
15 |
-
* @param string $
|
|
|
16 |
*/
|
17 |
-
public function
|
18 |
-
if (
|
19 |
if ( ! self::$info_modal_launched ) {
|
20 |
self::$info_modal_launched = true;
|
21 |
-
|
22 |
-
wp_enqueue_script( 'lingotek_professional_workflow_defaults', LINGOTEK_URL . '/js/workflow/professional-workflow-defaults.js' );
|
23 |
|
24 |
$client = new Lingotek_API();
|
25 |
|
26 |
$payment_info = $client->get_user_payment_information();
|
27 |
|
28 |
$vars = array(
|
29 |
-
'workflow_id'
|
30 |
-
'bridge_payment'
|
31 |
'translation_icon' => LINGOTEK_URL . '/img/translation-logo.png',
|
32 |
-
'loading_gif'
|
33 |
-
'icon_url'
|
34 |
-
'payment_info'
|
35 |
);
|
36 |
wp_localize_script( 'lingotek_professional_workflow_defaults', 'professional_vars', $vars );
|
37 |
|
38 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
39 |
$args = array(
|
40 |
'parent_elements' => $this->get_payment_portal_html(),
|
41 |
-
'body'
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
</
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
</div>
|
61 |
-
|
62 |
-
", 'lingotek-translation' ),
|
63 |
-
'id' => $this->workflow_id,
|
64 |
);
|
65 |
$this->_echo_modal( $args );
|
66 |
-
}
|
67 |
-
}
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
72 |
*
|
73 |
-
* @param string $
|
|
|
|
|
74 |
*/
|
75 |
public function echo_posts_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
76 |
-
$this->add_item_id($item_id, $wp_locale);
|
77 |
-
if (
|
78 |
if ( ! self::$post_modal_launched ) {
|
79 |
-
self::$post_modal_launched = true;
|
80 |
$this->echo_upload_warning_modal();
|
81 |
$this->echo_request_modal( 'post' );
|
82 |
}
|
@@ -88,12 +86,13 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
88 |
/**
|
89 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
90 |
*
|
91 |
-
* @param string $
|
|
|
|
|
92 |
*/
|
93 |
public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
94 |
-
$this->add_item_id($item_id, $wp_locale);
|
95 |
-
if (
|
96 |
-
{
|
97 |
if ( ! self::$terms_modal_launched ) {
|
98 |
self::$terms_modal_launched = true;
|
99 |
$this->echo_upload_warning_modal();
|
@@ -106,12 +105,13 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
106 |
/**
|
107 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
108 |
*
|
109 |
-
* @param string $
|
|
|
|
|
110 |
*/
|
111 |
public function echo_strings_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
112 |
-
$this->add_item_id($item_id, $wp_locale);
|
113 |
-
if (
|
114 |
-
{
|
115 |
if ( ! self::$strings_modal_launched ) {
|
116 |
self::$strings_modal_launched = true;
|
117 |
$this->echo_upload_warning_modal();
|
@@ -123,56 +123,54 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
123 |
|
124 |
/**
|
125 |
* Writes a modal to the output buffer that tells the user if certain translations will
|
126 |
-
*
|
127 |
-
*
|
128 |
-
* @param string $id the workflow id.
|
129 |
*/
|
130 |
private function echo_upload_warning_modal() {
|
131 |
-
$id
|
132 |
$args = array(
|
133 |
'header' => __( 'Confirm Document Upload', 'lingotek-translation' ),
|
134 |
-
'body'
|
|
|
135 |
<div id='warning-wrapper'>
|
136 |
<div class='professional-upload-warning-header-container'>
|
137 |
<span class='professional-upload-warning-header'>By uploading these changes, your professional translations may be lost.</span>
|
138 |
</div>
|
139 |
-
|
140 |
<div class='professional-upload-warning-body-container'>
|
141 |
<span class='professional-upload-warning-body'>
|
142 |
By editing this document and then re-uploading it to Lingotek any professional translations that you have not downloaded yet will be lost. Additionally, any professional translations that are in-progress for this document will be lost.
|
143 |
</span>
|
144 |
</div>
|
145 |
-
|
146 |
<div class='professional-warning-checkbox-container'><input id='professional-warning-checkbox' type='checkbox' name='confirm-request' value='professional-warning-upload></div>
|
147 |
<div class='professional-warning-checkbox-text-container'><span class='professional-warning-checkbox-text'> I understand that translations that have not been downloaded or that are in progress will be lost and money paid for that translation will be forfeited by re-uploading them to Lingotek.</span></div>
|
148 |
|
149 |
<button type='button' id='cancel-warning-" . esc_attr( $id ) . "' class='professional-cancel-button float-bottom-right-next-to'>
|
150 |
<span class='ADD-PAYMENT-LATER'>CANCEL</span>
|
151 |
</button>
|
152 |
-
<div class='float-bottom-right' style='bottom:5%;'><img id='professional-warning-loading-spinner' style='display:none;' src='". esc_url_raw( LINGOTEK_URL )
|
153 |
<button type='button' id='ok-warning-" . esc_attr( $id ) . "' class='professional-okay-warning-button-disabled float-bottom-right' disabled='true'>
|
154 |
<span id='professional-warning-okay-text' class='ADD-PAYMENT-DISABLED'>PROCEED</span>
|
155 |
</button>
|
156 |
|
157 |
-
</div>",
|
158 |
-
'id'
|
159 |
);
|
160 |
$this->_echo_modal( $args );
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
-
*
|
165 |
-
*
|
166 |
*
|
167 |
-
*
|
168 |
*/
|
169 |
public function echo_request_modal( $type ) {
|
170 |
-
if (
|
171 |
-
{
|
172 |
$this->load_request_scripts_and_styles( $type );
|
173 |
-
$id
|
174 |
$args = array(
|
175 |
-
'header'
|
176 |
'parent_elements' => "
|
177 |
<img class='loading-element loading-translations-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
178 |
<div class='loading-element loading-progress-bar-outer'>
|
@@ -181,167 +179,148 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
181 |
<span class='loading-element loading-progress-percent'>65%</span>
|
182 |
<div class='loading-element Analyzing-translations'>Analyzing translations and gathering quotes...</div>
|
183 |
",
|
184 |
-
'body'
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
<span class='Congratulations-You payment-not-setup'>Welcome to Lingotek's Translation Quote Calculator<br><br></span>
|
194 |
-
<div class='You-can-now-connect payment-not-setup'>
|
195 |
-
Using the quote calculator below you can get an idea of how much your translations will cost. You will need to add a payment method to the Lingotek Secure Payment Portal In order to purchase these translations.
|
196 |
-
</div>
|
197 |
-
<br>
|
198 |
-
<div class='minimum-per-language-warning minimum-warning'>
|
199 |
-
<img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-warning.svg' />
|
200 |
-
<span >*$59.99 minimum per language.</span>
|
201 |
-
<span ltk-data-tooltip='This minimum ensures that we can retain the best professional linguists for your translation job.'><img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-help.svg' /></span>
|
202 |
-
</div>
|
203 |
-
<br class='payment-not-setup'>
|
204 |
-
<span class='Translation-Request payment-not-setup'>Translation Quotes<br><br></span>
|
205 |
-
<br class='payment-method-setup'>
|
206 |
-
<span class='Translation-Request payment-method-setup'>Translation Request Summary<br><br></span>
|
207 |
-
<div id='table-wrapper'>
|
208 |
-
<table class='request-table'>
|
209 |
-
<tr class='bordered-bottom'><th style='display: table-cell;' class='table-header'>Title</th><th style='display: table-cell;' class='table-header' id='words-column'>Words</th><th style='text-align:center;'><a href='#' id='next-language-set'> <img id='next-language-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/right-arrow.svg' /> </a> </th><th class='table-header table-total invisible'>Total</th></tr>
|
210 |
-
</table>
|
211 |
-
</div>
|
212 |
-
</div>
|
213 |
-
<div id='professional-terms-and-conditions'>
|
214 |
-
<span class='terms-and-conditions-header'>Lingotek Terms and Conditions</span><br><br>
|
215 |
-
<div class='terms-and-conditions-content'>
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
<img id='terms-of-service-loading-ltk' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading.gif'/>
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
</div>
|
237 |
-
<button type='button' id='close-terms-and-conditions'>
|
238 |
-
<span class='CLOSE-TERMS-CONDITIONS'>CLOSE</span>
|
239 |
-
</button>
|
240 |
</div>
|
241 |
-
|
242 |
-
|
243 |
-
<
|
244 |
-
|
245 |
-
<div class='payment-method-setup professional-card-border'>
|
246 |
-
<div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/blue-radio-button.svg'/></div>
|
247 |
-
<div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/credit-dots.svg'/></div>
|
248 |
-
<div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'>XXXX</span></div>
|
249 |
-
<div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src='" . Lingotek_Credit_Card_To_Path::get_cc_type_asset_url( Lingotek_Credit_Card_To_Path::get_default_cc_key() ) . "'/></div>
|
250 |
</div>
|
251 |
-
<br class='payment-method-setup'>
|
252 |
-
<br class='payment-method-setup'>
|
253 |
-
|
254 |
-
|
255 |
-
<span class='Payment-Method payment-not-setup'>Benefits of Professional Translation</span><br class='payment-not-setup'>
|
256 |
-
<ul class='translation-summary-list payment-not-setup'>
|
257 |
-
<li><span class='translation-summary-list-text'>Translations will be translated by professional in-country linguists.</span></li>
|
258 |
-
<li><span class='translation-summary-list-text'>Receive your translations in just a few days.</span></li>
|
259 |
-
<li><span class='translation-summary-list-text'>100% customer satisfaction guarantee.</span></li>
|
260 |
-
</ul>
|
261 |
-
<br class='payment-not-setup'>
|
262 |
-
<span class='Translation-Request-Right payment-method-setup'>Translation Request Summary</span>
|
263 |
-
<span class='Translation-Request-Right payment-not-setup'>Translation Quote Summary</span>
|
264 |
-
<ul class='translation-summary-list translation-summary-list-ltk'>
|
265 |
-
|
266 |
-
</ul>
|
267 |
-
<div class='minimum-disclaimer'>*Minimum charge $59.99 per language</div>
|
268 |
<br>
|
269 |
-
<div
|
270 |
-
<
|
|
|
|
|
271 |
</div>
|
272 |
-
|
273 |
-
<
|
274 |
-
|
|
|
|
|
|
|
|
|
|
|
275 |
</div>
|
276 |
-
|
277 |
-
|
278 |
-
<
|
279 |
-
<div class='
|
280 |
-
|
281 |
-
Please note that none of the selections you have made in the table will be saved.
|
282 |
</div>
|
283 |
-
<
|
284 |
-
|
285 |
-
<div class='delivery-estimation'>Estimated delivery: <span class='business-days'>3 - 5 business days.</span><span ltk-data-tooltip='This is an estimate, not a guaranteed delivery time.'><img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-help.svg' /></span></div>
|
286 |
-
<div class='request-checkbox payment-method-setup'><input id='accept-terms-and-conditions-input' type='checkbox' name='confirm-request' value='request-translation><span class='terms-conditions'> I agree to the <a id='terms-and-conditions-href' href='#'>Lingotek Terms and Conditions</a></span></div>
|
287 |
-
<br class='payment-method-setup'>
|
288 |
-
|
289 |
-
<button type='button' id='yes-" . esc_attr( $id ) . "-add-payment' class='professional-action-button float-center payment-not-setup' style='float:left'>
|
290 |
-
<span id='professional-add-payment' class='ADD-PAYMENT payment-not-setup'>ADD PAYMENT METHOD</span>
|
291 |
-
</button>
|
292 |
-
<button type='button' id='yes-" . esc_attr( $id ) . "-buy-now' class='professional-action-button-disabled float-center payment-method-setup' style='float:left; bottom:-2%;' disabled='true'>
|
293 |
-
<span id='professional-buy-now' class='ADD-PAYMENT-DISABLED payment-method-setup'>BUY NOW</span>
|
294 |
</button>
|
295 |
</div>
|
296 |
-
<div id='cleared'></div>
|
297 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
<div id='requesting-translation-success-screen' class='professional-translation-request-success-element'>
|
307 |
-
<img class='professional-translation-request-success-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
|
308 |
-
<img class='professional-translation-request-success-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/checkmark-green.svg'/>
|
309 |
-
<div class='professional-translation-request-success-element professional-translation-view-invoice' style='height: 28px;'>Your translations have been successfully requested.</div>
|
310 |
-
<div class='professional-translation-request-success-element professional-translation-view-invoice'>You will be receiving a confirmation email shortly.</div>
|
311 |
-
<div class='professional-translation-request-success-element professional-translation-view-invoice'>Your credit card will be charged <span id='professional-translation-cost-success' class='professional-translation-request-success-element'></span></div>
|
312 |
-
<button type='button' id='professional-post-transaction-button' class='professional-translation-request-success-element professional-view-invoice-btn float-center'>
|
313 |
-
<span id='professional-post-transaction' class='ADD-PAYMENT professional-translation-request-success-element'>OK</span>
|
314 |
</button>
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
<div id='requesting-translation-error-screen' class='professional-translation-request-error-element'>
|
320 |
-
<img class='professional-translation-request-error-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
|
321 |
-
<img class='professional-translation-request-error-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/error.svg'/>
|
322 |
-
<div id='error-requesting-translation-ltk' class='professional-translation-request-error-element professional-translation-view-invoice'>There was an error requesting your translation.</div>
|
323 |
-
<div id='error-requesting-translation-ltk-2' class='professional-translation-request-error-element professional-translation-view-invoice'>Please refresh the page and try again.</div>
|
324 |
-
<button type='button' id='professional-post-transaction-button' class='professional-translation-request-error-element professional-view-invoice-btn float-center'>
|
325 |
-
<span id='professional-post-transaction-failure' class='ADD-PAYMENT professional-translation-request-error-element'>Ok</span>
|
326 |
</button>
|
327 |
</div>
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
);
|
335 |
$this->_echo_modal( $args );
|
336 |
-
}
|
337 |
}
|
338 |
|
339 |
/**
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
public static function is_allowed_user()
|
344 |
-
{
|
345 |
return true;
|
346 |
}
|
347 |
|
@@ -354,17 +333,19 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
354 |
private static $pre_uploaded = array();
|
355 |
|
356 |
/**
|
357 |
-
* We disassociate the document before uploading to avoid automatic requesting of translations.
|
358 |
*
|
359 |
-
* @param string $item_id
|
360 |
* @param string $type
|
361 |
* @return void
|
362 |
*/
|
363 |
-
public function pre_upload_to_lingotek($item_id, $type) {
|
364 |
-
$lgtm
|
365 |
-
|
366 |
-
|
367 |
-
self::$pre_uploaded[$document->document_id]
|
|
|
|
|
368 |
$document->delete();
|
369 |
}
|
370 |
}
|
@@ -379,11 +360,11 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
379 |
* @return void
|
380 |
*/
|
381 |
public function save_post_hook() {
|
382 |
-
if (! self::$save_post_hook_executed) {
|
383 |
self::$save_post_hook_executed = true;
|
384 |
-
$post_vars
|
385 |
-
|
386 |
-
if ('inline-save' === $post_vars['action']) {
|
387 |
echo '<script>location.reload();</script>';
|
388 |
}
|
389 |
}
|
@@ -398,11 +379,11 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
398 |
* @return void
|
399 |
*/
|
400 |
public function save_term_hook() {
|
401 |
-
if (! self::$save_terms_hook_executed) {
|
402 |
self::$save_terms_hook_executed = true;
|
403 |
-
$post_vars
|
404 |
-
|
405 |
-
if ('inline-save-tax' === $post_vars['action']) {
|
406 |
echo '<script>location.reload();</script>';
|
407 |
}
|
408 |
}
|
@@ -413,19 +394,22 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
413 |
*
|
414 |
* @return boolean
|
415 |
*/
|
416 |
-
public function has_custom_request_procedure() {
|
|
|
417 |
|
418 |
/**
|
419 |
* We don't want documents being uploaded automatically because of the chance
|
420 |
* that a user may lose translations that they have paid for if they haven't finished or downloaded.
|
421 |
*
|
422 |
-
* @return
|
423 |
*/
|
424 |
-
public function auto_upload_allowed() {
|
|
|
|
|
425 |
|
426 |
|
427 |
-
public function get_custom_in_progress_icon() {
|
428 |
-
return '<div title="Professional translation in progress" class="lingotek-professional-icon"><img src="'. LINGOTEK_URL .
|
429 |
}
|
430 |
|
431 |
/**
|
@@ -434,68 +418,64 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
434 |
* @param string $type
|
435 |
* @return void
|
436 |
*/
|
437 |
-
private function load_request_scripts_and_styles($type)
|
438 |
-
{
|
439 |
add_thickbox();
|
440 |
-
wp_enqueue_script( 'lingotek_professional_workflow', LINGOTEK_URL . '/js/workflow/professional-workflow.js', array(), LINGOTEK_VERSION );
|
441 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
442 |
|
443 |
$client = new Lingotek_API();
|
444 |
|
445 |
$language_mappings = $client->get_language_mappings();
|
446 |
-
$locales_list
|
447 |
|
448 |
$enabled_langs = array();
|
449 |
-
foreach ($locales_list as $locale)
|
450 |
-
|
451 |
-
$
|
452 |
-
$enabled_langs[$locale->locale] = array(
|
453 |
'lingotek_locale' => $locale->lingotek_locale,
|
454 |
-
'language'
|
455 |
-
? $language_mappings[$lingotek_gmc_locale]['language_name']
|
456 |
: null,
|
457 |
-
'country_name'
|
458 |
-
? $language_mappings[$lingotek_gmc_locale]['country_name']
|
459 |
: null,
|
460 |
);
|
461 |
}
|
462 |
-
|
463 |
$vars = array(
|
464 |
-
'workflow_id'
|
465 |
-
'icon_url'
|
466 |
-
'question_mark_icon_url'
|
467 |
'bridge_payment_redirect' => BRIDGE_URL . '/#/payment/portal',
|
468 |
-
'enabled_langs'
|
469 |
-
'curr_item_type'
|
470 |
-
'cc_type_map'
|
471 |
-
'default_cc_type'
|
472 |
-
'nonce'
|
473 |
);
|
474 |
wp_localize_script( 'lingotek_professional_workflow', 'workflow_vars', $vars );
|
475 |
}
|
476 |
|
477 |
|
478 |
/**
|
479 |
-
* As the table is being built (for posts, pages, terms, etc.) we only want to attach listeners to locales that have the professional
|
480 |
* workflow enabled. This list is build as the table is being rendered.
|
481 |
*
|
482 |
* @param string $item_id
|
483 |
* @param string $wp_locale
|
484 |
* @return void
|
485 |
*/
|
486 |
-
|
487 |
private function add_item_id( $item_id, $wp_locale ) {
|
488 |
-
self::$item_id_list[$item_id][] = $wp_locale;
|
489 |
}
|
490 |
|
491 |
/**
|
492 |
-
* Because a new workflow object is created every time a new locale is rendered on the table we can't preserve the list in a single object.
|
493 |
* Instead, we store that list statically and update the list that will eventually be sent to the front end everytime a workflow object is destroyed.
|
494 |
*
|
495 |
* @return void
|
496 |
*/
|
497 |
-
private function flush_list()
|
498 |
-
{
|
499 |
$vars = array(
|
500 |
'ids' => self::$item_id_list,
|
501 |
);
|
@@ -505,14 +485,13 @@ class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
|
505 |
/**
|
506 |
* Returns the HTML that displays the payment portal loading screen.
|
507 |
*
|
508 |
-
* @return
|
509 |
*/
|
510 |
-
private function get_payment_portal_html()
|
511 |
-
{
|
512 |
return "
|
513 |
<div id='payment-portal-wrapper' class='payment-portal-element'>
|
514 |
-
<img class='payment-portal-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL )
|
515 |
-
<img class='payment-portal-element payment-portal-loading' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading.gif'/>
|
516 |
<span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
|
517 |
</div>
|
518 |
";
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Overrides uploads for Posts, Pages and Terms in order to display a modal and handle redirecting to bridge for payment.
|
4 |
+
* The base class contains better documentation on what each individual function means.
|
5 |
*/
|
6 |
class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
7 |
|
11 |
/**
|
12 |
* Writes a modal to the output buffer that contains information about this workflow.
|
13 |
*
|
14 |
+
* @param string $item_id The workflow id.
|
15 |
+
* @param string $item_type
|
16 |
*/
|
17 |
+
public function lingotek_translation_professional_translation_info_modal( $item_id = null, $item_type = null ) {
|
18 |
+
if ( self::is_allowed_user() ) {
|
19 |
if ( ! self::$info_modal_launched ) {
|
20 |
self::$info_modal_launched = true;
|
21 |
+
|
22 |
+
wp_enqueue_script( 'lingotek_professional_workflow_defaults', LINGOTEK_URL . '/js/workflow/professional-workflow-defaults.js', array(), LINGOTEK_VERSION, false );
|
23 |
|
24 |
$client = new Lingotek_API();
|
25 |
|
26 |
$payment_info = $client->get_user_payment_information();
|
27 |
|
28 |
$vars = array(
|
29 |
+
'workflow_id' => $this->workflow_id,
|
30 |
+
'bridge_payment' => BRIDGE_URL . '/#/payment/portal',
|
31 |
'translation_icon' => LINGOTEK_URL . '/img/translation-logo.png',
|
32 |
+
'loading_gif' => LINGOTEK_URL . '/img/loading.gif',
|
33 |
+
'icon_url' => LINGOTEK_URL . '/img/lingotek-logo-white.png',
|
34 |
+
'payment_info' => $payment_info,
|
35 |
);
|
36 |
wp_localize_script( 'lingotek_professional_workflow_defaults', 'professional_vars', $vars );
|
37 |
|
38 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
39 |
$args = array(
|
40 |
'parent_elements' => $this->get_payment_portal_html(),
|
41 |
+
'body' =>
|
42 |
+
"
|
43 |
+
<div class='Youve-Selected-Prof'>You've Selected Professional Translation</div><br>
|
44 |
+
<div class='By-Selecting-this-op'>
|
45 |
+
By selecting this option as your workflow you will be able to request professional translations through Lingotek’s Languages Services.
|
46 |
+
Please click the \"ADD PAYMENT METHOD\" button to use this service.
|
47 |
+
</div><br><br><br>
|
48 |
+
<div class='Note-By-using-the-'>
|
49 |
+
Note: By using the 'Lingotek Professional Translation' workflow you will be asked to confirm payment before the professional translation request is processed.
|
50 |
+
</div>
|
51 |
+
<button type='button' id='no-" . esc_attr( $this->workflow_id ) . "' class='background-test float-bottom-right-next-to-default'>
|
52 |
+
<span class='ADD-PAYMENT-LATER'>LATER</span>
|
53 |
+
</button>
|
54 |
+
<button type='button' id='yes-" . esc_attr( $this->workflow_id ) . "' class='prefessional-action-button-default float-bottom-right'>
|
55 |
+
<span class='ADD-PAYMENT'>ADD PAYMENT METHOD</span>
|
56 |
+
</button>
|
57 |
+
</div>
|
58 |
+
",
|
59 |
+
'id' => $this->workflow_id,
|
|
|
|
|
|
|
|
|
60 |
);
|
61 |
$this->_echo_modal( $args );
|
62 |
+
}//end if
|
63 |
+
}//end if
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
68 |
*
|
69 |
+
* @param string $item_id The workflow id.
|
70 |
+
* @param string $wp_locale
|
71 |
+
* @param string $item_type
|
72 |
*/
|
73 |
public function echo_posts_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
74 |
+
$this->add_item_id( $item_id, $wp_locale );
|
75 |
+
if ( self::is_allowed_user() ) {
|
76 |
if ( ! self::$post_modal_launched ) {
|
77 |
+
self::$post_modal_launched = true;
|
78 |
$this->echo_upload_warning_modal();
|
79 |
$this->echo_request_modal( 'post' );
|
80 |
}
|
86 |
/**
|
87 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
88 |
*
|
89 |
+
* @param string $item_id The workflow id.
|
90 |
+
* @param string $wp_locale
|
91 |
+
* @param string $item_type
|
92 |
*/
|
93 |
public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
94 |
+
$this->add_item_id( $item_id, $wp_locale );
|
95 |
+
if ( self::is_allowed_user() ) {
|
|
|
96 |
if ( ! self::$terms_modal_launched ) {
|
97 |
self::$terms_modal_launched = true;
|
98 |
$this->echo_upload_warning_modal();
|
105 |
/**
|
106 |
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
107 |
*
|
108 |
+
* @param string $item_id The workflow id.
|
109 |
+
* @param string $wp_locale
|
110 |
+
* @param string $item_type
|
111 |
*/
|
112 |
public function echo_strings_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
|
113 |
+
$this->add_item_id( $item_id, $wp_locale );
|
114 |
+
if ( self::is_allowed_user() ) {
|
|
|
115 |
if ( ! self::$strings_modal_launched ) {
|
116 |
self::$strings_modal_launched = true;
|
117 |
$this->echo_upload_warning_modal();
|
123 |
|
124 |
/**
|
125 |
* Writes a modal to the output buffer that tells the user if certain translations will
|
126 |
+
* be overwritten by a given action.
|
|
|
|
|
127 |
*/
|
128 |
private function echo_upload_warning_modal() {
|
129 |
+
$id = $this->workflow_id . '-warning';
|
130 |
$args = array(
|
131 |
'header' => __( 'Confirm Document Upload', 'lingotek-translation' ),
|
132 |
+
'body' =>
|
133 |
+
"
|
134 |
<div id='warning-wrapper'>
|
135 |
<div class='professional-upload-warning-header-container'>
|
136 |
<span class='professional-upload-warning-header'>By uploading these changes, your professional translations may be lost.</span>
|
137 |
</div>
|
138 |
+
|
139 |
<div class='professional-upload-warning-body-container'>
|
140 |
<span class='professional-upload-warning-body'>
|
141 |
By editing this document and then re-uploading it to Lingotek any professional translations that you have not downloaded yet will be lost. Additionally, any professional translations that are in-progress for this document will be lost.
|
142 |
</span>
|
143 |
</div>
|
144 |
+
|
145 |
<div class='professional-warning-checkbox-container'><input id='professional-warning-checkbox' type='checkbox' name='confirm-request' value='professional-warning-upload></div>
|
146 |
<div class='professional-warning-checkbox-text-container'><span class='professional-warning-checkbox-text'> I understand that translations that have not been downloaded or that are in progress will be lost and money paid for that translation will be forfeited by re-uploading them to Lingotek.</span></div>
|
147 |
|
148 |
<button type='button' id='cancel-warning-" . esc_attr( $id ) . "' class='professional-cancel-button float-bottom-right-next-to'>
|
149 |
<span class='ADD-PAYMENT-LATER'>CANCEL</span>
|
150 |
</button>
|
151 |
+
<div class='float-bottom-right' style='bottom:5%;'><img id='professional-warning-loading-spinner' style='display:none;' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/loading_mini.gif' /></div>
|
152 |
<button type='button' id='ok-warning-" . esc_attr( $id ) . "' class='professional-okay-warning-button-disabled float-bottom-right' disabled='true'>
|
153 |
<span id='professional-warning-okay-text' class='ADD-PAYMENT-DISABLED'>PROCEED</span>
|
154 |
</button>
|
155 |
|
156 |
+
</div>",
|
157 |
+
'id' => $id,
|
158 |
);
|
159 |
$this->_echo_modal( $args );
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
+
* Writes a modal to the output buffer that is launched when the user clicks on the 'request translation'
|
164 |
+
* option.
|
165 |
*
|
166 |
+
* @param string $type
|
167 |
*/
|
168 |
public function echo_request_modal( $type ) {
|
169 |
+
if ( self::is_allowed_user() ) {
|
|
|
170 |
$this->load_request_scripts_and_styles( $type );
|
171 |
+
$id = $this->workflow_id . '-request';
|
172 |
$args = array(
|
173 |
+
'header' => __( 'Confirm Request Translation', 'lingotek-translation' ),
|
174 |
'parent_elements' => "
|
175 |
<img class='loading-element loading-translations-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
176 |
<div class='loading-element loading-progress-bar-outer'>
|
179 |
<span class='loading-element loading-progress-percent'>65%</span>
|
180 |
<div class='loading-element Analyzing-translations'>Analyzing translations and gathering quotes...</div>
|
181 |
",
|
182 |
+
'body' =>
|
183 |
+
"
|
184 |
+
<div id='wrapper'>
|
185 |
+
<div id='content'><br>
|
186 |
+
<div id='professional-table-content'>
|
187 |
+
<span class='Congratulations-You payment-method-setup'>You have elected to use our Professional Translation Services.<br><br></span>
|
188 |
+
<div class='You-can-now-connect payment-method-setup'>
|
189 |
+
You can now connect with audiences around the globe using Lingotek's network of 5000+ professional, in-country, translators. Professional Translation ensures that your audiences will feel the sentiment of your content.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
</div>
|
191 |
+
|
192 |
+
<span class='Congratulations-You payment-not-setup'>Welcome to Lingotek's Translation Quote Calculator<br><br></span>
|
193 |
+
<div class='You-can-now-connect payment-not-setup'>
|
194 |
+
Using the quote calculator below you can get an idea of how much your translations will cost. You will need to add a payment method to the Lingotek Secure Payment Portal In order to purchase these translations.
|
|
|
|
|
|
|
|
|
|
|
195 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
<br>
|
197 |
+
<div class='minimum-per-language-warning minimum-warning'>
|
198 |
+
<img src='" . esc_url_raw( LINGOTEK_URL ) . "/img/minimum-warning.svg' />
|
199 |
+
<span >*$59.99 minimum per language.</span>
|
200 |
+
<span ltk-data-tooltip='This minimum ensures that we can retain the best professional linguists for your translation job.'><img src='" . esc_url_raw( LINGOTEK_URL ) . "/img/minimum-help.svg' /></span>
|
201 |
</div>
|
202 |
+
<br class='payment-not-setup'>
|
203 |
+
<span class='Translation-Request payment-not-setup'>Translation Quotes<br><br></span>
|
204 |
+
<br class='payment-method-setup'>
|
205 |
+
<span class='Translation-Request payment-method-setup'>Translation Request Summary<br><br></span>
|
206 |
+
<div id='table-wrapper'>
|
207 |
+
<table class='request-table'>
|
208 |
+
<tr class='bordered-bottom'><th style='display: table-cell;' class='table-header'>Title</th><th style='display: table-cell;' class='table-header' id='words-column'>Words</th><th style='text-align:center;'><a href='#' id='next-language-set'> <img id='next-language-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/right-arrow.svg' /> </a> </th><th class='table-header table-total invisible'>Total</th></tr>
|
209 |
+
</table>
|
210 |
</div>
|
211 |
+
</div>
|
212 |
+
<div id='professional-terms-and-conditions'>
|
213 |
+
<span class='terms-and-conditions-header'>Lingotek Terms and Conditions</span><br><br>
|
214 |
+
<div class='terms-and-conditions-content'>
|
215 |
+
<img id='terms-of-service-loading-ltk' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/loading.gif'/>
|
|
|
216 |
</div>
|
217 |
+
<button type='button' id='close-terms-and-conditions'>
|
218 |
+
<span class='CLOSE-TERMS-CONDITIONS'>CLOSE</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
</button>
|
220 |
</div>
|
|
|
221 |
</div>
|
222 |
+
<div id='sidebar'>
|
223 |
+
<span class='Payment-Method payment-method-setup'>Payment Method</span><br class='payment-method-setup'><br class='payment-method-setup'>
|
224 |
+
<span class='payment-method-setup credit-card-header'>Credit Card</span><br class='payment-method-setup'><br class='payment-method-setup'>
|
225 |
+
<div class='payment-method-setup professional-card-border'>
|
226 |
+
<div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/blue-radio-button.svg'/></div>
|
227 |
+
<div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/credit-dots.svg'/></div>
|
228 |
+
<div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'>XXXX</span></div>
|
229 |
+
<div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src='" . Lingotek_Credit_Card_To_Path::get_cc_type_asset_url( Lingotek_Credit_Card_To_Path::get_default_cc_key() ) . "'/></div>
|
230 |
+
</div>
|
231 |
+
<br class='payment-method-setup'>
|
232 |
+
<br class='payment-method-setup'>
|
233 |
+
|
234 |
+
|
235 |
+
<span class='Payment-Method payment-not-setup'>Benefits of Professional Translation</span><br class='payment-not-setup'>
|
236 |
+
<ul class='translation-summary-list payment-not-setup'>
|
237 |
+
<li><span class='translation-summary-list-text'>Translations will be translated by professional in-country linguists.</span></li>
|
238 |
+
<li><span class='translation-summary-list-text'>Receive your translations in just a few days.</span></li>
|
239 |
+
<li><span class='translation-summary-list-text'>100% customer satisfaction guarantee.</span></li>
|
240 |
+
</ul>
|
241 |
+
<br class='payment-not-setup'>
|
242 |
+
<span class='Translation-Request-Right payment-method-setup'>Translation Request Summary</span>
|
243 |
+
<span class='Translation-Request-Right payment-not-setup'>Translation Quote Summary</span>
|
244 |
+
<ul class='translation-summary-list translation-summary-list-ltk'>
|
245 |
+
|
246 |
+
</ul>
|
247 |
+
<div class='minimum-disclaimer'>*Minimum charge $59.99 per language</div>
|
248 |
+
<br>
|
249 |
+
<div style='float:right;'>
|
250 |
+
<span class='request-total'>TOTAL: </span><span class='lingotek-total-amount'></span>
|
251 |
+
</div>
|
252 |
|
253 |
+
<div class='ltk-request-payment-disclaimer payment-method-setup'>
|
254 |
+
Note: By clicking the 'Buy Now' button your translations will be requested and you will be charged for the amount shown above.
|
255 |
+
</div>
|
256 |
+
|
257 |
+
|
258 |
+
<br class='payment-not-setup'><br class='payment-not-setup'><br class='payment-not-setup'>
|
259 |
+
<div class='disclaimer-request payment-not-setup'>
|
260 |
+
Note: By clicking the 'Add Payment Method' button you will be redirected to the Lingotek Secure Payment Portal.
|
261 |
+
Please note that none of the selections you have made in the table will be saved.
|
262 |
+
</div>
|
263 |
+
<br class='payment-method-setup'><br class='payment-method-setup'>
|
264 |
|
265 |
+
<div class='delivery-estimation'>Estimated delivery: <span class='business-days'>3 - 5 business days.</span><span ltk-data-tooltip='This is an estimate, not a guaranteed delivery time.'><img src='" . esc_url_raw( LINGOTEK_URL ) . "/img/minimum-help.svg' /></span></div>
|
266 |
+
<div class='request-checkbox payment-method-setup'><input id='accept-terms-and-conditions-input' type='checkbox' name='confirm-request' value='request-translation><span class='terms-conditions'> I agree to the <a id='terms-and-conditions-href' href='#'>Lingotek Terms and Conditions</a></span></div>
|
267 |
+
<br class='payment-method-setup'>
|
268 |
+
|
269 |
+
<button type='button' id='yes-" . esc_attr( $id ) . "-add-payment' class='professional-action-button float-center payment-not-setup' style='float:left'>
|
270 |
+
<span id='professional-add-payment' class='ADD-PAYMENT payment-not-setup'>ADD PAYMENT METHOD</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
</button>
|
272 |
+
<button type='button' id='yes-" . esc_attr( $id ) . "-buy-now' class='professional-action-button-disabled float-center payment-method-setup' style='float:left; bottom:-2%;' disabled='true'>
|
273 |
+
<span id='professional-buy-now' class='ADD-PAYMENT-DISABLED payment-method-setup'>BUY NOW</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
</button>
|
275 |
</div>
|
276 |
+
<div id='cleared'></div>
|
277 |
+
</div>
|
278 |
+
|
279 |
+
|
280 |
+
<div id='requesting-translation-screen' class='requesting-element'>
|
281 |
+
<img class='requesting-element payment-portal-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
282 |
+
<img class='requesting-element payment-portal-loading' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/loading.gif'/>
|
283 |
+
<div class='requesting-element Analyzing-translations'>Requesting Translations</div>
|
284 |
+
</div>
|
285 |
+
|
286 |
+
<div id='requesting-translation-success-screen' class='professional-translation-request-success-element'>
|
287 |
+
<img class='professional-translation-request-success-element payment-portal-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
288 |
+
<img class='professional-translation-request-success-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/checkmark-green.svg'/>
|
289 |
+
<div class='professional-translation-request-success-element professional-translation-view-invoice' style='height: 28px;'>Your translations have been successfully requested.</div>
|
290 |
+
<div class='professional-translation-request-success-element professional-translation-view-invoice'>You will be receiving a confirmation email shortly.</div>
|
291 |
+
<div class='professional-translation-request-success-element professional-translation-view-invoice'>Your credit card will be charged <span id='professional-translation-cost-success' class='professional-translation-request-success-element'></span></div>
|
292 |
+
<button type='button' id='professional-post-transaction-button' class='professional-translation-request-success-element professional-view-invoice-btn float-center'>
|
293 |
+
<span id='professional-post-transaction' class='ADD-PAYMENT professional-translation-request-success-element'>OK</span>
|
294 |
+
</button>
|
295 |
+
</div>
|
296 |
+
|
297 |
+
|
298 |
+
|
299 |
+
<div id='requesting-translation-error-screen' class='professional-translation-request-error-element'>
|
300 |
+
<img class='professional-translation-request-error-element payment-portal-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
301 |
+
<img class='professional-translation-request-error-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/error.svg'/>
|
302 |
+
<div id='error-requesting-translation-ltk' class='professional-translation-request-error-element professional-translation-view-invoice'>There was an error requesting your translation.</div>
|
303 |
+
<div id='error-requesting-translation-ltk-2' class='professional-translation-request-error-element professional-translation-view-invoice'>Please refresh the page and try again.</div>
|
304 |
+
<button type='button' id='professional-post-transaction-button' class='professional-translation-request-error-element professional-view-invoice-btn float-center'>
|
305 |
+
<span id='professional-post-transaction-failure' class='ADD-PAYMENT professional-translation-request-error-element'>Ok</span>
|
306 |
+
</button>
|
307 |
+
</div>
|
308 |
+
|
309 |
+
</div>
|
310 |
+
" . $this->get_payment_portal_html() . '
|
311 |
+
|
312 |
+
',
|
313 |
+
'id' => $id,
|
314 |
);
|
315 |
$this->_echo_modal( $args );
|
316 |
+
}//end if
|
317 |
}
|
318 |
|
319 |
/**
|
320 |
+
* This method will be used to roll out the Professional Translation workflow to a select number of users.
|
321 |
+
* The method will be called before anything is sent to the client.
|
322 |
+
*/
|
323 |
+
public static function is_allowed_user() {
|
|
|
324 |
return true;
|
325 |
}
|
326 |
|
333 |
private static $pre_uploaded = array();
|
334 |
|
335 |
/**
|
336 |
+
* We disassociate the document before uploading to avoid automatic requesting of translations.
|
337 |
*
|
338 |
+
* @param string $item_id The workflow id.
|
339 |
* @param string $type
|
340 |
* @return void
|
341 |
*/
|
342 |
+
public function pre_upload_to_lingotek( $item_id, $type ) {
|
343 |
+
$lgtm = new Lingotek_Model();
|
344 |
+
$document = $lgtm->get_group( $type, $item_id );
|
345 |
+
if ( $document ) {
|
346 |
+
if ( isset( self::$pre_uploaded[ $document->document_id ] ) ) {
|
347 |
+
return; }
|
348 |
+
self::$pre_uploaded[ $document->document_id ] = true;
|
349 |
$document->delete();
|
350 |
}
|
351 |
}
|
360 |
* @return void
|
361 |
*/
|
362 |
public function save_post_hook() {
|
363 |
+
if ( ! self::$save_post_hook_executed ) {
|
364 |
self::$save_post_hook_executed = true;
|
365 |
+
$post_vars = filter_input_array( INPUT_POST );
|
366 |
+
|
367 |
+
if ( 'inline-save' === $post_vars['action'] ) {
|
368 |
echo '<script>location.reload();</script>';
|
369 |
}
|
370 |
}
|
379 |
* @return void
|
380 |
*/
|
381 |
public function save_term_hook() {
|
382 |
+
if ( ! self::$save_terms_hook_executed ) {
|
383 |
self::$save_terms_hook_executed = true;
|
384 |
+
$post_vars = filter_input_array( INPUT_POST );
|
385 |
+
|
386 |
+
if ( 'inline-save-tax' === $post_vars['action'] ) {
|
387 |
echo '<script>location.reload();</script>';
|
388 |
}
|
389 |
}
|
394 |
*
|
395 |
* @return boolean
|
396 |
*/
|
397 |
+
public function has_custom_request_procedure() {
|
398 |
+
return true; }
|
399 |
|
400 |
/**
|
401 |
* We don't want documents being uploaded automatically because of the chance
|
402 |
* that a user may lose translations that they have paid for if they haven't finished or downloaded.
|
403 |
*
|
404 |
+
* @return bool
|
405 |
*/
|
406 |
+
public function auto_upload_allowed() {
|
407 |
+
return false;
|
408 |
+
}
|
409 |
|
410 |
|
411 |
+
public function get_custom_in_progress_icon() {
|
412 |
+
return '<div title="Professional translation in progress" class="lingotek-professional-icon"><img src="' . LINGOTEK_URL . '/img/human-translation.svg" /></div>';
|
413 |
}
|
414 |
|
415 |
/**
|
418 |
* @param string $type
|
419 |
* @return void
|
420 |
*/
|
421 |
+
private function load_request_scripts_and_styles( $type ) {
|
|
|
422 |
add_thickbox();
|
423 |
+
wp_enqueue_script( 'lingotek_professional_workflow', LINGOTEK_URL . '/js/workflow/professional-workflow.js', array(), LINGOTEK_VERSION, false );
|
424 |
wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
|
425 |
|
426 |
$client = new Lingotek_API();
|
427 |
|
428 |
$language_mappings = $client->get_language_mappings();
|
429 |
+
$locales_list = PLL()->model->get_languages_list();
|
430 |
|
431 |
$enabled_langs = array();
|
432 |
+
foreach ( $locales_list as $locale ) {
|
433 |
+
$lingotek_gmc_locale = str_replace( '-', '_', $locale->lingotek_locale );
|
434 |
+
$enabled_langs[ $locale->locale ] = array(
|
|
|
435 |
'lingotek_locale' => $locale->lingotek_locale,
|
436 |
+
'language' => isset( $language_mappings[ $lingotek_gmc_locale ] )
|
437 |
+
? $language_mappings[ $lingotek_gmc_locale ]['language_name']
|
438 |
: null,
|
439 |
+
'country_name' => isset( $language_mappings[ $lingotek_gmc_locale ] )
|
440 |
+
? $language_mappings[ $lingotek_gmc_locale ]['country_name']
|
441 |
: null,
|
442 |
);
|
443 |
}
|
444 |
+
|
445 |
$vars = array(
|
446 |
+
'workflow_id' => $this->workflow_id,
|
447 |
+
'icon_url' => LINGOTEK_URL . '/img/lingotek-logo-white.png',
|
448 |
+
'question_mark_icon_url' => LINGOTEK_URL . '/img/questionmark.svg',
|
449 |
'bridge_payment_redirect' => BRIDGE_URL . '/#/payment/portal',
|
450 |
+
'enabled_langs' => $enabled_langs,
|
451 |
+
'curr_item_type' => $type,
|
452 |
+
'cc_type_map' => Lingotek_Credit_Card_To_Path::get_cc_map(),
|
453 |
+
'default_cc_type' => Lingotek_Credit_Card_To_Path::get_default_cc_key(),
|
454 |
+
'nonce' => wp_create_nonce( 'lingotek_professional' ),
|
455 |
);
|
456 |
wp_localize_script( 'lingotek_professional_workflow', 'workflow_vars', $vars );
|
457 |
}
|
458 |
|
459 |
|
460 |
/**
|
461 |
+
* As the table is being built (for posts, pages, terms, etc.) we only want to attach listeners to locales that have the professional
|
462 |
* workflow enabled. This list is build as the table is being rendered.
|
463 |
*
|
464 |
* @param string $item_id
|
465 |
* @param string $wp_locale
|
466 |
* @return void
|
467 |
*/
|
|
|
468 |
private function add_item_id( $item_id, $wp_locale ) {
|
469 |
+
self::$item_id_list[ $item_id ][] = $wp_locale;
|
470 |
}
|
471 |
|
472 |
/**
|
473 |
+
* Because a new workflow object is created every time a new locale is rendered on the table we can't preserve the list in a single object.
|
474 |
* Instead, we store that list statically and update the list that will eventually be sent to the front end everytime a workflow object is destroyed.
|
475 |
*
|
476 |
* @return void
|
477 |
*/
|
478 |
+
private function flush_list() {
|
|
|
479 |
$vars = array(
|
480 |
'ids' => self::$item_id_list,
|
481 |
);
|
485 |
/**
|
486 |
* Returns the HTML that displays the payment portal loading screen.
|
487 |
*
|
488 |
+
* @return string
|
489 |
*/
|
490 |
+
private function get_payment_portal_html() {
|
|
|
491 |
return "
|
492 |
<div id='payment-portal-wrapper' class='payment-portal-element'>
|
493 |
+
<img class='payment-portal-element payment-portal-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
|
494 |
+
<img class='payment-portal-element payment-portal-loading' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/loading.gif'/>
|
495 |
<span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
|
496 |
</div>
|
497 |
";
|
admin/workflows/workflow-factory.php
CHANGED
@@ -26,7 +26,8 @@ class Lingotek_Workflow_Factory {
|
|
26 |
* @var array
|
27 |
*/
|
28 |
private static $map = array(
|
29 |
-
|
|
|
30 |
);
|
31 |
|
32 |
/**
|
@@ -36,12 +37,9 @@ class Lingotek_Workflow_Factory {
|
|
36 |
* @param string $workflow_id the Id of the given workflow.
|
37 |
*/
|
38 |
public static function get_workflow_instance( $workflow_id ) {
|
39 |
-
if ( ! isset( self::$map[ $workflow_id ] ) )
|
40 |
-
{
|
41 |
return new Lingotek_Workflow();
|
42 |
-
}
|
43 |
-
else
|
44 |
-
{
|
45 |
self::class_load( self::$map[ $workflow_id ] );
|
46 |
return new self::$map[ $workflow_id ]( $workflow_id );
|
47 |
}
|
@@ -50,11 +48,11 @@ class Lingotek_Workflow_Factory {
|
|
50 |
/**
|
51 |
* Echos the information modals describing various details about the workflow.
|
52 |
*/
|
53 |
-
public static function
|
54 |
add_thickbox();
|
55 |
foreach ( self::$map as $id => $class ) {
|
56 |
$workflow = new $class( $id );
|
57 |
-
$workflow->
|
58 |
}
|
59 |
}
|
60 |
|
@@ -64,7 +62,9 @@ class Lingotek_Workflow_Factory {
|
|
64 |
* @param string $class class name to be loaded.
|
65 |
*/
|
66 |
private static function class_load( $class ) {
|
67 |
-
if ( ! isset( $class ) ) {
|
68 |
-
|
|
|
|
|
69 |
}
|
70 |
}
|
26 |
* @var array
|
27 |
*/
|
28 |
private static $map = array(
|
29 |
+
// Prod.
|
30 |
+
'ltk-professional-translation' => 'Lingotek_Professional_Translation_Workflow',
|
31 |
);
|
32 |
|
33 |
/**
|
37 |
* @param string $workflow_id the Id of the given workflow.
|
38 |
*/
|
39 |
public static function get_workflow_instance( $workflow_id ) {
|
40 |
+
if ( ! isset( self::$map[ $workflow_id ] ) ) {
|
|
|
41 |
return new Lingotek_Workflow();
|
42 |
+
} else {
|
|
|
|
|
43 |
self::class_load( self::$map[ $workflow_id ] );
|
44 |
return new self::$map[ $workflow_id ]( $workflow_id );
|
45 |
}
|
48 |
/**
|
49 |
* Echos the information modals describing various details about the workflow.
|
50 |
*/
|
51 |
+
public static function lingotek_translation_professional_translation_info_modals() {
|
52 |
add_thickbox();
|
53 |
foreach ( self::$map as $id => $class ) {
|
54 |
$workflow = new $class( $id );
|
55 |
+
$workflow->lingotek_translation_professional_translation_info_modal();
|
56 |
}
|
57 |
}
|
58 |
|
62 |
* @param string $class class name to be loaded.
|
63 |
*/
|
64 |
private static function class_load( $class ) {
|
65 |
+
if ( ! isset( $class ) ) {
|
66 |
+
return; }
|
67 |
+
if ( ! class_exists( $class ) ) {
|
68 |
+
require_once LINGOTEK_WORKFLOWS . '/' . Lingotek::convert_class_to_file( $class ) . '.php'; }
|
69 |
}
|
70 |
}
|
admin/workflows/workflow.php
CHANGED
@@ -6,83 +6,83 @@
|
|
6 |
class Lingotek_Workflow {
|
7 |
|
8 |
private $allowed_html = array(
|
9 |
-
'div'
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
),
|
14 |
-
'hr'
|
15 |
'width' => array(),
|
16 |
-
'size'
|
17 |
),
|
18 |
-
'h2'
|
19 |
'style' => array(),
|
20 |
),
|
21 |
-
'br'
|
22 |
'class' => array(),
|
23 |
),
|
24 |
-
'b'
|
25 |
-
'p'
|
26 |
-
'id'
|
27 |
'style' => array(),
|
28 |
),
|
29 |
-
'a'
|
30 |
-
'id'
|
31 |
-
'href'
|
32 |
'style' => array(),
|
33 |
-
'class' => array()
|
34 |
),
|
35 |
-
'img'
|
36 |
-
'id'
|
37 |
-
'src'
|
38 |
'style' => array(),
|
39 |
'class' => array(),
|
40 |
),
|
41 |
-
'span'
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
),
|
47 |
'button' => array(
|
48 |
-
'type'
|
49 |
-
'style'
|
50 |
-
'class'
|
51 |
-
'id'
|
52 |
'disabled' => array(),
|
53 |
),
|
54 |
-
'table'
|
55 |
'class' => array(),
|
56 |
),
|
57 |
-
'tbody'
|
58 |
-
'class' => array()
|
59 |
),
|
60 |
-
'thead'
|
61 |
'class' => array(),
|
62 |
-
'id'
|
63 |
),
|
64 |
-
'tr'
|
65 |
'class' => array(),
|
66 |
-
'id'
|
67 |
-
),
|
68 |
-
'th'
|
69 |
-
'id'
|
70 |
'class' => array(),
|
71 |
'style' => array(),
|
72 |
),
|
73 |
-
'td'
|
74 |
-
'class' => array()
|
75 |
),
|
76 |
-
'ul'
|
77 |
-
'class' => array()
|
78 |
),
|
79 |
-
'li'
|
80 |
-
'input'
|
81 |
-
'id'
|
82 |
-
'type'
|
83 |
-
'name'
|
84 |
'value' => array(),
|
85 |
-
'class' => array()
|
86 |
),
|
87 |
);
|
88 |
|
@@ -128,8 +128,8 @@ class Lingotek_Workflow {
|
|
128 |
protected static $loading_modal_launched = false;
|
129 |
|
130 |
/**
|
131 |
-
* This flag can be set to keep track of whether
|
132 |
-
* the save post action has already occured (for example, if multiple workflow objects are being instantiated and
|
133 |
* you don't want them to do the same thing twice.)
|
134 |
*
|
135 |
* @var boolean
|
@@ -155,7 +155,7 @@ class Lingotek_Workflow {
|
|
155 |
*
|
156 |
* @param string $workflow_id
|
157 |
*/
|
158 |
-
public function __construct($workflow_id = null) {
|
159 |
$this->workflow_id = $workflow_id;
|
160 |
}
|
161 |
|
@@ -168,7 +168,7 @@ class Lingotek_Workflow {
|
|
168 |
*
|
169 |
* @param string $id the workflow id.
|
170 |
*/
|
171 |
-
public function
|
172 |
|
173 |
/**
|
174 |
* This method is called when the Posts or Pages columns are being rendered.
|
@@ -183,8 +183,8 @@ class Lingotek_Workflow {
|
|
183 |
* This method is called when the Terms table is being rendered.
|
184 |
*
|
185 |
* @param string $item_id
|
186 |
-
*
|
187 |
-
*
|
188 |
*/
|
189 |
public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {}
|
190 |
|
@@ -209,11 +209,11 @@ class Lingotek_Workflow {
|
|
209 |
* @param string $type
|
210 |
* @return void
|
211 |
*/
|
212 |
-
public function pre_upload_to_lingotek($item_id, $type) {}
|
213 |
|
214 |
/**
|
215 |
* Workflows have the option to hook into the save post action. This action is executed
|
216 |
-
* BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
|
217 |
* method is called when the save post action is triggered.
|
218 |
*
|
219 |
* @return void
|
@@ -222,7 +222,7 @@ class Lingotek_Workflow {
|
|
222 |
|
223 |
/**
|
224 |
* Workflows have the option to hook into the save term action. This action is executed
|
225 |
-
* BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
|
226 |
* method is called when the save post action is triggered.
|
227 |
*
|
228 |
* @return void
|
@@ -235,11 +235,12 @@ class Lingotek_Workflow {
|
|
235 |
*
|
236 |
* @return boolean
|
237 |
*/
|
238 |
-
public function has_custom_request_procedure() {
|
|
|
239 |
|
240 |
/**
|
241 |
* If a workflow wants to perform a custom request this method will be called after the has_custom_request_procedure() has
|
242 |
-
* been called if it returns TRUE. As of now this method (do_custom_request()) only gets called for single requests.
|
243 |
* bulk requests are ignored if any of the locale items are linked to a workflow that returns true on has_custom_request_procedure().
|
244 |
*
|
245 |
* @return void
|
@@ -251,10 +252,12 @@ class Lingotek_Workflow {
|
|
251 |
*
|
252 |
* @return void
|
253 |
*/
|
254 |
-
public function auto_upload_allowed() {
|
|
|
255 |
|
256 |
|
257 |
-
public function get_custom_in_progress_icon() {
|
|
|
258 |
/**
|
259 |
* This method acts as a template for building the modals. The arguments passed
|
260 |
* are inserted into the html string and then echo'd. If any extra html elements
|
@@ -268,26 +271,27 @@ class Lingotek_Workflow {
|
|
268 |
* This allows us to use the 'display' CSS attribute. WP
|
269 |
* blacklists it by default.
|
270 |
*/
|
271 |
-
add_filter( 'safe_style_css', array(&$this, 'add_modal_styles'));
|
272 |
|
273 |
-
$id
|
274 |
$parent_elements = isset( $args['parent_elements'] ) ? $args['parent_elements'] : '';
|
275 |
-
echo wp_kses(
|
276 |
-
|
277 |
-
|
|
|
278 |
// <br>
|
279 |
-
|
280 |
// <div style='float:right; padding-right:55px;'>
|
281 |
-
|
282 |
-
|
283 |
-
</div>
|
|
|
|
|
284 |
}
|
285 |
|
286 |
|
287 |
-
public function add_modal_styles()
|
288 |
-
|
289 |
-
|
290 |
-
$styles = array();
|
291 |
$styles[] = 'display';
|
292 |
$styles[] = 'position';
|
293 |
$styles[] = 'bottom';
|
6 |
class Lingotek_Workflow {
|
7 |
|
8 |
private $allowed_html = array(
|
9 |
+
'div' => array(
|
10 |
+
'id' => array(),
|
11 |
+
'style' => array(),
|
12 |
+
'class' => array(),
|
13 |
),
|
14 |
+
'hr' => array(
|
15 |
'width' => array(),
|
16 |
+
'size' => array(),
|
17 |
),
|
18 |
+
'h2' => array(
|
19 |
'style' => array(),
|
20 |
),
|
21 |
+
'br' => array(
|
22 |
'class' => array(),
|
23 |
),
|
24 |
+
'b' => array(),
|
25 |
+
'p' => array(
|
26 |
+
'id' => array(),
|
27 |
'style' => array(),
|
28 |
),
|
29 |
+
'a' => array(
|
30 |
+
'id' => array(),
|
31 |
+
'href' => array(),
|
32 |
'style' => array(),
|
33 |
+
'class' => array(),
|
34 |
),
|
35 |
+
'img' => array(
|
36 |
+
'id' => array(),
|
37 |
+
'src' => array(),
|
38 |
'style' => array(),
|
39 |
'class' => array(),
|
40 |
),
|
41 |
+
'span' => array(
|
42 |
+
'id' => array(),
|
43 |
+
'style' => array(),
|
44 |
+
'class' => array(),
|
45 |
+
'ltk-data-tooltip' => array(),
|
46 |
),
|
47 |
'button' => array(
|
48 |
+
'type' => array(),
|
49 |
+
'style' => array(),
|
50 |
+
'class' => array(),
|
51 |
+
'id' => array(),
|
52 |
'disabled' => array(),
|
53 |
),
|
54 |
+
'table' => array(
|
55 |
'class' => array(),
|
56 |
),
|
57 |
+
'tbody' => array(
|
58 |
+
'class' => array(),
|
59 |
),
|
60 |
+
'thead' => array(
|
61 |
'class' => array(),
|
62 |
+
'id' => array(),
|
63 |
),
|
64 |
+
'tr' => array(
|
65 |
'class' => array(),
|
66 |
+
'id' => array(),
|
67 |
+
),
|
68 |
+
'th' => array(
|
69 |
+
'id' => array(),
|
70 |
'class' => array(),
|
71 |
'style' => array(),
|
72 |
),
|
73 |
+
'td' => array(
|
74 |
+
'class' => array(),
|
75 |
),
|
76 |
+
'ul' => array(
|
77 |
+
'class' => array(),
|
78 |
),
|
79 |
+
'li' => array(),
|
80 |
+
'input' => array(
|
81 |
+
'id' => array(),
|
82 |
+
'type' => array(),
|
83 |
+
'name' => array(),
|
84 |
'value' => array(),
|
85 |
+
'class' => array(),
|
86 |
),
|
87 |
);
|
88 |
|
128 |
protected static $loading_modal_launched = false;
|
129 |
|
130 |
/**
|
131 |
+
* This flag can be set to keep track of whether
|
132 |
+
* the save post action has already occured (for example, if multiple workflow objects are being instantiated and
|
133 |
* you don't want them to do the same thing twice.)
|
134 |
*
|
135 |
* @var boolean
|
155 |
*
|
156 |
* @param string $workflow_id
|
157 |
*/
|
158 |
+
public function __construct( $workflow_id = null ) {
|
159 |
$this->workflow_id = $workflow_id;
|
160 |
}
|
161 |
|
168 |
*
|
169 |
* @param string $id the workflow id.
|
170 |
*/
|
171 |
+
public function lingotek_translation_professional_translation_info_modal( $item_id = null, $item_type = null ) {}
|
172 |
|
173 |
/**
|
174 |
* This method is called when the Posts or Pages columns are being rendered.
|
183 |
* This method is called when the Terms table is being rendered.
|
184 |
*
|
185 |
* @param string $item_id
|
186 |
+
* @param string $wp_locale
|
187 |
+
* @param string $item_type
|
188 |
*/
|
189 |
public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {}
|
190 |
|
209 |
* @param string $type
|
210 |
* @return void
|
211 |
*/
|
212 |
+
public function pre_upload_to_lingotek( $item_id, $type ) {}
|
213 |
|
214 |
/**
|
215 |
* Workflows have the option to hook into the save post action. This action is executed
|
216 |
+
* BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
|
217 |
* method is called when the save post action is triggered.
|
218 |
*
|
219 |
* @return void
|
222 |
|
223 |
/**
|
224 |
* Workflows have the option to hook into the save term action. This action is executed
|
225 |
+
* BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
|
226 |
* method is called when the save post action is triggered.
|
227 |
*
|
228 |
* @return void
|
235 |
*
|
236 |
* @return boolean
|
237 |
*/
|
238 |
+
public function has_custom_request_procedure() {
|
239 |
+
return false; }
|
240 |
|
241 |
/**
|
242 |
* If a workflow wants to perform a custom request this method will be called after the has_custom_request_procedure() has
|
243 |
+
* been called if it returns TRUE. As of now this method (do_custom_request()) only gets called for single requests.
|
244 |
* bulk requests are ignored if any of the locale items are linked to a workflow that returns true on has_custom_request_procedure().
|
245 |
*
|
246 |
* @return void
|
252 |
*
|
253 |
* @return void
|
254 |
*/
|
255 |
+
public function auto_upload_allowed() {
|
256 |
+
return true; }
|
257 |
|
258 |
|
259 |
+
public function get_custom_in_progress_icon() {
|
260 |
+
return false; }
|
261 |
/**
|
262 |
* This method acts as a template for building the modals. The arguments passed
|
263 |
* are inserted into the html string and then echo'd. If any extra html elements
|
271 |
* This allows us to use the 'display' CSS attribute. WP
|
272 |
* blacklists it by default.
|
273 |
*/
|
274 |
+
add_filter( 'safe_style_css', array( &$this, 'add_modal_styles' ) );
|
275 |
|
276 |
+
$id = isset( $args['id'] ) ? '-' . $args['id'] : '';
|
277 |
$parent_elements = isset( $args['parent_elements'] ) ? $args['parent_elements'] : '';
|
278 |
+
echo wp_kses(
|
279 |
+
"<div id='modal-window-id" . esc_attr( $id ) . "' style='display:none;' >"
|
280 |
+
. wp_kses( $parent_elements, $this->allowed_html ) .
|
281 |
+
"<div id='modal-body" . esc_attr( $id ) . "' style='height:100%;position: relative;'>" . wp_kses( $args['body'], $this->allowed_html ) . '</div>' .
|
282 |
// <br>
|
283 |
+
// <a id='yes" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:left; bottom:30px;'>Continue</a>
|
284 |
// <div style='float:right; padding-right:55px;'>
|
285 |
+
// <a id='no" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:right; bottom:30px;'>Cancel</a>
|
286 |
+
'</div>
|
287 |
+
</div>',
|
288 |
+
$this->allowed_html
|
289 |
+
);
|
290 |
}
|
291 |
|
292 |
|
293 |
+
public function add_modal_styles() {
|
294 |
+
$styles = array();
|
|
|
|
|
295 |
$styles[] = 'display';
|
296 |
$styles[] = 'position';
|
297 |
$styles[] = 'bottom';
|
admin/wp-import.php
CHANGED
@@ -13,12 +13,12 @@ class Lingotek_WP_Import extends PLL_WP_Import {
|
|
13 |
* @since 1.0.6
|
14 |
*/
|
15 |
public function process_posts() {
|
16 |
-
if (empty($this->post_translations)) {
|
17 |
-
foreach ($this->posts as &$post) {
|
18 |
-
foreach ($post['terms'] as $key => &$term) {
|
19 |
-
if (!empty($post['terms'])) {
|
20 |
-
if (in_array('post_translations', $term)) {
|
21 |
-
unset($post['terms'][$key]);
|
22 |
}
|
23 |
}
|
24 |
}
|
@@ -28,4 +28,4 @@ class Lingotek_WP_Import extends PLL_WP_Import {
|
|
28 |
}
|
29 |
}
|
30 |
|
31 |
-
|
13 |
* @since 1.0.6
|
14 |
*/
|
15 |
public function process_posts() {
|
16 |
+
if ( empty( $this->post_translations ) ) {
|
17 |
+
foreach ( $this->posts as &$post ) {
|
18 |
+
foreach ( $post['terms'] as $key => &$term ) {
|
19 |
+
if ( ! empty( $post['terms'] ) ) {
|
20 |
+
if ( in_array( 'post_translations', $term, true ) ) {
|
21 |
+
unset( $post['terms'][ $key ] );
|
22 |
}
|
23 |
}
|
24 |
}
|
28 |
}
|
29 |
}
|
30 |
|
31 |
+
|
bin/githook-pre-commit.sh
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
PROJECT=`git rev-parse --show-toplevel`
|
4 |
+
STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
|
5 |
+
# This is valid for roots/bedrock, not for standard WordPress.
|
6 |
+
DOCKER_BASE_PATH='/var/www/html/web/app/plugins/lingotek-translation/'
|
7 |
+
|
8 |
+
# Determine if a file list is passed
|
9 |
+
if [ "$#" -eq 1 ]
|
10 |
+
then
|
11 |
+
SFILES = "$*"
|
12 |
+
fi
|
13 |
+
SFILES=${SFILES:-$STAGED_FILES_CMD}
|
14 |
+
|
15 |
+
echo "Checking PHP Lint..."
|
16 |
+
for FILE in $SFILES
|
17 |
+
do
|
18 |
+
ddev exec bash -c "php -l -d display_errors=0 $DOCKER_BASE_PATH/$FILE"
|
19 |
+
if [ $? != 0 ]
|
20 |
+
then
|
21 |
+
echo "Fix the error before commit."
|
22 |
+
exit 1
|
23 |
+
fi
|
24 |
+
FILES="$FILES $PROJECT/$FILE"
|
25 |
+
done
|
26 |
+
|
27 |
+
if [ "$FILES" != "" ]
|
28 |
+
then
|
29 |
+
echo "Running Code Sniffer..."
|
30 |
+
phpcs --standard=phpcs.xml --encoding=utf-8 $FILES
|
31 |
+
if [ $? != 0 ]
|
32 |
+
then
|
33 |
+
echo 'We are allowing the commit, but take into account the warnings above.'
|
34 |
+
#echo "Fix the error before commit."
|
35 |
+
#exit 1
|
36 |
+
fi
|
37 |
+
fi
|
bin/githook-prepare-commit-msg.sh
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
# Get git repository information
|
4 |
+
commit_msg_file=$1
|
5 |
+
commit_type=$2
|
6 |
+
commit_branch=`git symbolic-ref --short HEAD`
|
7 |
+
raw_ticket_num=`echo $commit_branch | grep -oh -E '^[a-zA-Z]+-{0,1}[0-9]+'`
|
8 |
+
ticket_num=`echo $raw_ticket_num | sed -E 's,^([a-zA-Z]+)([0-9]+).*,\1-\2,1'`
|
9 |
+
|
10 |
+
if [ "${commit_type}" = "merge" ];then
|
11 |
+
exit 0
|
12 |
+
fi
|
13 |
+
# Check if branch begins with a valid ticket number
|
14 |
+
if [ -z "$ticket_num" ];
|
15 |
+
then
|
16 |
+
read -p \
|
17 |
+
"Please enter the ticket number in the format XX-####: " \
|
18 |
+
ticket_num </dev/tty
|
19 |
+
fi
|
20 |
+
|
21 |
+
VALID_TICKET=`echo $ticket_num | grep -oh -E '^[a-zA-Z]+-[0-9]+'`
|
22 |
+
|
23 |
+
# Check user-entered value or previously captured ticket number to make sure it conforms
|
24 |
+
if [ -z "$VALID_TICKET" ];
|
25 |
+
then
|
26 |
+
echo 'Invalid ticket number. Please try to commit again'
|
27 |
+
exit 1
|
28 |
+
fi
|
29 |
+
|
30 |
+
# Create commit message
|
31 |
+
issue_string="Issue #$ticket_num:"
|
32 |
+
# Keep all newlines in captured commit message
|
33 |
+
IFS=
|
34 |
+
raw_commit_msg="$(cat $commit_msg_file)"
|
35 |
+
commit_msg="$issue_string $raw_commit_msg"
|
36 |
+
echo $commit_msg > $commit_msg_file
|
37 |
+
|
38 |
+
if [ "$commit_type" = "message" ];
|
39 |
+
then
|
40 |
+
commit_msg="$issue_string $raw_commit_msg"
|
41 |
+
else
|
42 |
+
commit_msg=`echo -e "$issue_string\n\n$raw_commit_msg"`
|
43 |
+
fi
|
44 |
+
|
45 |
+
# Store new commit message
|
46 |
+
echo $commit_msg > $commit_msg_file
|
bin/install-git-hooks.sh
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
# Switch to git root directory
|
4 |
+
git_root=`git rev-parse --show-toplevel`
|
5 |
+
cd $git_root
|
6 |
+
|
7 |
+
# Add hook if necessary
|
8 |
+
if [ ! -f .git/hooks/prepare-commit-msg ];
|
9 |
+
then
|
10 |
+
echo 'Adding commit message hook.'
|
11 |
+
cp ./bin/githook-prepare-commit-msg.sh .git/hooks/prepare-commit-msg \
|
12 |
+
&& echo '***Commit message hook added successfully.***'
|
13 |
+
else
|
14 |
+
echo 'Commit message hook already in place. Not overwriting.'
|
15 |
+
fi
|
16 |
+
|
17 |
+
if [ ! -f .git/hooks/pre-commit ];
|
18 |
+
then
|
19 |
+
echo 'Adding pre-comit hook.'
|
20 |
+
cp ./bin/githook-pre-commit.sh .git/hooks/pre-commit \
|
21 |
+
&& echo '***Pre-commit hook added successfully.***'
|
22 |
+
else
|
23 |
+
echo 'Pre-commit hook already in place. Not overwriting.'
|
24 |
+
fi
|
25 |
+
|
bin/install-wp-tests.sh
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
if [ $# -lt 3 ]; then
|
4 |
+
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
|
5 |
+
exit 1
|
6 |
+
fi
|
7 |
+
|
8 |
+
DB_NAME=$1
|
9 |
+
DB_USER=$2
|
10 |
+
DB_PASS=$3
|
11 |
+
DB_HOST=${4-localhost}
|
12 |
+
WP_VERSION=${5-latest}
|
13 |
+
SKIP_DB_CREATE=${6-false}
|
14 |
+
|
15 |
+
TMPDIR=${TMPDIR-/tmp}
|
16 |
+
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
|
17 |
+
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
|
18 |
+
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}
|
19 |
+
|
20 |
+
download() {
|
21 |
+
if [ `which curl` ]; then
|
22 |
+
curl -s "$1" > "$2";
|
23 |
+
elif [ `which wget` ]; then
|
24 |
+
wget -nv -O "$2" "$1"
|
25 |
+
fi
|
26 |
+
}
|
27 |
+
|
28 |
+
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
|
29 |
+
WP_BRANCH=${WP_VERSION%\-*}
|
30 |
+
WP_TESTS_TAG="branches/$WP_BRANCH"
|
31 |
+
|
32 |
+
elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
|
33 |
+
WP_TESTS_TAG="branches/$WP_VERSION"
|
34 |
+
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
35 |
+
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
36 |
+
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
37 |
+
WP_TESTS_TAG="tags/${WP_VERSION%??}"
|
38 |
+
else
|
39 |
+
WP_TESTS_TAG="tags/$WP_VERSION"
|
40 |
+
fi
|
41 |
+
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
42 |
+
WP_TESTS_TAG="trunk"
|
43 |
+
else
|
44 |
+
# http serves a single offer, whereas https serves multiple. we only want one
|
45 |
+
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
|
46 |
+
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
|
47 |
+
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
|
48 |
+
if [[ -z "$LATEST_VERSION" ]]; then
|
49 |
+
echo "Latest WordPress version could not be found"
|
50 |
+
exit 1
|
51 |
+
fi
|
52 |
+
WP_TESTS_TAG="tags/$LATEST_VERSION"
|
53 |
+
fi
|
54 |
+
set -ex
|
55 |
+
|
56 |
+
install_wp() {
|
57 |
+
|
58 |
+
if [ -d $WP_CORE_DIR ]; then
|
59 |
+
return;
|
60 |
+
fi
|
61 |
+
|
62 |
+
mkdir -p $WP_CORE_DIR
|
63 |
+
|
64 |
+
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
65 |
+
mkdir -p $TMPDIR/wordpress-trunk
|
66 |
+
rm -rf $TMPDIR/wordpress-trunk/*
|
67 |
+
svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress
|
68 |
+
mv $TMPDIR/wordpress-trunk/wordpress/* $WP_CORE_DIR
|
69 |
+
else
|
70 |
+
if [ $WP_VERSION == 'latest' ]; then
|
71 |
+
local ARCHIVE_NAME='latest'
|
72 |
+
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
|
73 |
+
# https serves multiple offers, whereas http serves single.
|
74 |
+
download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
|
75 |
+
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
76 |
+
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
77 |
+
LATEST_VERSION=${WP_VERSION%??}
|
78 |
+
else
|
79 |
+
# otherwise, scan the releases and get the most up to date minor version of the major release
|
80 |
+
local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
|
81 |
+
LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
|
82 |
+
fi
|
83 |
+
if [[ -z "$LATEST_VERSION" ]]; then
|
84 |
+
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
85 |
+
else
|
86 |
+
local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
|
87 |
+
fi
|
88 |
+
else
|
89 |
+
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
90 |
+
fi
|
91 |
+
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
|
92 |
+
tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
|
93 |
+
fi
|
94 |
+
|
95 |
+
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
|
96 |
+
}
|
97 |
+
|
98 |
+
install_test_suite() {
|
99 |
+
# portable in-place argument for both GNU sed and Mac OSX sed
|
100 |
+
if [[ $(uname -s) == 'Darwin' ]]; then
|
101 |
+
local ioption='-i.bak'
|
102 |
+
else
|
103 |
+
local ioption='-i'
|
104 |
+
fi
|
105 |
+
|
106 |
+
# set up testing suite if it doesn't yet exist
|
107 |
+
if [ ! -d $WP_TESTS_DIR ]; then
|
108 |
+
# set up testing suite
|
109 |
+
mkdir -p $WP_TESTS_DIR
|
110 |
+
rm -rf $WP_TESTS_DIR/{includes,data}
|
111 |
+
svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
|
112 |
+
svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
|
113 |
+
fi
|
114 |
+
|
115 |
+
if [ ! -f wp-tests-config.php ]; then
|
116 |
+
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
|
117 |
+
# remove all forward slashes in the end
|
118 |
+
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
|
119 |
+
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
|
120 |
+
sed $ioption "s:__DIR__ . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
|
121 |
+
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
|
122 |
+
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
|
123 |
+
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
|
124 |
+
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
|
125 |
+
fi
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
+
recreate_db() {
|
130 |
+
shopt -s nocasematch
|
131 |
+
if [[ $1 =~ ^(y|yes)$ ]]
|
132 |
+
then
|
133 |
+
mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA
|
134 |
+
create_db
|
135 |
+
echo "Recreated the database ($DB_NAME)."
|
136 |
+
else
|
137 |
+
echo "Leaving the existing database ($DB_NAME) in place."
|
138 |
+
fi
|
139 |
+
shopt -u nocasematch
|
140 |
+
}
|
141 |
+
|
142 |
+
create_db() {
|
143 |
+
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
|
144 |
+
}
|
145 |
+
|
146 |
+
install_db() {
|
147 |
+
|
148 |
+
if [ ${SKIP_DB_CREATE} = "true" ]; then
|
149 |
+
return 0
|
150 |
+
fi
|
151 |
+
|
152 |
+
# parse DB_HOST for port or socket references
|
153 |
+
local PARTS=(${DB_HOST//\:/ })
|
154 |
+
local DB_HOSTNAME=${PARTS[0]};
|
155 |
+
local DB_SOCK_OR_PORT=${PARTS[1]};
|
156 |
+
local EXTRA=""
|
157 |
+
|
158 |
+
if ! [ -z $DB_HOSTNAME ] ; then
|
159 |
+
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
|
160 |
+
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
|
161 |
+
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
|
162 |
+
EXTRA=" --socket=$DB_SOCK_OR_PORT"
|
163 |
+
elif ! [ -z $DB_HOSTNAME ] ; then
|
164 |
+
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
|
165 |
+
fi
|
166 |
+
fi
|
167 |
+
|
168 |
+
# create database
|
169 |
+
if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ]
|
170 |
+
then
|
171 |
+
echo "Reinstalling will delete the existing test database ($DB_NAME)"
|
172 |
+
read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB
|
173 |
+
recreate_db $DELETE_EXISTING_DB
|
174 |
+
else
|
175 |
+
create_db
|
176 |
+
fi
|
177 |
+
}
|
178 |
+
|
179 |
+
install_wp
|
180 |
+
install_test_suite
|
181 |
+
install_db
|
include/api.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
require_once
|
4 |
|
5 |
/**
|
6 |
* manages communication with Lingotek TMS
|
@@ -14,8 +14,9 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
14 |
protected $client_id;
|
15 |
private $auth_temp;
|
16 |
|
17 |
-
const PRODUCTION_URL =
|
18 |
-
|
|
|
19 |
|
20 |
|
21 |
private $bridge_url = '';
|
@@ -26,36 +27,42 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
26 |
* @since 0.1
|
27 |
*/
|
28 |
public function __construct() {
|
29 |
-
$base_url
|
30 |
-
$this->base_url
|
31 |
-
$this->api_url
|
32 |
$this->client_id = self::CLIENT_ID;
|
33 |
-
$token_details
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
37 |
$this->bridge_url = BRIDGE_URL . '/api/v2/transaction/translation/';
|
38 |
}
|
39 |
|
40 |
-
public function get_token_details($access_token) {
|
41 |
$url = "{$this->base_url}/auth/oauth2/access_token_info";
|
42 |
-
Lingotek_Logger::debug(
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
'headers' => array(
|
45 |
'Authorization' => "Bearer $access_token",
|
46 |
),
|
47 |
);
|
48 |
-
$response
|
49 |
-
$response_code = wp_remote_retrieve_response_code($response);
|
50 |
|
51 |
-
if ($response_code == 200) {
|
52 |
-
$response_body = json_decode(wp_remote_retrieve_body($response));
|
53 |
$token_details = $response_body;
|
|
|
|
|
54 |
}
|
55 |
-
|
56 |
-
$token_details = FALSE;
|
57 |
-
}
|
58 |
-
$this->log_error_on_response_failure($response, "GetTokenDetails: Error occured");
|
59 |
return $token_details;
|
60 |
}
|
61 |
|
@@ -70,37 +77,50 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
70 |
*
|
71 |
* @param string $project_id
|
72 |
*/
|
73 |
-
public function update_callback_url($project_id) {
|
74 |
-
$args
|
75 |
-
$response = $this->patch($this->api_url . '/project/' . $project_id, $args);
|
76 |
-
Lingotek_Logger::info('Request to update callback url', array('project_id' => $project_id));
|
77 |
-
$this->log_error_on_response_failure($response, 'UpdateCallbackUrl: Error occured', array('project_id' => $project_id));
|
78 |
-
return !is_wp_error($response) && 204 == wp_remote_retrieve_response_code($response);
|
79 |
}
|
80 |
|
81 |
-
|
82 |
* creates a new project
|
83 |
*
|
84 |
* @since 0.2
|
85 |
*
|
86 |
* @param string $title
|
87 |
*/
|
88 |
-
public function create_project($title, $community_id) {
|
89 |
$args = array(
|
90 |
-
'title'
|
91 |
'community_id' => $community_id,
|
92 |
-
'workflow_id'
|
93 |
-
'callback_url' => add_query_arg('lingotek', 1, site_url()),
|
94 |
);
|
95 |
|
96 |
-
$response = $this->post($this->api_url . '/project', $args);
|
97 |
-
if(!is_wp_error($response) && 201 == wp_remote_retrieve_response_code($response)) {
|
98 |
-
$new_id = json_decode(wp_remote_retrieve_body($response));
|
99 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
return $new_id->properties->id;
|
101 |
}
|
102 |
-
|
103 |
-
$this->log_error_on_response_failure(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
return false;
|
105 |
}
|
106 |
|
@@ -112,24 +132,37 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
112 |
* @param array $args expects array with title, content and locale_code
|
113 |
* @returns bool|string document_id, false if something got wrong
|
114 |
*/
|
115 |
-
public function upload_document($args, $wp_id = null) {
|
116 |
-
Lingotek::log(debug_backtrace());
|
117 |
-
Lingotek::log('uploading document');
|
118 |
-
$args = wp_parse_args(
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
return $b->properties->id;
|
127 |
-
} elseif ($code == 402) {
|
128 |
-
$lingotek_log_errors
|
129 |
-
$error_message
|
130 |
-
$this->get_error_message_from_response($response) :
|
131 |
-
$lingotek_log_errors['patch_document_error'] = __("Payment required. Message: $error_message", 'lingotek-translation');
|
132 |
-
update_option('lingotek_log_errors', $lingotek_log_errors, false);
|
133 |
}
|
134 |
return false;
|
135 |
}
|
@@ -140,159 +173,197 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
140 |
* @since 0.1
|
141 |
*
|
142 |
* @param string $id document id
|
143 |
-
* @param array
|
144 |
-
* @return bool false if something got wrong
|
145 |
*/
|
146 |
-
public function patch_document($id, $args, $wp_id = null) {
|
147 |
-
$lgtm
|
148 |
-
$document = $lgtm->get_group_by_id($id);
|
149 |
-
$args
|
150 |
-
$title
|
151 |
-
$this->format_as_multipart($args);
|
152 |
-
$response
|
153 |
-
$status_code = wp_remote_retrieve_response_code($response);
|
154 |
-
$body
|
155 |
-
if ($status_code == 400 && strpos($body->messages[0], 'has previously been cancelled')) {
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
$
|
160 |
-
if (isset($document->translations)) {
|
161 |
-
foreach ($document->translations as $locale) {
|
162 |
-
$document->translations[$locale] = 'pending';
|
163 |
-
}
|
164 |
-
}
|
165 |
-
$document->document_id = '';
|
166 |
-
unset($document->desc_array['lingotek']);
|
167 |
$document->save();
|
168 |
-
return $
|
169 |
}
|
170 |
-
if ($status_code == 423) {
|
171 |
$document->document_id = $body->next_document_id;
|
172 |
$document->save();
|
173 |
-
return $this->patch_document($body->next_document_id, $unformatted_args, $wp_id);
|
174 |
}
|
175 |
|
176 |
// We will handle patch errors separately. All we want to do is return the result of the current patch request to the user if payment is required
|
177 |
// (although in theory this will never happen, because the WP model is document count based, and it will not allow them to upload documents until
|
178 |
// they choose to buy more documents)
|
179 |
-
$this->update_patch_error_message($response, $status_code, $title);
|
180 |
// The current behavior sends no body, so we will just check to see if the body is empty for now in order to maintain current behavior
|
181 |
-
if (empty($body)) {
|
182 |
-
$success = !is_wp_error($response) && 202 == wp_remote_retrieve_response_code($response);
|
183 |
-
if ($success) {
|
184 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
} else {
|
186 |
-
Lingotek_Logger::error(
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
}
|
188 |
return $success;
|
189 |
-
}
|
190 |
-
|
191 |
-
if ($status_code == 410) {
|
192 |
-
Lingotek_Logger::info(
|
193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
$unformatted_args['translation_locale_code'] = $targets;
|
195 |
-
$this->format_args_for_upload($unformatted_args, $wp_id);
|
196 |
-
foreach ($document->translations as $locale) {
|
197 |
-
$document->translations[$locale] = 'pending';
|
198 |
}
|
199 |
-
$document->document_id = '';
|
200 |
-
unset($document->desc_array['lingotek']);
|
201 |
$document->save();
|
202 |
-
return $this->upload_document($unformatted_args, $wp_id);
|
203 |
}
|
204 |
-
if ($status_code == 402) {
|
205 |
-
Lingotek_Logger::error('There was an error updating WordPress item', array('error' => $this->get_error_message_from_response($response)));
|
206 |
$document->source_failed();
|
207 |
-
return
|
208 |
}
|
209 |
-
if ($status_code == 202 && !is_wp_error($response)) {
|
210 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
$document->document_id = $body->next_document_id;
|
212 |
$document->save();
|
213 |
return $body->next_document_id;
|
214 |
}
|
215 |
-
return
|
216 |
}
|
217 |
|
218 |
-
private function format_args_for_upload(&$args, $wp_id) {
|
219 |
-
$lgtm
|
220 |
-
$post
|
221 |
-
$language
|
222 |
-
$project_id
|
223 |
-
$workflow_id = $lgtm->get_profile_option('workflow_id', $post->post_type, $language, false, $wp_id);
|
224 |
$locale_code = $language->lingotek_locale;
|
225 |
-
unset($args['format']);
|
226 |
$args['locale_code'] = $locale_code;
|
227 |
-
$args['project_id']
|
228 |
$args['workflow_id'] = $workflow_id;
|
229 |
}
|
230 |
|
231 |
-
private function update_patch_error_message($response, $status_code, $title) {
|
232 |
// Do not inform user if call was successful.
|
233 |
-
if ($status_code == 202 || $status_code == 410) {
|
234 |
return;
|
235 |
}
|
236 |
-
$lingotek_log_errors = get_option('lingotek_log_errors', array());
|
237 |
-
if (!is_array($lingotek_log_errors)) {
|
238 |
$lingotek_log_errors = array();
|
239 |
}
|
240 |
-
$error_message = $this->get_error_message_from_response($response) !==
|
241 |
-
$this->get_error_message_from_response($response) :
|
242 |
|
243 |
-
if ($status_code == 402) {
|
244 |
-
$lingotek_log_errors['patch_document_error'] = __("Payment required. Message: $error_message", 'lingotek-translation');
|
245 |
-
}
|
246 |
-
|
247 |
-
$lingotek_log_errors['patch_document_error'] = __("Error occurred while updating document $title. Message: $error_message", 'lingotek-translation');
|
248 |
}
|
249 |
-
update_option('lingotek_log_errors', $lingotek_log_errors);
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
* cancels a document
|
254 |
-
*
|
255 |
* @since 1.4.2
|
256 |
-
*
|
257 |
* @param string $id document id
|
258 |
*/
|
259 |
-
public function cancel_document(&$id, $wp_id = null) {
|
260 |
-
$args
|
261 |
-
$response = $this->post("$this->api_url/document/$id/cancel", $args);
|
262 |
-
if($wp_id) {
|
263 |
-
$arr = get_option('lingotek_log_errors');
|
264 |
-
if(isset($arr[$wp_id])) {
|
265 |
-
unset($arr[$wp_id]);
|
266 |
-
update_option('lingotek_log_errors', $arr, false);
|
267 |
}
|
268 |
}
|
269 |
-
$this->log_error_on_response_failure(
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
$document->status = 'cancelled';
|
275 |
-
if ($is_success) {
|
276 |
-
wp_remove_object_terms($wp_id, "lingotek_hash_{$wp_id}",
|
277 |
-
Lingotek_Logger::info(
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
$document->save();
|
279 |
return $is_success;
|
280 |
-
} elseif (403 != wp_remote_retrieve_response_code($response)) {
|
281 |
-
wp_remove_object_terms($wp_id, "lingotek_hash_{$wp_id}",
|
282 |
-
Lingotek_Logger::warning(
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
$document->save();
|
285 |
return true;
|
286 |
-
}
|
287 |
-
$document->status
|
288 |
-
$lingotek_log_errors = get_option('lingotek_log_errors', array());
|
289 |
-
if (!is_array($lingotek_log_errors)) {
|
290 |
$lingotek_log_errors = array();
|
291 |
}
|
292 |
-
$error_message
|
293 |
-
$this->get_error_message_from_response($response) :
|
294 |
$lingotek_log_errors['disassociate_document_error'] = $error_message;
|
295 |
-
update_option('lingotek_log_errors', $lingotek_log_errors, false);
|
296 |
return $is_success;
|
297 |
}
|
298 |
|
@@ -302,31 +373,31 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
302 |
*
|
303 |
* @since 0.1
|
304 |
*/
|
305 |
-
public function get_document_ids($args = array()) {
|
306 |
-
$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
|
307 |
-
$ids
|
308 |
|
309 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
310 |
-
$documents = json_decode(wp_remote_retrieve_body($response));
|
311 |
-
foreach ($documents->entities as $doc) {
|
312 |
$ids[] = $doc->properties->id;
|
313 |
}
|
314 |
}
|
315 |
|
316 |
-
$this->log_error_on_response_failure($response, 'GetDocumentIds: Error occured');
|
317 |
return $ids;
|
318 |
}
|
319 |
|
320 |
-
public function get_document_count($args = array()) {
|
321 |
-
$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
|
322 |
-
$docs
|
323 |
|
324 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
325 |
-
$response = json_decode(wp_remote_retrieve_body($response));
|
326 |
return $response->properties->total;
|
327 |
}
|
328 |
|
329 |
-
$this->log_error_on_response_failure($response, 'GetDocumentCount: Error occured');
|
330 |
return null;
|
331 |
}
|
332 |
|
@@ -335,18 +406,18 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
335 |
*
|
336 |
* @since 0.1
|
337 |
*/
|
338 |
-
public function get_documents($args = array()) {
|
339 |
-
$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
|
340 |
-
$docs
|
341 |
|
342 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
343 |
-
$documents = json_decode(wp_remote_retrieve_body($response));
|
344 |
-
foreach ($documents->entities as $doc) {
|
345 |
$docs[] = $doc;
|
346 |
}
|
347 |
}
|
348 |
|
349 |
-
$this->log_error_on_response_failure($response, 'GetDocuments: Error occured');
|
350 |
return $docs;
|
351 |
}
|
352 |
|
@@ -355,27 +426,26 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
355 |
*
|
356 |
* @since 0.1
|
357 |
*/
|
358 |
-
public function get_document($doc_id) {
|
359 |
-
$response = $this->get($this->api_url . '/document/' . $doc_id);
|
360 |
|
361 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
362 |
-
$document = json_decode(wp_remote_retrieve_body($response));
|
363 |
}
|
364 |
|
365 |
-
$this->log_error_on_response_failure($response, 'GetDocument: Error occured');
|
366 |
return $document;
|
367 |
}
|
368 |
|
369 |
-
public function get_document_status($doc_id)
|
370 |
-
|
371 |
-
$
|
372 |
-
$response = $this->get($this->api_url . '/document/' . $doc_id . '/status');
|
373 |
|
374 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
375 |
-
$imported =
|
376 |
}
|
377 |
|
378 |
-
$this->log_error_on_response_failure($response, 'GetDocumentStatus: Error occured', array('document_id' => $doc_id));
|
379 |
return $imported;
|
380 |
}
|
381 |
|
@@ -388,14 +458,14 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
388 |
* @param string $id document id
|
389 |
* @return string
|
390 |
*/
|
391 |
-
public function get_document_content($doc_id) {
|
392 |
-
$response = $this->get($this->api_url . "/document/$doc_id/content");
|
393 |
|
394 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
395 |
$content = wp_remote_retrieve_body( $response );
|
396 |
}
|
397 |
|
398 |
-
$this->log_error_on_response_failure($response, 'GetDocumentContent: Error occured',
|
399 |
return $content;
|
400 |
}
|
401 |
|
@@ -408,16 +478,23 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
408 |
* @param string $locale locale
|
409 |
* @return int with locale percent_complete
|
410 |
*/
|
411 |
-
public function get_translation_status($doc_id, $locale) {
|
412 |
-
$locale
|
413 |
-
$status
|
414 |
-
$response = $this->get($this->api_url."/document/$doc_id/translation/$locale");
|
415 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
416 |
-
$b
|
417 |
$status = $b->properties->percent_complete;
|
418 |
}
|
419 |
|
420 |
-
$this->log_error_on_response_failure(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
return $status;
|
422 |
}
|
423 |
|
@@ -429,150 +506,209 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
429 |
* @param string $id document id
|
430 |
* @return array with locale as key and status as value
|
431 |
*/
|
432 |
-
public function get_translations_status($doc_id, $wp_id = null) {
|
433 |
-
$response = $this->get($this->api_url . '/document/' . $doc_id . '/translation');
|
434 |
-
if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
|
435 |
-
$b = json_decode(wp_remote_retrieve_body($response));
|
436 |
-
foreach ($b->entities as $e) {
|
437 |
-
if($e->properties->status != 'CANCELLED') {
|
438 |
// cancelled is in a completed state, but it does not mean the translation is 100% complete
|
439 |
-
$translations[$e->properties->locale_code] =
|
|
|
|
|
|
|
440 |
}
|
441 |
}
|
442 |
}
|
443 |
|
444 |
-
Lingotek_Logger::info(
|
445 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
446 |
$this->update_lingotek_error_option(
|
447 |
-
$response,
|
448 |
-
$wp_id,
|
449 |
-
'get_translations_status',
|
450 |
-
sprintf(__('There was an error updating the translations status for WordPress item %1$s', 'lingotek-translation'), $wp_id),
|
451 |
-
array('document_id'
|
|
|
452 |
|
453 |
-
return empty($translations) ? array() : $translations;
|
454 |
}
|
455 |
|
456 |
|
457 |
-
public function get_language_mappings()
|
458 |
-
|
459 |
-
$
|
460 |
-
|
461 |
-
return json_decode(wp_remote_retrieve_body($response),true);
|
462 |
}
|
463 |
|
464 |
/**
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
public function get_cost_estimate($lingotek_auth, $document_id, $locale) {
|
472 |
$this->start_bridge_call();
|
473 |
|
474 |
-
$args
|
475 |
'document_id' => $document_id,
|
476 |
-
'locale'
|
477 |
);
|
478 |
-
$response = $this->get($this->bridge_url . 'estimate', $args);
|
479 |
|
480 |
-
$success = 200 === wp_remote_retrieve_response_code($response);
|
481 |
|
482 |
$this->end_bridge_call();
|
483 |
|
484 |
-
$this->log_error_on_response_failure(
|
485 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
486 |
}
|
487 |
|
488 |
/**
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
public function request_professional_translation($document_id, $locale, $workflow_id) {
|
496 |
$this->start_bridge_call();
|
497 |
-
|
498 |
-
$args
|
499 |
'document_id' => $document_id,
|
500 |
-
'locale'
|
501 |
'workflow_id' => $workflow_id,
|
502 |
);
|
503 |
-
$response = $this->post($this->bridge_url . 'request', $args);
|
504 |
-
$success
|
505 |
|
506 |
$this->end_bridge_call();
|
507 |
|
508 |
-
if ($success) {
|
509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
-
return array(
|
|
|
|
|
|
|
512 |
}
|
513 |
|
514 |
/**
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
public function request_professional_translation_bulk($workflow_id, $translations, $total_estimate, $summary) {
|
522 |
$this->start_bridge_call();
|
523 |
-
|
524 |
-
$args
|
525 |
-
'workflow_id'
|
526 |
-
'translations'
|
527 |
'total_estimate' => $total_estimate,
|
528 |
-
'summary'
|
529 |
);
|
530 |
-
$response = $this->post($this->bridge_url . 'request/bulk', $args, 60);
|
531 |
-
$success
|
532 |
|
533 |
$this->end_bridge_call();
|
534 |
|
535 |
-
if ($success) {
|
536 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
537 |
|
538 |
-
return array('data' => $this->get_response_body_from_bridge($response));
|
539 |
}
|
540 |
|
541 |
|
542 |
public function get_lingotek_terms_and_conditions() {
|
543 |
$this->start_bridge_call();
|
544 |
-
$response = $this->get(BRIDGE_URL . '/api/v2/transaction/terms/');
|
545 |
-
$success
|
546 |
$this->end_bridge_call();
|
547 |
|
548 |
-
$this->log_error_on_response_failure($response, 'GetLingotekTermsAndConditions: Error occured');
|
549 |
-
return array(
|
|
|
|
|
|
|
550 |
}
|
551 |
|
552 |
/**
|
553 |
-
|
554 |
-
|
555 |
public function get_user_payment_information() {
|
556 |
$this->start_bridge_call();
|
557 |
|
558 |
-
$response = $this->get(BRIDGE_URL . '/api/v2/transaction/payment');
|
559 |
-
$success
|
560 |
|
561 |
$this->end_bridge_call();
|
562 |
|
563 |
-
$this->log_error_on_response_failure($response,
|
564 |
-
return array(
|
|
|
|
|
|
|
565 |
}
|
566 |
|
567 |
/**
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
private function get_response_body_from_bridge($response)
|
573 |
-
|
574 |
-
$body
|
575 |
-
return isset($body) ? $body : wp_remote_retrieve_body($response);
|
576 |
}
|
577 |
|
578 |
/**
|
@@ -582,72 +718,82 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
582 |
*
|
583 |
* @param string $id document id
|
584 |
* @param string $locale Lingotek locale
|
585 |
-
* @param array
|
586 |
* @return bool true if the request succeeded
|
587 |
*/
|
588 |
-
public function request_translation($id, $locale, $args = array(), $wp_id = null) {
|
589 |
-
$lgtm
|
590 |
-
$document = $lgtm->get_group_by_id($id);
|
591 |
-
$locale
|
592 |
-
$args
|
593 |
-
$args
|
594 |
-
$response = $this->post($this->api_url . '/document/' . $id . '/translation', $args);
|
595 |
-
$title
|
596 |
-
if ($wp_id) {
|
597 |
-
$arr
|
598 |
-
$status_code = wp_remote_retrieve_response_code($response);
|
599 |
-
$body
|
600 |
-
$this->update_patch_error_message($response, $status_code, $title);
|
601 |
-
if (423 === $status_code) {
|
602 |
$document->document_id = $body->next_document_id;
|
603 |
$document->save();
|
604 |
-
return $this->request_translation($body->next_document_id, $locale, $unformatted_args, $wp_id);
|
605 |
}
|
606 |
-
if (402 === $status_code) {
|
607 |
-
Lingotek_Logger::error('There was an error updating WordPress item', array('error' => $this->get_error_message_from_response($response)));
|
608 |
$document->source_failed();
|
609 |
return false;
|
610 |
}
|
611 |
-
if (410 === $status_code) {
|
612 |
// WP hooks automatically check source status so this might not get called
|
613 |
-
$targets
|
614 |
-
$targets[]
|
615 |
$unformatted_args['translation_locale_code'] = $targets;
|
616 |
-
$this->format_args_for_upload($unformatted_args, $wp_id);
|
617 |
-
unset($document->desc_array['lingotek']);
|
618 |
$document->save();
|
619 |
-
foreach ($document->translations as $locale) {
|
620 |
-
$document->translations[$locale] = 'pending';
|
621 |
}
|
622 |
-
return $this->upload_document($unformatted_args, $wp_id);
|
623 |
}
|
624 |
-
if (400 === $status_code &&
|
625 |
-
!empty($body->messages) &&
|
626 |
-
strpos($body->messages[0], 'already exists')) {
|
627 |
// Translation has already been requested, treat it as a 201 response
|
628 |
$status_code = 201;
|
629 |
}
|
630 |
-
if (201 === $status_code) {
|
631 |
-
if (isset($arr[$wp_id])) {
|
632 |
-
unset($arr[$wp_id]['wp_error']);
|
633 |
-
unset($arr[$wp_id]['request_translation'][$locale]);
|
634 |
-
if (empty($arr[$wp_id])){
|
635 |
-
unset($arr[$wp_id]);
|
636 |
}
|
637 |
}
|
638 |
-
} elseif (is_wp_error($response)) {
|
639 |
-
$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
|
640 |
-
} elseif (400 == $status_code || 404 == $status_code) {
|
641 |
-
$arr[$wp_id]['request_translation'][$locale] = sprintf(
|
642 |
-
__('There was an error requesting translation %1$s for WordPress item %2$s', 'lingotek-translation'),
|
|
|
|
|
643 |
);
|
644 |
}
|
645 |
-
update_option('lingotek_log_errors', $arr, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
}
|
647 |
-
|
648 |
-
$this->log_error_on_response_failure($response, "RequestTranslation: Error Occurred", ['document_id' => $id, 'locale' => $locale, 'args' => $args]);
|
649 |
-
}
|
650 |
-
return !is_wp_error($response) && 201 === $status_code;
|
651 |
}
|
652 |
|
653 |
/**
|
@@ -659,77 +805,112 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
659 |
* @param string $locale Lingotek locale
|
660 |
* @return string|bool the translation, false if there is none
|
661 |
*/
|
662 |
-
public function get_translation($doc_id, $locale, $wp_id = null) {
|
663 |
-
$locale = Lingotek::map_to_lingotek_locale($locale);
|
664 |
-
|
665 |
-
$response = $this->get(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
|
667 |
-
if ($wp_id) {
|
668 |
-
$arr
|
669 |
-
$status_code = wp_remote_retrieve_response_code($response);
|
670 |
-
if (410 == $status_code) {
|
671 |
-
$lgtm
|
672 |
-
$document = $lgtm->get_group_by_id($doc_id);
|
673 |
$document->source_failed();
|
674 |
//TODO IS THIS SETTING ERROR PROPERLY?
|
675 |
-
$arr[$wp_id]['wp_error'] = __("Document $doc_id has been archived. Please re-upload source", 'lingotek-translation');
|
676 |
return false;
|
677 |
-
}
|
678 |
-
if (isset($arr[$wp_id])) {
|
679 |
-
unset($arr[$wp_id]['wp_error']);
|
680 |
-
unset($arr[$wp_id]['get_translation'][$locale]);
|
681 |
-
if (empty($arr[$wp_id])) {
|
682 |
-
unset($arr[$wp_id]);
|
683 |
}
|
684 |
}
|
685 |
-
}
|
686 |
-
$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
|
687 |
-
}
|
688 |
-
$arr[$wp_id]['get_translation'][$locale] = sprintf(
|
689 |
-
__('There was an error downloading translation %1$s for WordPress item %2$s'),
|
|
|
|
|
690 |
);
|
691 |
-
}
|
692 |
-
update_option('lingotek_log_errors', $arr, false);
|
693 |
-
}
|
694 |
-
$this->log_error_on_response_failure(
|
695 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
696 |
}
|
697 |
|
698 |
/**
|
699 |
* cancels a translation
|
700 |
-
*
|
701 |
* @since 1.4.2
|
702 |
-
*
|
703 |
* @param string $id document id
|
704 |
* @param string $locale Lingotek locale
|
705 |
*/
|
706 |
-
public function cancel_translation($id, $locale, $wp_id = null) {
|
707 |
-
$args
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
|
|
|
|
|
|
|
|
|
|
715 |
}
|
716 |
}
|
717 |
-
$this->log_error_on_response_failure(
|
718 |
-
|
719 |
-
|
720 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
721 |
return $is_success;
|
722 |
}
|
723 |
-
$lingotek_log_errors = get_option('lingotek_log_errors', array());
|
724 |
-
if (!is_array($lingotek_log_errors)) {
|
725 |
$lingotek_log_errors = array();
|
726 |
}
|
727 |
// Use the response message if it's an authorization error
|
728 |
-
$response_error_message
|
729 |
-
$this->get_error_message_from_response($response) :
|
730 |
-
$error_message
|
731 |
$lingotek_log_errors['disassociate_document_error'] = $error_message;
|
732 |
-
update_option('lingotek_log_errors', $lingotek_log_errors, false);
|
733 |
|
734 |
return $is_success;
|
735 |
}
|
@@ -740,64 +921,92 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
740 |
* @param string $redirect_uri the location where to redirect to after account has been connected
|
741 |
* @return string the complete url for the connect account link
|
742 |
*/
|
743 |
-
public function get_connect_url($redirect_uri, $env =
|
744 |
-
$base_url
|
745 |
$client_id = $this->client_id;
|
746 |
-
if(!is_null($env)){
|
747 |
$base_url = self::PRODUCTION_URL;
|
748 |
}
|
749 |
-
return "$base_url/auth/authorize.html?client_id=$client_id&redirect_uri=" . urlencode($redirect_uri) .
|
750 |
}
|
751 |
|
752 |
-
public function get_new_url($redirect_uri) {
|
753 |
-
$base_url
|
754 |
$client_id = $this->client_id;
|
755 |
-
return "$base_url/lingopoint/portal/requestAccount.action?client_id=$client_id&app=" . urlencode($redirect_uri) .
|
756 |
-
|
757 |
}
|
758 |
|
759 |
public function get_communities() {
|
760 |
-
$response = $this->get(add_query_arg(array('limit' => 1000), $this->api_url . '/community'));
|
761 |
-
return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
|
762 |
}
|
763 |
|
764 |
-
public function get_projects($community_id) {
|
765 |
-
$response = $this->get(
|
766 |
-
|
767 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
768 |
}
|
769 |
-
return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
|
770 |
}
|
771 |
|
772 |
-
public function get_vaults($community_id) {
|
773 |
-
$response = $this->get(
|
774 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
775 |
}
|
776 |
|
777 |
-
public function get_workflows($community_id) {
|
778 |
-
$response = $this->get(
|
779 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
780 |
}
|
781 |
|
782 |
public function get_filters() {
|
783 |
-
$response = $this->get(add_query_arg(array('limit' => 1000), $this->api_url . '/filter'));
|
784 |
-
return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
|
785 |
}
|
786 |
|
787 |
-
public function upload_filter($name, $type, $content) {
|
788 |
-
$args
|
789 |
-
|
|
|
|
|
|
|
|
|
790 |
}
|
791 |
|
792 |
private function start_bridge_call() {
|
793 |
$this->auth_temp = $this->headers['Authorization'];
|
794 |
-
unset($this->headers['Authorization']);
|
795 |
-
$option
|
796 |
$this->headers['Authorization-Lingotek'] = $option['access_token'];
|
797 |
}
|
798 |
|
799 |
private function end_bridge_call() {
|
800 |
-
unset($this->headers['Authorization-Lingotek']);
|
801 |
$this->headers['Authorization'] = $this->auth_temp;
|
802 |
}
|
803 |
|
@@ -806,93 +1015,137 @@ class Lingotek_API extends Lingotek_HTTP {
|
|
806 |
}
|
807 |
|
808 |
/**
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
private function update_lingotek_error_option_for_translation($response, $wp_id, $action, $error_message, $locale, $extra_data = array()){
|
819 |
-
if ($wp_id) {
|
820 |
-
$arr
|
821 |
-
$response_message_code = wp_remote_retrieve_response_code($response);
|
822 |
-
if (200 == $response_message_code || 201 == $response_message_code) {
|
823 |
-
if (isset($arr[$wp_id])) {
|
824 |
-
unset($arr[$wp_id]['wp_error']);
|
825 |
-
unset($arr[$wp_id][$action][$locale]);
|
826 |
-
if (empty($arr[$wp_id])) {
|
827 |
-
unset($arr[$wp_id]);
|
828 |
}
|
829 |
}
|
830 |
-
}
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
841 |
}
|
842 |
|
843 |
/**
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
private function update_lingotek_error_option($response, $wp_id, $action, $error_message, $extra_data = array()){
|
853 |
-
if ($wp_id){
|
854 |
-
$arr
|
855 |
-
$response_message_code = wp_remote_retrieve_response_code($response);
|
856 |
-
if (empty($arr)) {
|
857 |
return;
|
858 |
}
|
859 |
|
860 |
-
if (200 == $response_message_code || 202 == $response_message_code) {
|
861 |
-
if (isset($arr[$wp_id])) {
|
862 |
-
unset($arr[$wp_id]);
|
863 |
}
|
864 |
-
}
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
875 |
}
|
876 |
|
877 |
/**
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
private function log_error_on_response_failure($response, $error_message, $extra_data = array()){
|
886 |
-
$http_code = wp_remote_retrieve_response_code($response);
|
887 |
-
$success
|
888 |
-
if (
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
894 |
return false;
|
895 |
}
|
896 |
-
return property_exists($responseBody,
|
897 |
}
|
898 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
require_once 'http.php';
|
4 |
|
5 |
/**
|
6 |
* manages communication with Lingotek TMS
|
14 |
protected $client_id;
|
15 |
private $auth_temp;
|
16 |
|
17 |
+
const PRODUCTION_URL = 'https://myaccount.lingotek.com';
|
18 |
+
// Lingotek App ID.
|
19 |
+
const CLIENT_ID = '780966c9-f9c8-4691-96e2-c0aaf47f62ff';
|
20 |
|
21 |
|
22 |
private $bridge_url = '';
|
27 |
* @since 0.1
|
28 |
*/
|
29 |
public function __construct() {
|
30 |
+
$base_url = get_option( 'lingotek_base_url' );
|
31 |
+
$this->base_url = $base_url ? $base_url : self::PRODUCTION_URL;
|
32 |
+
$this->api_url = $this->base_url . '/api';
|
33 |
$this->client_id = self::CLIENT_ID;
|
34 |
+
$token_details = get_option( 'lingotek_token', array() );
|
35 |
+
if ( isset( $token_details['access_token'] ) ) {
|
36 |
+
$this->headers['Authorization'] = 'bearer ' . $token_details['access_token'];
|
37 |
+
}
|
38 |
+
$this->defaults = get_option( 'lingotek_defaults', array() );
|
39 |
$this->bridge_url = BRIDGE_URL . '/api/v2/transaction/translation/';
|
40 |
}
|
41 |
|
42 |
+
public function get_token_details( $access_token ) {
|
43 |
$url = "{$this->base_url}/auth/oauth2/access_token_info";
|
44 |
+
Lingotek_Logger::debug(
|
45 |
+
'GET',
|
46 |
+
array(
|
47 |
+
'url' => $url,
|
48 |
+
'method' => __METHOD__,
|
49 |
+
)
|
50 |
+
);
|
51 |
+
$args = array(
|
52 |
'headers' => array(
|
53 |
'Authorization' => "Bearer $access_token",
|
54 |
),
|
55 |
);
|
56 |
+
$response = wp_remote_get( $url, $args );
|
57 |
+
$response_code = wp_remote_retrieve_response_code( $response );
|
58 |
|
59 |
+
if ( $response_code == 200 ) {
|
60 |
+
$response_body = json_decode( wp_remote_retrieve_body( $response ) );
|
61 |
$token_details = $response_body;
|
62 |
+
} else {
|
63 |
+
$token_details = false;
|
64 |
}
|
65 |
+
$this->log_error_on_response_failure( $response, 'GetTokenDetails: Error occured' );
|
|
|
|
|
|
|
66 |
return $token_details;
|
67 |
}
|
68 |
|
77 |
*
|
78 |
* @param string $project_id
|
79 |
*/
|
80 |
+
public function update_callback_url( $project_id ) {
|
81 |
+
$args = array( 'callback_url' => add_query_arg( 'lingotek', 1, site_url() ) );
|
82 |
+
$response = $this->patch( $this->api_url . '/project/' . $project_id, $args );
|
83 |
+
Lingotek_Logger::info( 'Request to update callback url', array( 'project_id' => $project_id ) );
|
84 |
+
$this->log_error_on_response_failure( $response, 'UpdateCallbackUrl: Error occured', array( 'project_id' => $project_id ) );
|
85 |
+
return ! is_wp_error( $response ) && 204 == wp_remote_retrieve_response_code( $response );
|
86 |
}
|
87 |
|
88 |
+
/**
|
89 |
* creates a new project
|
90 |
*
|
91 |
* @since 0.2
|
92 |
*
|
93 |
* @param string $title
|
94 |
*/
|
95 |
+
public function create_project( $title, $community_id ) {
|
96 |
$args = array(
|
97 |
+
'title' => $title,
|
98 |
'community_id' => $community_id,
|
99 |
+
'workflow_id' => $this->get_workflow_id(),
|
100 |
+
'callback_url' => add_query_arg( 'lingotek', 1, site_url() ),
|
101 |
);
|
102 |
|
103 |
+
$response = $this->post( $this->api_url . '/project', $args );
|
104 |
+
if ( ! is_wp_error( $response ) && 201 == wp_remote_retrieve_response_code( $response ) ) {
|
105 |
+
$new_id = json_decode( wp_remote_retrieve_body( $response ) );
|
106 |
+
Lingotek_Logger::info(
|
107 |
+
'Project created',
|
108 |
+
array(
|
109 |
+
'id' => $new_id->properties->id,
|
110 |
+
'title' => $title,
|
111 |
+
)
|
112 |
+
);
|
113 |
return $new_id->properties->id;
|
114 |
}
|
115 |
+
|
116 |
+
$this->log_error_on_response_failure(
|
117 |
+
$response,
|
118 |
+
'CreateProject: Error occured',
|
119 |
+
array(
|
120 |
+
'title' => $title,
|
121 |
+
'community_id' => $community_id,
|
122 |
+
)
|
123 |
+
);
|
124 |
return false;
|
125 |
}
|
126 |
|
132 |
* @param array $args expects array with title, content and locale_code
|
133 |
* @returns bool|string document_id, false if something got wrong
|
134 |
*/
|
135 |
+
public function upload_document( $args, $wp_id = null ) {
|
136 |
+
Lingotek::log( debug_backtrace() );
|
137 |
+
Lingotek::log( 'uploading document' );
|
138 |
+
$args = wp_parse_args(
|
139 |
+
$args,
|
140 |
+
array(
|
141 |
+
'format' => 'JSON',
|
142 |
+
'project_id' => $this->defaults['project_id'],
|
143 |
+
'workflow_id' => $this->get_workflow_id(),
|
144 |
+
)
|
145 |
+
);
|
146 |
+
$this->format_as_multipart( $args );
|
147 |
+
$response = $this->post( $this->api_url . '/document', $args );
|
148 |
+
$this->update_lingotek_error_option( $response, $wp_id, 'upload_document', sprintf( __( 'There was an error uploading WordPress item %1$s', 'lingotek-translation' ), $wp_id ) );
|
149 |
+
$code = wp_remote_retrieve_response_code( $response );
|
150 |
+
if ( ! is_wp_error( $response ) && 202 == $code ) {
|
151 |
+
$b = json_decode( wp_remote_retrieve_body( $response ) );
|
152 |
+
Lingotek_Logger::info(
|
153 |
+
'Document uploaded',
|
154 |
+
array(
|
155 |
+
'document_id' => $b->properties->id,
|
156 |
+
'wp_id' => $wp_id,
|
157 |
+
)
|
158 |
+
);
|
159 |
return $b->properties->id;
|
160 |
+
} elseif ( $code == 402 ) {
|
161 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors' );
|
162 |
+
$error_message = $this->get_error_message_from_response( $response ) !== false ?
|
163 |
+
$this->get_error_message_from_response( $response ) : 'No error message set by Lingotek';
|
164 |
+
$lingotek_log_errors['patch_document_error'] = __( "Payment required. Message: $error_message", 'lingotek-translation' );
|
165 |
+
update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
|
166 |
}
|
167 |
return false;
|
168 |
}
|
173 |
* @since 0.1
|
174 |
*
|
175 |
* @param string $id document id
|
176 |
+
* @param array $args expects array with content
|
177 |
+
* @return bool|string false if something got wrong
|
178 |
*/
|
179 |
+
public function patch_document( $id, $args, $wp_id = null ) {
|
180 |
+
$lgtm = $GLOBALS['wp_lingotek']->model;
|
181 |
+
$document = $lgtm->get_group_by_id( $id );
|
182 |
+
$args = $unformatted_args = wp_parse_args( $args, array( 'format' => 'JSON' ) );
|
183 |
+
$title = isset( $args['title'] ) ? $args['title'] : $id;
|
184 |
+
$this->format_as_multipart( $args );
|
185 |
+
$response = $this->patch( $this->api_url . '/document/' . $id, $args );
|
186 |
+
$status_code = wp_remote_retrieve_response_code( $response );
|
187 |
+
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
188 |
+
if ( $status_code == 400 && strpos( $body->messages[0], 'has previously been cancelled' ) ) {
|
189 |
+
// Document has been cancelled, re-upload the post
|
190 |
+
// Slug can't be empty or duplicated, so we prefix `disassociated` to show the document id is no longer associated with this post
|
191 |
+
$document->document_id = 'disassociated_' . $document->document_id;
|
192 |
+
unset( $document->desc_array['lingotek'] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
$document->save();
|
194 |
+
return $lgtm->upload_post( $wp_id );
|
195 |
}
|
196 |
+
if ( $status_code == 423 ) {
|
197 |
$document->document_id = $body->next_document_id;
|
198 |
$document->save();
|
199 |
+
return $this->patch_document( $body->next_document_id, $unformatted_args, $wp_id );
|
200 |
}
|
201 |
|
202 |
// We will handle patch errors separately. All we want to do is return the result of the current patch request to the user if payment is required
|
203 |
// (although in theory this will never happen, because the WP model is document count based, and it will not allow them to upload documents until
|
204 |
// they choose to buy more documents)
|
205 |
+
$this->update_patch_error_message( $response, $status_code, $title );
|
206 |
// The current behavior sends no body, so we will just check to see if the body is empty for now in order to maintain current behavior
|
207 |
+
if ( empty( $body ) ) {
|
208 |
+
$success = ! is_wp_error( $response ) && 202 == wp_remote_retrieve_response_code( $response );
|
209 |
+
if ( $success ) {
|
210 |
+
Lingotek_Logger::info(
|
211 |
+
'Document updated',
|
212 |
+
array(
|
213 |
+
'document_id' => $id,
|
214 |
+
'wp_id' => $wp_id,
|
215 |
+
)
|
216 |
+
);
|
217 |
} else {
|
218 |
+
Lingotek_Logger::error(
|
219 |
+
'Document failed to update',
|
220 |
+
array(
|
221 |
+
'document_id' => $id,
|
222 |
+
'wp_id' => $wp_id,
|
223 |
+
)
|
224 |
+
);
|
225 |
}
|
226 |
return $success;
|
227 |
+
}//end if
|
228 |
+
|
229 |
+
if ( $status_code == 410 ) {
|
230 |
+
Lingotek_Logger::info(
|
231 |
+
'Document ID was archived, reuploading document',
|
232 |
+
array(
|
233 |
+
'old_document_id' => $id,
|
234 |
+
'wp_id' => $wp_id,
|
235 |
+
'args' => $args,
|
236 |
+
)
|
237 |
+
);
|
238 |
+
$targets = array_keys( $document->translations );
|
239 |
$unformatted_args['translation_locale_code'] = $targets;
|
240 |
+
$this->format_args_for_upload( $unformatted_args, $wp_id );
|
241 |
+
foreach ( $document->translations as $locale ) {
|
242 |
+
$document->translations[ $locale ] = 'pending';
|
243 |
}
|
244 |
+
$document->document_id = 'disassociated_' . $document->document_id;
|
245 |
+
unset( $document->desc_array['lingotek'] );
|
246 |
$document->save();
|
247 |
+
return $this->upload_document( $unformatted_args, $wp_id );
|
248 |
}
|
249 |
+
if ( $status_code == 402 ) {
|
250 |
+
Lingotek_Logger::error( 'There was an error updating WordPress item', array( 'error' => $this->get_error_message_from_response( $response ) ) );
|
251 |
$document->source_failed();
|
252 |
+
return false;
|
253 |
}
|
254 |
+
if ( $status_code == 202 && ! is_wp_error( $response ) ) {
|
255 |
+
Lingotek_Logger::info(
|
256 |
+
'Document updated',
|
257 |
+
array(
|
258 |
+
'old_document_id' => $id,
|
259 |
+
'new_document_id' => $body->next_document_id,
|
260 |
+
'wp_id' => $wp_id,
|
261 |
+
)
|
262 |
+
);
|
263 |
$document->document_id = $body->next_document_id;
|
264 |
$document->save();
|
265 |
return $body->next_document_id;
|
266 |
}
|
267 |
+
return false;
|
268 |
}
|
269 |
|
270 |
+
private function format_args_for_upload( &$args, $wp_id ) {
|
271 |
+
$lgtm = $GLOBALS['wp_lingotek']->model;
|
272 |
+
$post = get_post( $wp_id );
|
273 |
+
$language = PLL()->model->post->get_language( $wp_id );
|
274 |
+
$project_id = $lgtm->get_profile_option( 'project_id', $post->post_type, $language, false, $wp_id );
|
275 |
+
$workflow_id = $lgtm->get_profile_option( 'workflow_id', $post->post_type, $language, false, $wp_id );
|
276 |
$locale_code = $language->lingotek_locale;
|
277 |
+
unset( $args['format'] );
|
278 |
$args['locale_code'] = $locale_code;
|
279 |
+
$args['project_id'] = $project_id;
|
280 |
$args['workflow_id'] = $workflow_id;
|
281 |
}
|
282 |
|
283 |
+
private function update_patch_error_message( $response, $status_code, $title ) {
|
284 |
// Do not inform user if call was successful.
|
285 |
+
if ( $status_code == 202 || $status_code == 410 ) {
|
286 |
return;
|
287 |
}
|
288 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
|
289 |
+
if ( ! is_array( $lingotek_log_errors ) ) {
|
290 |
$lingotek_log_errors = array();
|
291 |
}
|
292 |
+
$error_message = $this->get_error_message_from_response( $response ) !== false ?
|
293 |
+
$this->get_error_message_from_response( $response ) : 'No error message set by Lingotek.';
|
294 |
|
295 |
+
if ( $status_code == 402 ) {
|
296 |
+
$lingotek_log_errors['patch_document_error'] = __( "Payment required. Message: $error_message", 'lingotek-translation' );
|
297 |
+
} else {
|
298 |
+
$lingotek_log_errors['patch_document_error'] = __( "Error occurred while updating document $title. Message: $error_message", 'lingotek-translation' );
|
|
|
299 |
}
|
300 |
+
update_option( 'lingotek_log_errors', $lingotek_log_errors );
|
301 |
}
|
302 |
|
303 |
/**
|
304 |
* cancels a document
|
305 |
+
*
|
306 |
* @since 1.4.2
|
307 |
+
*
|
308 |
* @param string $id document id
|
309 |
*/
|
310 |
+
public function cancel_document( &$id, $wp_id = null ) {
|
311 |
+
$args = wp_parse_args( array( 'cancelled_reason' => 'CANCELLED_BY_AUTHOR' ) );
|
312 |
+
$response = $this->post( "$this->api_url/document/$id/cancel", $args );
|
313 |
+
if ( $wp_id ) {
|
314 |
+
$arr = get_option( 'lingotek_log_errors' );
|
315 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
316 |
+
unset( $arr[ $wp_id ] );
|
317 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
318 |
}
|
319 |
}
|
320 |
+
$this->log_error_on_response_failure(
|
321 |
+
$response,
|
322 |
+
'CancelDocument: Error occurred',
|
323 |
+
array(
|
324 |
+
'id' => $id,
|
325 |
+
'wordpress_id' => $wp_id,
|
326 |
+
)
|
327 |
+
);
|
328 |
+
$is_success = ! is_wp_error( $response ) && ( 204 == wp_remote_retrieve_response_code( $response ) || 202 == wp_remote_retrieve_response_code( $response ) );
|
329 |
+
$lgtm = $GLOBALS['wp_lingotek']->model;
|
330 |
+
$document = $lgtm->get_group_by_id( $id );
|
331 |
+
$current_status = $document->status;
|
332 |
$document->status = 'cancelled';
|
333 |
+
if ( $is_success ) {
|
334 |
+
wp_remove_object_terms( $wp_id, "lingotek_hash_{$wp_id}", 'lingotek_hash' );
|
335 |
+
Lingotek_Logger::info(
|
336 |
+
'Document cancelled',
|
337 |
+
array(
|
338 |
+
'document_id' => $id,
|
339 |
+
'wp_id' => $wp_id,
|
340 |
+
)
|
341 |
+
);
|
342 |
$document->save();
|
343 |
return $is_success;
|
344 |
+
} elseif ( 403 != wp_remote_retrieve_response_code( $response ) ) {
|
345 |
+
wp_remove_object_terms( $wp_id, "lingotek_hash_{$wp_id}", 'lingotek_hash' );
|
346 |
+
Lingotek_Logger::warning(
|
347 |
+
'Document was not cancelled in TMS',
|
348 |
+
array(
|
349 |
+
'document' => $id,
|
350 |
+
'wp_id' => $wp_id,
|
351 |
+
)
|
352 |
+
);
|
353 |
+
// Slug can't be empty or duplicated, so we prefix `disassociated` to show the document id is no longer associated with this post
|
354 |
+
$document->document_id = $id = 'disassociated_' . $document->document_id;
|
355 |
$document->save();
|
356 |
return true;
|
357 |
+
}//end if
|
358 |
+
$document->status = $current_status;
|
359 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
|
360 |
+
if ( ! is_array( $lingotek_log_errors ) ) {
|
361 |
$lingotek_log_errors = array();
|
362 |
}
|
363 |
+
$error_message = $this->get_error_message_from_response( $response ) !== false ?
|
364 |
+
$this->get_error_message_from_response( $response ) : 'No error message set by Lingotek.';
|
365 |
$lingotek_log_errors['disassociate_document_error'] = $error_message;
|
366 |
+
update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
|
367 |
return $is_success;
|
368 |
}
|
369 |
|
373 |
*
|
374 |
* @since 0.1
|
375 |
*/
|
376 |
+
public function get_document_ids( $args = array() ) {
|
377 |
+
$response = $this->get( add_query_arg( $args, $this->api_url . '/document' ) );
|
378 |
+
$ids = array();
|
379 |
|
380 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
381 |
+
$documents = json_decode( wp_remote_retrieve_body( $response ) );
|
382 |
+
foreach ( $documents->entities as $doc ) {
|
383 |
$ids[] = $doc->properties->id;
|
384 |
}
|
385 |
}
|
386 |
|
387 |
+
$this->log_error_on_response_failure( $response, 'GetDocumentIds: Error occured' );
|
388 |
return $ids;
|
389 |
}
|
390 |
|
391 |
+
public function get_document_count( $args = array() ) {
|
392 |
+
$response = $this->get( add_query_arg( $args, $this->api_url . '/document' ) );
|
393 |
+
$docs = array();
|
394 |
|
395 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
396 |
+
$response = json_decode( wp_remote_retrieve_body( $response ) );
|
397 |
return $response->properties->total;
|
398 |
}
|
399 |
|
400 |
+
$this->log_error_on_response_failure( $response, 'GetDocumentCount: Error occured' );
|
401 |
return null;
|
402 |
}
|
403 |
|
406 |
*
|
407 |
* @since 0.1
|
408 |
*/
|
409 |
+
public function get_documents( $args = array() ) {
|
410 |
+
$response = $this->get( add_query_arg( $args, $this->api_url . '/document' ) );
|
411 |
+
$docs = array();
|
412 |
|
413 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
414 |
+
$documents = json_decode( wp_remote_retrieve_body( $response ) );
|
415 |
+
foreach ( $documents->entities as $doc ) {
|
416 |
$docs[] = $doc;
|
417 |
}
|
418 |
}
|
419 |
|
420 |
+
$this->log_error_on_response_failure( $response, 'GetDocuments: Error occured' );
|
421 |
return $docs;
|
422 |
}
|
423 |
|
426 |
*
|
427 |
* @since 0.1
|
428 |
*/
|
429 |
+
public function get_document( $doc_id ) {
|
430 |
+
$response = $this->get( $this->api_url . '/document/' . $doc_id );
|
431 |
|
432 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
433 |
+
$document = json_decode( wp_remote_retrieve_body( $response ) );
|
434 |
}
|
435 |
|
436 |
+
$this->log_error_on_response_failure( $response, 'GetDocument: Error occured' );
|
437 |
return $document;
|
438 |
}
|
439 |
|
440 |
+
public function get_document_status( $doc_id ) {
|
441 |
+
$imported = false;
|
442 |
+
$response = $this->get( $this->api_url . '/document/' . $doc_id . '/status' );
|
|
|
443 |
|
444 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
445 |
+
$imported = true;
|
446 |
}
|
447 |
|
448 |
+
$this->log_error_on_response_failure( $response, 'GetDocumentStatus: Error occured', array( 'document_id' => $doc_id ) );
|
449 |
return $imported;
|
450 |
}
|
451 |
|
458 |
* @param string $id document id
|
459 |
* @return string
|
460 |
*/
|
461 |
+
public function get_document_content( $doc_id ) {
|
462 |
+
$response = $this->get( $this->api_url . "/document/$doc_id/content" );
|
463 |
|
464 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
465 |
$content = wp_remote_retrieve_body( $response );
|
466 |
}
|
467 |
|
468 |
+
$this->log_error_on_response_failure( $response, 'GetDocumentContent: Error occured', array( 'document_id' => $doc_id ) );
|
469 |
return $content;
|
470 |
}
|
471 |
|
478 |
* @param string $locale locale
|
479 |
* @return int with locale percent_complete
|
480 |
*/
|
481 |
+
public function get_translation_status( $doc_id, $locale ) {
|
482 |
+
$locale = Lingotek::map_to_lingotek_locale( $locale );
|
483 |
+
$status = -1;
|
484 |
+
$response = $this->get( $this->api_url . "/document/$doc_id/translation/$locale" );
|
485 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
486 |
+
$b = json_decode( wp_remote_retrieve_body( $response ) );
|
487 |
$status = $b->properties->percent_complete;
|
488 |
}
|
489 |
|
490 |
+
$this->log_error_on_response_failure(
|
491 |
+
$response,
|
492 |
+
'GetTranslationStatus: Error occurred',
|
493 |
+
array(
|
494 |
+
'document_id' => $doc_id,
|
495 |
+
'locale' => $locale,
|
496 |
+
)
|
497 |
+
);
|
498 |
return $status;
|
499 |
}
|
500 |
|
506 |
* @param string $id document id
|
507 |
* @return array with locale as key and status as value
|
508 |
*/
|
509 |
+
public function get_translations_status( $doc_id, $wp_id = null ) {
|
510 |
+
$response = $this->get( $this->api_url . '/document/' . $doc_id . '/translation' );
|
511 |
+
if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
512 |
+
$b = json_decode( wp_remote_retrieve_body( $response ) );
|
513 |
+
foreach ( $b->entities as $e ) {
|
514 |
+
if ( $e->properties->status != 'CANCELLED' ) {
|
515 |
// cancelled is in a completed state, but it does not mean the translation is 100% complete
|
516 |
+
$translations[ $e->properties->locale_code ] = array(
|
517 |
+
'progress' => $e->properties->status,
|
518 |
+
'percent_complete' => $e->properties->percent_complete,
|
519 |
+
);
|
520 |
}
|
521 |
}
|
522 |
}
|
523 |
|
524 |
+
Lingotek_Logger::info(
|
525 |
+
'Translation status requested',
|
526 |
+
array(
|
527 |
+
'document_id' => $doc_id,
|
528 |
+
'wp_id' => $wp_id,
|
529 |
+
'translations' => isset( $translations ) ? $translations : '',
|
530 |
+
)
|
531 |
+
);
|
532 |
+
|
533 |
$this->update_lingotek_error_option(
|
534 |
+
$response,
|
535 |
+
$wp_id,
|
536 |
+
'get_translations_status',
|
537 |
+
sprintf( __( 'There was an error updating the translations status for WordPress item %1$s', 'lingotek-translation' ), $wp_id ),
|
538 |
+
array( 'document_id' => $doc_id )
|
539 |
+
);
|
540 |
|
541 |
+
return empty( $translations ) ? array() : $translations;
|
542 |
}
|
543 |
|
544 |
|
545 |
+
public function get_language_mappings() {
|
546 |
+
$url = 'https://gmc.lingotek.com/v1/locales';
|
547 |
+
$response = $this->get( $url );
|
548 |
+
return json_decode( wp_remote_retrieve_body( $response ), true );
|
|
|
549 |
}
|
550 |
|
551 |
/**
|
552 |
+
* Makes an API call to bridge to get the estimated cost for translating a particular document professionally.
|
553 |
+
*
|
554 |
+
* @param string $lingotek_auth the auth token to make an API call to bridge.
|
555 |
+
* @param string $document_id the id of the specific document.
|
556 |
+
* @param string $locale the locale of the document being requested.
|
557 |
+
*/
|
558 |
+
public function get_cost_estimate( $lingotek_auth, $document_id, $locale ) {
|
559 |
$this->start_bridge_call();
|
560 |
|
561 |
+
$args = array(
|
562 |
'document_id' => $document_id,
|
563 |
+
'locale' => $locale,
|
564 |
);
|
565 |
+
$response = $this->get( $this->bridge_url . 'estimate', $args );
|
566 |
|
567 |
+
$success = 200 === wp_remote_retrieve_response_code( $response );
|
568 |
|
569 |
$this->end_bridge_call();
|
570 |
|
571 |
+
$this->log_error_on_response_failure(
|
572 |
+
$response,
|
573 |
+
'GetCostEstimate: Error occured',
|
574 |
+
array(
|
575 |
+
'document_id' => $document_id,
|
576 |
+
'locale' => $locale,
|
577 |
+
)
|
578 |
+
);
|
579 |
+
return array(
|
580 |
+
'success' => $success,
|
581 |
+
'data' => $this->get_response_body_from_bridge( $response ),
|
582 |
+
);
|
583 |
}
|
584 |
|
585 |
/**
|
586 |
+
* Makes an API call to bridge request translation for a document using the professional workflow.
|
587 |
+
*
|
588 |
+
* @param string $document_id the id of the specific document.
|
589 |
+
* @param string $locale the locale of the document being requested.
|
590 |
+
* @param string $workflow_id the id used to process the document.
|
591 |
+
*/
|
592 |
+
public function request_professional_translation( $document_id, $locale, $workflow_id ) {
|
593 |
$this->start_bridge_call();
|
594 |
+
|
595 |
+
$args = array(
|
596 |
'document_id' => $document_id,
|
597 |
+
'locale' => $locale,
|
598 |
'workflow_id' => $workflow_id,
|
599 |
);
|
600 |
+
$response = $this->post( $this->bridge_url . 'request', $args );
|
601 |
+
$success = 200 === wp_remote_retrieve_response_code( $response );
|
602 |
|
603 |
$this->end_bridge_call();
|
604 |
|
605 |
+
if ( $success ) {
|
606 |
+
Lingotek_Logger::info(
|
607 |
+
'Professional translation requested',
|
608 |
+
array(
|
609 |
+
'document_id' => $document_id,
|
610 |
+
'locale' => $locale,
|
611 |
+
'wordflow_id' => $workflow_id,
|
612 |
+
)
|
613 |
+
); }
|
614 |
+
$this->log_error_on_response_failure(
|
615 |
+
$response,
|
616 |
+
'RequestProfessionalTranslation: Error occured',
|
617 |
+
array(
|
618 |
+
'document_id' => $document_id,
|
619 |
+
'locale' => $locale,
|
620 |
+
'workflow_id' => $workflow_id,
|
621 |
+
)
|
622 |
+
);
|
623 |
|
624 |
+
return array(
|
625 |
+
'success' => $success,
|
626 |
+
'data' => $this->get_response_body_from_bridge( $response ),
|
627 |
+
);
|
628 |
}
|
629 |
|
630 |
/**
|
631 |
+
* Makes an API call to bridge request bulk translations for a document using the professional workflow.
|
632 |
+
*
|
633 |
+
* @param string $document_id the id of the specific document.
|
634 |
+
* @param string $locale the locale of the document being requested.
|
635 |
+
* @param string $workflow_id the id used to process the document.
|
636 |
+
*/
|
637 |
+
public function request_professional_translation_bulk( $workflow_id, $translations, $total_estimate, $summary ) {
|
638 |
$this->start_bridge_call();
|
639 |
+
|
640 |
+
$args = array(
|
641 |
+
'workflow_id' => $workflow_id,
|
642 |
+
'translations' => $translations,
|
643 |
'total_estimate' => $total_estimate,
|
644 |
+
'summary' => $summary,
|
645 |
);
|
646 |
+
$response = $this->post( $this->bridge_url . 'request/bulk', $args, 60 );
|
647 |
+
$success = 200 === wp_remote_retrieve_response_code( $response );
|
648 |
|
649 |
$this->end_bridge_call();
|
650 |
|
651 |
+
if ( $success ) {
|
652 |
+
Lingotek_Logger::info(
|
653 |
+
'Professional translation (bulk) requested',
|
654 |
+
array(
|
655 |
+
'translations' => $translations,
|
656 |
+
'wordflow_id' => $workflow_id,
|
657 |
+
)
|
658 |
+
); }
|
659 |
+
$this->log_error_on_response_failure(
|
660 |
+
$response,
|
661 |
+
'RequestProfessionalTranslationBulk: Error occured',
|
662 |
+
array(
|
663 |
+
'translations' => $translations,
|
664 |
+
'total_estimate' => $total_estimate,
|
665 |
+
'workflow_id' => $workflow_id,
|
666 |
+
)
|
667 |
+
);
|
668 |
|
669 |
+
return array( 'data' => $this->get_response_body_from_bridge( $response ) );
|
670 |
}
|
671 |
|
672 |
|
673 |
public function get_lingotek_terms_and_conditions() {
|
674 |
$this->start_bridge_call();
|
675 |
+
$response = $this->get( BRIDGE_URL . '/api/v2/transaction/terms/' );
|
676 |
+
$success = 200 === wp_remote_retrieve_response_code( $response );
|
677 |
$this->end_bridge_call();
|
678 |
|
679 |
+
$this->log_error_on_response_failure( $response, 'GetLingotekTermsAndConditions: Error occured' );
|
680 |
+
return array(
|
681 |
+
'success' => $success,
|
682 |
+
'data' => $this->get_response_body_from_bridge( $response ),
|
683 |
+
);
|
684 |
}
|
685 |
|
686 |
/**
|
687 |
+
* Makes an API call to bridge to get the payment information about the user.
|
688 |
+
*/
|
689 |
public function get_user_payment_information() {
|
690 |
$this->start_bridge_call();
|
691 |
|
692 |
+
$response = $this->get( BRIDGE_URL . '/api/v2/transaction/payment' );
|
693 |
+
$success = 200 === wp_remote_retrieve_response_code( $response );
|
694 |
|
695 |
$this->end_bridge_call();
|
696 |
|
697 |
+
$this->log_error_on_response_failure( $response, 'GetUserPaymentInformation: Error occured' );
|
698 |
+
return array(
|
699 |
+
'success' => $success,
|
700 |
+
'payment_info' => $this->get_response_body_from_bridge( $response ),
|
701 |
+
);
|
702 |
}
|
703 |
|
704 |
/**
|
705 |
+
* Helper function to retrieve the response body from bridge.
|
706 |
+
*
|
707 |
+
* @param array $response the response from bridge.
|
708 |
+
*/
|
709 |
+
private function get_response_body_from_bridge( $response ) {
|
710 |
+
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
711 |
+
return isset( $body ) ? $body : wp_remote_retrieve_body( $response );
|
|
|
712 |
}
|
713 |
|
714 |
/**
|
718 |
*
|
719 |
* @param string $id document id
|
720 |
* @param string $locale Lingotek locale
|
721 |
+
* @param array $args optional arguments (only workflow_id at the moment)
|
722 |
* @return bool true if the request succeeded
|
723 |
*/
|
724 |
+
public function request_translation( $id, $locale, $args = array(), $wp_id = null ) {
|
725 |
+
$lgtm = $GLOBALS['wp_lingotek']->model;
|
726 |
+
$document = $lgtm->get_group_by_id( $id );
|
727 |
+
$locale = Lingotek::map_to_lingotek_locale( $locale );
|
728 |
+
$args = $unformatted_args = wp_parse_args( $args, array( 'workflow_id' => $this->get_workflow_id() ) );
|
729 |
+
$args = array_merge( array( 'locale_code' => $locale ), $args );
|
730 |
+
$response = $this->post( $this->api_url . '/document/' . $id . '/translation', $args );
|
731 |
+
$title = isset( $args['title'] ) ? $args['title'] : $id;
|
732 |
+
if ( $wp_id ) {
|
733 |
+
$arr = get_option( 'lingotek_log_errors', array() );
|
734 |
+
$status_code = wp_remote_retrieve_response_code( $response );
|
735 |
+
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
736 |
+
$this->update_patch_error_message( $response, $status_code, $title );
|
737 |
+
if ( 423 === $status_code ) {
|
738 |
$document->document_id = $body->next_document_id;
|
739 |
$document->save();
|
740 |
+
return $this->request_translation( $body->next_document_id, $locale, $unformatted_args, $wp_id );
|
741 |
}
|
742 |
+
if ( 402 === $status_code ) {
|
743 |
+
Lingotek_Logger::error( 'There was an error updating WordPress item', array( 'error' => $this->get_error_message_from_response( $response ) ) );
|
744 |
$document->source_failed();
|
745 |
return false;
|
746 |
}
|
747 |
+
if ( 410 === $status_code ) {
|
748 |
// WP hooks automatically check source status so this might not get called
|
749 |
+
$targets = array_keys( $document->translations );
|
750 |
+
$targets[] = $locale;
|
751 |
$unformatted_args['translation_locale_code'] = $targets;
|
752 |
+
$this->format_args_for_upload( $unformatted_args, $wp_id );
|
753 |
+
unset( $document->desc_array['lingotek'] );
|
754 |
$document->save();
|
755 |
+
foreach ( $document->translations as $locale ) {
|
756 |
+
$document->translations[ $locale ] = 'pending';
|
757 |
}
|
758 |
+
return $this->upload_document( $unformatted_args, $wp_id );
|
759 |
}
|
760 |
+
if ( 400 === $status_code &&
|
761 |
+
! empty( $body->messages ) &&
|
762 |
+
strpos( $body->messages[0], 'already exists' ) ) {
|
763 |
// Translation has already been requested, treat it as a 201 response
|
764 |
$status_code = 201;
|
765 |
}
|
766 |
+
if ( 201 === $status_code ) {
|
767 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
768 |
+
unset( $arr[ $wp_id ]['wp_error'] );
|
769 |
+
unset( $arr[ $wp_id ]['request_translation'][ $locale ] );
|
770 |
+
if ( empty( $arr[ $wp_id ] ) ) {
|
771 |
+
unset( $arr[ $wp_id ] );
|
772 |
}
|
773 |
}
|
774 |
+
} elseif ( is_wp_error( $response ) ) {
|
775 |
+
$arr[ $wp_id ]['wp_error'] = __( 'Make sure you have internet connectivity', 'lingotek-translation' );
|
776 |
+
} elseif ( 400 == $status_code || 404 == $status_code ) {
|
777 |
+
$arr[ $wp_id ]['request_translation'][ $locale ] = sprintf(
|
778 |
+
__( 'There was an error requesting translation %1$s for WordPress item %2$s', 'lingotek-translation' ),
|
779 |
+
$locale,
|
780 |
+
$wp_id
|
781 |
);
|
782 |
}
|
783 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
784 |
+
}//end if
|
785 |
+
if ( 201 !== $status_code ) {
|
786 |
+
$this->log_error_on_response_failure(
|
787 |
+
$response,
|
788 |
+
'RequestTranslation: Error Occurred',
|
789 |
+
array(
|
790 |
+
'document_id' => $id,
|
791 |
+
'locale' => $locale,
|
792 |
+
'args' => $args,
|
793 |
+
)
|
794 |
+
);
|
795 |
}
|
796 |
+
return ! is_wp_error( $response ) && 201 === $status_code;
|
|
|
|
|
|
|
797 |
}
|
798 |
|
799 |
/**
|
805 |
* @param string $locale Lingotek locale
|
806 |
* @return string|bool the translation, false if there is none
|
807 |
*/
|
808 |
+
public function get_translation( $doc_id, $locale, $wp_id = null ) {
|
809 |
+
$locale = Lingotek::map_to_lingotek_locale( $locale );
|
810 |
+
|
811 |
+
$response = $this->get(
|
812 |
+
add_query_arg(
|
813 |
+
array(
|
814 |
+
'locale_code' => $locale,
|
815 |
+
'auto_format' => 'true',
|
816 |
+
),
|
817 |
+
$this->api_url . '/document/' . $doc_id . '/content'
|
818 |
+
)
|
819 |
+
);
|
820 |
|
821 |
+
if ( $wp_id ) {
|
822 |
+
$arr = get_option( 'lingotek_log_errors' );
|
823 |
+
$status_code = wp_remote_retrieve_response_code( $response );
|
824 |
+
if ( 410 == $status_code ) {
|
825 |
+
$lgtm = $GLOBALS['wp_lingotek']->model;
|
826 |
+
$document = $lgtm->get_group_by_id( $doc_id );
|
827 |
$document->source_failed();
|
828 |
//TODO IS THIS SETTING ERROR PROPERLY?
|
829 |
+
$arr[ $wp_id ]['wp_error'] = __( "Document $doc_id has been archived. Please re-upload source", 'lingotek-translation' );
|
830 |
return false;
|
831 |
+
} elseif ( 200 == $status_code ) {
|
832 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
833 |
+
unset( $arr[ $wp_id ]['wp_error'] );
|
834 |
+
unset( $arr[ $wp_id ]['get_translation'][ $locale ] );
|
835 |
+
if ( empty( $arr[ $wp_id ] ) ) {
|
836 |
+
unset( $arr[ $wp_id ] );
|
837 |
}
|
838 |
}
|
839 |
+
} elseif ( is_wp_error( $response ) ) {
|
840 |
+
$arr[ $wp_id ]['wp_error'] = __( 'Make sure you have internet connectivity', 'lingotek-translation' );
|
841 |
+
} elseif ( 400 == $status_code || 404 == $status_code ) {
|
842 |
+
$arr[ $wp_id ]['get_translation'][ $locale ] = sprintf(
|
843 |
+
__( 'There was an error downloading translation %1$s for WordPress item %2$s' ),
|
844 |
+
$locale,
|
845 |
+
$wp_id
|
846 |
);
|
847 |
+
}//end if
|
848 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
849 |
+
}//end if
|
850 |
+
$this->log_error_on_response_failure(
|
851 |
+
$response,
|
852 |
+
'GetTranslation: Error Occurred',
|
853 |
+
array(
|
854 |
+
'document_id' => $doc_id,
|
855 |
+
'locale' => $locale,
|
856 |
+
)
|
857 |
+
);
|
858 |
+
return ! is_wp_error( $response ) && 200 == $status_code ? wp_remote_retrieve_body( $response ) : false;
|
859 |
}
|
860 |
|
861 |
/**
|
862 |
* cancels a translation
|
863 |
+
*
|
864 |
* @since 1.4.2
|
865 |
+
*
|
866 |
* @param string $id document id
|
867 |
* @param string $locale Lingotek locale
|
868 |
*/
|
869 |
+
public function cancel_translation( $id, $locale, $wp_id = null ) {
|
870 |
+
$args = wp_parse_args(
|
871 |
+
array(
|
872 |
+
'cancelled_reason' => 'CANCELLED_BY_AUTHOR',
|
873 |
+
'mark_invoiceable' => true,
|
874 |
+
)
|
875 |
+
);
|
876 |
+
$response = $this->post( "$this->api_url/document/$id/translation/$locale/cancel", $args );
|
877 |
+
|
878 |
+
if ( $wp_id ) {
|
879 |
+
$arr = get_option( 'lingotek_log_errors' );
|
880 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
881 |
+
unset( $arr[ $wp_id ] );
|
882 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
883 |
}
|
884 |
}
|
885 |
+
$this->log_error_on_response_failure(
|
886 |
+
$response,
|
887 |
+
'CancelTranslation: Error occurred',
|
888 |
+
array(
|
889 |
+
'id' => $id,
|
890 |
+
'wordpress_id' => $wp_id,
|
891 |
+
)
|
892 |
+
);
|
893 |
+
$is_success = ! is_wp_error( $response ) && ( 204 == wp_remote_retrieve_response_code( $response ) || 202 == wp_remote_retrieve_response_code( $response ) );
|
894 |
+
if ( $is_success ) {
|
895 |
+
Lingotek_Logger::info(
|
896 |
+
'Target cancelled',
|
897 |
+
array(
|
898 |
+
'document_id' => $id,
|
899 |
+
'wp_id' => $wp_id,
|
900 |
+
)
|
901 |
+
);
|
902 |
return $is_success;
|
903 |
}
|
904 |
+
$lingotek_log_errors = get_option( 'lingotek_log_errors', array() );
|
905 |
+
if ( ! is_array( $lingotek_log_errors ) ) {
|
906 |
$lingotek_log_errors = array();
|
907 |
}
|
908 |
// Use the response message if it's an authorization error
|
909 |
+
$response_error_message = 403 == wp_remote_retrieve_response_code( $response ) && $this->get_error_message_from_response( $response ) !== false ?
|
910 |
+
$this->get_error_message_from_response( $response ) : false;
|
911 |
+
$error_message = $response_error_message ? $response_error_message : "{$locale} was already completed in the TMS and cannot be cancelled unless the entire document is cancelled.";
|
912 |
$lingotek_log_errors['disassociate_document_error'] = $error_message;
|
913 |
+
update_option( 'lingotek_log_errors', $lingotek_log_errors, false );
|
914 |
|
915 |
return $is_success;
|
916 |
}
|
921 |
* @param string $redirect_uri the location where to redirect to after account has been connected
|
922 |
* @return string the complete url for the connect account link
|
923 |
*/
|
924 |
+
public function get_connect_url( $redirect_uri, $env = null ) {
|
925 |
+
$base_url = $this->base_url;
|
926 |
$client_id = $this->client_id;
|
927 |
+
if ( ! is_null( $env ) ) {
|
928 |
$base_url = self::PRODUCTION_URL;
|
929 |
}
|
930 |
+
return "$base_url/auth/authorize.html?client_id=$client_id&redirect_uri=" . urlencode( $redirect_uri ) . '&response_type=token';
|
931 |
}
|
932 |
|
933 |
+
public function get_new_url( $redirect_uri ) {
|
934 |
+
$base_url = self::PRODUCTION_URL;
|
935 |
$client_id = $this->client_id;
|
936 |
+
return "$base_url/lingopoint/portal/requestAccount.action?client_id=$client_id&app=" . urlencode( $redirect_uri ) . '&response_type=token';
|
|
|
937 |
}
|
938 |
|
939 |
public function get_communities() {
|
940 |
+
$response = $this->get( add_query_arg( array( 'limit' => 1000 ), $this->api_url . '/community' ) );
|
941 |
+
return ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : false;
|
942 |
}
|
943 |
|
944 |
+
public function get_projects( $community_id ) {
|
945 |
+
$response = $this->get(
|
946 |
+
add_query_arg(
|
947 |
+
array(
|
948 |
+
'community_id' => $community_id,
|
949 |
+
'limit' => 1000,
|
950 |
+
),
|
951 |
+
$this->api_url . '/project'
|
952 |
+
)
|
953 |
+
);
|
954 |
+
if ( wp_remote_retrieve_response_code( $response ) == 204 ) {
|
955 |
+
// There are currently no projects.
|
956 |
+
return array();
|
957 |
}
|
958 |
+
return ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : false;
|
959 |
}
|
960 |
|
961 |
+
public function get_vaults( $community_id ) {
|
962 |
+
$response = $this->get(
|
963 |
+
add_query_arg(
|
964 |
+
array(
|
965 |
+
'community_id' => $community_id,
|
966 |
+
'limit' => 1000,
|
967 |
+
),
|
968 |
+
$this->api_url . '/vault'
|
969 |
+
)
|
970 |
+
);
|
971 |
+
return ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : false;
|
972 |
}
|
973 |
|
974 |
+
public function get_workflows( $community_id ) {
|
975 |
+
$response = $this->get(
|
976 |
+
add_query_arg(
|
977 |
+
array(
|
978 |
+
'community_id' => $community_id,
|
979 |
+
'limit' => 1000,
|
980 |
+
),
|
981 |
+
$this->api_url . '/workflow'
|
982 |
+
)
|
983 |
+
);
|
984 |
+
return ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : false;
|
985 |
}
|
986 |
|
987 |
public function get_filters() {
|
988 |
+
$response = $this->get( add_query_arg( array( 'limit' => 1000 ), $this->api_url . '/filter' ) );
|
989 |
+
return ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : false;
|
990 |
}
|
991 |
|
992 |
+
public function upload_filter( $name, $type, $content ) {
|
993 |
+
$args = array(
|
994 |
+
'name' => $name,
|
995 |
+
'type' => $type,
|
996 |
+
'content' => $content,
|
997 |
+
);
|
998 |
+
$response = $this->post( "$this->api_url/filter", $args );
|
999 |
}
|
1000 |
|
1001 |
private function start_bridge_call() {
|
1002 |
$this->auth_temp = $this->headers['Authorization'];
|
1003 |
+
unset( $this->headers['Authorization'] );
|
1004 |
+
$option = get_option( 'lingotek_token' );
|
1005 |
$this->headers['Authorization-Lingotek'] = $option['access_token'];
|
1006 |
}
|
1007 |
|
1008 |
private function end_bridge_call() {
|
1009 |
+
unset( $this->headers['Authorization-Lingotek'] );
|
1010 |
$this->headers['Authorization'] = $this->auth_temp;
|
1011 |
}
|
1012 |
|
1015 |
}
|
1016 |
|
1017 |
/**
|
1018 |
+
* Helper function to update lingotek errors as 'lingotek_log_errors' option in case of translation actions (get / request).
|
1019 |
+
*
|
1020 |
+
* @param $response the response from the action (wp_remote_*).
|
1021 |
+
* @param $wp_id id that represents the object in the WP world (post_id / term_id / etc)
|
1022 |
+
* @param $action the name of the action performed (for ex 'reqeust_translation')
|
1023 |
+
* @param $error_message the message to write in case the response indicates failure
|
1024 |
+
* @param $locale the locale the translation action was performed on
|
1025 |
+
* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
|
1026 |
+
*/
|
1027 |
+
private function update_lingotek_error_option_for_translation( $response, $wp_id, $action, $error_message, $locale, $extra_data = array() ) {
|
1028 |
+
if ( $wp_id ) {
|
1029 |
+
$arr = get_option( 'lingotek_log_errors' );
|
1030 |
+
$response_message_code = wp_remote_retrieve_response_code( $response );
|
1031 |
+
if ( 200 == $response_message_code || 201 == $response_message_code ) {
|
1032 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
1033 |
+
unset( $arr[ $wp_id ]['wp_error'] );
|
1034 |
+
unset( $arr[ $wp_id ][ $action ][ $locale ] );
|
1035 |
+
if ( empty( $arr[ $wp_id ] ) ) {
|
1036 |
+
unset( $arr[ $wp_id ] );
|
1037 |
}
|
1038 |
}
|
1039 |
+
} elseif ( is_wp_error( $response ) ) {
|
1040 |
+
$arr[ $wp_id ]['wp_error'] = __( 'Make sure you have internet connectivity', 'lingotek-translation' );
|
1041 |
+
Lingotek_Logger::error(
|
1042 |
+
$action . ': WordPress error occured, please make sure you have internet connectivity',
|
1043 |
+
array_merge(
|
1044 |
+
array(
|
1045 |
+
'http_status' => $response_message_code,
|
1046 |
+
'wordpress_id' => $wp_id,
|
1047 |
+
),
|
1048 |
+
$extra_data
|
1049 |
+
)
|
1050 |
+
);
|
1051 |
+
} elseif ( 400 == $response_message_code || 404 == $response_message_code ) {
|
1052 |
+
$arr[ $wp_id ][ $action ][ $locale ] = $error_message;
|
1053 |
+
Lingotek_Logger::error(
|
1054 |
+
$action . ': Error occured',
|
1055 |
+
array_merge(
|
1056 |
+
array(
|
1057 |
+
'response_message_code' => $response_message_code,
|
1058 |
+
'wordpress_id' => $wp_id,
|
1059 |
+
'response_message' => $this->get_error_message_from_response( $response ),
|
1060 |
+
),
|
1061 |
+
$extra_data
|
1062 |
+
)
|
1063 |
+
);
|
1064 |
+
}//end if
|
1065 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
1066 |
+
}//end if
|
1067 |
}
|
1068 |
|
1069 |
/**
|
1070 |
+
* Helper function to update lingotek errors as 'lingotek_log_errors' option.
|
1071 |
+
*
|
1072 |
+
* @param $response the response from the action (wp_remote_*).
|
1073 |
+
* @param $wp_id id that represents the object in the WP world (post_id / term_id / etc)
|
1074 |
+
* @param $action the name of the action performed (for ex 'reqeust_translation')
|
1075 |
+
* @param $error_message the message to write in case the response indicates failure
|
1076 |
+
* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
|
1077 |
+
*/
|
1078 |
+
private function update_lingotek_error_option( $response, $wp_id, $action, $error_message, $extra_data = array() ) {
|
1079 |
+
if ( $wp_id ) {
|
1080 |
+
$arr = get_option( 'lingotek_log_errors' );
|
1081 |
+
$response_message_code = wp_remote_retrieve_response_code( $response );
|
1082 |
+
if ( empty( $arr ) ) {
|
1083 |
return;
|
1084 |
}
|
1085 |
|
1086 |
+
if ( 200 == $response_message_code || 202 == $response_message_code ) {
|
1087 |
+
if ( isset( $arr[ $wp_id ] ) ) {
|
1088 |
+
unset( $arr[ $wp_id ] );
|
1089 |
}
|
1090 |
+
} elseif ( is_wp_error( $response ) ) {
|
1091 |
+
$arr[ $wp_id ]['wp_error'] = __( 'Make sure you have internet connectivity', 'lingotek-translation' );
|
1092 |
+
Lingotek_Logger::error(
|
1093 |
+
"$action: WordPress error occured, please make sure you have internet connectivity",
|
1094 |
+
array_merge(
|
1095 |
+
array(
|
1096 |
+
'http_status' => $response_message_code,
|
1097 |
+
'wordpress_id' => $wp_id,
|
1098 |
+
),
|
1099 |
+
$extra_data
|
1100 |
+
)
|
1101 |
+
);
|
1102 |
+
} elseif ( 400 == $response_message_code || 404 == $response_message_code ) {
|
1103 |
+
$arr[ $wp_id ][ $action ] = $error_message;
|
1104 |
+
Lingotek_Logger::error(
|
1105 |
+
"$action: Error occured",
|
1106 |
+
array_merge(
|
1107 |
+
array(
|
1108 |
+
'http_status' => $response_message_code,
|
1109 |
+
'wordpress_id' => $wp_id,
|
1110 |
+
'response_message' => $this->get_error_message_from_response( $response ),
|
1111 |
+
),
|
1112 |
+
$extra_data
|
1113 |
+
)
|
1114 |
+
);
|
1115 |
+
}//end if
|
1116 |
+
update_option( 'lingotek_log_errors', $arr, false );
|
1117 |
+
}//end if
|
1118 |
}
|
1119 |
|
1120 |
/**
|
1121 |
+
* Helper function to send error log entry to Lingotek_Logger in case the response indicates failure.
|
1122 |
+
* Failure response has http status different than 200/201/202/204 and is not wp_error response
|
1123 |
+
*
|
1124 |
+
* @param $response the response from the action (wp_remote_*).
|
1125 |
+
* @param $error_message the message to write in case the response indicates failure
|
1126 |
+
* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
|
1127 |
+
*/
|
1128 |
+
private function log_error_on_response_failure( $response, $error_message, $extra_data = array() ) {
|
1129 |
+
$http_code = wp_remote_retrieve_response_code( $response );
|
1130 |
+
$success = 200 === $http_code || 201 === $http_code || 202 === $http_code || 204 === $http_code;
|
1131 |
+
if ( ! $success || is_wp_error( $response ) ) {
|
1132 |
+
Lingotek_Logger::error(
|
1133 |
+
$error_message,
|
1134 |
+
array_merge(
|
1135 |
+
array(
|
1136 |
+
'http_status' => $http_code,
|
1137 |
+
$extra_data,
|
1138 |
+
)
|
1139 |
+
)
|
1140 |
+
);
|
1141 |
+
}
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
private function get_error_message_from_response( $response ) {
|
1145 |
+
$responseBody = json_decode( wp_remote_retrieve_body( $response ) );
|
1146 |
+
if ( empty( $responseBody ) ) {
|
1147 |
return false;
|
1148 |
}
|
1149 |
+
return property_exists( $responseBody, 'messages' ) && is_array( $responseBody->messages ) ? implode( ' ', $responseBody->messages ) : false;
|
1150 |
}
|
1151 |
+
}
|
include/callback.php
CHANGED
@@ -13,9 +13,9 @@ class Lingotek_Callback {
|
|
13 |
*
|
14 |
* @since 0.1
|
15 |
*/
|
16 |
-
public function __construct(&$model) {
|
17 |
$this->lgtm = &$model;
|
18 |
-
add_filter('request', array(&$this, 'request'));
|
19 |
}
|
20 |
|
21 |
/*
|
@@ -23,174 +23,179 @@ class Lingotek_Callback {
|
|
23 |
*
|
24 |
* @since 0.1
|
25 |
*
|
26 |
-
* @param array $query_vars query vars known to
|
27 |
* @return array unmodified query vars if the request is not a Lingotek callback
|
28 |
*/
|
29 |
-
public function request($query_vars) {
|
30 |
-
if (empty($query_vars['lingotek'])) {
|
31 |
return $query_vars;
|
32 |
}
|
33 |
$type = $_GET['type'];
|
34 |
-
if (isset($type, $_GET['document_id']) && $document = $this->lgtm->get_group_by_id($_GET['document_id'])) {
|
35 |
-
switch ($type) {
|
36 |
case 'get':
|
37 |
-
$this->handleGet($document);
|
38 |
break;
|
39 |
case 'target':
|
40 |
case 'phase':
|
41 |
-
|
|
|
42 |
break;
|
43 |
case 'target_cancelled':
|
44 |
-
$this->handleTargetCancelled($document);
|
45 |
break;
|
46 |
case 'document_uploaded':
|
47 |
case 'document_updated':
|
48 |
-
$this->handleDocumentUploadedOrUpdated($document);
|
49 |
break;
|
50 |
case 'import_failure':
|
51 |
-
$this->handleImportFailure($document);
|
52 |
break;
|
53 |
case 'document_archived':
|
54 |
case 'document_deleted':
|
55 |
-
$this->handleDocumentArchivedOrDeleted($document);
|
56 |
break;
|
57 |
case 'document_cancelled';
|
58 |
-
$this->handleDocumentCancelled($document);
|
59 |
break;
|
60 |
default:
|
61 |
-
Lingotek_Logger::info('Callback received, no handler for type', array('Type' => $type));
|
62 |
-
}
|
63 |
-
|
|
|
64 |
die();
|
65 |
-
}
|
66 |
-
|
|
|
67 |
die();
|
68 |
}
|
69 |
|
70 |
-
public function handleGet($document) {
|
71 |
// url for in context review
|
72 |
-
if (isset($_GET['locale'])) {
|
73 |
-
|
74 |
-
|
|
|
75 |
// posts
|
76 |
-
if (post_type_exists($document->type)) {
|
77 |
-
if ($id = PLL()->model->post->get($document->source, $locale)) {
|
78 |
-
wp_redirect(get_permalink($id), 301);
|
79 |
exit();
|
80 |
-
}
|
81 |
-
|
82 |
-
wp_redirect(get_permalink($document->source), 302);
|
83 |
exit();
|
84 |
}
|
85 |
}
|
86 |
// taxonomy terms
|
87 |
-
elseif (taxonomy_exists($document->type) && $id = $document->pllm->get_term($document->source, $locale)) {
|
88 |
-
wp_redirect(get_term_link($id, $document->type), 301);
|
89 |
exit();
|
90 |
}
|
91 |
|
92 |
-
|
|
|
93 |
die();
|
94 |
-
}
|
95 |
}
|
96 |
|
97 |
-
public function
|
98 |
-
if (isset($_GET['locale'])) {
|
99 |
$callback_parameters = array(
|
100 |
-
'Target Locale'
|
101 |
-
'Phase Name'
|
102 |
-
'Status'
|
103 |
-
'Document ID'
|
104 |
-
'Project ID'
|
105 |
-
'Community ID'
|
106 |
-
'Progress'
|
107 |
-
'Complete'
|
108 |
-
'Type'
|
109 |
-
'Document Status' => isset($_GET['doc_status']) ? $_GET['doc_status'] :
|
110 |
);
|
111 |
-
Lingotek_Logger::info('Callback received', array('Callback Parameters' => $callback_parameters));
|
112 |
// We will need access to PLL_Admin_Sync::copy_post_metas
|
113 |
global $polylang;
|
114 |
-
$polylang->sync = new PLL_Admin_Sync($polylang);
|
115 |
-
|
116 |
-
$
|
117 |
-
|
|
|
118 |
}
|
119 |
|
120 |
-
public function handleDocumentUploadedOrUpdated($document) {
|
121 |
$document->source_ready();
|
122 |
$callback_parameters = array(
|
123 |
-
'Document ID'
|
124 |
-
'Project ID'
|
125 |
-
'Community ID'
|
126 |
-
'Progress'
|
127 |
-
'Complete'
|
128 |
-
'Type'
|
129 |
-
'Document Status' => isset($_GET['doc_status']) ? $_GET['doc_status'] :
|
130 |
);
|
131 |
-
Lingotek_Logger::info('Callback received', array('Callback Parameters' => $callback_parameters));
|
132 |
-
if ($document->is_automatic_upload()) {
|
133 |
$document->request_translations();
|
134 |
}
|
135 |
}
|
136 |
|
137 |
-
public function handleImportFailure($document) {
|
138 |
$callback_parameters = array(
|
139 |
-
'Document ID' => isset($_GET['document_id']) ? $_GET['document_id'] :
|
140 |
-
'Type'
|
141 |
);
|
142 |
-
if (isset($_GET['prev_document_id'])) {
|
143 |
-
Lingotek_Logger::info(
|
144 |
$document->id = $_GET['prev_document_id'];
|
145 |
}
|
146 |
-
Lingotek_Logger::info('Callback received', array('Callback Parameters' => $callback_parameters));
|
147 |
$document->source_failed();
|
148 |
}
|
149 |
-
|
150 |
-
public function handleDocumentArchivedOrDeleted($document) {
|
151 |
-
$callback_parameters = array
|
152 |
-
'Document ID' => isset($_GET['document_id']) ? $_GET['document_id'] :
|
153 |
-
'Type'
|
154 |
);
|
155 |
-
Lingotek_Logger::info('Callback received', array('Callback Parameters' => $callback_parameters));
|
156 |
-
$wp_id = isset($document->desc_array['lingotek']['source']) ? $document->desc_array['lingotek']['source'] :
|
157 |
-
unset($document->desc_array['lingotek']);
|
158 |
$document->document_id = '';
|
159 |
$document->save();
|
160 |
-
wp_remove_object_terms($wp_id, "lingotek_hash_{$wp_id}",
|
161 |
}
|
162 |
|
163 |
-
public function handleDocumentCancelled($document) {
|
164 |
$callback_parameters = array(
|
165 |
-
'Document ID' => isset($_GET['document_id']) ? $_GET['document_id'] :
|
166 |
-
'Type'
|
167 |
);
|
168 |
-
if (isset($document->desc_array['lingotek']['translations']) && count($document->desc_array['lingotek']['translations']) > 0 ) {
|
169 |
-
unset($document->desc_array['lingotek']['translations']);
|
170 |
$document->desc_array['lingotek']['status'] = 'cancelled';
|
171 |
} else {
|
172 |
-
unset($document->desc_array['lingotek']);
|
173 |
}
|
174 |
-
$wp_id
|
175 |
$document->status = 'cancelled';
|
176 |
$document->save();
|
177 |
-
wp_remove_object_terms($wp_id, "lingotek_hash_{$wp_id}",
|
178 |
-
Lingotek_Logger::info('Callback Received', array('Callback Parameters' => $callback_parameters));
|
179 |
}
|
180 |
|
181 |
-
public function handleTargetCancelled($document) {
|
182 |
$callback_parameters = array(
|
183 |
-
'Document ID' => isset($_GET['document_id'])
|
184 |
-
'Type'
|
185 |
-
'Locale'
|
186 |
);
|
187 |
-
|
188 |
-
|
|
|
189 |
$document->desc_array['lingotek']['translations'][] = $locale;
|
|
|
190 |
}
|
191 |
-
$document->
|
192 |
-
$
|
193 |
-
Lingotek_Logger::info('Callback received', array('Callback Parameters' => $callback_parameters));
|
194 |
}
|
195 |
-
|
196 |
}
|
13 |
*
|
14 |
* @since 0.1
|
15 |
*/
|
16 |
+
public function __construct( &$model ) {
|
17 |
$this->lgtm = &$model;
|
18 |
+
add_filter( 'request', array( &$this, 'request' ) );
|
19 |
}
|
20 |
|
21 |
/*
|
23 |
*
|
24 |
* @since 0.1
|
25 |
*
|
26 |
+
* @param array $query_vars query vars known to WordPress
|
27 |
* @return array unmodified query vars if the request is not a Lingotek callback
|
28 |
*/
|
29 |
+
public function request( $query_vars ) {
|
30 |
+
if ( empty( $query_vars['lingotek'] ) ) {
|
31 |
return $query_vars;
|
32 |
}
|
33 |
$type = $_GET['type'];
|
34 |
+
if ( isset( $type, $_GET['document_id'] ) && $document = $this->lgtm->get_group_by_id( $_GET['document_id'] ) ) {
|
35 |
+
switch ( $type ) {
|
36 |
case 'get':
|
37 |
+
$this->handleGet( $document );
|
38 |
break;
|
39 |
case 'target':
|
40 |
case 'phase':
|
41 |
+
case 'download_interim_translation':
|
42 |
+
$this->handleTargetOrPhaseOrDownloadInterimTranslation( $document, $type );
|
43 |
break;
|
44 |
case 'target_cancelled':
|
45 |
+
$this->handleTargetCancelled( $document );
|
46 |
break;
|
47 |
case 'document_uploaded':
|
48 |
case 'document_updated':
|
49 |
+
$this->handleDocumentUploadedOrUpdated( $document );
|
50 |
break;
|
51 |
case 'import_failure':
|
52 |
+
$this->handleImportFailure( $document );
|
53 |
break;
|
54 |
case 'document_archived':
|
55 |
case 'document_deleted':
|
56 |
+
$this->handleDocumentArchivedOrDeleted( $document );
|
57 |
break;
|
58 |
case 'document_cancelled';
|
59 |
+
$this->handleDocumentCancelled( $document );
|
60 |
break;
|
61 |
default:
|
62 |
+
Lingotek_Logger::info( 'Callback received, no handler for type', array( 'Type' => $type ) );
|
63 |
+
}//end switch
|
64 |
+
// Useless as it the default value.
|
65 |
+
status_header( 200 );
|
66 |
die();
|
67 |
+
}//end if
|
68 |
+
// No document found.
|
69 |
+
status_header( 404 );
|
70 |
die();
|
71 |
}
|
72 |
|
73 |
+
public function handleGet( $document ) {
|
74 |
// url for in context review
|
75 |
+
if ( isset( $_GET['locale'] ) ) {
|
76 |
+
// Map to WordPress locale.
|
77 |
+
$locale = Lingotek::map_to_wp_locale( $_GET['locale'] );
|
78 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $_GET ) );
|
79 |
// posts
|
80 |
+
if ( post_type_exists( $document->type ) ) {
|
81 |
+
if ( $id = PLL()->model->post->get( $document->source, $locale ) ) {
|
82 |
+
wp_redirect( get_permalink( $id ), 301 );
|
83 |
exit();
|
84 |
+
} else {
|
85 |
+
wp_redirect( get_permalink( $document->source ), 302 );
|
|
|
86 |
exit();
|
87 |
}
|
88 |
}
|
89 |
// taxonomy terms
|
90 |
+
elseif ( taxonomy_exists( $document->type ) && $id = $document->pllm->get_term( $document->source, $locale ) ) {
|
91 |
+
wp_redirect( get_term_link( $id, $document->type ), 301 );
|
92 |
exit();
|
93 |
}
|
94 |
|
95 |
+
// No document found.
|
96 |
+
status_header( 404 );
|
97 |
die();
|
98 |
+
}//end if
|
99 |
}
|
100 |
|
101 |
+
public function handleTargetOrPhaseOrDownloadInterimTranslation( $document, $type ) {
|
102 |
+
if ( isset( $_GET['locale'] ) ) {
|
103 |
$callback_parameters = array(
|
104 |
+
'Target Locale' => isset( $_GET['locale_code'] ) ? $_GET['locale_code'] : null,
|
105 |
+
'Phase Name' => isset( $_GET['phase_name'] ) ? $_GET['phase_name'] : null,
|
106 |
+
'Status' => isset( $_GET['status'] ) ? $_GET['status'] : null,
|
107 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
108 |
+
'Project ID' => isset( $_GET['projectId'] ) ? (int) $_GET['projectId'] : null,
|
109 |
+
'Community ID' => isset( $_GET['community_id'] ) ? $_GET['community_id'] : null,
|
110 |
+
'Progress' => isset( $_GET['progress'] ) ? (int) $_GET['progress'] : null,
|
111 |
+
'Complete' => isset( $_GET['complete'] ) ? $_GET['complete'] : null,
|
112 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
113 |
+
'Document Status' => isset( $_GET['doc_status'] ) ? $_GET['doc_status'] : null,
|
114 |
);
|
115 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
|
116 |
// We will need access to PLL_Admin_Sync::copy_post_metas
|
117 |
global $polylang;
|
118 |
+
$polylang->sync = new PLL_Admin_Sync( $polylang );
|
119 |
+
// Map to WordPress locale.
|
120 |
+
$locale = Lingotek::map_to_wp_locale( $_GET['locale'] );
|
121 |
+
$document->is_automatic_download( $locale ) ? $document->create_translation( $locale, true, $type ) : $document->translation_ready( $locale );
|
122 |
+
}//end if
|
123 |
}
|
124 |
|
125 |
+
public function handleDocumentUploadedOrUpdated( $document ) {
|
126 |
$document->source_ready();
|
127 |
$callback_parameters = array(
|
128 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
129 |
+
'Project ID' => isset( $_GET['projectId'] ) ? (int) $_GET['projectId'] : null,
|
130 |
+
'Community ID' => isset( $_GET['community_id'] ) ? $_GET['community_id'] : null,
|
131 |
+
'Progress' => isset( $_GET['progress'] ) ? (int) $_GET['progress'] : null,
|
132 |
+
'Complete' => isset( $_GET['complete'] ) ? $_GET['complete'] : null,
|
133 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
134 |
+
'Document Status' => isset( $_GET['doc_status'] ) ? $_GET['doc_status'] : null,
|
135 |
);
|
136 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
|
137 |
+
if ( $document->is_automatic_upload() ) {
|
138 |
$document->request_translations();
|
139 |
}
|
140 |
}
|
141 |
|
142 |
+
public function handleImportFailure( $document ) {
|
143 |
$callback_parameters = array(
|
144 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
145 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
146 |
);
|
147 |
+
if ( isset( $_GET['prev_document_id'] ) ) {
|
148 |
+
Lingotek_Logger::info( 'Document update failed. Reverting to previous id', $callback_parameters );
|
149 |
$document->id = $_GET['prev_document_id'];
|
150 |
}
|
151 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
|
152 |
$document->source_failed();
|
153 |
}
|
154 |
+
|
155 |
+
public function handleDocumentArchivedOrDeleted( $document ) {
|
156 |
+
$callback_parameters = array(
|
157 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
158 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
159 |
);
|
160 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
|
161 |
+
$wp_id = isset( $document->desc_array['lingotek']['source'] ) ? $document->desc_array['lingotek']['source'] : null;
|
162 |
+
unset( $document->desc_array['lingotek'] );
|
163 |
$document->document_id = '';
|
164 |
$document->save();
|
165 |
+
wp_remove_object_terms( $wp_id, "lingotek_hash_{$wp_id}", 'lingotek_hash' );
|
166 |
}
|
167 |
|
168 |
+
public function handleDocumentCancelled( $document ) {
|
169 |
$callback_parameters = array(
|
170 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
171 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
172 |
);
|
173 |
+
if ( isset( $document->desc_array['lingotek']['translations'] ) && count( $document->desc_array['lingotek']['translations'] ) > 0 ) {
|
174 |
+
unset( $document->desc_array['lingotek']['translations'] );
|
175 |
$document->desc_array['lingotek']['status'] = 'cancelled';
|
176 |
} else {
|
177 |
+
unset( $document->desc_array['lingotek'] );
|
178 |
}
|
179 |
+
$wp_id = isset( $document->desc_array['lingotek']['source'] ) ? $document->desc_array['lingotek']['source'] : null;
|
180 |
$document->status = 'cancelled';
|
181 |
$document->save();
|
182 |
+
wp_remove_object_terms( $wp_id, "lingotek_hash_{$wp_id}", 'lingotek_hash' );
|
183 |
+
Lingotek_Logger::info( 'Callback Received', array( 'Callback Parameters' => $callback_parameters ) );
|
184 |
}
|
185 |
|
186 |
+
public function handleTargetCancelled( $document ) {
|
187 |
$callback_parameters = array(
|
188 |
+
'Document ID' => isset( $_GET['document_id'] ) ? $_GET['document_id'] : null,
|
189 |
+
'Type' => isset( $_GET['type'] ) ? $_GET['type'] : null,
|
190 |
+
'Locale' => isset( $_GET['locale'] ) ? $_GET['locale'] : null,
|
191 |
);
|
192 |
+
// Map to WordPress locale.
|
193 |
+
$locale = Lingotek::map_to_wp_locale( $_GET['locale'] );
|
194 |
+
if ( ! isset( $document->desc_array['lingotek']['translations'][ $locale ] ) ) {
|
195 |
$document->desc_array['lingotek']['translations'][] = $locale;
|
196 |
+
$document->save();
|
197 |
}
|
198 |
+
$document->update_translation_status( $locale, 'cancelled' );
|
199 |
+
Lingotek_Logger::info( 'Callback received', array( 'Callback Parameters' => $callback_parameters ) );
|
|
|
200 |
}
|
|
|
201 |
}
|
include/dashboard.php
CHANGED
@@ -21,33 +21,35 @@ class Lingotek_Dashboard {
|
|
21 |
function ajax_language_dashboard() {
|
22 |
global $polylang;
|
23 |
|
24 |
-
$request_method = isset($_REQUEST['_method']) ? $_REQUEST['_method'] : (isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET');
|
25 |
|
26 |
$response = array(
|
27 |
-
'method' => $request_method
|
28 |
);
|
29 |
|
30 |
-
switch ($request_method) {
|
31 |
case 'POST':
|
32 |
-
if (isset($_REQUEST['code'], $_REQUEST['native'], $_REQUEST['direction'])) {
|
33 |
$name = $_REQUEST['native'];
|
34 |
-
|
35 |
-
$
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
41 |
|
42 |
-
$rtl
|
43 |
$term_group = 0;
|
44 |
|
45 |
// adds the language
|
46 |
-
$polylang->model->add_language(compact('name', 'slug', 'locale', 'rtl', 'term_group'));
|
47 |
|
48 |
// attempts to install the language pack
|
49 |
-
require_once
|
50 |
-
wp_download_language_pack($locale);
|
51 |
|
52 |
// force checking for themes and plugins translations updates
|
53 |
wp_update_themes();
|
@@ -55,148 +57,154 @@ class Lingotek_Dashboard {
|
|
55 |
|
56 |
$response = array(
|
57 |
'request' => 'POST: add target language to CMS and Lingotek Project Language',
|
58 |
-
'locale'
|
59 |
-
'xcode'
|
60 |
-
'active'
|
61 |
'enabled' => 1,
|
62 |
-
'source'
|
63 |
-
'target'
|
64 |
);
|
65 |
-
status_header(200);
|
66 |
} else {
|
67 |
-
$code
|
68 |
-
$native
|
69 |
$direction = $_REQUEST['direction'];
|
70 |
-
$response
|
71 |
'request' => 'POST: add target language to CMS and and Lingotek Project Language',
|
72 |
'success' => false,
|
73 |
-
'message' => __("Missing locale, direction, or name. Locale: $code, Name: $native, Direction: $direction", 'lingotek-translation')
|
74 |
-
|
75 |
|
76 |
-
status_header(400);
|
77 |
-
}
|
78 |
break;
|
79 |
|
80 |
case 'DELETE':
|
81 |
-
$body = file_get_contents(
|
82 |
-
$code = str_replace('code=', '', $body);
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
'
|
|
|
90 |
'success' => false,
|
91 |
-
'message' => __('You must keep at least one language.', 'lingotek-translation')
|
92 |
);
|
93 |
-
status_header(403);
|
94 |
-
}
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
wp_delete_term( $default_category, 'category' ); // delete the default category after the language
|
100 |
|
101 |
// Deletes the translation status so when re-adding a language the string groups translations won't display as current
|
102 |
$lingotek_model = new Lingotek_Model();
|
103 |
-
$strings
|
104 |
-
foreach ($strings as $string) {
|
105 |
-
$group = $lingotek_model->get_group('string', $string['context']);
|
106 |
-
if ($group) {
|
107 |
-
unset($group->translations[$lang->locale]);
|
108 |
$group->save();
|
109 |
}
|
110 |
}
|
111 |
|
112 |
-
$response = array
|
113 |
-
'request' => sprintf('DELETE: remove language from CMS and project (%s)', $code),
|
114 |
-
'code'
|
115 |
-
'active'
|
116 |
-
'success' => true
|
117 |
);
|
118 |
-
status_header(204);
|
119 |
-
}
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
'request' => sprintf('DELETE: remove language from CMS and project (%s)', $code),
|
124 |
-
'code' => $code,
|
125 |
'success' => false,
|
126 |
-
'message' => __('The language can only be removed when no existing content is using it. If you would like to remove this language from the site, then first remove any content assigned to this language.', 'lingotek-translation')
|
127 |
);
|
128 |
-
status_header(403);
|
129 |
-
}
|
130 |
break;
|
131 |
|
132 |
case 'GET':
|
133 |
default:
|
134 |
-
$locale_code = isset($_REQUEST['code']) ? $_REQUEST['code'] :
|
135 |
-
$response
|
136 |
break;
|
137 |
-
}
|
138 |
|
139 |
-
wp_send_json($response);
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
* Lingotek - get the details of each language
|
144 |
*/
|
145 |
-
function get_language_details($locale_requested =
|
146 |
global $polylang;
|
147 |
|
148 |
-
$response
|
149 |
$available_languages = $polylang->model->get_languages_list();
|
150 |
-
$source_total
|
151 |
-
$target_total
|
152 |
-
$source_totals
|
153 |
-
$target_totals
|
154 |
|
155 |
// If we get a parameter, only return that language. Otherwise return all languages.
|
156 |
-
foreach ($available_languages as $lang_details) {
|
157 |
$wordpress_lang_code = $lang_details->slug;
|
158 |
-
$locale
|
159 |
-
if (!is_null($locale_requested) && $locale_requested != $locale) {
|
160 |
continue;
|
161 |
}
|
162 |
|
163 |
-
$lingotek_locale = str_replace('-', '_', $lang_details->lingotek_locale);
|
164 |
-
$source_counts
|
165 |
-
$target_counts
|
166 |
-
self::standardize_and_sort($source_counts['types'], $target_counts['types']);
|
167 |
-
$source_count = $source_counts['total'];
|
168 |
$target_count = $target_counts['total'];
|
169 |
|
170 |
$target_status = array(
|
171 |
-
|
172 |
-
'
|
173 |
-
'
|
174 |
-
|
175 |
-
'
|
176 |
-
|
|
|
|
|
|
|
177 |
);
|
178 |
-
if ($locale_requested == $locale) {
|
179 |
$response = $target_status;
|
180 |
-
}
|
181 |
-
|
182 |
-
$response[$lingotek_locale] = $target_status;
|
183 |
}
|
184 |
//$source_total += $source_count;
|
185 |
$target_total += $target_count;
|
186 |
//$source_totals = self::array_sum_values($source_totals, $source_counts['types']);
|
187 |
-
$target_totals = self::array_sum_values($target_totals, $target_counts['types']);
|
188 |
-
}
|
189 |
-
if (is_null($locale_requested)) {
|
190 |
$source_totals_package = self::get_unique_source_counts_by_type();
|
191 |
-
$source_totals
|
192 |
-
$source_total
|
193 |
-
self::standardize_and_sort($source_totals, $target_totals);
|
194 |
|
195 |
$response = array(
|
196 |
'languages' => $response,
|
197 |
-
'source'
|
198 |
-
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
);
|
201 |
}
|
202 |
return $response;
|
@@ -205,72 +213,74 @@ class Lingotek_Dashboard {
|
|
205 |
/**
|
206 |
* Lingotek - standardize and sort helper function
|
207 |
*/
|
208 |
-
static function standardize_and_sort(&$a1, &$a2) {
|
209 |
-
$merged_totals = array_fill_keys(array_keys($a1 + $a2), 0);
|
210 |
-
$a1
|
211 |
-
$a2
|
212 |
-
ksort($a1);
|
213 |
-
ksort($a2);
|
214 |
}
|
215 |
|
216 |
/**
|
217 |
* Lingotek - get_source_counts
|
218 |
*/
|
219 |
-
function get_source_counts($locale) {
|
220 |
-
return self::get_counts_by_type($locale, 'sources');
|
221 |
}
|
222 |
|
223 |
/**
|
224 |
* Lingotek - get_target_counts
|
225 |
*/
|
226 |
-
function get_target_counts($locale) {
|
227 |
-
return self::get_counts_by_type($locale, 'targets');
|
228 |
}
|
229 |
|
230 |
/**
|
231 |
* Lingotek - get_counts_by_type
|
232 |
*/
|
233 |
-
static function get_counts_by_type($locale, $condition) {
|
234 |
global $polylang;
|
235 |
|
236 |
-
|
|
|
237 |
|
238 |
-
foreach ($polylang->model->get_translated_post_types() as $post_type) {
|
239 |
-
$count
|
240 |
-
$post_type_object = get_post_type_object($post_type);
|
241 |
-
$response['types'][$post_type_object->labels->name] = isset($count[$condition][$locale]) ? $count[$condition][$locale] : 0;
|
242 |
}
|
243 |
|
244 |
-
foreach ($polylang->model->get_translated_taxonomies() as $tax) {
|
245 |
-
$count
|
246 |
-
$taxonomy
|
247 |
-
$response['types'][$taxonomy->labels->name] = isset($count[$condition][$locale]) ? $count[$condition][$locale] : 0;
|
248 |
}
|
249 |
|
250 |
-
$response['total'] = array_sum($response['types']);
|
251 |
|
252 |
return $response;
|
253 |
}
|
254 |
|
255 |
-
static function get_unique_source_counts_by_type(){
|
256 |
-
|
257 |
global $polylang;
|
258 |
|
259 |
-
|
260 |
-
|
261 |
-
foreach ($polylang->model->get_translated_post_types() as $post_type) {
|
262 |
-
$count
|
263 |
-
$post_type_object = get_post_type_object($post_type);
|
264 |
-
|
|
|
265 |
}
|
266 |
|
267 |
-
foreach ($polylang->model->get_translated_taxonomies() as $tax) {
|
268 |
-
$count
|
269 |
-
$taxonomy = get_taxonomy($tax);
|
270 |
-
|
|
|
271 |
}
|
272 |
|
273 |
-
$response['total'] = array_sum($response['types']);
|
274 |
|
275 |
return $response;
|
276 |
}
|
@@ -280,30 +290,30 @@ class Lingotek_Dashboard {
|
|
280 |
* array array_sum_values ( array array1 [, array array2 [, array ...]] )
|
281 |
*/
|
282 |
public static function array_sum_values() {
|
283 |
-
$return
|
284 |
$intArgs = func_num_args();
|
285 |
$arrArgs = func_get_args();
|
286 |
-
if ($intArgs < 1) {
|
287 |
-
trigger_error('Warning: Wrong parameter count for arraySumValues()', E_USER_WARNING);
|
288 |
}
|
289 |
|
290 |
-
foreach ($arrArgs as $arrItem) {
|
291 |
-
if (!is_array($arrItem)) {
|
292 |
-
trigger_error('Warning: Wrong parameter values for arraySumValues()', E_USER_WARNING);
|
293 |
}
|
294 |
-
foreach ($arrItem as $k => $v) {
|
295 |
-
if (!key_exists($k, $return)) {
|
296 |
-
$return[$k] = 0;
|
297 |
}
|
298 |
-
$return[$k] += $v;
|
299 |
}
|
300 |
}
|
301 |
return $return;
|
302 |
|
303 |
$sumArray = array();
|
304 |
-
foreach ($myArray as $k => $subArray) {
|
305 |
-
foreach ($subArray as $id => $value) {
|
306 |
-
$sumArray[$id]
|
307 |
}
|
308 |
}
|
309 |
return $sumArray;
|
@@ -317,23 +327,23 @@ class Lingotek_Dashboard {
|
|
317 |
* @param object $language
|
318 |
* @return bool false if no content in the language or only the default category
|
319 |
*/
|
320 |
-
static
|
321 |
// posts
|
322 |
-
$objects = get_objects_in_term($language->term_id, 'language');
|
323 |
-
if (!empty($objects)) {
|
324 |
-
foreach ($objects as $key => $object) {
|
325 |
-
$post = get_post($object);
|
326 |
-
if ($post->post_status == 'auto-draft') {
|
327 |
-
unset($objects[$key]);
|
328 |
}
|
329 |
}
|
330 |
-
if (!empty($objects)) {
|
331 |
return true;
|
332 |
}
|
333 |
}
|
334 |
|
335 |
// terms, only the default category is accepted
|
336 |
-
$objects = get_objects_in_term($language->tl_term_id, 'term_language');
|
337 |
-
return count($objects) > 1 || (isset($objects[0]) && $objects[0] != pll_get_term(get_option('default_category'), $language->slug));
|
338 |
}
|
339 |
}
|
21 |
function ajax_language_dashboard() {
|
22 |
global $polylang;
|
23 |
|
24 |
+
$request_method = isset( $_REQUEST['_method'] ) ? $_REQUEST['_method'] : ( isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : 'GET' );
|
25 |
|
26 |
$response = array(
|
27 |
+
'method' => $request_method,
|
28 |
);
|
29 |
|
30 |
+
switch ( $request_method ) {
|
31 |
case 'POST':
|
32 |
+
if ( isset( $_REQUEST['code'], $_REQUEST['native'], $_REQUEST['direction'] ) ) {
|
33 |
$name = $_REQUEST['native'];
|
34 |
+
// 3rd parameter of strstr needs PHP 5.3.
|
35 |
+
$slug = substr( $_REQUEST['code'], 0, strpos( $_REQUEST['code'], '_' ) );
|
36 |
+
$locale = Lingotek::map_to_wp_locale( $_REQUEST['code'] );
|
37 |
+
|
38 |
+
// Avoid conflicts between language slugs.
|
39 |
+
$existing_slugs = $polylang->model->get_languages_list( array( 'fields' => 'slug' ) );
|
40 |
+
if ( ! empty( $existing_slugs ) && in_array( $slug, $existing_slugs ) ) {
|
41 |
+
$slug = strtolower( str_replace( '_', '-', $locale ) );
|
42 |
+
}
|
43 |
|
44 |
+
$rtl = $_REQUEST['direction'] == 'RTL';
|
45 |
$term_group = 0;
|
46 |
|
47 |
// adds the language
|
48 |
+
$polylang->model->add_language( compact( 'name', 'slug', 'locale', 'rtl', 'term_group' ) );
|
49 |
|
50 |
// attempts to install the language pack
|
51 |
+
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
52 |
+
wp_download_language_pack( $locale );
|
53 |
|
54 |
// force checking for themes and plugins translations updates
|
55 |
wp_update_themes();
|
57 |
|
58 |
$response = array(
|
59 |
'request' => 'POST: add target language to CMS and Lingotek Project Language',
|
60 |
+
'locale' => $_REQUEST['code'],
|
61 |
+
'xcode' => $locale,
|
62 |
+
'active' => 1,
|
63 |
'enabled' => 1,
|
64 |
+
'source' => self::get_counts_by_type( $locale, 'sources' ),
|
65 |
+
'target' => self::get_counts_by_type( $locale, 'targets' ),
|
66 |
);
|
67 |
+
status_header( 200 );
|
68 |
} else {
|
69 |
+
$code = $_REQUEST['code'];
|
70 |
+
$native = $_REQUEST['native'];
|
71 |
$direction = $_REQUEST['direction'];
|
72 |
+
$response = array(
|
73 |
'request' => 'POST: add target language to CMS and and Lingotek Project Language',
|
74 |
'success' => false,
|
75 |
+
'message' => __( "Missing locale, direction, or name. Locale: $code, Name: $native, Direction: $direction", 'lingotek-translation' ),
|
76 |
+
);
|
77 |
|
78 |
+
status_header( 400 );
|
79 |
+
}//end if
|
80 |
break;
|
81 |
|
82 |
case 'DELETE':
|
83 |
+
$body = file_get_contents( 'php://input' );
|
84 |
+
$code = str_replace( 'code=', '', $body );
|
85 |
+
// Map code to WP locales to find the language.
|
86 |
+
$lang = $polylang->model->get_language( Lingotek::map_to_wp_locale( $code ) );
|
87 |
+
|
88 |
+
// Prevents deleting the last language as it would break the Lingotek dashboard.
|
89 |
+
if ( 1 == count( $polylang->model->get_languages_list() ) ) {
|
90 |
+
$response = array(
|
91 |
+
'request' => sprintf( 'DELETE: remove language from CMS and project (%s)', $code ),
|
92 |
+
'code' => $code,
|
93 |
'success' => false,
|
94 |
+
'message' => __( 'You must keep at least one language.', 'lingotek-translation' ),
|
95 |
);
|
96 |
+
status_header( 403 );
|
97 |
+
} elseif ( ! self::has_language_content( $lang ) ) {
|
98 |
+
$default_category = pll_get_term( get_option( 'default_category' ), $lang->slug );
|
99 |
+
$polylang->model->delete_language( (int) $lang->term_id );
|
100 |
+
// Delete the default category after the language.
|
101 |
+
wp_delete_term( $default_category, 'category' );
|
|
|
102 |
|
103 |
// Deletes the translation status so when re-adding a language the string groups translations won't display as current
|
104 |
$lingotek_model = new Lingotek_Model();
|
105 |
+
$strings = $lingotek_model->get_strings();
|
106 |
+
foreach ( $strings as $string ) {
|
107 |
+
$group = $lingotek_model->get_group( 'string', $string['context'] );
|
108 |
+
if ( $group ) {
|
109 |
+
unset( $group->translations[ $lang->locale ] );
|
110 |
$group->save();
|
111 |
}
|
112 |
}
|
113 |
|
114 |
+
$response = array(
|
115 |
+
'request' => sprintf( 'DELETE: remove language from CMS and project (%s)', $code ),
|
116 |
+
'code' => $code,
|
117 |
+
'active' => false,
|
118 |
+
'success' => true,
|
119 |
);
|
120 |
+
status_header( 204 );
|
121 |
+
} else {
|
122 |
+
$response = array(
|
123 |
+
'request' => sprintf( 'DELETE: remove language from CMS and project (%s)', $code ),
|
124 |
+
'code' => $code,
|
|
|
|
|
125 |
'success' => false,
|
126 |
+
'message' => __( 'The language can only be removed when no existing content is using it. If you would like to remove this language from the site, then first remove any content assigned to this language.', 'lingotek-translation' ),
|
127 |
);
|
128 |
+
status_header( 403 );
|
129 |
+
}//end if
|
130 |
break;
|
131 |
|
132 |
case 'GET':
|
133 |
default:
|
134 |
+
$locale_code = isset( $_REQUEST['code'] ) ? $_REQUEST['code'] : null;
|
135 |
+
$response = $response + $this->get_language_details( $locale_code );
|
136 |
break;
|
137 |
+
}//end switch
|
138 |
|
139 |
+
wp_send_json( $response );
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
* Lingotek - get the details of each language
|
144 |
*/
|
145 |
+
function get_language_details( $locale_requested = null ) {
|
146 |
global $polylang;
|
147 |
|
148 |
+
$response = array();
|
149 |
$available_languages = $polylang->model->get_languages_list();
|
150 |
+
$source_total = 0;
|
151 |
+
$target_total = 0;
|
152 |
+
$source_totals = array();
|
153 |
+
$target_totals = array();
|
154 |
|
155 |
// If we get a parameter, only return that language. Otherwise return all languages.
|
156 |
+
foreach ( $available_languages as $lang_details ) {
|
157 |
$wordpress_lang_code = $lang_details->slug;
|
158 |
+
$locale = $lang_details->locale;
|
159 |
+
if ( ! is_null( $locale_requested ) && $locale_requested != $locale ) {
|
160 |
continue;
|
161 |
}
|
162 |
|
163 |
+
$lingotek_locale = str_replace( '-', '_', $lang_details->lingotek_locale );
|
164 |
+
$source_counts = self::get_source_counts( $wordpress_lang_code );
|
165 |
+
$target_counts = self::get_target_counts( $wordpress_lang_code );
|
166 |
+
self::standardize_and_sort( $source_counts['types'], $target_counts['types'] );
|
167 |
+
$source_count = $source_counts['total'];
|
168 |
$target_count = $target_counts['total'];
|
169 |
|
170 |
$target_status = array(
|
171 |
+
// Return this language code as the Lingotek language code.
|
172 |
+
'locale' => $lingotek_locale,
|
173 |
+
'xcode' => $wordpress_lang_code,
|
174 |
+
// Lingotek enabled (active).
|
175 |
+
'active' => 1,
|
176 |
+
// WordPress enabled (enabled)
|
177 |
+
'enabled' => 1,
|
178 |
+
'source' => $source_counts,
|
179 |
+
'target' => $target_counts,
|
180 |
);
|
181 |
+
if ( $locale_requested == $locale ) {
|
182 |
$response = $target_status;
|
183 |
+
} else {
|
184 |
+
$response[ $lingotek_locale ] = $target_status;
|
|
|
185 |
}
|
186 |
//$source_total += $source_count;
|
187 |
$target_total += $target_count;
|
188 |
//$source_totals = self::array_sum_values($source_totals, $source_counts['types']);
|
189 |
+
$target_totals = self::array_sum_values( $target_totals, $target_counts['types'] );
|
190 |
+
}//end foreach
|
191 |
+
if ( is_null( $locale_requested ) ) {
|
192 |
$source_totals_package = self::get_unique_source_counts_by_type();
|
193 |
+
$source_totals = $source_totals_package['types'];
|
194 |
+
$source_total = $source_totals_package['total'];
|
195 |
+
self::standardize_and_sort( $source_totals, $target_totals );
|
196 |
|
197 |
$response = array(
|
198 |
'languages' => $response,
|
199 |
+
'source' => array(
|
200 |
+
'types' => $source_totals,
|
201 |
+
'total' => $source_total,
|
202 |
+
),
|
203 |
+
'target' => array(
|
204 |
+
'types' => $target_totals,
|
205 |
+
'total' => $target_total,
|
206 |
+
),
|
207 |
+
'count' => count( $available_languages ),
|
208 |
);
|
209 |
}
|
210 |
return $response;
|
213 |
/**
|
214 |
* Lingotek - standardize and sort helper function
|
215 |
*/
|
216 |
+
static function standardize_and_sort( &$a1, &$a2 ) {
|
217 |
+
$merged_totals = array_fill_keys( array_keys( $a1 + $a2 ), 0 );
|
218 |
+
$a1 = $a1 + $merged_totals;
|
219 |
+
$a2 = $a2 + $merged_totals;
|
220 |
+
ksort( $a1 );
|
221 |
+
ksort( $a2 );
|
222 |
}
|
223 |
|
224 |
/**
|
225 |
* Lingotek - get_source_counts
|
226 |
*/
|
227 |
+
function get_source_counts( $locale ) {
|
228 |
+
return self::get_counts_by_type( $locale, 'sources' );
|
229 |
}
|
230 |
|
231 |
/**
|
232 |
* Lingotek - get_target_counts
|
233 |
*/
|
234 |
+
function get_target_counts( $locale ) {
|
235 |
+
return self::get_counts_by_type( $locale, 'targets' );
|
236 |
}
|
237 |
|
238 |
/**
|
239 |
* Lingotek - get_counts_by_type
|
240 |
*/
|
241 |
+
static function get_counts_by_type( $locale, $condition ) {
|
242 |
global $polylang;
|
243 |
|
244 |
+
// FIXME not created by Lingotek as Polylang believes we are doing ajax on frontend
|
245 |
+
$lgtm = new Lingotek_Model();
|
246 |
|
247 |
+
foreach ( $polylang->model->get_translated_post_types() as $post_type ) {
|
248 |
+
$count = $lgtm->count_posts( $post_type );
|
249 |
+
$post_type_object = get_post_type_object( $post_type );
|
250 |
+
$response['types'][ $post_type_object->labels->name ] = isset( $count[ $condition ][ $locale ] ) ? $count[ $condition ][ $locale ] : 0;
|
251 |
}
|
252 |
|
253 |
+
foreach ( $polylang->model->get_translated_taxonomies() as $tax ) {
|
254 |
+
$count = $lgtm->count_terms( $tax );
|
255 |
+
$taxonomy = get_taxonomy( $tax );
|
256 |
+
$response['types'][ $taxonomy->labels->name ] = isset( $count[ $condition ][ $locale ] ) ? $count[ $condition ][ $locale ] : 0;
|
257 |
}
|
258 |
|
259 |
+
$response['total'] = array_sum( $response['types'] );
|
260 |
|
261 |
return $response;
|
262 |
}
|
263 |
|
264 |
+
static function get_unique_source_counts_by_type() {
|
|
|
265 |
global $polylang;
|
266 |
|
267 |
+
// FIXME not created by Lingotek as Polylang believes we are doing ajax on frontend
|
268 |
+
$lgtm = new Lingotek_Model();
|
269 |
+
foreach ( $polylang->model->get_translated_post_types() as $post_type ) {
|
270 |
+
$count = $lgtm->count_posts( $post_type );
|
271 |
+
$post_type_object = get_post_type_object( $post_type );
|
272 |
+
// Only count translation sets.
|
273 |
+
$response['types'][ $post_type_object->labels->name ] = isset( $count['total'] ) ? $count['total'] : 0;
|
274 |
}
|
275 |
|
276 |
+
foreach ( $polylang->model->get_translated_taxonomies() as $tax ) {
|
277 |
+
$count = $lgtm->count_terms( $tax );
|
278 |
+
$taxonomy = get_taxonomy( $tax );
|
279 |
+
// Only count translation sets.
|
280 |
+
$response['types'][ $taxonomy->labels->name ] = isset( $count['total'] ) ? $count['total'] : 0;
|
281 |
}
|
282 |
|
283 |
+
$response['total'] = array_sum( $response['types'] );
|
284 |
|
285 |
return $response;
|
286 |
}
|
290 |
* array array_sum_values ( array array1 [, array array2 [, array ...]] )
|
291 |
*/
|
292 |
public static function array_sum_values() {
|
293 |
+
$return = array();
|
294 |
$intArgs = func_num_args();
|
295 |
$arrArgs = func_get_args();
|
296 |
+
if ( $intArgs < 1 ) {
|
297 |
+
trigger_error( 'Warning: Wrong parameter count for arraySumValues()', E_USER_WARNING );
|
298 |
}
|
299 |
|
300 |
+
foreach ( $arrArgs as $arrItem ) {
|
301 |
+
if ( ! is_array( $arrItem ) ) {
|
302 |
+
trigger_error( 'Warning: Wrong parameter values for arraySumValues()', E_USER_WARNING );
|
303 |
}
|
304 |
+
foreach ( $arrItem as $k => $v ) {
|
305 |
+
if ( ! key_exists( $k, $return ) ) {
|
306 |
+
$return[ $k ] = 0;
|
307 |
}
|
308 |
+
$return[ $k ] += $v;
|
309 |
}
|
310 |
}
|
311 |
return $return;
|
312 |
|
313 |
$sumArray = array();
|
314 |
+
foreach ( $myArray as $k => $subArray ) {
|
315 |
+
foreach ( $subArray as $id => $value ) {
|
316 |
+
$sumArray[ $id ] += $value;
|
317 |
}
|
318 |
}
|
319 |
return $sumArray;
|
327 |
* @param object $language
|
328 |
* @return bool false if no content in the language or only the default category
|
329 |
*/
|
330 |
+
public static function has_language_content( $language ) {
|
331 |
// posts
|
332 |
+
$objects = get_objects_in_term( $language->term_id, 'language' );
|
333 |
+
if ( ! empty( $objects ) ) {
|
334 |
+
foreach ( $objects as $key => $object ) {
|
335 |
+
$post = get_post( $object );
|
336 |
+
if ( $post->post_status == 'auto-draft' ) {
|
337 |
+
unset( $objects[ $key ] );
|
338 |
}
|
339 |
}
|
340 |
+
if ( ! empty( $objects ) ) {
|
341 |
return true;
|
342 |
}
|
343 |
}
|
344 |
|
345 |
// terms, only the default category is accepted
|
346 |
+
$objects = get_objects_in_term( $language->tl_term_id, 'term_language' );
|
347 |
+
return count( $objects ) > 1 || ( isset( $objects[0] ) && $objects[0] != pll_get_term( get_option( 'default_category' ), $language->slug ) );
|
348 |
}
|
349 |
}
|
include/group-post.php
CHANGED
@@ -7,8 +7,8 @@
|
|
7 |
*/
|
8 |
class Lingotek_Group_Post extends Lingotek_Group {
|
9 |
|
10 |
-
|
11 |
-
|
12 |
/*
|
13 |
* set a translation term for an object
|
14 |
*
|
@@ -18,18 +18,19 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
18 |
* @param object $language
|
19 |
* @param string $document_id translation term name (Lingotek document id)
|
20 |
*/
|
21 |
-
public static function create($object_id, $language, $document_id) {
|
22 |
$data = array(
|
23 |
-
'lingotek'
|
24 |
-
'type' => get_post_type($object_id),
|
25 |
'source' => $object_id,
|
26 |
'status' => 'importing',
|
27 |
-
'translations' => array()
|
28 |
),
|
29 |
-
|
|
|
30 |
);
|
31 |
-
self::save_hash_on_upload($object_id);
|
32 |
-
self::_create($object_id, $document_id, $data, 'post_translations');
|
33 |
}
|
34 |
|
35 |
/*
|
@@ -40,66 +41,66 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
40 |
* @param string $post_type
|
41 |
* @return array
|
42 |
*/
|
43 |
-
static
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
static
|
90 |
$wpml_config = PLL_WPML_Config::instance();
|
91 |
-
$arr
|
92 |
|
93 |
-
if (isset($wpml_config->tags['custom-fields'])) {
|
94 |
-
foreach ($wpml_config->tags['custom-fields'] as $context) {
|
95 |
-
foreach ($context['custom-field'] as $cf) {
|
96 |
-
$arr[$cf['value']] = $cf['attributes']['action'];
|
97 |
}
|
98 |
}
|
99 |
}
|
100 |
|
101 |
// allow plugins to modify the fields to translate
|
102 |
-
return apply_filters('lingotek_post_content_type_fields_from_wpml', $arr);
|
103 |
}
|
104 |
|
105 |
/*
|
@@ -109,59 +110,62 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
109 |
*
|
110 |
* @return array
|
111 |
*/
|
112 |
-
static
|
113 |
-
|
114 |
-
$
|
115 |
-
$
|
116 |
-
$
|
117 |
-
$
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
$p = get_post($post_ID);
|
122 |
$posts[] = $p;
|
123 |
} else {
|
124 |
-
$posts = get_posts(
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
//Only perform if ACF is installed and these functions are active
|
136 |
-
if (function_exists('acf_get_field_groups') && function_exists('acf_get_fields')) {
|
137 |
-
$groups
|
138 |
-
$field_holder =
|
139 |
-
foreach ($groups as $group) {
|
140 |
-
if (isset($group['key'])) {
|
141 |
-
$field_holder = acf_get_fields($group['key']);
|
142 |
-
foreach ($field_holder as $field) {
|
143 |
-
$field_data
|
144 |
-
$field_data['meta_key']
|
145 |
$field_data['meta_value'] = $field['key'];
|
146 |
-
$all_acf_fields[]
|
147 |
}
|
148 |
}
|
149 |
}
|
150 |
}
|
151 |
|
152 |
-
foreach ($posts as $post) {
|
153 |
-
$metadata = has_meta($post->ID);
|
154 |
-
foreach ($metadata as $key => $meta) {
|
155 |
-
if (in_array($meta['meta_key'], $meta_black_list) || in_array($meta['meta_key'], $keys)) {
|
156 |
-
unset($metadata[$key]);
|
157 |
}
|
158 |
$keys[] = $meta['meta_key'];
|
159 |
}
|
160 |
-
$arr = array_merge($arr, $metadata);
|
161 |
}
|
162 |
-
$arr = array_merge($arr, $all_acf_fields);
|
163 |
// allow plugins to modify the fields to translate
|
164 |
-
return apply_filters('lingotek_post_custom_fields', $arr);
|
165 |
}
|
166 |
|
167 |
/*
|
@@ -171,9 +175,8 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
171 |
*
|
172 |
* @return bool
|
173 |
*/
|
174 |
-
protected static function is_advanced_custom_fields_meta($key, $value)
|
175 |
-
|
176 |
-
return ((substr($key, 0, strlen('_')) === '_') && (substr($value, 0, strlen('field_')) === 'field_')) ? TRUE : FALSE;
|
177 |
}
|
178 |
|
179 |
/*
|
@@ -183,47 +186,46 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
183 |
*
|
184 |
* @return array
|
185 |
*/
|
186 |
-
public static function get_updated_meta_values($post_ID =
|
187 |
-
|
188 |
-
$
|
189 |
-
$
|
190 |
-
|
191 |
-
if (!is_array($custom_fields_from_lingotek)) {
|
192 |
$custom_fields_from_lingotek = array();
|
193 |
}
|
194 |
-
$default_custom_fields = get_option('lingotek_default_custom_fields') ? get_option('lingotek_default_custom_fields') : 'ignore';
|
195 |
-
$custom_fields
|
196 |
-
$items
|
197 |
|
198 |
-
foreach ($custom_fields_from_postmeta as $cf) {
|
199 |
// hide-copy means hide from user, and always copy to translations (Advanced Custom Fields plugin)
|
200 |
-
if (self::is_advanced_custom_fields_meta($cf['meta_key'], $cf['meta_value'])) {
|
201 |
-
$custom_fields[$cf['meta_key']] = 'hide-copy';
|
202 |
continue;
|
203 |
}
|
204 |
|
205 |
// no lingotek setting
|
206 |
-
if (!array_key_exists($cf['meta_key'], $custom_fields_from_lingotek)) {
|
207 |
// no lingotek setting, but there's a wpml setting
|
208 |
-
if (array_key_exists($cf['meta_key'], $custom_fields_from_wpml)) {
|
209 |
-
$custom_fields[$cf['meta_key']] = $custom_fields_from_wpml[$cf['meta_key']];
|
210 |
}
|
211 |
// no lingotek setting, no wpml setting, so save default setting of ignore
|
212 |
else {
|
213 |
-
$custom_fields[$cf['meta_key']] = $default_custom_fields;
|
214 |
}
|
215 |
}
|
216 |
// lingotek already has this field setting saved
|
217 |
else {
|
218 |
-
$custom_fields[$cf['meta_key']] = $custom_fields_from_lingotek[$cf['meta_key']];
|
219 |
}
|
220 |
-
}
|
221 |
|
222 |
-
if ($post_ID) {
|
223 |
// get_option sometimes returns empty string for `lingotek_custom_fields`
|
224 |
-
$custom_fields = is_array($custom_fields_from_lingotek) ? array_merge($custom_fields_from_lingotek, $custom_fields) : $custom_fields;
|
225 |
}
|
226 |
-
update_option('lingotek_custom_fields', $custom_fields, false);
|
227 |
}
|
228 |
|
229 |
/*
|
@@ -234,19 +236,18 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
234 |
* @return array
|
235 |
*/
|
236 |
|
237 |
-
public static function get_cached_meta_values()
|
238 |
-
|
239 |
-
$
|
240 |
-
$items = array();
|
241 |
|
242 |
-
if (is_array($custom_fields_from_lingotek)) {
|
243 |
-
foreach ($custom_fields_from_lingotek as $key => $setting) {
|
244 |
-
if ($setting === 'hide-copy') {
|
245 |
continue;
|
246 |
}
|
247 |
-
$arr
|
248 |
'meta_key' => $key,
|
249 |
-
'setting'
|
250 |
);
|
251 |
$items[] = $arr;
|
252 |
}
|
@@ -262,50 +263,50 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
262 |
* @param object $post
|
263 |
* @return string json encoded content to translate
|
264 |
*/
|
265 |
-
public static function get_content($post) {
|
266 |
-
$arr
|
267 |
-
$fields
|
268 |
-
$content_types
|
269 |
-
$post_custom_fields = get_post_meta($post->ID);
|
270 |
-
$meta_black_list
|
271 |
-
foreach (array_keys($fields) as $key) {
|
272 |
-
if ('metas' == $key) {
|
273 |
-
foreach ($post_custom_fields as $meta => $value) {
|
274 |
// check for advanced custom fields meta expects a string
|
275 |
// so if array, check first item
|
276 |
-
$value = is_array($value) ? current($value) : $value;
|
277 |
-
if (self::is_advanced_custom_fields_meta($meta, $value) || in_array($meta, $meta_black_list)) {
|
278 |
continue;
|
279 |
}
|
280 |
// Get all metas in array format
|
281 |
-
$meta_value = get_post_meta($post->ID, $meta, true);
|
282 |
-
if ($meta_value && isset($fields['metas'][$meta])) {
|
283 |
-
$arr['metas'][$meta] = $meta_value;
|
284 |
}
|
285 |
}
|
286 |
// Check if acf is active and using these functions
|
287 |
-
$acf_empty_string =
|
288 |
-
if (isset($fields['metas'][$acf_empty_string]) && function_exists('acf_get_field_groups') && function_exists('acf_get_fields')) {
|
289 |
-
$arr['metas'][$acf_empty_string] = get_post_meta($post->ID, $acf_empty_string, true);
|
290 |
}
|
291 |
}
|
292 |
// send slug for translation only if it has been modified
|
293 |
-
elseif ('post_name' == $key && empty($content_types[$post->post_type]['fields'][$key])) {
|
294 |
-
|
|
|
295 |
// if ($default_slug != $post->post_name)
|
296 |
-
$arr['post'][$key] = $post->$key;
|
297 |
-
} elseif (empty($content_types[$post->post_type]['fields'][$key])) {
|
298 |
-
$arr['post'][$key] = $post->$key;
|
299 |
}
|
300 |
-
}
|
301 |
-
return json_encode($arr);
|
302 |
}
|
303 |
|
304 |
-
public static function is_valid_auto_upload_post_status($post_status)
|
305 |
-
|
306 |
-
$prefs = Lingotek_Model::get_prefs();
|
307 |
$valid_statuses = $prefs['auto_upload_post_statuses'];
|
308 |
-
$valid
|
309 |
return $valid;
|
310 |
}
|
311 |
|
@@ -314,11 +315,10 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
314 |
*
|
315 |
* @since 0.1
|
316 |
*/
|
317 |
-
public function request_translations()
|
318 |
-
|
319 |
-
|
320 |
-
$
|
321 |
-
$this->_request_translations($language);
|
322 |
}
|
323 |
}
|
324 |
|
@@ -330,122 +330,135 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
330 |
*
|
331 |
* @param string $locale
|
332 |
*/
|
333 |
-
public function create_translation($locale, $automatic = false, $callback_type =
|
334 |
-
{
|
335 |
// Removes content sanitization so YouTube videos, links, etc don't get removed when inserting translations
|
336 |
-
remove_filter('content_save_pre', 'wp_filter_post_kses');
|
337 |
-
remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
338 |
$client = new Lingotek_API();
|
339 |
-
$status = $client->get_translation_status($this->document_id, $locale);
|
340 |
|
341 |
-
if ($status === -1) {
|
342 |
return;
|
343 |
}
|
344 |
|
345 |
-
$translation = $client->get_translation($this->document_id, $locale, $this->source);
|
346 |
-
|
347 |
-
$translation
|
|
|
|
|
|
|
|
|
348 |
|
349 |
self::$creating_translation = true;
|
350 |
-
|
|
|
351 |
|
352 |
$tr_post = $translation['post'];
|
353 |
-
if (isset($tr_post['post_name'])) {
|
354 |
-
$tr_post['post_name'] = sanitize_title($tr_post['post_name']);
|
355 |
}
|
356 |
|
357 |
-
|
358 |
-
$
|
|
|
|
|
359 |
|
360 |
// update existing translation
|
361 |
-
if ($tr_id = PLL()->model->post->get($this->source, $locale)) {
|
362 |
$tr_post['ID'] = $tr_id;
|
363 |
|
364 |
// copy or ignore metas
|
365 |
-
self::copy_or_ignore_metas($post->ID, $tr_id);
|
366 |
|
367 |
// translate metas
|
368 |
-
if (isset($translation['metas'])) {
|
369 |
-
self::copy_translated_metas($translation['metas'], $tr_id);
|
370 |
}
|
371 |
|
372 |
-
wp_update_post($tr_post);
|
373 |
-
if ($status !== 100) {
|
374 |
-
$this->safe_translation_status_update($locale, 'interim');
|
375 |
} else {
|
376 |
-
$this->safe_translation_status_update($locale, 'current');
|
377 |
}
|
378 |
}
|
379 |
|
380 |
// create new translation
|
381 |
-
|
382 |
-
$content_type_options = get_option('lingotek_content_type');
|
383 |
-
if (!isset($content_type_options[$post->post_type]['fields']['post_name'])) {
|
384 |
-
|
|
|
385 |
}
|
386 |
-
|
387 |
-
$tr_post
|
|
|
|
|
388 |
|
389 |
// translate parent
|
390 |
-
$tr_post['post_parent'] = ($post->post_parent && $tr_parent = $this->pllm->post->get_translation($post->post_parent, $locale)) ? $tr_parent : 0;
|
391 |
|
392 |
-
if ('attachment' == $post->post_type) {
|
393 |
-
$tr_id = wp_insert_attachment($tr_post);
|
394 |
-
add_post_meta($tr_id, '_wp_attachment_metadata', get_post_meta($this->source, '_wp_attachment_metadata', true));
|
395 |
-
add_post_meta($tr_id, '_wp_attached_file', get_post_meta($this->source, '_wp_attached_file', true));
|
396 |
} else {
|
397 |
-
$tr_id = wp_insert_post($tr_post);
|
398 |
}
|
399 |
|
400 |
-
if ($tr_id) {
|
401 |
-
$tr_lang = $this->pllm->get_language($locale);
|
402 |
-
PLL()->model->post->set_language($tr_id, $tr_lang);
|
403 |
-
$this->safe_translation_status_update($locale, 'current', array($tr_lang->slug => $tr_id));
|
404 |
-
if ($status !== 100) {
|
405 |
-
$this->safe_translation_status_update($locale, 'interim');
|
406 |
}
|
407 |
-
wp_set_object_terms($tr_id, $this->term_id, 'post_translations');
|
408 |
|
409 |
// Copies categories and tags
|
410 |
-
$GLOBALS['polylang']->sync->taxonomies->copy($this->source, $tr_id, $tr_lang->slug);
|
411 |
|
412 |
// assign terms and metas
|
413 |
-
$GLOBALS['polylang']->sync->post_metas->copy($this->source, $tr_id, $tr_lang->slug);
|
414 |
|
415 |
// copy or ignore metas
|
416 |
-
self::copy_or_ignore_metas($post->ID, $tr_id);
|
417 |
|
418 |
// translate metas
|
419 |
-
if (isset($translation['metas'])) {
|
420 |
-
self::copy_translated_metas($translation['metas'], $tr_id);
|
421 |
}
|
422 |
|
423 |
-
if (class_exists('PLL_Share_Post_Slug', true) && $content_type_options[$post->post_type]['fields']['post_name'] == 1) {
|
424 |
-
wp_update_post(
|
|
|
|
|
|
|
|
|
|
|
425 |
}
|
426 |
-
}
|
427 |
}
|
428 |
|
429 |
self::$creating_translation = false;
|
430 |
|
431 |
// Adds content sanitization back in after Lingotek saves the translation
|
432 |
-
add_filter('content_save_pre', 'wp_filter_post_kses');
|
433 |
-
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
434 |
}
|
435 |
|
436 |
/**
|
437 |
-
* TMS will return an associative array with empty fields if the translation is not ready.
|
438 |
*
|
439 |
* @param array $translation the array returned from TMS.
|
440 |
*/
|
441 |
-
private function translation_not_ready($translation)
|
442 |
-
|
443 |
-
$
|
444 |
-
$
|
445 |
-
|
446 |
-
|
447 |
-
empty($
|
448 |
-
empty($trimmed_excerpt);
|
449 |
}
|
450 |
|
451 |
/*
|
@@ -454,19 +467,18 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
454 |
* @since 1.0.9
|
455 |
*/
|
456 |
|
457 |
-
public static function copy_or_ignore_metas($post_id, $tr_id)
|
458 |
-
{
|
459 |
// copy or ignore metas
|
460 |
-
$custom_fields
|
461 |
-
$post_custom_fields = get_post_meta($post_id);
|
462 |
-
foreach ($post_custom_fields as $key => $source_meta) {
|
463 |
// Set to blank string to ignore if no lingotek setting has been set.
|
464 |
-
$setting = isset($custom_fields[$key]) ? $custom_fields[$key] :
|
465 |
-
if ('copy' === $setting || 'hide-copy' === $setting) {
|
466 |
-
$source_meta = current(get_post_meta($post_id, $key));
|
467 |
-
update_post_meta($tr_id, $key, $source_meta);
|
468 |
-
} elseif ('ignore' === $setting) {
|
469 |
-
delete_post_meta($tr_id, $key);
|
470 |
}
|
471 |
}
|
472 |
}
|
@@ -476,11 +488,11 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
476 |
*
|
477 |
* @since 1.0.9
|
478 |
*/
|
479 |
-
protected static function copy_translated_metas($translation_metas, $tr_id)
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
}
|
485 |
}
|
486 |
|
@@ -491,9 +503,8 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
491 |
*
|
492 |
* @return bool
|
493 |
*/
|
494 |
-
public function is_automatic_upload()
|
495 |
-
|
496 |
-
return 'automatic' == Lingotek_Model::get_profile_option('upload', get_post_type($this->source), $this->get_source_language(), false, $this->source) && parent::is_automatic_upload();
|
497 |
}
|
498 |
|
499 |
/*
|
@@ -503,9 +514,8 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
503 |
*
|
504 |
* @return object
|
505 |
*/
|
506 |
-
public function get_source_language()
|
507 |
-
|
508 |
-
return PLL()->model->post->get_language($this->source);
|
509 |
}
|
510 |
|
511 |
/*
|
@@ -513,13 +523,12 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
513 |
*
|
514 |
* @since 1.0.9
|
515 |
*/
|
516 |
-
protected static function save_hash_on_upload($object_id)
|
517 |
-
|
518 |
-
$post = get_post($object_id);
|
519 |
$document_id = 'lingotek_hash_' . $post->ID;
|
520 |
-
$new_hash
|
521 |
|
522 |
-
wp_insert_term($document_id, 'lingotek_hash', array('description' => $new_hash));
|
523 |
-
wp_set_object_terms($post->ID, $document_id, 'lingotek_hash');
|
524 |
}
|
525 |
-
}
|
7 |
*/
|
8 |
class Lingotek_Group_Post extends Lingotek_Group {
|
9 |
|
10 |
+
// Preference constant used for downloaded translations.
|
11 |
+
const SAME_AS_SOURCE = 'SAME_AS_SOURCE';
|
12 |
/*
|
13 |
* set a translation term for an object
|
14 |
*
|
18 |
* @param object $language
|
19 |
* @param string $document_id translation term name (Lingotek document id)
|
20 |
*/
|
21 |
+
public static function create( $object_id, $language, $document_id ) {
|
22 |
$data = array(
|
23 |
+
'lingotek' => array(
|
24 |
+
'type' => get_post_type( $object_id ),
|
25 |
'source' => $object_id,
|
26 |
'status' => 'importing',
|
27 |
+
'translations' => array(),
|
28 |
),
|
29 |
+
// For Polylang.
|
30 |
+
$language->slug => $object_id,
|
31 |
);
|
32 |
+
self::save_hash_on_upload( $object_id );
|
33 |
+
self::_create( $object_id, $document_id, $data, 'post_translations' );
|
34 |
}
|
35 |
|
36 |
/*
|
41 |
* @param string $post_type
|
42 |
* @return array
|
43 |
*/
|
44 |
+
public static function get_content_type_fields( $post_type, $post_ID = null ) {
|
45 |
+
$cache_key = 'content_type_fields_' . $post_type;
|
46 |
+
$arr = wp_cache_get( $cache_key, 'lingotek' );
|
47 |
+
if ( ! $arr ) {
|
48 |
+
$arr = 'attachment' == $post_type ?
|
49 |
+
array(
|
50 |
+
'post_title' => __( 'Title', 'lingotek-translation' ),
|
51 |
+
'post_excerpt' => __( 'Caption', 'lingotek-translation' ),
|
52 |
+
'metas' => array( '_wp_attachment_image_alt' => __( 'Alternative Text', 'lingotek-translation' ) ),
|
53 |
+
'post_content' => __( 'Description', 'lingotek-translation' ),
|
54 |
+
) : array(
|
55 |
+
'post_title' => __( 'Title', 'lingotek-translation' ),
|
56 |
+
'post_name' => __( 'Slug', 'lingotek-translation' ),
|
57 |
+
'post_content' => __( 'Content', 'lingotek-translation' ),
|
58 |
+
'post_excerpt' => __( 'Excerpt', 'lingotek-translation' ),
|
59 |
+
);
|
60 |
+
|
61 |
+
// if the user hasn't visited the custom fields tab, and hasn't saved actions for custom
|
62 |
+
// fields, and uploaded a post, check the wpml file for settings
|
63 |
+
if ( $post_ID ) {
|
64 |
+
self::get_updated_meta_values( $post_ID );
|
65 |
+
}
|
66 |
+
// add the custom fields from the lingotek_custom_fields option
|
67 |
+
$custom_fields = get_option( 'lingotek_custom_fields', array() );
|
68 |
+
|
69 |
+
if ( is_array( $custom_fields ) && ! empty( $custom_fields ) ) {
|
70 |
+
foreach ( $custom_fields as $cf => $setting ) {
|
71 |
+
if ( 'translate' == $setting ) {
|
72 |
+
$arr['metas'][ $cf ] = $cf;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
wp_cache_set( $cache_key, $arr, 'lingotek', 300 );
|
77 |
+
}//end if
|
78 |
+
// allow plugins to modify the fields to translate
|
79 |
+
return apply_filters( 'lingotek_post_content_type_fields', $arr, $post_type );
|
80 |
+
}
|
81 |
+
|
82 |
+
/*
|
83 |
+
* returns custom fields from the wpml-config.xml file
|
84 |
+
*
|
85 |
+
* @since 0.2
|
86 |
+
*
|
87 |
+
* @param string $post_type
|
88 |
+
* @return array
|
89 |
+
*/
|
90 |
+
public static function get_custom_fields_from_wpml() {
|
91 |
$wpml_config = PLL_WPML_Config::instance();
|
92 |
+
$arr = array();
|
93 |
|
94 |
+
if ( isset( $wpml_config->tags['custom-fields'] ) ) {
|
95 |
+
foreach ( $wpml_config->tags['custom-fields'] as $context ) {
|
96 |
+
foreach ( $context['custom-field'] as $cf ) {
|
97 |
+
$arr[ $cf['value'] ] = $cf['attributes']['action'];
|
98 |
}
|
99 |
}
|
100 |
}
|
101 |
|
102 |
// allow plugins to modify the fields to translate
|
103 |
+
return apply_filters( 'lingotek_post_content_type_fields_from_wpml', $arr );
|
104 |
}
|
105 |
|
106 |
/*
|
110 |
*
|
111 |
* @return array
|
112 |
*/
|
113 |
+
public static function get_custom_fields_from_wp_postmeta( $post_ID = null ) {
|
114 |
+
$all_acf_fields = array();
|
115 |
+
$custom_fields = get_option( 'lingotek_custom_fields', array() );
|
116 |
+
$meta_black_list = array( '_encloseme', '_edit_last', '_edit_lock', '_wp_trash_meta_status', '_wp_trash_meta_time' );
|
117 |
+
$arr = array();
|
118 |
+
$keys = array();
|
119 |
+
|
120 |
+
if ( $post_ID ) {
|
121 |
+
$p = get_post( $post_ID );
|
|
|
122 |
$posts[] = $p;
|
123 |
} else {
|
124 |
+
$posts = get_posts(
|
125 |
+
array(
|
126 |
+
'posts_per_page' => -1,
|
127 |
+
'post_type' => 'post',
|
128 |
+
)
|
129 |
+
);
|
130 |
+
$pages = get_posts(
|
131 |
+
array(
|
132 |
+
'posts_per_page' => -1,
|
133 |
+
'post_type' => 'page',
|
134 |
+
)
|
135 |
+
);
|
136 |
+
|
137 |
+
$posts = array_merge( $posts, $pages );
|
138 |
}
|
139 |
//Only perform if ACF is installed and these functions are active
|
140 |
+
if ( function_exists( 'acf_get_field_groups' ) && function_exists( 'acf_get_fields' ) ) {
|
141 |
+
$groups = acf_get_field_groups();
|
142 |
+
$field_holder = array();
|
143 |
+
foreach ( $groups as $group ) {
|
144 |
+
if ( isset( $group['key'] ) ) {
|
145 |
+
$field_holder = acf_get_fields( $group['key'] );
|
146 |
+
foreach ( $field_holder as $field ) {
|
147 |
+
$field_data = array();
|
148 |
+
$field_data['meta_key'] = $field['name'];
|
149 |
$field_data['meta_value'] = $field['key'];
|
150 |
+
$all_acf_fields[] = $field_data;
|
151 |
}
|
152 |
}
|
153 |
}
|
154 |
}
|
155 |
|
156 |
+
foreach ( $posts as $post ) {
|
157 |
+
$metadata = has_meta( $post->ID );
|
158 |
+
foreach ( $metadata as $key => $meta ) {
|
159 |
+
if ( in_array( $meta['meta_key'], $meta_black_list ) || in_array( $meta['meta_key'], $keys ) ) {
|
160 |
+
unset( $metadata[ $key ] );
|
161 |
}
|
162 |
$keys[] = $meta['meta_key'];
|
163 |
}
|
164 |
+
$arr = array_merge( $arr, $metadata );
|
165 |
}
|
166 |
+
$arr = array_merge( $arr, $all_acf_fields );
|
167 |
// allow plugins to modify the fields to translate
|
168 |
+
return apply_filters( 'lingotek_post_custom_fields', $arr );
|
169 |
}
|
170 |
|
171 |
/*
|
175 |
*
|
176 |
* @return bool
|
177 |
*/
|
178 |
+
protected static function is_advanced_custom_fields_meta( $key, $value ) {
|
179 |
+
return ( ( substr( $key, 0, strlen( '_' ) ) === '_' ) && ( substr( $value, 0, strlen( 'field_' ) ) === 'field_' ) ) ? true : false;
|
|
|
180 |
}
|
181 |
|
182 |
/*
|
186 |
*
|
187 |
* @return array
|
188 |
*/
|
189 |
+
public static function get_updated_meta_values( $post_ID = null ) {
|
190 |
+
$custom_fields_from_wpml = self::get_custom_fields_from_wpml();
|
191 |
+
$custom_fields_from_postmeta = self::get_custom_fields_from_wp_postmeta( $post_ID );
|
192 |
+
$custom_fields_from_lingotek = get_option( 'lingotek_custom_fields', array() );
|
193 |
+
if ( ! is_array( $custom_fields_from_lingotek ) ) {
|
|
|
194 |
$custom_fields_from_lingotek = array();
|
195 |
}
|
196 |
+
$default_custom_fields = get_option( 'lingotek_default_custom_fields' ) ? get_option( 'lingotek_default_custom_fields' ) : 'ignore';
|
197 |
+
$custom_fields = array();
|
198 |
+
$items = array();
|
199 |
|
200 |
+
foreach ( $custom_fields_from_postmeta as $cf ) {
|
201 |
// hide-copy means hide from user, and always copy to translations (Advanced Custom Fields plugin)
|
202 |
+
if ( self::is_advanced_custom_fields_meta( $cf['meta_key'], $cf['meta_value'] ) ) {
|
203 |
+
$custom_fields[ $cf['meta_key'] ] = 'hide-copy';
|
204 |
continue;
|
205 |
}
|
206 |
|
207 |
// no lingotek setting
|
208 |
+
if ( ! array_key_exists( $cf['meta_key'], $custom_fields_from_lingotek ) ) {
|
209 |
// no lingotek setting, but there's a wpml setting
|
210 |
+
if ( array_key_exists( $cf['meta_key'], $custom_fields_from_wpml ) ) {
|
211 |
+
$custom_fields[ $cf['meta_key'] ] = $custom_fields_from_wpml[ $cf['meta_key'] ];
|
212 |
}
|
213 |
// no lingotek setting, no wpml setting, so save default setting of ignore
|
214 |
else {
|
215 |
+
$custom_fields[ $cf['meta_key'] ] = $default_custom_fields;
|
216 |
}
|
217 |
}
|
218 |
// lingotek already has this field setting saved
|
219 |
else {
|
220 |
+
$custom_fields[ $cf['meta_key'] ] = $custom_fields_from_lingotek[ $cf['meta_key'] ];
|
221 |
}
|
222 |
+
}//end foreach
|
223 |
|
224 |
+
if ( $post_ID ) {
|
225 |
// get_option sometimes returns empty string for `lingotek_custom_fields`
|
226 |
+
$custom_fields = is_array( $custom_fields_from_lingotek ) ? array_merge( $custom_fields_from_lingotek, $custom_fields ) : $custom_fields;
|
227 |
}
|
228 |
+
update_option( 'lingotek_custom_fields', $custom_fields, false );
|
229 |
}
|
230 |
|
231 |
/*
|
236 |
* @return array
|
237 |
*/
|
238 |
|
239 |
+
public static function get_cached_meta_values() {
|
240 |
+
$custom_fields_from_lingotek = get_option( 'lingotek_custom_fields', array() );
|
241 |
+
$items = array();
|
|
|
242 |
|
243 |
+
if ( is_array( $custom_fields_from_lingotek ) ) {
|
244 |
+
foreach ( $custom_fields_from_lingotek as $key => $setting ) {
|
245 |
+
if ( $setting === 'hide-copy' ) {
|
246 |
continue;
|
247 |
}
|
248 |
+
$arr = array(
|
249 |
'meta_key' => $key,
|
250 |
+
'setting' => $setting,
|
251 |
);
|
252 |
$items[] = $arr;
|
253 |
}
|
263 |
* @param object $post
|
264 |
* @return string json encoded content to translate
|
265 |
*/
|
266 |
+
public static function get_content( $post ) {
|
267 |
+
$arr = array();
|
268 |
+
$fields = self::get_content_type_fields( $post->post_type, $post->ID );
|
269 |
+
$content_types = get_option( 'lingotek_content_type' );
|
270 |
+
$post_custom_fields = get_post_meta( $post->ID );
|
271 |
+
$meta_black_list = array( '_encloseme', '_edit_last', '_edit_lock', '_wp_trash_meta_status', '_wp_trash_meta_time' );
|
272 |
+
foreach ( array_keys( $fields ) as $key ) {
|
273 |
+
if ( 'metas' == $key ) {
|
274 |
+
foreach ( $post_custom_fields as $meta => $value ) {
|
275 |
// check for advanced custom fields meta expects a string
|
276 |
// so if array, check first item
|
277 |
+
$value = is_array( $value ) ? current( $value ) : $value;
|
278 |
+
if ( self::is_advanced_custom_fields_meta( $meta, $value ) || in_array( $meta, $meta_black_list ) ) {
|
279 |
continue;
|
280 |
}
|
281 |
// Get all metas in array format
|
282 |
+
$meta_value = get_post_meta( $post->ID, $meta, true );
|
283 |
+
if ( $meta_value && isset( $fields['metas'][ $meta ] ) ) {
|
284 |
+
$arr['metas'][ $meta ] = $meta_value;
|
285 |
}
|
286 |
}
|
287 |
// Check if acf is active and using these functions
|
288 |
+
$acf_empty_string = '';
|
289 |
+
if ( isset( $fields['metas'][ $acf_empty_string ] ) && function_exists( 'acf_get_field_groups' ) && function_exists( 'acf_get_fields' ) ) {
|
290 |
+
$arr['metas'][ $acf_empty_string ] = get_post_meta( $post->ID, $acf_empty_string, true );
|
291 |
}
|
292 |
}
|
293 |
// send slug for translation only if it has been modified
|
294 |
+
elseif ( 'post_name' == $key && empty( $content_types[ $post->post_type ]['fields'][ $key ] ) ) {
|
295 |
+
// Default slug created by WordPress.
|
296 |
+
$default_slug = sanitize_title( $post->post_title );
|
297 |
// if ($default_slug != $post->post_name)
|
298 |
+
$arr['post'][ $key ] = $post->$key;
|
299 |
+
} elseif ( empty( $content_types[ $post->post_type ]['fields'][ $key ] ) ) {
|
300 |
+
$arr['post'][ $key ] = $post->$key;
|
301 |
}
|
302 |
+
}//end foreach
|
303 |
+
return json_encode( $arr );
|
304 |
}
|
305 |
|
306 |
+
public static function is_valid_auto_upload_post_status( $post_status ) {
|
307 |
+
$prefs = Lingotek_Model::get_prefs();
|
|
|
308 |
$valid_statuses = $prefs['auto_upload_post_statuses'];
|
309 |
+
$valid = isset( $valid_statuses[ $post_status ] ) && $valid_statuses[ $post_status ];
|
310 |
return $valid;
|
311 |
}
|
312 |
|
315 |
*
|
316 |
* @since 0.1
|
317 |
*/
|
318 |
+
public function request_translations() {
|
319 |
+
if ( isset( $this->source ) ) {
|
320 |
+
$language = PLL()->model->post->get_language( (int) $this->source );
|
321 |
+
$this->_request_translations( $language );
|
|
|
322 |
}
|
323 |
}
|
324 |
|
330 |
*
|
331 |
* @param string $locale
|
332 |
*/
|
333 |
+
public function create_translation( $locale, $automatic = false, $callback_type = null ) {
|
|
|
334 |
// Removes content sanitization so YouTube videos, links, etc don't get removed when inserting translations
|
335 |
+
remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
|
336 |
+
remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' );
|
337 |
$client = new Lingotek_API();
|
338 |
+
$status = $client->get_translation_status( $this->document_id, $locale );
|
339 |
|
340 |
+
if ( $status === -1 ) {
|
341 |
return;
|
342 |
}
|
343 |
|
344 |
+
$translation = $client->get_translation( $this->document_id, $locale, $this->source );
|
345 |
+
// If the request failed.
|
346 |
+
if ( ! $translation || $this->translation_not_ready( json_decode( $translation, true ) ) ) {
|
347 |
+
return;
|
348 |
+
}
|
349 |
+
// wp_insert_post expects array
|
350 |
+
$translation = json_decode( $translation, true );
|
351 |
|
352 |
self::$creating_translation = true;
|
353 |
+
// Need an array by default.
|
354 |
+
$prefs = Lingotek_Model::get_prefs();
|
355 |
|
356 |
$tr_post = $translation['post'];
|
357 |
+
if ( isset( $tr_post['post_name'] ) ) {
|
358 |
+
$tr_post['post_name'] = sanitize_title( $tr_post['post_name'] );
|
359 |
}
|
360 |
|
361 |
+
// source post
|
362 |
+
$post = get_post( $this->source );
|
363 |
+
// status
|
364 |
+
$tr_post['post_status'] = ( $prefs['download_post_status'] === self::SAME_AS_SOURCE ) ? $post->post_status : $prefs['download_post_status'];
|
365 |
|
366 |
// update existing translation
|
367 |
+
if ( $tr_id = PLL()->model->post->get( $this->source, $locale ) ) {
|
368 |
$tr_post['ID'] = $tr_id;
|
369 |
|
370 |
// copy or ignore metas
|
371 |
+
self::copy_or_ignore_metas( $post->ID, $tr_id );
|
372 |
|
373 |
// translate metas
|
374 |
+
if ( isset( $translation['metas'] ) ) {
|
375 |
+
self::copy_translated_metas( $translation['metas'], $tr_id );
|
376 |
}
|
377 |
|
378 |
+
wp_update_post( $tr_post );
|
379 |
+
if ( $status !== 100 ) {
|
380 |
+
$this->safe_translation_status_update( $locale, 'interim' );
|
381 |
} else {
|
382 |
+
$this->safe_translation_status_update( $locale, 'current' );
|
383 |
}
|
384 |
}
|
385 |
|
386 |
// create new translation
|
387 |
+
elseif ( ( $this->translations[ $locale ] == 'ready' || $this->translations[ $locale ] == 'pending' ) || $automatic ) {
|
388 |
+
$content_type_options = get_option( 'lingotek_content_type' );
|
389 |
+
if ( ! isset( $content_type_options[ $post->post_type ]['fields']['post_name'] ) ) {
|
390 |
+
// Forces the creation of a new default slug if not translated by Lingotek.
|
391 |
+
unset( $post->post_name );
|
392 |
}
|
393 |
+
// Copy all untranslated fields from the original post.
|
394 |
+
$tr_post = array_merge( (array) $post, $tr_post );
|
395 |
+
// Will force the creation of a new post.
|
396 |
+
$tr_post['ID'] = null;
|
397 |
|
398 |
// translate parent
|
399 |
+
$tr_post['post_parent'] = ( $post->post_parent && $tr_parent = $this->pllm->post->get_translation( $post->post_parent, $locale ) ) ? $tr_parent : 0;
|
400 |
|
401 |
+
if ( 'attachment' == $post->post_type ) {
|
402 |
+
$tr_id = wp_insert_attachment( $tr_post );
|
403 |
+
add_post_meta( $tr_id, '_wp_attachment_metadata', get_post_meta( $this->source, '_wp_attachment_metadata', true ) );
|
404 |
+
add_post_meta( $tr_id, '_wp_attached_file', get_post_meta( $this->source, '_wp_attached_file', true ) );
|
405 |
} else {
|
406 |
+
$tr_id = wp_insert_post( $tr_post );
|
407 |
}
|
408 |
|
409 |
+
if ( $tr_id ) {
|
410 |
+
$tr_lang = $this->pllm->get_language( $locale );
|
411 |
+
PLL()->model->post->set_language( $tr_id, $tr_lang );
|
412 |
+
$this->safe_translation_status_update( $locale, 'current', array( $tr_lang->slug => $tr_id ) );
|
413 |
+
if ( $status !== 100 ) {
|
414 |
+
$this->safe_translation_status_update( $locale, 'interim' );
|
415 |
}
|
416 |
+
wp_set_object_terms( $tr_id, $this->term_id, 'post_translations' );
|
417 |
|
418 |
// Copies categories and tags
|
419 |
+
$GLOBALS['polylang']->sync->taxonomies->copy( $this->source, $tr_id, $tr_lang->slug );
|
420 |
|
421 |
// assign terms and metas
|
422 |
+
$GLOBALS['polylang']->sync->post_metas->copy( $this->source, $tr_id, $tr_lang->slug );
|
423 |
|
424 |
// copy or ignore metas
|
425 |
+
self::copy_or_ignore_metas( $post->ID, $tr_id );
|
426 |
|
427 |
// translate metas
|
428 |
+
if ( isset( $translation['metas'] ) ) {
|
429 |
+
self::copy_translated_metas( $translation['metas'], $tr_id );
|
430 |
}
|
431 |
|
432 |
+
if ( class_exists( 'PLL_Share_Post_Slug', true ) && $content_type_options[ $post->post_type ]['fields']['post_name'] == 1 ) {
|
433 |
+
wp_update_post(
|
434 |
+
array(
|
435 |
+
'ID' => $tr_id,
|
436 |
+
'post_name' => $post->post_name,
|
437 |
+
)
|
438 |
+
);
|
439 |
}
|
440 |
+
}//end if
|
441 |
}
|
442 |
|
443 |
self::$creating_translation = false;
|
444 |
|
445 |
// Adds content sanitization back in after Lingotek saves the translation
|
446 |
+
add_filter( 'content_save_pre', 'wp_filter_post_kses' );
|
447 |
+
add_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' );
|
448 |
}
|
449 |
|
450 |
/**
|
451 |
+
* TMS will return an associative array with empty fields if the translation is not ready.
|
452 |
*
|
453 |
* @param array $translation the array returned from TMS.
|
454 |
*/
|
455 |
+
private function translation_not_ready( $translation ) {
|
456 |
+
$trimmed_title = trim( $translation['post']['post_title'] );
|
457 |
+
$trimmed_content = trim( $translation['post']['post_content'] );
|
458 |
+
$trimmed_excerpt = trim( $translation['post']['post_excerpt'] );
|
459 |
+
return empty( $trimmed_title ) &&
|
460 |
+
empty( $trimmed_content ) &&
|
461 |
+
empty( $trimmed_excerpt );
|
|
|
462 |
}
|
463 |
|
464 |
/*
|
467 |
* @since 1.0.9
|
468 |
*/
|
469 |
|
470 |
+
public static function copy_or_ignore_metas( $post_id, $tr_id ) {
|
|
|
471 |
// copy or ignore metas
|
472 |
+
$custom_fields = get_option( 'lingotek_custom_fields', array() );
|
473 |
+
$post_custom_fields = get_post_meta( $post_id );
|
474 |
+
foreach ( $post_custom_fields as $key => $source_meta ) {
|
475 |
// Set to blank string to ignore if no lingotek setting has been set.
|
476 |
+
$setting = isset( $custom_fields[ $key ] ) ? $custom_fields[ $key ] : '';
|
477 |
+
if ( 'copy' === $setting || 'hide-copy' === $setting ) {
|
478 |
+
$source_meta = current( get_post_meta( $post_id, $key ) );
|
479 |
+
update_post_meta( $tr_id, $key, $source_meta );
|
480 |
+
} elseif ( 'ignore' === $setting ) {
|
481 |
+
delete_post_meta( $tr_id, $key );
|
482 |
}
|
483 |
}
|
484 |
}
|
488 |
*
|
489 |
* @since 1.0.9
|
490 |
*/
|
491 |
+
protected static function copy_translated_metas( $translation_metas, $tr_id ) {
|
492 |
+
if ( ! empty( $translation_metas ) ) {
|
493 |
+
foreach ( $translation_metas as $key => $meta ) {
|
494 |
+
update_post_meta( $tr_id, $key, $meta );
|
495 |
+
}
|
496 |
}
|
497 |
}
|
498 |
|
503 |
*
|
504 |
* @return bool
|
505 |
*/
|
506 |
+
public function is_automatic_upload() {
|
507 |
+
return 'automatic' == Lingotek_Model::get_profile_option( 'upload', get_post_type( $this->source ), $this->get_source_language(), false, $this->source ) && parent::is_automatic_upload();
|
|
|
508 |
}
|
509 |
|
510 |
/*
|
514 |
*
|
515 |
* @return object
|
516 |
*/
|
517 |
+
public function get_source_language() {
|
518 |
+
return PLL()->model->post->get_language( $this->source );
|
|
|
519 |
}
|
520 |
|
521 |
/*
|
523 |
*
|
524 |
* @since 1.0.9
|
525 |
*/
|
526 |
+
protected static function save_hash_on_upload( $object_id ) {
|
527 |
+
$post = get_post( $object_id );
|
|
|
528 |
$document_id = 'lingotek_hash_' . $post->ID;
|
529 |
+
$new_hash = md5( self::get_content( $post ) );
|
530 |
|
531 |
+
wp_insert_term( $document_id, 'lingotek_hash', array( 'description' => $new_hash ) );
|
532 |
+
wp_set_object_terms( $post->ID, $document_id, 'lingotek_hash' );
|
533 |
}
|
534 |
+
}
|
include/group-string.php
CHANGED
@@ -14,10 +14,10 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
14 |
*
|
15 |
* @param object $term term translation object
|
16 |
*/
|
17 |
-
protected function load($term) {
|
18 |
-
parent::load($term);
|
19 |
$this->name = $term->name;
|
20 |
-
$this->md5
|
21 |
}
|
22 |
|
23 |
/*
|
@@ -26,7 +26,15 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
26 |
* @since 0.2
|
27 |
*/
|
28 |
public function save() {
|
29 |
-
wp_update_term(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
/*
|
@@ -38,32 +46,44 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
38 |
* @param object $language
|
39 |
* @param string $document_id translation term name (Lingotek document id)
|
40 |
*/
|
41 |
-
public static function create($name, $language, $document_id) {
|
42 |
$desc = array(
|
43 |
'lingotek' => array(
|
44 |
'type' => 'string',
|
45 |
-
'md5' => md5(self::get_content($name)),
|
46 |
'source' => $language->mo_id,
|
47 |
'status' => 'importing',
|
48 |
-
'translations' => array()
|
49 |
),
|
50 |
);
|
51 |
|
52 |
-
$terms = wp_get_object_terms($language->mo_id, 'post_translations');
|
53 |
|
54 |
// the translation already exists but was previously disassociated
|
55 |
-
if ($key = array_search($name, wp_list_pluck($terms, 'name'))) {
|
56 |
-
wp_update_term(
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
-
|
67 |
/*
|
68 |
* uploads a modified source
|
69 |
*
|
@@ -72,18 +92,18 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
72 |
* @param string $group group name
|
73 |
* @param string $empty used for compatibility with parent class
|
74 |
*/
|
75 |
-
public function patch($params, $group = '', $content = null) {
|
76 |
-
$client = new Lingotek_API();
|
77 |
-
$res
|
78 |
-
|
79 |
-
if ($res !==
|
80 |
-
$this->md5
|
81 |
-
$this->status
|
82 |
-
$this->translations = array_fill_keys(array_keys($this->translations), 'pending');
|
83 |
$this->save();
|
84 |
}
|
85 |
}
|
86 |
-
|
87 |
/*
|
88 |
* returns the content to translate
|
89 |
*
|
@@ -92,22 +112,24 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
92 |
* @param object $group string group name
|
93 |
* @return string json encoded content to translate
|
94 |
*/
|
95 |
-
public static function get_content($group) {
|
96 |
-
foreach (PLL_Admin_Strings::get_strings() as $string) {
|
97 |
-
if ($string['context'] == $group)
|
98 |
-
$arr[$string['string']] = $string['string'];
|
|
|
99 |
}
|
100 |
-
return json_encode($arr);
|
101 |
}
|
102 |
-
|
103 |
/*
|
104 |
* requests translations to Lingotek TMS
|
105 |
*
|
106 |
* @since 0.2
|
107 |
*/
|
108 |
public function request_translations() {
|
109 |
-
if (isset($this->source))
|
110 |
-
$this->_request_translations($this->get_source_language());
|
|
|
111 |
}
|
112 |
|
113 |
/*
|
@@ -118,26 +140,29 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
118 |
*
|
119 |
* @param string $locale
|
120 |
*/
|
121 |
-
public function create_translation($locale) {
|
122 |
$client = new Lingotek_API();
|
123 |
|
124 |
-
if (false === ($translation = $client->get_translation($this->document_id, $locale, $this->name)))
|
125 |
return;
|
|
|
126 |
|
127 |
-
|
128 |
-
$
|
129 |
-
|
|
|
|
|
130 |
|
131 |
$mo = new PLL_MO();
|
132 |
-
$mo->import_from_db($language);
|
133 |
|
134 |
-
foreach ($translations as $key => $translation) {
|
135 |
-
$translation = apply_filters('pll_sanitize_string_translation', $translation, $strings[$key], $this->name);
|
136 |
-
$mo->add_entry($mo->make_entry($key, $translation));
|
137 |
}
|
138 |
|
139 |
-
$mo->export_to_db($language);
|
140 |
-
$this->safe_translation_status_update($locale, 'current');
|
141 |
}
|
142 |
|
143 |
/*
|
@@ -148,7 +173,7 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
148 |
* @return bool
|
149 |
*/
|
150 |
public function is_automatic_upload() {
|
151 |
-
return 'automatic' == Lingotek_Model::get_profile_option('upload', 'string', $this->get_source_language()) && parent::is_automatic_upload();
|
152 |
}
|
153 |
|
154 |
/*
|
@@ -159,6 +184,6 @@ class Lingotek_Group_String extends Lingotek_Group {
|
|
159 |
* @return object
|
160 |
*/
|
161 |
public function get_source_language() {
|
162 |
-
return $this->pllm->get_language($this->pllm->options['default_lang']);
|
163 |
}
|
164 |
-
}
|
14 |
*
|
15 |
* @param object $term term translation object
|
16 |
*/
|
17 |
+
protected function load( $term ) {
|
18 |
+
parent::load( $term );
|
19 |
$this->name = $term->name;
|
20 |
+
$this->md5 = &$this->desc_array['lingotek']['md5'];
|
21 |
}
|
22 |
|
23 |
/*
|
26 |
* @since 0.2
|
27 |
*/
|
28 |
public function save() {
|
29 |
+
wp_update_term(
|
30 |
+
(int) $this->term_id,
|
31 |
+
$this->taxonomy,
|
32 |
+
array(
|
33 |
+
'slug' => $this->document_id,
|
34 |
+
'name' => $this->name,
|
35 |
+
'description' => serialize( $this->desc_array ),
|
36 |
+
)
|
37 |
+
);
|
38 |
}
|
39 |
|
40 |
/*
|
46 |
* @param object $language
|
47 |
* @param string $document_id translation term name (Lingotek document id)
|
48 |
*/
|
49 |
+
public static function create( $name, $language, $document_id ) {
|
50 |
$desc = array(
|
51 |
'lingotek' => array(
|
52 |
'type' => 'string',
|
53 |
+
'md5' => md5( self::get_content( $name ) ),
|
54 |
'source' => $language->mo_id,
|
55 |
'status' => 'importing',
|
56 |
+
'translations' => array(),
|
57 |
),
|
58 |
);
|
59 |
|
60 |
+
$terms = wp_get_object_terms( $language->mo_id, 'post_translations' );
|
61 |
|
62 |
// the translation already exists but was previously disassociated
|
63 |
+
if ( $key = array_search( $name, wp_list_pluck( $terms, 'name' ) ) ) {
|
64 |
+
wp_update_term(
|
65 |
+
(int) $terms[ $key ]->term_id,
|
66 |
+
'post_translations',
|
67 |
+
array(
|
68 |
+
'slug' => $document_id,
|
69 |
+
'name' => $name,
|
70 |
+
'description' => serialize( $desc ),
|
71 |
+
)
|
72 |
+
);
|
73 |
+
} else {
|
74 |
+
wp_insert_term(
|
75 |
+
$name,
|
76 |
+
'post_translations',
|
77 |
+
array(
|
78 |
+
'slug' => $document_id,
|
79 |
+
'description' => serialize( $desc ),
|
80 |
+
)
|
81 |
+
);
|
82 |
+
}//end if
|
83 |
+
// Add terms.
|
84 |
+
wp_set_object_terms( $language->mo_id, $document_id, 'post_translations', true );
|
85 |
}
|
86 |
+
|
87 |
/*
|
88 |
* uploads a modified source
|
89 |
*
|
92 |
* @param string $group group name
|
93 |
* @param string $empty used for compatibility with parent class
|
94 |
*/
|
95 |
+
public function patch( $params, $group = '', $content = null ) {
|
96 |
+
$client = new Lingotek_API();
|
97 |
+
$res = $client->patch_document( $this->document_id, $params, $group );
|
98 |
+
|
99 |
+
if ( $res !== false ) {
|
100 |
+
$this->md5 = md5( $content );
|
101 |
+
$this->status = 'importing';
|
102 |
+
$this->translations = array_fill_keys( array_keys( $this->translations ), 'pending' );
|
103 |
$this->save();
|
104 |
}
|
105 |
}
|
106 |
+
|
107 |
/*
|
108 |
* returns the content to translate
|
109 |
*
|
112 |
* @param object $group string group name
|
113 |
* @return string json encoded content to translate
|
114 |
*/
|
115 |
+
public static function get_content( $group ) {
|
116 |
+
foreach ( PLL_Admin_Strings::get_strings() as $string ) {
|
117 |
+
if ( $string['context'] == $group ) {
|
118 |
+
$arr[ $string['string'] ] = $string['string'];
|
119 |
+
}
|
120 |
}
|
121 |
+
return json_encode( $arr );
|
122 |
}
|
123 |
+
|
124 |
/*
|
125 |
* requests translations to Lingotek TMS
|
126 |
*
|
127 |
* @since 0.2
|
128 |
*/
|
129 |
public function request_translations() {
|
130 |
+
if ( isset( $this->source ) ) {
|
131 |
+
$this->_request_translations( $this->get_source_language() );
|
132 |
+
}
|
133 |
}
|
134 |
|
135 |
/*
|
140 |
*
|
141 |
* @param string $locale
|
142 |
*/
|
143 |
+
public function create_translation( $locale ) {
|
144 |
$client = new Lingotek_API();
|
145 |
|
146 |
+
if ( false === ( $translation = $client->get_translation( $this->document_id, $locale, $this->name ) ) ) {
|
147 |
return;
|
148 |
+
}
|
149 |
|
150 |
+
// Get the strings name for the filter.
|
151 |
+
$strings = wp_list_pluck( PLL_Admin_Strings::get_strings(), 'name', 'string' );
|
152 |
+
// wp_insert_post expects array.
|
153 |
+
$translations = json_decode( $translation, true );
|
154 |
+
$language = $this->pllm->get_language( $locale );
|
155 |
|
156 |
$mo = new PLL_MO();
|
157 |
+
$mo->import_from_db( $language );
|
158 |
|
159 |
+
foreach ( $translations as $key => $translation ) {
|
160 |
+
$translation = apply_filters( 'pll_sanitize_string_translation', $translation, $strings[ $key ], $this->name );
|
161 |
+
$mo->add_entry( $mo->make_entry( $key, $translation ) );
|
162 |
}
|
163 |
|
164 |
+
$mo->export_to_db( $language );
|
165 |
+
$this->safe_translation_status_update( $locale, 'current' );
|
166 |
}
|
167 |
|
168 |
/*
|
173 |
* @return bool
|
174 |
*/
|
175 |
public function is_automatic_upload() {
|
176 |
+
return 'automatic' == Lingotek_Model::get_profile_option( 'upload', 'string', $this->get_source_language() ) && parent::is_automatic_upload();
|
177 |
}
|
178 |
|
179 |
/*
|
184 |
* @return object
|
185 |
*/
|
186 |
public function get_source_language() {
|
187 |
+
return $this->pllm->get_language( $this->pllm->options['default_lang'] );
|
188 |
}
|
189 |
+
}
|
include/group-term.php
CHANGED
@@ -17,18 +17,19 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
17 |
* @param object $language
|
18 |
* @param string $document_id translation term name (Lingotek document id)
|
19 |
*/
|
20 |
-
public static function create($object_id, $tax, $language, $document_id) {
|
21 |
$data = array(
|
22 |
-
'lingotek'
|
23 |
'type' => $tax,
|
24 |
'source' => $object_id,
|
25 |
'status' => 'importing',
|
26 |
-
'translations' => array()
|
27 |
),
|
28 |
-
|
|
|
29 |
);
|
30 |
|
31 |
-
self::_create($object_id, $document_id, $data, 'term_translations');
|
32 |
}
|
33 |
|
34 |
/*
|
@@ -39,16 +40,16 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
39 |
* @param string $taxonomy
|
40 |
* @return array
|
41 |
*/
|
42 |
-
static
|
43 |
$arr = array(
|
44 |
-
'name' => __('Name', 'lingotek-translation'),
|
45 |
'args' => array(
|
46 |
-
'slug' => __('Slug', 'lingotek-translation'),
|
47 |
-
'description' => __('Description', 'lingotek-translation')
|
48 |
-
)
|
49 |
);
|
50 |
|
51 |
-
return apply_filters('lingotek_term_content_type_fields', $arr, $taxonomy);
|
52 |
}
|
53 |
|
54 |
/*
|
@@ -59,24 +60,23 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
59 |
* @param object $term
|
60 |
* @return string json encoded content to translate
|
61 |
*/
|
62 |
-
public static function get_content($term) {
|
63 |
-
$fields
|
64 |
-
$content_types = get_option('lingotek_content_type');
|
65 |
-
|
66 |
-
foreach (array_keys($fields) as $key) {
|
67 |
-
if ('args' == $key) {
|
68 |
-
foreach (array_keys($fields['args']) as $arg) {
|
69 |
-
if (empty($content_types[$term->taxonomy]['fields']['args'][$arg]))
|
70 |
-
$arr['args'][$arg] = $term->$arg;
|
|
|
71 |
}
|
72 |
-
}
|
73 |
-
|
74 |
-
elseif (empty($content_types[$term->taxonomy]['fields'][$key])) {
|
75 |
-
$arr[$key] = $term->$key;
|
76 |
}
|
77 |
}
|
78 |
|
79 |
-
return json_encode($arr);
|
80 |
}
|
81 |
|
82 |
/*
|
@@ -85,9 +85,9 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
85 |
* @since 0.2
|
86 |
*/
|
87 |
public function request_translations() {
|
88 |
-
if (isset($this->source)) {
|
89 |
-
$language = PLL()->model->term->get_language((int) $this->source);
|
90 |
-
$this->_request_translations($language);
|
91 |
}
|
92 |
}
|
93 |
|
@@ -99,61 +99,62 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
99 |
*
|
100 |
* @param string $locale
|
101 |
*/
|
102 |
-
public function create_translation($locale) {
|
103 |
$client = new Lingotek_API();
|
104 |
|
105 |
-
if (false === ($translation = $client->get_translation($this->document_id, $locale, $this->source)))
|
106 |
return;
|
|
|
107 |
|
108 |
self::$creating_translation = true;
|
109 |
|
110 |
-
|
111 |
-
$
|
|
|
112 |
|
113 |
// update existing translation
|
114 |
-
if ($tr_id = PLL()->model->term->get($this->source, $locale)) {
|
115 |
$args['name'] = $translation['name'];
|
116 |
-
wp_update_term($tr_id, $this->type, $args);
|
117 |
|
118 |
-
$this->safe_translation_status_update($locale, 'current');
|
119 |
}
|
120 |
|
121 |
// create new translation
|
122 |
else {
|
123 |
-
$content_type_options = get_option('lingotek_content_type');
|
124 |
-
$tr_lang
|
125 |
|
126 |
// translate parent
|
127 |
-
$term
|
128 |
-
$args['parent'] = ($term->parent && $tr_parent = PLL()->model->term->get_translation($term->parent, $locale)) ? $tr_parent : 0;
|
129 |
|
130 |
-
if (class_exists('PLL_Share_Term_Slug', true) && isset($content_type_options[$this->type]['fields']['args']['slug'])) {
|
131 |
remove_action( 'create_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
132 |
remove_action( 'edit_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
133 |
-
remove_action( 'pre_post_update', array( PLL()->filters_term, 'pre_post_update' ));
|
134 |
-
remove_filter( 'pre_term_name', array( PLL()->filters_term, 'pre_term_name' ));
|
135 |
-
remove_filter( 'pre_term_slug', array( PLL()->filters_term, 'pre_term_slug' ), 10, 2);
|
136 |
add_action( 'pre_post_update', array( PLL()->share_term_slug, 'pre_post_update' ) );
|
137 |
add_filter( 'pre_term_name', array( PLL()->share_term_slug, 'pre_term_name' ) );
|
138 |
add_filter( 'pre_term_slug', array( PLL()->share_term_slug, 'pre_term_slug' ), 10, 2 );
|
139 |
add_action( 'create_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
140 |
add_action( 'edit_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
141 |
$_POST['term_lang_choice'] = $tr_lang->slug;
|
142 |
-
$args['slug']
|
143 |
-
}
|
144 |
-
else {
|
145 |
// attempt to get a unique slug in case it already exists in another language
|
146 |
-
if (isset($args['slug']) && term_exists($args['slug'])) {
|
147 |
$args['slug'] .= '-' . $tr_lang->slug;
|
148 |
}
|
149 |
}
|
150 |
|
151 |
-
$tr = wp_insert_term($translation['name'], $this->type, $args);
|
152 |
|
153 |
-
if (!is_wp_error($tr)) {
|
154 |
-
PLL()->model->term->set_language($tr['term_id'], $tr_lang);
|
155 |
-
$this->safe_translation_status_update($locale, 'current', array($tr_lang->slug => $tr['term_id']));
|
156 |
-
wp_set_object_terms($tr['term_id'], $this->term_id, 'term_translations');
|
157 |
}
|
158 |
}
|
159 |
|
@@ -168,7 +169,7 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
168 |
* @return bool
|
169 |
*/
|
170 |
public function is_automatic_upload() {
|
171 |
-
return 'automatic' == Lingotek_Model::get_profile_option('upload', $this->type, $this->get_source_language()) && parent::is_automatic_upload();
|
172 |
}
|
173 |
|
174 |
/*
|
@@ -179,6 +180,6 @@ class Lingotek_Group_Term extends Lingotek_Group {
|
|
179 |
* @return object
|
180 |
*/
|
181 |
public function get_source_language() {
|
182 |
-
return PLL()->model->term->get_language($this->source);
|
183 |
}
|
184 |
}
|
17 |
* @param object $language
|
18 |
* @param string $document_id translation term name (Lingotek document id)
|
19 |
*/
|
20 |
+
public static function create( $object_id, $tax, $language, $document_id ) {
|
21 |
$data = array(
|
22 |
+
'lingotek' => array(
|
23 |
'type' => $tax,
|
24 |
'source' => $object_id,
|
25 |
'status' => 'importing',
|
26 |
+
'translations' => array(),
|
27 |
),
|
28 |
+
// for Polylang
|
29 |
+
$language->slug => $object_id,
|
30 |
);
|
31 |
|
32 |
+
self::_create( $object_id, $document_id, $data, 'term_translations' );
|
33 |
}
|
34 |
|
35 |
/*
|
40 |
* @param string $taxonomy
|
41 |
* @return array
|
42 |
*/
|
43 |
+
public static function get_content_type_fields( $taxonomy ) {
|
44 |
$arr = array(
|
45 |
+
'name' => __( 'Name', 'lingotek-translation' ),
|
46 |
'args' => array(
|
47 |
+
'slug' => __( 'Slug', 'lingotek-translation' ),
|
48 |
+
'description' => __( 'Description', 'lingotek-translation' ),
|
49 |
+
),
|
50 |
);
|
51 |
|
52 |
+
return apply_filters( 'lingotek_term_content_type_fields', $arr, $taxonomy );
|
53 |
}
|
54 |
|
55 |
/*
|
60 |
* @param object $term
|
61 |
* @return string json encoded content to translate
|
62 |
*/
|
63 |
+
public static function get_content( $term ) {
|
64 |
+
$fields = self::get_content_type_fields( $term->taxonomy );
|
65 |
+
$content_types = get_option( 'lingotek_content_type' );
|
66 |
+
|
67 |
+
foreach ( array_keys( $fields ) as $key ) {
|
68 |
+
if ( 'args' == $key ) {
|
69 |
+
foreach ( array_keys( $fields['args'] ) as $arg ) {
|
70 |
+
if ( empty( $content_types[ $term->taxonomy ]['fields']['args'][ $arg ] ) ) {
|
71 |
+
$arr['args'][ $arg ] = $term->$arg;
|
72 |
+
}
|
73 |
}
|
74 |
+
} elseif ( empty( $content_types[ $term->taxonomy ]['fields'][ $key ] ) ) {
|
75 |
+
$arr[ $key ] = $term->$key;
|
|
|
|
|
76 |
}
|
77 |
}
|
78 |
|
79 |
+
return json_encode( $arr );
|
80 |
}
|
81 |
|
82 |
/*
|
85 |
* @since 0.2
|
86 |
*/
|
87 |
public function request_translations() {
|
88 |
+
if ( isset( $this->source ) ) {
|
89 |
+
$language = PLL()->model->term->get_language( (int) $this->source );
|
90 |
+
$this->_request_translations( $language );
|
91 |
}
|
92 |
}
|
93 |
|
99 |
*
|
100 |
* @param string $locale
|
101 |
*/
|
102 |
+
public function create_translation( $locale ) {
|
103 |
$client = new Lingotek_API();
|
104 |
|
105 |
+
if ( false === ( $translation = $client->get_translation( $this->document_id, $locale, $this->source ) ) ) {
|
106 |
return;
|
107 |
+
}
|
108 |
|
109 |
self::$creating_translation = true;
|
110 |
|
111 |
+
// wp_insert_post expects array
|
112 |
+
$translation = json_decode( $translation, true );
|
113 |
+
$args = $translation['args'];
|
114 |
|
115 |
// update existing translation
|
116 |
+
if ( $tr_id = PLL()->model->term->get( $this->source, $locale ) ) {
|
117 |
$args['name'] = $translation['name'];
|
118 |
+
wp_update_term( $tr_id, $this->type, $args );
|
119 |
|
120 |
+
$this->safe_translation_status_update( $locale, 'current' );
|
121 |
}
|
122 |
|
123 |
// create new translation
|
124 |
else {
|
125 |
+
$content_type_options = get_option( 'lingotek_content_type' );
|
126 |
+
$tr_lang = $this->pllm->get_language( $locale );
|
127 |
|
128 |
// translate parent
|
129 |
+
$term = get_term( $this->source, $this->type );
|
130 |
+
$args['parent'] = ( $term->parent && $tr_parent = PLL()->model->term->get_translation( $term->parent, $locale ) ) ? $tr_parent : 0;
|
131 |
|
132 |
+
if ( class_exists( 'PLL_Share_Term_Slug', true ) && isset( $content_type_options[ $this->type ]['fields']['args']['slug'] ) ) {
|
133 |
remove_action( 'create_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
134 |
remove_action( 'edit_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
135 |
+
remove_action( 'pre_post_update', array( PLL()->filters_term, 'pre_post_update' ) );
|
136 |
+
remove_filter( 'pre_term_name', array( PLL()->filters_term, 'pre_term_name' ) );
|
137 |
+
remove_filter( 'pre_term_slug', array( PLL()->filters_term, 'pre_term_slug' ), 10, 2 );
|
138 |
add_action( 'pre_post_update', array( PLL()->share_term_slug, 'pre_post_update' ) );
|
139 |
add_filter( 'pre_term_name', array( PLL()->share_term_slug, 'pre_term_name' ) );
|
140 |
add_filter( 'pre_term_slug', array( PLL()->share_term_slug, 'pre_term_slug' ), 10, 2 );
|
141 |
add_action( 'create_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
142 |
add_action( 'edit_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
143 |
$_POST['term_lang_choice'] = $tr_lang->slug;
|
144 |
+
$args['slug'] = $term->slug;
|
145 |
+
} else {
|
|
|
146 |
// attempt to get a unique slug in case it already exists in another language
|
147 |
+
if ( isset( $args['slug'] ) && term_exists( $args['slug'] ) ) {
|
148 |
$args['slug'] .= '-' . $tr_lang->slug;
|
149 |
}
|
150 |
}
|
151 |
|
152 |
+
$tr = wp_insert_term( $translation['name'], $this->type, $args );
|
153 |
|
154 |
+
if ( ! is_wp_error( $tr ) ) {
|
155 |
+
PLL()->model->term->set_language( $tr['term_id'], $tr_lang );
|
156 |
+
$this->safe_translation_status_update( $locale, 'current', array( $tr_lang->slug => $tr['term_id'] ) );
|
157 |
+
wp_set_object_terms( $tr['term_id'], $this->term_id, 'term_translations' );
|
158 |
}
|
159 |
}
|
160 |
|
169 |
* @return bool
|
170 |
*/
|
171 |
public function is_automatic_upload() {
|
172 |
+
return 'automatic' == Lingotek_Model::get_profile_option( 'upload', $this->type, $this->get_source_language() ) && parent::is_automatic_upload();
|
173 |
}
|
174 |
|
175 |
/*
|
180 |
* @return object
|
181 |
*/
|
182 |
public function get_source_language() {
|
183 |
+
return PLL()->model->term->get_language( $this->source );
|
184 |
}
|
185 |
}
|
include/group.php
CHANGED
@@ -1,110 +1,118 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Abstract class for Translations groups objects
|
5 |
*
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
abstract class Lingotek_Group {
|
9 |
-
|
|
|
10 |
|
11 |
-
|
12 |
* constructor
|
13 |
*
|
14 |
* @since 0.2
|
15 |
*/
|
16 |
-
public function __construct($term, &$pllm) {
|
17 |
$this->pllm = &$pllm;
|
18 |
-
$this->load($term);
|
19 |
}
|
20 |
|
21 |
-
|
22 |
* assigns this object properties from the underlying term
|
23 |
*
|
24 |
* @since 0.2
|
25 |
*
|
26 |
* @param object $term term translation object
|
27 |
*/
|
28 |
-
protected function load($term) {
|
29 |
-
$this->term_id
|
30 |
-
$this->tt_id
|
31 |
$this->document_id = $term->slug;
|
32 |
-
$this->taxonomy
|
33 |
-
$this->desc_array
|
34 |
|
35 |
-
foreach (array('type', 'source', 'status', 'translations') as $prop)
|
36 |
-
$this->$prop = &$this->desc_array['lingotek'][$prop];
|
|
|
37 |
}
|
38 |
|
39 |
-
|
40 |
* updates the translation term in DB
|
41 |
*
|
42 |
* @since 0.2
|
43 |
*/
|
44 |
public function save() {
|
45 |
$args = array(
|
46 |
-
'description' => serialize($this->desc_array),
|
47 |
-
'slug'
|
|
|
48 |
);
|
49 |
-
|
50 |
-
// Name is required for the term, cannot be null or empty
|
51 |
-
$args['name'] = $this->document_id;
|
52 |
-
}
|
53 |
-
$update = wp_update_term((int) $this->term_id, $this->taxonomy, $args);
|
54 |
}
|
55 |
|
56 |
-
|
57 |
* provides a safe way to update the translations statuses when receiving "simultaneous" TMS callbacks
|
58 |
*
|
59 |
* @since 0.2
|
60 |
*
|
61 |
* @param string $locale
|
62 |
* @param string $status
|
63 |
-
* @param array
|
64 |
*/
|
65 |
-
protected function safe_translation_status_update($locale, $status, $arr = array()) {
|
66 |
global $wpdb;
|
67 |
-
$wpdb->query("LOCK TABLES $wpdb->term_taxonomy WRITE");
|
68 |
-
$d
|
69 |
-
$d
|
70 |
-
$this->translations[$locale] = $d['lingotek']['translations'][$locale] = $status;
|
71 |
-
|
72 |
-
$d =
|
73 |
-
$
|
74 |
-
$wpdb->query("
|
|
|
75 |
}
|
76 |
|
77 |
-
|
78 |
* creates a new term translation object in DB
|
79 |
*
|
80 |
* @since 0.2
|
81 |
*
|
82 |
-
* @param int
|
83 |
* @param string $document_id Lingotek document id
|
84 |
-
* @param array
|
85 |
* @param string $taxonomy either 'post_translations' or 'term_translations'
|
86 |
*/
|
87 |
-
protected static function _create($object_id, $document_id, $desc, $taxonomy) {
|
88 |
-
$terms = wp_get_object_terms($object_id, $taxonomy);
|
89 |
-
$term
|
90 |
|
91 |
-
if (empty($term)) {
|
92 |
-
wp_insert_term($document_id, $taxonomy, array('description' => serialize($desc)));
|
93 |
}
|
94 |
|
95 |
// the translation already exists but was not managed by Lingotek
|
96 |
else {
|
97 |
-
if (is_array($old_desc = maybe_unserialize($term->description)))
|
98 |
-
$desc = array_merge($old_desc, $desc);
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
101 |
|
102 |
-
wp_set_object_terms($object_id, $document_id, $taxonomy);
|
103 |
}
|
104 |
|
105 |
-
|
106 |
* deletes translations downloaded from the Lingotek TMS
|
107 |
-
*
|
108 |
*
|
109 |
* @since 0.2
|
110 |
*
|
@@ -112,79 +120,79 @@ abstract class Lingotek_Group {
|
|
112 |
*/
|
113 |
public function delete() {
|
114 |
$client = new Lingotek_API();
|
115 |
-
if ($client->cancel_document($this->document_id, $this->source)) {
|
116 |
-
update_option(
|
117 |
-
unset($this->desc_array['lingotek']);
|
118 |
-
foreach ($this->desc_array as $locale) {
|
119 |
-
if ($locale !== $this->source) {
|
120 |
wp_trash_post( $locale );
|
121 |
-
unset($this->desc_array[$locale]);
|
122 |
}
|
123 |
}
|
124 |
$this->save();
|
125 |
-
wp_delete_term($this->term_id, $this->taxonomy);
|
126 |
-
update_option(
|
127 |
} else {
|
128 |
-
update_option('disassociate_source_failed',
|
129 |
}
|
130 |
}
|
131 |
|
132 |
|
133 |
/**
|
134 |
* cancels translations from the Lingotek TMS
|
135 |
-
*
|
136 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
137 |
*/
|
138 |
public function cancel() {
|
139 |
$client = new Lingotek_API();
|
140 |
-
if ($client->cancel_document($this->document_id, $this->source)) {
|
141 |
-
if (isset($this->desc_array['lingotek']['translations']) && count
|
142 |
-
unset($this->desc_array['lingotek']['translations']);
|
143 |
$this->desc_array['lingotek']['status'] = 'cancelled';
|
144 |
} else {
|
145 |
-
unset($this->desc_array['lingotek']);
|
146 |
}
|
147 |
} else {
|
148 |
-
update_option('cancel_source_failed',
|
149 |
}
|
150 |
$this->save();
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
* delete translation from the Lingotek TMS
|
155 |
-
*
|
156 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
157 |
*/
|
158 |
-
public function delete_translation($language, $id){
|
159 |
$client = new Lingotek_API();
|
160 |
-
if ($client->cancel_translation($this->document_id, $language->lingotek_locale, $id)) {
|
161 |
-
update_option(
|
162 |
-
$this->desc_array['lingotek']['translations'][$language->locale] = 'cancelled';
|
163 |
-
unset($this->desc_array[$language->locale]);
|
164 |
-
wp_trash_post($id);
|
165 |
$this->save();
|
166 |
-
update_option(
|
167 |
} else {
|
168 |
-
update_option('disassociate_target_failed',
|
169 |
}
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
* cancel target from the Lingotek TMS
|
174 |
-
*
|
175 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
176 |
*/
|
177 |
-
public function cancel_translation($language, $id) {
|
178 |
$client = new Lingotek_API();
|
179 |
-
if ($client->cancel_translation($this->document_id, $language->lingotek_locale, $id)) {
|
180 |
-
$this->desc_array['lingotek']['translations'][$language->locale] = 'cancelled';
|
181 |
$this->save();
|
182 |
} else {
|
183 |
-
update_option('cancel_target_failed',
|
184 |
}
|
185 |
}
|
186 |
|
187 |
-
|
188 |
* uploads a modified source
|
189 |
*
|
190 |
* @since 0.2
|
@@ -192,33 +200,33 @@ abstract class Lingotek_Group {
|
|
192 |
* @param string $title
|
193 |
* @param object $content can be a post object, a term object
|
194 |
*/
|
195 |
-
public function patch($params) {
|
196 |
$client = new Lingotek_API();
|
197 |
-
$res
|
198 |
|
199 |
-
if ($res !==
|
200 |
-
$this->document_id
|
201 |
-
$this->status
|
202 |
-
$this->translations = isset($this->translations) ? array_fill_keys(array_keys($this->translations), 'pending') : null;
|
203 |
$this->save();
|
204 |
}
|
205 |
}
|
206 |
|
207 |
-
|
208 |
* checks the status of source document
|
209 |
*
|
210 |
* @since 0.2
|
211 |
*/
|
212 |
-
|
213 |
$client = new Lingotek_API();
|
214 |
|
215 |
-
if ('importing' == $this->status && $client->get_document_status($this->document_id)){
|
216 |
$this->status = 'current';
|
217 |
$this->save();
|
218 |
}
|
219 |
}
|
220 |
|
221 |
-
|
222 |
* sets source status to ready
|
223 |
*
|
224 |
* @since 0.2
|
@@ -228,172 +236,166 @@ abstract class Lingotek_Group {
|
|
228 |
$this->save();
|
229 |
}
|
230 |
|
231 |
-
|
232 |
* requests a translation to Lingotek TMS
|
233 |
*
|
234 |
* @since 0.2
|
235 |
*
|
236 |
* @param string $locale
|
237 |
*/
|
238 |
-
public function request_translation($locale) {
|
239 |
-
$workflow = $this->get_workflow_object($this->get_source_language(), $locale, $this->type, $this->source);
|
240 |
-
if ($workflow->has_custom_request_procedure()) {
|
241 |
$workflow->do_custom_request();
|
242 |
} else {
|
243 |
-
$client
|
244 |
-
$language = $this->pllm->get_language($locale);
|
245 |
-
$workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $this->get_source_language(), $language, $this->source);
|
246 |
-
if ('project-default' === $workflow) {
|
247 |
$workflow = null;
|
248 |
}
|
249 |
-
$args = $workflow ? array('workflow_id' => $workflow) : array();
|
250 |
|
251 |
-
if (
|
252 |
// don't change translations to pending if the api call failed
|
253 |
-
if ($client->request_translation($this->document_id, $language->locale, $args, $this->source)) {
|
254 |
-
$this->status
|
255 |
-
$this->translations[$language->locale] = 'pending';
|
256 |
}
|
257 |
|
258 |
$this->save();
|
259 |
}
|
260 |
-
}
|
261 |
}
|
262 |
|
263 |
-
|
264 |
* requests translations to Lingotek TMS
|
265 |
*
|
266 |
* @since 0.2
|
267 |
*
|
268 |
* @param object $source_language language of the source
|
269 |
*/
|
270 |
-
protected function _request_translations($source_language) {
|
|
|
|
|
271 |
|
272 |
-
$
|
273 |
-
|
274 |
-
|
275 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
276 |
-
$workflow = $this->get_workflow_object($source_language, $lang->locale, $this->type, $this->source);
|
277 |
-
if ($workflow->has_custom_request_procedure()) {
|
278 |
$workflow->do_custom_request();
|
279 |
} else {
|
280 |
-
if ($source_language->slug != $lang->slug &&
|
281 |
-
$workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $source_language, $lang, $this->source);
|
282 |
-
if ('project-default' === $workflow) {
|
283 |
$workflow = null;
|
284 |
}
|
285 |
-
$args = $workflow ? array('workflow_id' => $workflow) : array();
|
286 |
|
287 |
-
if ($this->type == 'string') {
|
288 |
$type_id = $this->name;
|
289 |
-
}
|
290 |
-
else {
|
291 |
$type_id = $this->source;
|
292 |
}
|
293 |
// don't change translations to pending if the api call failed
|
294 |
-
if ($client->request_translation($this->document_id, $lang->locale, $args, $type_id)) {
|
295 |
|
296 |
/**
|
297 |
-
* This is a fix that reloads the object before editing & saving it. The problem
|
298 |
-
* was that the callbacks were coming back before this method finished so the
|
299 |
* $this->translations array was out of sync with what was in the database. We fix this
|
300 |
* by reading the DB only when we need to -> make our edit -> save the edit. This keeps us from holding on to
|
301 |
* old data and overwritting the new data.
|
302 |
*/
|
303 |
-
if ('post_translations' === $this->taxonomy) {
|
304 |
-
$this->load( PLL()->model->post->get_object_term((int) $this->source, 'post_translations') );
|
305 |
-
}
|
306 |
-
$this->load( PLL()->model->term->get_object_term((int) $this->source, 'term_translations') );
|
307 |
}
|
308 |
$this->status = 'current';
|
309 |
-
if (!isset($this->translations[$lang->locale]) || isset($this->translations[$lang->locale]) && $this->translations[$lang->locale] != 'current') {
|
310 |
-
$this->translations[$lang->locale] = 'pending';
|
311 |
}
|
312 |
$this->save();
|
313 |
}
|
314 |
-
}
|
315 |
-
}
|
316 |
-
}
|
317 |
}
|
318 |
|
319 |
/**
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
public function update_translation_status($locale, $status)
|
325 |
-
|
326 |
-
$this->safe_translation_status_update($locale, $status);
|
327 |
}
|
328 |
|
329 |
-
|
330 |
* checks the translations status of a document
|
331 |
*
|
332 |
* @since 0.1
|
333 |
*/
|
334 |
public function translations_status() {
|
335 |
-
// $client = new Lingotek_API();
|
336 |
-
// $translations = $client->get_translations_status($this->document_id, $this->source); // key are Lingotek locales
|
337 |
-
// foreach($this->translations as $locale => $status) {
|
338 |
-
// $lingotek_locale = $this->pllm->get_language($locale)->lingotek_locale;
|
339 |
-
// if ('current' != $status && isset($translations[$lingotek_locale]) && 100 == $translations[$lingotek_locale])
|
340 |
-
// $this->translations[$locale] = 'ready';
|
341 |
-
// }
|
342 |
-
// $this->save();
|
343 |
-
|
344 |
$this->translation_status_hard_refresh();
|
345 |
}
|
346 |
|
347 |
public function translation_status_hard_refresh() {
|
348 |
$client = new Lingotek_API();
|
349 |
-
|
|
|
350 |
$lingotek_locale_to_pll_locale = array();
|
351 |
-
foreach (PLL()->model->get_languages_list() as $pll_language) {
|
352 |
-
$lingotek_locale_to_pll_locale[$pll_language->lingotek_locale] = $pll_language->locale;
|
353 |
}
|
354 |
-
foreach ($translations as $lingotek_locale => $
|
355 |
-
|
356 |
-
|
357 |
-
$wp_locale = $lingotek_locale_to_pll_locale[$lingotek_locale];
|
358 |
-
|
359 |
-
if ($translations[$lingotek_locale] < 100 && $this->translations[$wp_locale] !== 'interim') {
|
360 |
-
$this->translations[$wp_locale] = 'pending';
|
361 |
-
}
|
362 |
-
else if ($this->translations[$wp_locale] === 'interim' && $translations[$lingotek_locale] === 100) {
|
363 |
-
$this->translations[$wp_locale] = 'ready';
|
364 |
}
|
365 |
-
|
366 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
}
|
368 |
}
|
369 |
|
370 |
$this->save();
|
371 |
}
|
372 |
|
373 |
-
|
374 |
* sets translation status to ready
|
375 |
*
|
376 |
* @since 0.1
|
377 |
* @uses Lingotek_Group::safe_translation_status_update() as the status can be automatically set by the TMS callback
|
378 |
*/
|
379 |
-
public function translation_ready($locale) {
|
380 |
-
$this->safe_translation_status_update($locale, 'ready');
|
381 |
}
|
382 |
|
383 |
-
|
384 |
* attempts to create all translations from an object
|
385 |
*
|
386 |
* @since 0.2
|
387 |
*/
|
388 |
public function create_translations() {
|
389 |
-
if (isset($this->translations)) {
|
390 |
-
foreach ($this->translations as $locale => $status)
|
391 |
-
if ('pending' == $status || 'ready' == $status)
|
392 |
-
$this->create_translation($locale);
|
|
|
|
|
393 |
}
|
394 |
}
|
395 |
|
396 |
-
|
397 |
* sets document status to edited
|
398 |
*
|
399 |
* @since 0.1
|
@@ -403,7 +405,7 @@ abstract class Lingotek_Group {
|
|
403 |
// $this->translations = array_fill_keys(array_keys($this->translations), 'not-current');
|
404 |
$this->save();
|
405 |
}
|
406 |
-
|
407 |
* sets document status to failed_import
|
408 |
*
|
409 |
* @since 1.4.3
|
@@ -413,7 +415,7 @@ abstract class Lingotek_Group {
|
|
413 |
$this->save();
|
414 |
}
|
415 |
|
416 |
-
|
417 |
* returns true if at least one of the translations has the requested status
|
418 |
*
|
419 |
* @since 0.2
|
@@ -421,11 +423,11 @@ abstract class Lingotek_Group {
|
|
421 |
* @param string $status
|
422 |
* @return bool
|
423 |
*/
|
424 |
-
public function has_translation_status($status) {
|
425 |
-
return isset($this->translations) && array_intersect(array_keys($this->translations, $status), $this->pllm->get_languages_list(array('fields' => 'locale')));
|
426 |
}
|
427 |
|
428 |
-
|
429 |
* checks if target should be automatically downloaded
|
430 |
*
|
431 |
* @since 0.2
|
@@ -433,27 +435,27 @@ abstract class Lingotek_Group {
|
|
433 |
* @param string $locale
|
434 |
* @return bool
|
435 |
*/
|
436 |
-
public function is_automatic_download($locale) {
|
437 |
-
return 'automatic' == Lingotek_Model::get_profile_option('download', $this->type, $this->get_source_language(), $this->pllm->get_language($locale), $this->source);
|
438 |
}
|
439 |
|
440 |
public function is_automatic_upload() {
|
441 |
-
$workflow
|
442 |
$can_auto_upload = $workflow->auto_upload_allowed();
|
443 |
-
if ($can_auto_upload) {
|
444 |
/**
|
445 |
* Check each of the translations and if one of them doesn't allow automatic upload then we don't auto upload the doc.
|
446 |
*/
|
447 |
-
foreach ($this->translations as $locale => $progress) {
|
448 |
-
$workflow
|
449 |
$can_auto_upload = $can_auto_upload && $workflow->auto_upload_allowed();
|
450 |
}
|
451 |
}
|
452 |
-
|
453 |
return $can_auto_upload;
|
454 |
}
|
455 |
|
456 |
-
|
457 |
* checks if translation is disabled for a target language
|
458 |
*
|
459 |
* @since 0.2
|
@@ -461,13 +463,12 @@ abstract class Lingotek_Group {
|
|
461 |
* @param string $type post type or taxonomy
|
462 |
* @param object $language
|
463 |
*/
|
464 |
-
public function is_disabled_target($language, $target = null) {
|
465 |
-
$profile = Lingotek_Model::get_profile($this->type, $language, $this->source);
|
466 |
-
if ($target) {
|
467 |
-
return isset($profile['targets'][$target->slug]) && ('disabled' == $profile['targets'][$target->slug] || 'copy' == $profile['targets'][$target->slug]);
|
468 |
-
}
|
469 |
-
|
470 |
-
return isset($profile['targets'][$language->slug]) && ('disabled' == $profile['targets'][$language->slug] || 'copy' == $profile['targets'][$language->slug]);
|
471 |
}
|
472 |
}
|
473 |
|
@@ -480,15 +481,15 @@ abstract class Lingotek_Group {
|
|
480 |
* @param object $source_language
|
481 |
* @return void
|
482 |
*/
|
483 |
-
public function pre_upload_to_lingotek($item_id, $type, $source_language, $item_type) {
|
484 |
-
$workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
|
485 |
-
$workflow->pre_upload_to_lingotek($item_id, $item_type);
|
486 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
487 |
-
if ($this->_is_disabled_target($lang, $type, $item_id)) {
|
488 |
continue;
|
489 |
}
|
490 |
-
$workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
|
491 |
-
$workflow->pre_upload_to_lingotek($item_id, $item_type);
|
492 |
}
|
493 |
}
|
494 |
|
@@ -501,14 +502,14 @@ abstract class Lingotek_Group {
|
|
501 |
* @param object $source_language
|
502 |
* @return void
|
503 |
*/
|
504 |
-
public function pre_save_post($item_id, $type, $source_language) {
|
505 |
-
$workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
|
506 |
$workflow->save_post_hook();
|
507 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
508 |
-
if ($this->_is_disabled_target($lang, $type, $item_id)) {
|
509 |
continue;
|
510 |
}
|
511 |
-
$workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
|
512 |
$workflow->save_post_hook();
|
513 |
}
|
514 |
}
|
@@ -522,25 +523,25 @@ abstract class Lingotek_Group {
|
|
522 |
* @param object $source_language
|
523 |
* @return void
|
524 |
*/
|
525 |
-
public function pre_save_terms($item_id, $type, $source_language) {
|
526 |
-
$workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
|
527 |
$workflow->save_term_hook();
|
528 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
529 |
-
if ($this->_is_disabled_target($lang, $type, $item_id)) {
|
530 |
continue;
|
531 |
}
|
532 |
-
$workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
|
533 |
$workflow->save_term_hook();
|
534 |
}
|
535 |
}
|
536 |
|
537 |
-
public function get_custom_in_progress_icon($language) {
|
538 |
-
$workflow = $this->get_workflow_object($this->get_source_language(), $language->locale, $this->type, $this->source);
|
539 |
return $workflow->get_custom_in_progress_icon();
|
540 |
}
|
541 |
|
542 |
/**
|
543 |
-
* Checks the source language and all of its target language's workflows to determine whether a bulk translation request is allowed.
|
544 |
* If one or more of the workflows return true on has_custom_request_procedure() then the bulk translation request will be aborted.
|
545 |
*
|
546 |
* @param object $source_language
|
@@ -548,16 +549,18 @@ abstract class Lingotek_Group {
|
|
548 |
* @param string $item_id
|
549 |
* @return boolean
|
550 |
*/
|
551 |
-
private function can_bulk_request_translations($source_language, $type, $item_id) {
|
552 |
-
$workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
|
553 |
-
if ($workflow->has_custom_request_procedure()) {
|
|
|
554 |
|
555 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
556 |
-
if ($this->_is_disabled_target($lang, $type, $item_id)) {
|
557 |
continue;
|
558 |
}
|
559 |
-
$workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
|
560 |
-
if ($workflow->has_custom_request_procedure()) {
|
|
|
561 |
}
|
562 |
|
563 |
return true;
|
@@ -565,30 +568,30 @@ abstract class Lingotek_Group {
|
|
565 |
|
566 |
/**
|
567 |
* Instantiates and returns a workflow object. If only the source language is passed in then it will return the workflow object
|
568 |
-
* for the source locale; however, if a locale is passed in with the source language then a workflow object will be returned
|
569 |
* for the locale.
|
570 |
*
|
571 |
-
* @param string
|
572 |
* @param boolean | string $locale
|
573 |
-
* @param string
|
574 |
-
* @param string
|
575 |
* @return void
|
576 |
*/
|
577 |
-
private function get_workflow_object( $source_language, $locale = false, $type = null,
|
578 |
-
$target_language = ($locale) ? $this->pllm->get_language($locale) : false;
|
579 |
-
$source_language = (
|
580 |
-
if ($type === 'post') {
|
581 |
-
$post
|
582 |
-
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language
|
583 |
} else {
|
584 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $type, $source_language, $target_language );
|
585 |
}
|
586 |
-
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
|
587 |
return $workflow;
|
588 |
}
|
589 |
|
590 |
/**
|
591 |
-
* Checks if a target language has been disabled. Is different than the other is_disabled_target method by
|
592 |
* allowing the caller to supply all of the arguments used.
|
593 |
*
|
594 |
* @param object $target_language
|
@@ -596,8 +599,8 @@ abstract class Lingotek_Group {
|
|
596 |
* @param string $item_id
|
597 |
* @return void
|
598 |
*/
|
599 |
-
private function _is_disabled_target($target_language, $type, $item_id) {
|
600 |
-
$profile = Lingotek_Model::get_profile($type, $target_language, $item_id);
|
601 |
-
return isset($profile['targets'][$target_language->slug]) && ('disabled' == $profile['targets'][$target_language->slug] || 'cancelled' == $profile['targets'][$target_language->slug] || 'copy' == $profile['targets'][$target_language->slug]);
|
602 |
}
|
603 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Abstract class for Translations groups objects
|
5 |
*
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
abstract class Lingotek_Group {
|
9 |
+
// used to avoid uploading a translation when using automatinc upload
|
10 |
+
public static $creating_translation;
|
11 |
|
12 |
+
/**
|
13 |
* constructor
|
14 |
*
|
15 |
* @since 0.2
|
16 |
*/
|
17 |
+
public function __construct( $term, &$pllm ) {
|
18 |
$this->pllm = &$pllm;
|
19 |
+
$this->load( $term );
|
20 |
}
|
21 |
|
22 |
+
/**
|
23 |
* assigns this object properties from the underlying term
|
24 |
*
|
25 |
* @since 0.2
|
26 |
*
|
27 |
* @param object $term term translation object
|
28 |
*/
|
29 |
+
protected function load( $term ) {
|
30 |
+
$this->term_id = (int) $term->term_id;
|
31 |
+
$this->tt_id = (int) $term->term_taxonomy_id;
|
32 |
$this->document_id = $term->slug;
|
33 |
+
$this->taxonomy = $term->taxonomy;
|
34 |
+
$this->desc_array = unserialize( $term->description );
|
35 |
|
36 |
+
foreach ( array( 'type', 'source', 'status', 'translations' ) as $prop ) {
|
37 |
+
$this->$prop = &$this->desc_array['lingotek'][ $prop ];
|
38 |
+
}
|
39 |
}
|
40 |
|
41 |
+
/**
|
42 |
* updates the translation term in DB
|
43 |
*
|
44 |
* @since 0.2
|
45 |
*/
|
46 |
public function save() {
|
47 |
$args = array(
|
48 |
+
'description' => serialize( $this->desc_array ),
|
49 |
+
'slug' => $this->document_id,
|
50 |
+
'name' => $this->document_id,
|
51 |
);
|
52 |
+
wp_update_term( (int) $this->term_id, $this->taxonomy, $args );
|
|
|
|
|
|
|
|
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
* provides a safe way to update the translations statuses when receiving "simultaneous" TMS callbacks
|
57 |
*
|
58 |
* @since 0.2
|
59 |
*
|
60 |
* @param string $locale
|
61 |
* @param string $status
|
62 |
+
* @param array $arr translations to add
|
63 |
*/
|
64 |
+
protected function safe_translation_status_update( $locale, $status, $arr = array() ) {
|
65 |
global $wpdb;
|
66 |
+
$wpdb->query( "LOCK TABLES $wpdb->term_taxonomy WRITE" );
|
67 |
+
$d = $wpdb->get_var( $wpdb->prepare( "SELECT description FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $this->tt_id ) );
|
68 |
+
$d = unserialize( $d );
|
69 |
+
$this->translations[ $locale ] = $d['lingotek']['translations'][ $locale ] = $status;
|
70 |
+
// Optionally add a new translation.
|
71 |
+
$d = array_merge( $d, $arr );
|
72 |
+
$d = serialize( $d );
|
73 |
+
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->term_taxonomy SET description = %s WHERE term_taxonomy_id = %d", $d, $this->tt_id ) );
|
74 |
+
$wpdb->query( 'UNLOCK TABLES' );
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
* creates a new term translation object in DB
|
79 |
*
|
80 |
* @since 0.2
|
81 |
*
|
82 |
+
* @param int $object_id the id of the object to translate
|
83 |
* @param string $document_id Lingotek document id
|
84 |
+
* @param array $desc data to store in the Lingotek array
|
85 |
* @param string $taxonomy either 'post_translations' or 'term_translations'
|
86 |
*/
|
87 |
+
protected static function _create( $object_id, $document_id, $desc, $taxonomy ) {
|
88 |
+
$terms = wp_get_object_terms( $object_id, $taxonomy );
|
89 |
+
$term = array_pop( $terms );
|
90 |
|
91 |
+
if ( empty( $term ) ) {
|
92 |
+
wp_insert_term( $document_id, $taxonomy, array( 'description' => serialize( $desc ) ) );
|
93 |
}
|
94 |
|
95 |
// the translation already exists but was not managed by Lingotek
|
96 |
else {
|
97 |
+
if ( is_array( $old_desc = maybe_unserialize( $term->description ) ) ) {
|
98 |
+
$desc = array_merge( $old_desc, $desc );
|
99 |
+
}
|
100 |
+
wp_update_term(
|
101 |
+
(int) $term->term_id,
|
102 |
+
$taxonomy,
|
103 |
+
array(
|
104 |
+
'slug' => $document_id,
|
105 |
+
'name' => $document_id,
|
106 |
+
'description' => serialize( $desc ),
|
107 |
+
)
|
108 |
+
);
|
109 |
}
|
110 |
|
111 |
+
wp_set_object_terms( $object_id, $document_id, $taxonomy );
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
* deletes translations downloaded from the Lingotek TMS
|
|
|
116 |
*
|
117 |
* @since 0.2
|
118 |
*
|
120 |
*/
|
121 |
public function delete() {
|
122 |
$client = new Lingotek_API();
|
123 |
+
if ( $client->cancel_document( $this->document_id, $this->source ) ) {
|
124 |
+
update_option( 'ignore_delete_pref', true );
|
125 |
+
unset( $this->desc_array['lingotek'] );
|
126 |
+
foreach ( $this->desc_array as $locale ) {
|
127 |
+
if ( $locale !== $this->source ) {
|
128 |
wp_trash_post( $locale );
|
129 |
+
unset( $this->desc_array[ $locale ] );
|
130 |
}
|
131 |
}
|
132 |
$this->save();
|
133 |
+
wp_delete_term( $this->term_id, $this->taxonomy );
|
134 |
+
update_option( 'ignore_delete_pref', false );
|
135 |
} else {
|
136 |
+
update_option( 'disassociate_source_failed', true );
|
137 |
}
|
138 |
}
|
139 |
|
140 |
|
141 |
/**
|
142 |
* cancels translations from the Lingotek TMS
|
143 |
+
*
|
144 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
145 |
*/
|
146 |
public function cancel() {
|
147 |
$client = new Lingotek_API();
|
148 |
+
if ( $client->cancel_document( $this->document_id, $this->source ) ) {
|
149 |
+
if ( isset( $this->desc_array['lingotek']['translations'] ) && count( $this->desc_array['lingotek']['translations'] ) > 0 ) {
|
150 |
+
unset( $this->desc_array['lingotek']['translations'] );
|
151 |
$this->desc_array['lingotek']['status'] = 'cancelled';
|
152 |
} else {
|
153 |
+
unset( $this->desc_array['lingotek'] );
|
154 |
}
|
155 |
} else {
|
156 |
+
update_option( 'cancel_source_failed', true );
|
157 |
}
|
158 |
$this->save();
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
* delete translation from the Lingotek TMS
|
163 |
+
*
|
164 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
165 |
*/
|
166 |
+
public function delete_translation( $language, $id ) {
|
167 |
$client = new Lingotek_API();
|
168 |
+
if ( $client->cancel_translation( $this->document_id, $language->lingotek_locale, $id ) ) {
|
169 |
+
update_option( 'ignore_delete_pref', true );
|
170 |
+
$this->desc_array['lingotek']['translations'][ $language->locale ] = 'cancelled';
|
171 |
+
unset( $this->desc_array[ $language->locale ] );
|
172 |
+
wp_trash_post( $id );
|
173 |
$this->save();
|
174 |
+
update_option( 'ignore_delete_pref', false );
|
175 |
} else {
|
176 |
+
update_option( 'disassociate_target_failed', true );
|
177 |
}
|
178 |
}
|
179 |
|
180 |
/**
|
181 |
* cancel target from the Lingotek TMS
|
182 |
+
*
|
183 |
* @param bool $cancel whether to cancel the Lingotek document or not
|
184 |
*/
|
185 |
+
public function cancel_translation( $language, $id ) {
|
186 |
$client = new Lingotek_API();
|
187 |
+
if ( $client->cancel_translation( $this->document_id, $language->lingotek_locale, $id ) ) {
|
188 |
+
$this->desc_array['lingotek']['translations'][ $language->locale ] = 'cancelled';
|
189 |
$this->save();
|
190 |
} else {
|
191 |
+
update_option( 'cancel_target_failed', true );
|
192 |
}
|
193 |
}
|
194 |
|
195 |
+
/**
|
196 |
* uploads a modified source
|
197 |
*
|
198 |
* @since 0.2
|
200 |
* @param string $title
|
201 |
* @param object $content can be a post object, a term object
|
202 |
*/
|
203 |
+
public function patch( $params ) {
|
204 |
$client = new Lingotek_API();
|
205 |
+
$res = $client->patch_document( $this->document_id, $params, $this->source );
|
206 |
|
207 |
+
if ( $res !== false ) {
|
208 |
+
$this->document_id = $res;
|
209 |
+
$this->status = 'importing';
|
210 |
+
$this->translations = isset( $this->translations ) ? array_fill_keys( array_keys( $this->translations ), 'pending' ) : null;
|
211 |
$this->save();
|
212 |
}
|
213 |
}
|
214 |
|
215 |
+
/**
|
216 |
* checks the status of source document
|
217 |
*
|
218 |
* @since 0.2
|
219 |
*/
|
220 |
+
public function source_status() {
|
221 |
$client = new Lingotek_API();
|
222 |
|
223 |
+
if ( 'importing' == $this->status && $client->get_document_status( $this->document_id ) ) {
|
224 |
$this->status = 'current';
|
225 |
$this->save();
|
226 |
}
|
227 |
}
|
228 |
|
229 |
+
/**
|
230 |
* sets source status to ready
|
231 |
*
|
232 |
* @since 0.2
|
236 |
$this->save();
|
237 |
}
|
238 |
|
239 |
+
/**
|
240 |
* requests a translation to Lingotek TMS
|
241 |
*
|
242 |
* @since 0.2
|
243 |
*
|
244 |
* @param string $locale
|
245 |
*/
|
246 |
+
public function request_translation( $locale ) {
|
247 |
+
$workflow = $this->get_workflow_object( $this->get_source_language(), $locale, $this->type, $this->source );
|
248 |
+
if ( $workflow->has_custom_request_procedure() ) {
|
249 |
$workflow->do_custom_request();
|
250 |
} else {
|
251 |
+
$client = new Lingotek_API();
|
252 |
+
$language = $this->pllm->get_language( $locale );
|
253 |
+
$workflow = Lingotek_Model::get_profile_option( 'workflow_id', $this->type, $this->get_source_language(), $language, $this->source );
|
254 |
+
if ( 'project-default' === $workflow ) {
|
255 |
$workflow = null;
|
256 |
}
|
257 |
+
$args = $workflow ? array( 'workflow_id' => $workflow ) : array();
|
258 |
|
259 |
+
if ( ! $this->is_disabled_target( $language ) && empty( $this->translations[ $language->locale ] ) ) {
|
260 |
// don't change translations to pending if the api call failed
|
261 |
+
if ( $client->request_translation( $this->document_id, $language->locale, $args, $this->source ) ) {
|
262 |
+
$this->status = 'current';
|
263 |
+
$this->translations[ $language->locale ] = 'pending';
|
264 |
}
|
265 |
|
266 |
$this->save();
|
267 |
}
|
268 |
+
}//end if
|
269 |
}
|
270 |
|
271 |
+
/**
|
272 |
* requests translations to Lingotek TMS
|
273 |
*
|
274 |
* @since 0.2
|
275 |
*
|
276 |
* @param object $source_language language of the source
|
277 |
*/
|
278 |
+
protected function _request_translations( $source_language ) {
|
279 |
+
$type_id = null;
|
280 |
+
$client = new Lingotek_API();
|
281 |
|
282 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
283 |
+
$workflow = $this->get_workflow_object( $source_language, $lang->locale, $this->type, $this->source );
|
284 |
+
if ( $workflow->has_custom_request_procedure() ) {
|
|
|
|
|
|
|
285 |
$workflow->do_custom_request();
|
286 |
} else {
|
287 |
+
if ( $source_language->slug != $lang->slug && ! $this->is_disabled_target( $source_language, $lang ) && empty( $this->translations[ $lang->locale ] ) ) {
|
288 |
+
$workflow = Lingotek_Model::get_profile_option( 'workflow_id', $this->type, $source_language, $lang, $this->source );
|
289 |
+
if ( 'project-default' === $workflow ) {
|
290 |
$workflow = null;
|
291 |
}
|
292 |
+
$args = $workflow ? array( 'workflow_id' => $workflow ) : array();
|
293 |
|
294 |
+
if ( $this->type == 'string' ) {
|
295 |
$type_id = $this->name;
|
296 |
+
} else {
|
|
|
297 |
$type_id = $this->source;
|
298 |
}
|
299 |
// don't change translations to pending if the api call failed
|
300 |
+
if ( $client->request_translation( $this->document_id, $lang->locale, $args, $type_id ) ) {
|
301 |
|
302 |
/**
|
303 |
+
* This is a fix that reloads the object before editing & saving it. The problem
|
304 |
+
* was that the callbacks were coming back before this method finished so the
|
305 |
* $this->translations array was out of sync with what was in the database. We fix this
|
306 |
* by reading the DB only when we need to -> make our edit -> save the edit. This keeps us from holding on to
|
307 |
* old data and overwritting the new data.
|
308 |
*/
|
309 |
+
if ( 'post_translations' === $this->taxonomy ) {
|
310 |
+
$this->load( PLL()->model->post->get_object_term( (int) $this->source, 'post_translations' ) );
|
311 |
+
} elseif ( 'term_translations' === $this->taxonomy ) {
|
312 |
+
$this->load( PLL()->model->term->get_object_term( (int) $this->source, 'term_translations' ) );
|
313 |
}
|
314 |
$this->status = 'current';
|
315 |
+
if ( ! isset( $this->translations[ $lang->locale ] ) || isset( $this->translations[ $lang->locale ] ) && $this->translations[ $lang->locale ] != 'current' ) {
|
316 |
+
$this->translations[ $lang->locale ] = 'pending';
|
317 |
}
|
318 |
$this->save();
|
319 |
}
|
320 |
+
}//end if
|
321 |
+
}//end if
|
322 |
+
}//end foreach
|
323 |
}
|
324 |
|
325 |
/**
|
326 |
+
* Publicly exposes the safe_translation_status_update method that allows us to safely update
|
327 |
+
* translation statuses. This method is used when a request translation call is made to bridge and that
|
328 |
+
* translation was requested successfully.
|
329 |
+
*/
|
330 |
+
public function update_translation_status( $locale, $status ) {
|
331 |
+
$this->safe_translation_status_update( $locale, $status );
|
|
|
332 |
}
|
333 |
|
334 |
+
/**
|
335 |
* checks the translations status of a document
|
336 |
*
|
337 |
* @since 0.1
|
338 |
*/
|
339 |
public function translations_status() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
$this->translation_status_hard_refresh();
|
341 |
}
|
342 |
|
343 |
public function translation_status_hard_refresh() {
|
344 |
$client = new Lingotek_API();
|
345 |
+
// Keys are Lingotek locales.
|
346 |
+
$translations = $client->get_translations_status( $this->document_id, $this->source );
|
347 |
$lingotek_locale_to_pll_locale = array();
|
348 |
+
foreach ( PLL()->model->get_languages_list() as $pll_language ) {
|
349 |
+
$lingotek_locale_to_pll_locale[ $pll_language->lingotek_locale ] = $pll_language->locale;
|
350 |
}
|
351 |
+
foreach ( $translations as $lingotek_locale => $locale_status ) {
|
352 |
+
if ( ! isset( $lingotek_locale_to_pll_locale[ $lingotek_locale ] ) ) {
|
353 |
+
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
}
|
355 |
+
$wp_locale = $lingotek_locale_to_pll_locale[ $lingotek_locale ];
|
356 |
+
|
357 |
+
if ( $locale_status['percent_complete'] < 100 && $this->translations[ $wp_locale ] !== 'interim' ) {
|
358 |
+
if ( strtolower( $locale_status['progress'] ) === 'in_progress' ) {
|
359 |
+
$this->translations[ $wp_locale ] = 'ready';
|
360 |
+
} else {
|
361 |
+
$this->translations[ $wp_locale ] = 'pending';
|
362 |
+
}
|
363 |
+
} elseif ( $this->translations[ $wp_locale ] === 'interim' && $locale_status['percent_complete'] === 100 ) {
|
364 |
+
$this->translations[ $wp_locale ] = 'ready';
|
365 |
+
} elseif ( ( ! isset( $this->translations[ $wp_locale ] ) ) || ( $this->translations[ $wp_locale ] !== 'current' ) && $this->translations[ $wp_locale ] !== 'interim' ) {
|
366 |
+
$this->translations[ $wp_locale ] = 'ready';
|
367 |
}
|
368 |
}
|
369 |
|
370 |
$this->save();
|
371 |
}
|
372 |
|
373 |
+
/**
|
374 |
* sets translation status to ready
|
375 |
*
|
376 |
* @since 0.1
|
377 |
* @uses Lingotek_Group::safe_translation_status_update() as the status can be automatically set by the TMS callback
|
378 |
*/
|
379 |
+
public function translation_ready( $locale ) {
|
380 |
+
$this->safe_translation_status_update( $locale, 'ready' );
|
381 |
}
|
382 |
|
383 |
+
/**
|
384 |
* attempts to create all translations from an object
|
385 |
*
|
386 |
* @since 0.2
|
387 |
*/
|
388 |
public function create_translations() {
|
389 |
+
if ( isset( $this->translations ) ) {
|
390 |
+
foreach ( $this->translations as $locale => $status ) {
|
391 |
+
if ( 'pending' == $status || 'ready' == $status ) {
|
392 |
+
$this->create_translation( $locale );
|
393 |
+
}
|
394 |
+
}
|
395 |
}
|
396 |
}
|
397 |
|
398 |
+
/**
|
399 |
* sets document status to edited
|
400 |
*
|
401 |
* @since 0.1
|
405 |
// $this->translations = array_fill_keys(array_keys($this->translations), 'not-current');
|
406 |
$this->save();
|
407 |
}
|
408 |
+
/**
|
409 |
* sets document status to failed_import
|
410 |
*
|
411 |
* @since 1.4.3
|
415 |
$this->save();
|
416 |
}
|
417 |
|
418 |
+
/**
|
419 |
* returns true if at least one of the translations has the requested status
|
420 |
*
|
421 |
* @since 0.2
|
423 |
* @param string $status
|
424 |
* @return bool
|
425 |
*/
|
426 |
+
public function has_translation_status( $status ) {
|
427 |
+
return isset( $this->translations ) && array_intersect( array_keys( $this->translations, $status ), $this->pllm->get_languages_list( array( 'fields' => 'locale' ) ) );
|
428 |
}
|
429 |
|
430 |
+
/**
|
431 |
* checks if target should be automatically downloaded
|
432 |
*
|
433 |
* @since 0.2
|
435 |
* @param string $locale
|
436 |
* @return bool
|
437 |
*/
|
438 |
+
public function is_automatic_download( $locale ) {
|
439 |
+
return 'automatic' == Lingotek_Model::get_profile_option( 'download', $this->type, $this->get_source_language(), $this->pllm->get_language( $locale ), $this->source );
|
440 |
}
|
441 |
|
442 |
public function is_automatic_upload() {
|
443 |
+
$workflow = $this->get_workflow_object( $this->get_source_language(), false, $this->type, $this->source );
|
444 |
$can_auto_upload = $workflow->auto_upload_allowed();
|
445 |
+
if ( $can_auto_upload ) {
|
446 |
/**
|
447 |
* Check each of the translations and if one of them doesn't allow automatic upload then we don't auto upload the doc.
|
448 |
*/
|
449 |
+
foreach ( $this->translations as $locale => $progress ) {
|
450 |
+
$workflow = $this->get_workflow_object( $this->get_source_language(), $locale, $this->type, $this->source );
|
451 |
$can_auto_upload = $can_auto_upload && $workflow->auto_upload_allowed();
|
452 |
}
|
453 |
}
|
454 |
+
|
455 |
return $can_auto_upload;
|
456 |
}
|
457 |
|
458 |
+
/**
|
459 |
* checks if translation is disabled for a target language
|
460 |
*
|
461 |
* @since 0.2
|
463 |
* @param string $type post type or taxonomy
|
464 |
* @param object $language
|
465 |
*/
|
466 |
+
public function is_disabled_target( $language, $target = null ) {
|
467 |
+
$profile = Lingotek_Model::get_profile( $this->type, $language, $this->source );
|
468 |
+
if ( $target ) {
|
469 |
+
return isset( $profile['targets'][ $target->slug ] ) && ( 'disabled' == $profile['targets'][ $target->slug ] || 'copy' == $profile['targets'][ $target->slug ] );
|
470 |
+
} else {
|
471 |
+
return isset( $profile['targets'][ $language->slug ] ) && ( 'disabled' == $profile['targets'][ $language->slug ] || 'copy' == $profile['targets'][ $language->slug ] );
|
|
|
472 |
}
|
473 |
}
|
474 |
|
481 |
* @param object $source_language
|
482 |
* @return void
|
483 |
*/
|
484 |
+
public function pre_upload_to_lingotek( $item_id, $type, $source_language, $item_type ) {
|
485 |
+
$workflow = $this->get_workflow_object( $source_language, false, $type, $item_id );
|
486 |
+
$workflow->pre_upload_to_lingotek( $item_id, $item_type );
|
487 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
488 |
+
if ( $this->_is_disabled_target( $lang, $type, $item_id ) ) {
|
489 |
continue;
|
490 |
}
|
491 |
+
$workflow = $this->get_workflow_object( $source_language, $lang->locale, $type, $item_id );
|
492 |
+
$workflow->pre_upload_to_lingotek( $item_id, $item_type );
|
493 |
}
|
494 |
}
|
495 |
|
502 |
* @param object $source_language
|
503 |
* @return void
|
504 |
*/
|
505 |
+
public function pre_save_post( $item_id, $type, $source_language ) {
|
506 |
+
$workflow = $this->get_workflow_object( $source_language, false, $type, $item_id );
|
507 |
$workflow->save_post_hook();
|
508 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
509 |
+
if ( $this->_is_disabled_target( $lang, $type, $item_id ) ) {
|
510 |
continue;
|
511 |
}
|
512 |
+
$workflow = $this->get_workflow_object( $source_language, $lang->locale, $type, $item_id );
|
513 |
$workflow->save_post_hook();
|
514 |
}
|
515 |
}
|
523 |
* @param object $source_language
|
524 |
* @return void
|
525 |
*/
|
526 |
+
public function pre_save_terms( $item_id, $type, $source_language ) {
|
527 |
+
$workflow = $this->get_workflow_object( $source_language, false, $type, $item_id );
|
528 |
$workflow->save_term_hook();
|
529 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
530 |
+
if ( $this->_is_disabled_target( $lang, $type, $item_id ) ) {
|
531 |
continue;
|
532 |
}
|
533 |
+
$workflow = $this->get_workflow_object( $source_language, $lang->locale, $type, $item_id );
|
534 |
$workflow->save_term_hook();
|
535 |
}
|
536 |
}
|
537 |
|
538 |
+
public function get_custom_in_progress_icon( $language ) {
|
539 |
+
$workflow = $this->get_workflow_object( $this->get_source_language(), $language->locale, $this->type, $this->source );
|
540 |
return $workflow->get_custom_in_progress_icon();
|
541 |
}
|
542 |
|
543 |
/**
|
544 |
+
* Checks the source language and all of its target language's workflows to determine whether a bulk translation request is allowed.
|
545 |
* If one or more of the workflows return true on has_custom_request_procedure() then the bulk translation request will be aborted.
|
546 |
*
|
547 |
* @param object $source_language
|
549 |
* @param string $item_id
|
550 |
* @return boolean
|
551 |
*/
|
552 |
+
private function can_bulk_request_translations( $source_language, $type, $item_id ) {
|
553 |
+
$workflow = $this->get_workflow_object( $source_language, false, $type, $item_id );
|
554 |
+
if ( $workflow->has_custom_request_procedure() ) {
|
555 |
+
return false; }
|
556 |
|
557 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
558 |
+
if ( $this->_is_disabled_target( $lang, $type, $item_id ) ) {
|
559 |
continue;
|
560 |
}
|
561 |
+
$workflow = $this->get_workflow_object( $source_language, $lang->locale, $type, $item_id );
|
562 |
+
if ( $workflow->has_custom_request_procedure() ) {
|
563 |
+
return false; }
|
564 |
}
|
565 |
|
566 |
return true;
|
568 |
|
569 |
/**
|
570 |
* Instantiates and returns a workflow object. If only the source language is passed in then it will return the workflow object
|
571 |
+
* for the source locale; however, if a locale is passed in with the source language then a workflow object will be returned
|
572 |
* for the locale.
|
573 |
*
|
574 |
+
* @param string $source_language
|
575 |
* @param boolean | string $locale
|
576 |
+
* @param string $type
|
577 |
+
* @param string $item_id
|
578 |
* @return void
|
579 |
*/
|
580 |
+
private function get_workflow_object( $source_language, $locale = false, $type = null, $item_id = null ) {
|
581 |
+
$target_language = ( $locale ) ? $this->pllm->get_language( $locale ) : false;
|
582 |
+
$source_language = ( ! $source_language ) ? PLL()->model->post->get_language( $this->source ) : $source_language;
|
583 |
+
if ( $type === 'post' ) {
|
584 |
+
$post = ( $item_id ) ? get_post( $item_id ) : get_post( $this->source );
|
585 |
+
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language, $this->source );
|
586 |
} else {
|
587 |
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $type, $source_language, $target_language );
|
588 |
}
|
589 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
|
590 |
return $workflow;
|
591 |
}
|
592 |
|
593 |
/**
|
594 |
+
* Checks if a target language has been disabled. Is different than the other is_disabled_target method by
|
595 |
* allowing the caller to supply all of the arguments used.
|
596 |
*
|
597 |
* @param object $target_language
|
599 |
* @param string $item_id
|
600 |
* @return void
|
601 |
*/
|
602 |
+
private function _is_disabled_target( $target_language, $type, $item_id ) {
|
603 |
+
$profile = Lingotek_Model::get_profile( $type, $target_language, $item_id );
|
604 |
+
return isset( $profile['targets'][ $target_language->slug ] ) && ( 'disabled' == $profile['targets'][ $target_language->slug ] || 'cancelled' == $profile['targets'][ $target_language->slug ] || 'copy' == $profile['targets'][ $target_language->slug ] );
|
605 |
}
|
606 |
+
}
|
include/http.php
CHANGED
@@ -11,31 +11,32 @@ class Lingotek_HTTP {
|
|
11 |
const TIMEOUT = 30;
|
12 |
/*
|
13 |
* formats a request as multipart
|
14 |
-
* greatly inspired from mailgun
|
15 |
*
|
16 |
* @since 0.1
|
17 |
*/
|
18 |
-
public function format_as_multipart(&$body) {
|
19 |
-
|
|
|
20 |
|
21 |
$this->headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
|
22 |
|
23 |
$data = '';
|
24 |
|
25 |
-
foreach ($body as $key => $value) {
|
26 |
-
if (is_array($value)) {
|
27 |
-
foreach($value as $k => $v) {
|
28 |
$data .= '--' . $boundary . "\r\n";
|
29 |
$data .= 'Content-Disposition: form-data; name="' . $key;
|
30 |
-
|
|
|
31 |
$data .= '[' . $k . ']';
|
32 |
-
}
|
33 |
-
$data.= "\"\r\n\r\n";
|
34 |
$data .= $v . "\r\n";
|
35 |
}
|
36 |
-
}
|
37 |
-
|
38 |
-
$data .= '--' . $boundary ."\r\n";
|
39 |
$data .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
|
40 |
$data .= $value . "\r\n";
|
41 |
}
|
@@ -49,12 +50,19 @@ class Lingotek_HTTP {
|
|
49 |
*
|
50 |
* @since 0.1
|
51 |
*/
|
52 |
-
public function post($url, $args
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
/*
|
@@ -62,25 +70,40 @@ class Lingotek_HTTP {
|
|
62 |
*
|
63 |
* @since 0.1
|
64 |
*/
|
65 |
-
public function get($url, $args = array()) {
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
-
|
74 |
* send a DELETE request
|
75 |
*
|
76 |
* @since 0.1
|
77 |
*/
|
78 |
-
public function delete($url, $args
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
|
86 |
/*
|
@@ -88,11 +111,19 @@ class Lingotek_HTTP {
|
|
88 |
*
|
89 |
* @since 0.1
|
90 |
*/
|
91 |
-
public function patch($url, $args
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
}
|
11 |
const TIMEOUT = 30;
|
12 |
/*
|
13 |
* formats a request as multipart
|
14 |
+
* greatly inspired from mailgun WordPress plugin
|
15 |
*
|
16 |
* @since 0.1
|
17 |
*/
|
18 |
+
public function format_as_multipart( &$body ) {
|
19 |
+
// Arbitrary boundary.
|
20 |
+
$boundary = '----------------------------32052ee8fd2c';
|
21 |
|
22 |
$this->headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
|
23 |
|
24 |
$data = '';
|
25 |
|
26 |
+
foreach ( $body as $key => $value ) {
|
27 |
+
if ( is_array( $value ) ) {
|
28 |
+
foreach ( $value as $k => $v ) {
|
29 |
$data .= '--' . $boundary . "\r\n";
|
30 |
$data .= 'Content-Disposition: form-data; name="' . $key;
|
31 |
+
// Request targets cannot be in an array, as they need to have the same key.
|
32 |
+
if ( $key !== 'translation_locale_code' && $key !== 'translation_workflow_id' ) {
|
33 |
$data .= '[' . $k . ']';
|
34 |
+
}
|
35 |
+
$data .= "\"\r\n\r\n";
|
36 |
$data .= $v . "\r\n";
|
37 |
}
|
38 |
+
} else {
|
39 |
+
$data .= '--' . $boundary . "\r\n";
|
|
|
40 |
$data .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
|
41 |
$data .= $value . "\r\n";
|
42 |
}
|
50 |
*
|
51 |
* @since 0.1
|
52 |
*/
|
53 |
+
public function post( $url, $args = array(), $custom_timeout = false ) {
|
54 |
+
Lingotek::log( "POST $url" );
|
55 |
+
if ( ! empty( $args ) ) {
|
56 |
+
Lingotek::log( $args );
|
57 |
+
}
|
58 |
+
return wp_remote_post(
|
59 |
+
$url,
|
60 |
+
array(
|
61 |
+
'headers' => $this->headers,
|
62 |
+
'body' => $args,
|
63 |
+
'timeout' => ( $custom_timeout ) ? $custom_timeout : self::TIMEOUT,
|
64 |
+
)
|
65 |
+
);
|
66 |
}
|
67 |
|
68 |
/*
|
70 |
*
|
71 |
* @since 0.1
|
72 |
*/
|
73 |
+
public function get( $url, $args = array() ) {
|
74 |
+
Lingotek::log( "GET $url" );
|
75 |
+
if ( ! empty( $args ) ) {
|
76 |
+
Lingotek::log( $args );
|
77 |
+
}
|
78 |
+
return wp_remote_get(
|
79 |
+
$url,
|
80 |
+
array(
|
81 |
+
'headers' => $this->headers,
|
82 |
+
'body' => $args,
|
83 |
+
'timeout' => self::TIMEOUT,
|
84 |
+
)
|
85 |
+
);
|
86 |
+
}
|
87 |
|
88 |
+
/*
|
89 |
* send a DELETE request
|
90 |
*
|
91 |
* @since 0.1
|
92 |
*/
|
93 |
+
public function delete( $url, $args = array() ) {
|
94 |
+
Lingotek::log( "DELETE $url" );
|
95 |
+
if ( ! empty( $args ) ) {
|
96 |
+
Lingotek::log( $args );
|
97 |
+
}
|
98 |
+
return wp_remote_request(
|
99 |
+
$url,
|
100 |
+
array(
|
101 |
+
'method' => 'DELETE',
|
102 |
+
'headers' => $this->headers,
|
103 |
+
'body' => $args,
|
104 |
+
'timeout' => self::TIMEOUT,
|
105 |
+
)
|
106 |
+
);
|
107 |
}
|
108 |
|
109 |
/*
|
111 |
*
|
112 |
* @since 0.1
|
113 |
*/
|
114 |
+
public function patch( $url, $args = array() ) {
|
115 |
+
Lingotek::log( "PATCH $url" );
|
116 |
+
if ( ! empty( $args ) ) {
|
117 |
+
Lingotek::log( $args );
|
118 |
+
}
|
119 |
+
return wp_remote_request(
|
120 |
+
$url,
|
121 |
+
array(
|
122 |
+
'method' => 'PATCH',
|
123 |
+
'headers' => $this->headers,
|
124 |
+
'body' => $args,
|
125 |
+
'timeout' => self::TIMEOUT,
|
126 |
+
)
|
127 |
+
);
|
128 |
}
|
129 |
}
|
include/logger.php
CHANGED
@@ -1,44 +1,48 @@
|
|
1 |
<?php
|
2 |
|
3 |
/*
|
4 |
-
* This class handles logging events by giving the option to report / subscribe to logging events
|
5 |
*
|
6 |
* @since 1.3.1
|
7 |
*/
|
8 |
class Lingotek_Logger {
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
}
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
}
|
1 |
<?php
|
2 |
|
3 |
/*
|
4 |
+
* This class handles logging events by giving the option to report / subscribe to logging events
|
5 |
*
|
6 |
* @since 1.3.1
|
7 |
*/
|
8 |
class Lingotek_Logger {
|
9 |
|
10 |
+
public static function fatal( $message, $extra_data = null, $error = null ) {
|
11 |
+
self::log( 'fatal', $message, $extra_data, $error ); }
|
12 |
+
public static function error( $message, $extra_data = null, $error = null ) {
|
13 |
+
self::log( 'error', $message, $extra_data, $error ); }
|
14 |
+
public static function warning( $message, $extra_data = null, $error = null ) {
|
15 |
+
self::log( 'warning', $message, $extra_data, $error ); }
|
16 |
+
public static function info( $message, $extra_data = null ) {
|
17 |
+
self::log( 'info', $message, $extra_data ); }
|
18 |
+
public static function debug( $message, $extra_data = null ) {
|
19 |
+
self::log( 'debug', $message, $extra_data ); }
|
20 |
|
21 |
+
private static function log( $level, $message, $extra_data, $error = null ) {
|
22 |
+
try {
|
23 |
+
do_action( 'lingotek_log', $level, $message, $extra_data, $error );
|
24 |
+
do_action( 'lingotek_log_' . $level, $message, $extra_data, $error );
|
25 |
+
$prefs = Lingotek_Model::get_prefs();
|
26 |
+
$logging = isset( $prefs['enable_lingotek_logs'] ) && '1' === $prefs['enable_lingotek_logs']['enabled'] ? true : false;
|
27 |
+
$is_logging = $logging ? 'true' : 'false';
|
28 |
+
if ( $logging ) {
|
29 |
+
$serialized_extra_data = self::serialize_extra_data( $extra_data );
|
30 |
+
$errorMessage = isset( $error ) && ! isempty( $error ) ? ', Error: ' . $error : '';
|
31 |
+
error_log( $level . ': ' . $message . $errorMessage . ', ExtraData: ' . $serialized_extra_data );
|
32 |
+
}
|
33 |
+
} catch ( Exception $e ) {
|
34 |
+
error_log( 'error occured while trying to write Lingotek log entry' );
|
35 |
+
}
|
36 |
+
}
|
|
|
37 |
|
38 |
+
private static function serialize_extra_data( $extra_data ) {
|
39 |
+
try {
|
40 |
+
if ( is_string( $extra_data ) ) {
|
41 |
+
return $extra_data;
|
42 |
+
}
|
43 |
+
return json_encode( $extra_data, JSON_PRETTY_PRINT );
|
44 |
+
} catch ( Exception $e ) {
|
45 |
+
return '';
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
include/model.php
CHANGED
@@ -1,17 +1,24 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Manages interactions with database
|
5 |
* Factory for Lingotek_Group objects
|
6 |
*
|
7 |
* @since 0.1
|
8 |
*/
|
9 |
class Lingotek_Model {
|
10 |
-
public $pllm; // Polylang model
|
11 |
-
static public $copying_post;
|
12 |
-
static public $copying_term;
|
13 |
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
* constructor
|
16 |
*
|
17 |
* @since 0.1
|
@@ -19,11 +26,29 @@ class Lingotek_Model {
|
|
19 |
public function __construct() {
|
20 |
$this->pllm = $GLOBALS['polylang']->model;
|
21 |
|
22 |
-
register_taxonomy(
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
|
26 |
-
|
27 |
* get the strings groups as well as their count
|
28 |
*
|
29 |
* @since 0.2
|
@@ -32,19 +57,20 @@ class Lingotek_Model {
|
|
32 |
*/
|
33 |
public static function get_strings() {
|
34 |
static $strings = array();
|
35 |
-
if (empty($strings)) {
|
36 |
-
|
|
|
37 |
|
38 |
-
foreach (PLL_Admin_Strings::get_strings() as $string) {
|
39 |
-
$strings[$string['context']]['context'] = $string['context'];
|
40 |
-
$strings[$string['context']]['count']
|
41 |
}
|
42 |
-
$strings = array_values($strings);
|
43 |
}
|
44 |
return $strings;
|
45 |
}
|
46 |
|
47 |
-
|
48 |
* create a translation group object from a translation term
|
49 |
*
|
50 |
* @since 0.2
|
@@ -52,59 +78,59 @@ class Lingotek_Model {
|
|
52 |
* @param object $term
|
53 |
* @return object
|
54 |
*/
|
55 |
-
protected function convert_term($term) {
|
56 |
-
switch($term->taxonomy) {
|
57 |
case 'term_translations':
|
58 |
-
return new Lingotek_Group_Term($term, $this->pllm);
|
59 |
|
60 |
case 'post_translations':
|
61 |
-
$class = $term->name
|
62 |
-
return new $class($term, $this->pllm);
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
|
67 |
* get the translation term of an object
|
68 |
*
|
69 |
* @since 0.2
|
70 |
*
|
71 |
-
* @param string
|
72 |
-
* @param int|string $id
|
73 |
-
* @return object
|
74 |
*/
|
75 |
-
public function get_group($type, $id) {
|
76 |
-
switch ($type) {
|
77 |
case 'post':
|
78 |
-
return ($post = PLL()->model->post->get_object_term((int) $id, $type . '_translations')) && !empty($post) ? $this->convert_term($post) : false;
|
79 |
case 'term':
|
80 |
-
return ($term = PLL()->model->term->get_object_term((int) $id, $type . '_translations')) && !empty($term) ? $this->convert_term($term) : false;
|
81 |
case 'string':
|
82 |
-
if (is_numeric($id)) {
|
83 |
$strings = self::get_strings();
|
84 |
-
$id
|
85 |
}
|
86 |
-
return ($term = get_term_by('name', $id, 'post_translations')) && !empty($term) ? $this->convert_term($term) : false;
|
87 |
default:
|
88 |
return false;
|
89 |
}
|
90 |
}
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
* get the translation term of an object by its Lingotek document id
|
109 |
*
|
110 |
* @since 0.2
|
@@ -112,16 +138,17 @@ class Lingotek_Model {
|
|
112 |
* @param string|object $document_id
|
113 |
* @return object translation term
|
114 |
*/
|
115 |
-
public function get_group_by_id($document_id) {
|
116 |
// we already passed a translation group object
|
117 |
-
if (is_object($document_id))
|
118 |
return $document_id;
|
|
|
119 |
|
120 |
-
$terms = get_terms(array('post_translations', 'term_translations'), array('slug' => $document_id));
|
121 |
-
return is_wp_error($terms) || empty($terms) ? false : $this->convert_term(reset($terms));
|
122 |
}
|
123 |
|
124 |
-
|
125 |
* get a translation profile
|
126 |
*
|
127 |
* @since 0.2
|
@@ -130,96 +157,106 @@ class Lingotek_Model {
|
|
130 |
* @param object $language
|
131 |
* @return array
|
132 |
*/
|
133 |
-
static
|
134 |
global $profileInformation, $ltk_profiles, $ltk_contentTypes;
|
135 |
|
136 |
-
if (is_null($ltk_profiles)) {
|
137 |
-
$ltk_profiles = get_option('lingotek_profiles');
|
138 |
}
|
139 |
-
if ($post_id && $profileInformation && isset($profileInformation[$type]) && isset($profileInformation[$type][$language->locale]) && isset($profileInformation[$type][$language->locale][$post_id])) {
|
140 |
-
return $ltk_profiles[$profileInformation[$type][$language->locale][$post_id]];
|
141 |
}
|
142 |
|
143 |
-
if (is_null($ltk_contentTypes)) {
|
144 |
-
$ltk_contentTypes = get_option('lingotek_content_type');
|
145 |
}
|
146 |
|
147 |
// If a profile is set for a specific post/page get that first
|
148 |
-
if ($post_id) {
|
149 |
-
$
|
150 |
-
if ($
|
151 |
-
if (!isset(
|
152 |
-
|
153 |
-
if (!isset($profileInformation[$type
|
154 |
-
|
155 |
-
|
|
|
|
|
|
|
156 |
}
|
157 |
}
|
158 |
|
159 |
-
//
|
160 |
$default = 'post' === $type || 'page' === $type ? 'manual' : 'disabled';
|
161 |
|
162 |
-
$profile = is_object($language) && isset($content_types[$type]['sources'][$language->slug]) ?
|
163 |
-
$ltk_contentTypes[$type]['sources'][$language->slug] :
|
164 |
-
(isset($ltk_contentTypes[$type]['profile']) ? $ltk_contentTypes[$type]['profile'] : $default);
|
165 |
-
|
166 |
-
if ($post_id) {
|
167 |
-
if (!isset(
|
168 |
-
|
169 |
-
if (!isset($profileInformation[$type
|
170 |
-
|
|
|
|
|
|
|
171 |
}
|
172 |
|
173 |
-
return $ltk_profiles[$profile];
|
174 |
}
|
175 |
|
176 |
-
static
|
177 |
$default = array(
|
178 |
-
'download_post_status'
|
179 |
'auto_upload_post_statuses' => array(
|
180 |
-
|
181 |
-
'
|
|
|
|
|
182 |
'publish' => 1,
|
183 |
-
'future'
|
184 |
'private' => 0,
|
185 |
),
|
186 |
-
'trash_linked_content'
|
187 |
-
|
188 |
-
|
189 |
-
'auto_update_status' => '10',
|
190 |
-
'enable_lingotek_logs' => 0,
|
191 |
);
|
192 |
-
|
|
|
193 |
return $prefs;
|
194 |
}
|
195 |
|
196 |
-
|
197 |
* get a profile option
|
198 |
*
|
199 |
* @since 0.2
|
200 |
*
|
201 |
-
* @param string $item 'project_id' | 'workflow_id' | 'upload' | 'download'
|
202 |
-
* @param string $type
|
203 |
* @param object $source_language
|
204 |
-
* @param object $target_language
|
205 |
-
* @return string | bool either the option or false if the translation is disabled
|
206 |
*/
|
207 |
-
static
|
208 |
-
$profile = self::get_profile($type, $source_language, $post_id);
|
209 |
-
if ('disabled' === $profile['profile'] || is_object($target_language) && isset($profile['targets'][$target_language->slug]) && 'disabled' === $profile['targets'][$target_language->slug])
|
210 |
return false;
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
-
if (!empty(
|
213 |
-
return $profile[
|
|
|
214 |
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
$defaults = get_option('lingotek_defaults');
|
219 |
-
return isset($defaults[$item]) ? $defaults[$item] : null;
|
220 |
}
|
221 |
|
222 |
-
|
223 |
* find targets that are set to copy in a profile
|
224 |
*
|
225 |
* @since 1.1.1
|
@@ -227,17 +264,16 @@ class Lingotek_Model {
|
|
227 |
* @param array $profile (use get_profile to retrieve)
|
228 |
* @return array of targets that should be copied. if none exist returns empty array
|
229 |
*/
|
230 |
-
public function targets_to_be_copied($profile) {
|
231 |
-
if (isset($profile['targets']) && in_array('copy', $profile['targets'])) {
|
232 |
-
$targets_to_copy = array_keys($profile['targets'], 'copy');
|
233 |
return $targets_to_copy;
|
234 |
-
}
|
235 |
-
else {
|
236 |
return array();
|
237 |
}
|
238 |
}
|
239 |
|
240 |
-
|
241 |
* copy a post from the source language to a target language
|
242 |
*
|
243 |
* @since 1.1.1
|
@@ -246,87 +282,93 @@ class Lingotek_Model {
|
|
246 |
* @param string $target polylang language slug (ex: en, de, fr, etc)
|
247 |
* @return $new_post_id if copy of post is successful, false otherwise
|
248 |
*/
|
249 |
-
public function copy_post($post, $target) {
|
250 |
-
self::$copying_post
|
251 |
-
$document
|
252 |
-
$prefs
|
253 |
-
$cp_lang
|
254 |
-
$cp_post
|
255 |
-
$cp_post['post_status'] = ($prefs['download_post_status'] === 'SAME_AS_SOURCE')? $post->post_status : $prefs['download_post_status'];
|
256 |
-
$slug
|
257 |
-
unset($cp_post['ID']);
|
258 |
-
unset($cp_post['post_name']);
|
259 |
-
if (!isset($document->desc_array[$target])) {
|
260 |
-
$new_post_id = wp_insert_post($cp_post, true);
|
261 |
-
if (!is_wp_error($new_post_id)) {
|
262 |
-
PLL()->model->post->set_language($new_post_id, $cp_lang);
|
263 |
-
wp_set_object_terms($new_post_id, $document->term_id, 'post_translations');
|
264 |
-
$GLOBALS['polylang']->sync->taxonomies->copy($document->source, $new_post_id, $cp_lang->slug);
|
265 |
-
$GLOBALS['polylang']->sync->post_metas->copy($document->source, $new_post_id, $cp_lang->slug);
|
266 |
-
Lingotek_Group_Post::copy_or_ignore_metas($post->ID, $new_post_id);
|
267 |
-
$document->desc_array[$target] = $new_post_id;
|
268 |
$document->save();
|
269 |
-
if (class_exists('PLL_Share_Post_Slug', true)) {
|
270 |
-
wp_update_post(
|
|
|
|
|
|
|
|
|
|
|
271 |
}
|
272 |
}
|
273 |
}
|
274 |
self::$copying_post = false;
|
275 |
}
|
276 |
|
277 |
-
public function copy_term($term, $target, $taxonomy) {
|
278 |
self::$copying_term = true;
|
279 |
-
$document
|
280 |
-
$cp_lang
|
281 |
-
$cp_term
|
282 |
-
//unset($cp_term['term_id']);
|
283 |
|
284 |
-
if (class_exists('PLL_Share_Term_Slug', true)) {
|
285 |
remove_action( 'create_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
286 |
remove_action( 'edit_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
287 |
-
remove_action( 'pre_post_update', array( PLL()->filters_term, 'pre_post_update' ));
|
288 |
-
remove_filter( 'pre_term_name', array( PLL()->filters_term, 'pre_term_name' ));
|
289 |
-
remove_filter( 'pre_term_slug', array( PLL()->filters_term, 'pre_term_slug' ), 10, 2);
|
290 |
add_action( 'pre_post_update', array( PLL()->share_term_slug, 'pre_post_update' ) );
|
291 |
add_filter( 'pre_term_name', array( PLL()->share_term_slug, 'pre_term_name' ) );
|
292 |
add_filter( 'pre_term_slug', array( PLL()->share_term_slug, 'pre_term_slug' ), 10, 2 );
|
293 |
add_action( 'create_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
294 |
add_action( 'edit_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
295 |
$_POST['term_lang_choice'] = $cp_lang->slug;
|
296 |
-
}
|
297 |
-
|
298 |
-
if (isset($cp_term['slug']) && term_exists($cp_term['slug'])) {
|
299 |
$cp_term['slug'] .= '-' . $cp_lang->slug;
|
300 |
}
|
301 |
}
|
302 |
|
303 |
-
$new_term = wp_insert_term($cp_term['name'], $taxonomy, $cp_term);
|
304 |
|
305 |
-
if (!is_wp_error($new_term)) {
|
306 |
-
PLL()->model->term->set_language($new_term['term_id'], $cp_lang);
|
307 |
-
wp_set_object_terms($new_term['term_id'], $document->term_id, 'term_translations');
|
308 |
-
$document->desc_array[$target] = $new_term['term_id'];
|
309 |
$document->save();
|
310 |
}
|
311 |
self::$copying_term = false;
|
312 |
}
|
313 |
|
314 |
-
private function format_patch_params($params, $profile, $source_lang) {
|
315 |
-
$params['translation_locale_code'] =
|
316 |
-
$params['translation_workflow_id'] =
|
317 |
|
318 |
-
foreach ($this->pllm->get_languages_list() as $lang) {
|
319 |
-
if ($lang->lingotek_locale == $source_lang->lingotek_locale
|
320 |
-
|| (isset($profile['targets'][$lang->slug]) && $profile['targets'][$lang->slug]
|
321 |
continue;
|
322 |
}
|
323 |
$params['translation_locale_code'][] = $lang->lingotek_locale;
|
324 |
-
if (isset($profile['custom']['workflow_id'][$lang->slug])) {
|
325 |
-
$params['translation_workflow_id'][] = $profile['custom']['workflow_id'][$lang->slug];
|
|
|
|
|
|
|
326 |
}
|
327 |
}
|
328 |
-
if (empty($params['translation_workflow_id'])) {
|
329 |
-
unset($params['translation_workflow_id']);
|
330 |
}
|
331 |
return $params;
|
332 |
}
|
@@ -337,75 +379,86 @@ class Lingotek_Model {
|
|
337 |
* @since 0.1
|
338 |
*
|
339 |
* @param int $post_id
|
|
|
340 |
*/
|
341 |
-
public function upload_post($post_id) {
|
342 |
-
$post
|
343 |
-
$language = PLL()->model->post->get_language($post_id);
|
344 |
-
$profile
|
345 |
-
if ('disabled'
|
346 |
return;
|
347 |
}
|
348 |
-
|
|
|
|
|
|
|
|
|
|
|
349 |
$content = null;
|
350 |
// If we already uploaded this doc, check if it changed and prevent the upload if it didn't.
|
351 |
-
if ($document_id) {
|
352 |
-
$content
|
353 |
-
$hash_terms = wp_get_object_terms($post->ID, 'lingotek_hash');
|
354 |
-
$hash_term
|
355 |
-
$new_hash
|
356 |
-
if (!empty($hash_term)) {
|
357 |
if ( $hash_term->description == $new_hash ) {
|
358 |
return;
|
359 |
}
|
360 |
}
|
361 |
}
|
362 |
-
$document = $this->get_group('post', $post_id);
|
363 |
// Customized workflows have the option to do any sort of pre-processing before a document
|
364 |
// is uploaded to lingotek.
|
365 |
-
if ($document) {
|
366 |
-
$document->pre_upload_to_lingotek($post_id, $post->post_type, $language, 'post');
|
367 |
-
}
|
368 |
-
|
369 |
-
$client = new Lingotek_API();
|
370 |
-
$external_url = get_page_link($post_id);
|
371 |
-
if (!$content) {
|
372 |
-
$content = Lingotek_Group_Post::get_content($post);
|
373 |
-
}
|
374 |
-
$params = $this->build_params($external_url, $post->post_title, $post->post_type, $content, $language, $profile, $post_id, $wp_target_locales);
|
375 |
-
$filter_ids = $this->get_filter_ids($post->post_type, $language, $post_id);
|
376 |
-
$params = array_merge($params, $filter_ids);
|
377 |
-
if ($document && in_array($document->status, array('edited', 'importing', 'current', 'cancelled')) && $document_id) {
|
378 |
-
$document->patch($this->format_patch_params($params, $profile, $language));
|
379 |
-
// Re-establish hash relation if needed
|
380 |
-
if (!isset($hash_term->term_id)) {
|
381 |
-
$hash_terms = wp_set_post_terms($post->ID, 'lingotek_hash_' . $post->ID, "lingotek_hash");
|
382 |
-
$hash_term_id = array_pop($hash_terms);
|
383 |
-
} else {
|
384 |
-
$hash_term_id = $hash_term->id;
|
385 |
-
}
|
386 |
-
wp_update_term($hash_term_id, 'lingotek_hash', array('description' => $new_hash));
|
387 |
-
} elseif (!Lingotek_Group::$creating_translation && !self::$copying_post && (!$document || $document->document_id )) {
|
388 |
-
$document_id = $client->upload_document($params, $post->ID);
|
389 |
|
390 |
-
|
391 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
$document = $this->get_group_by_id( $document_id );
|
393 |
-
if (isset($wp_target_locales)) {
|
394 |
-
foreach ($wp_target_locales as $locale){
|
395 |
-
$document->translations[$locale] = 'pending';
|
396 |
}
|
397 |
}
|
398 |
$document->save();
|
399 |
// If a translation profile has targets set to copy then copy them
|
400 |
-
$targets_to_copy = $this->targets_to_be_copied($profile);
|
401 |
-
$upload
|
402 |
-
if (!empty($targets_to_copy) && $upload
|
403 |
-
foreach ($targets_to_copy as $target) {
|
404 |
-
$this->copy_post($post, $target);
|
405 |
}
|
406 |
}
|
|
|
407 |
}
|
408 |
-
|
|
|
409 |
}
|
410 |
|
411 |
/**
|
@@ -413,122 +466,124 @@ class Lingotek_Model {
|
|
413 |
*
|
414 |
* @since 0.2
|
415 |
*
|
416 |
-
* @param int
|
417 |
* @param string $taxonomy
|
418 |
*/
|
419 |
-
public function upload_term($term_id, $taxonomy) {
|
420 |
-
$term
|
421 |
-
$language = PLL()->model->term->get_language($term_id);
|
422 |
-
if (empty($term) || empty($language))
|
423 |
return;
|
|
|
424 |
|
425 |
-
$profile = self::get_profile($taxonomy, $language);
|
426 |
-
if ('disabled'
|
427 |
return;
|
|
|
428 |
|
429 |
/**
|
430 |
* Customized workflows have the option to do any sort of pre-processing before a document is uploaded to lingotek.
|
431 |
*/
|
432 |
-
$document = $this->get_group('term', $term_id);
|
433 |
-
if ($document) {
|
434 |
-
$document->pre_upload_to_lingotek($term_id, $taxonomy, $language, 'term');
|
435 |
}
|
436 |
|
437 |
-
$client
|
438 |
-
$content
|
439 |
-
$params
|
440 |
-
$filter_ids = $this->get_filter_ids($taxonomy, $language, $term_id);
|
441 |
-
$params
|
442 |
-
|
443 |
-
if (($document = $this->get_group('term', $term_id)) && 'edited' == $document->status) {
|
444 |
-
$document->patch($this->format_patch_params($params, $profile, $language), $term->name, $term);
|
445 |
-
}
|
446 |
|
447 |
-
|
448 |
-
$
|
|
|
|
|
449 |
|
450 |
-
if ($document_id) {
|
451 |
-
Lingotek_Group_Term::create($term_id, $taxonomy
|
452 |
$document = $this->get_group_by_id( $document_id );
|
453 |
-
foreach ($wp_target_locales as $locale){
|
454 |
-
$document->translations[$locale] = 'pending';
|
455 |
}
|
456 |
$document->save();
|
457 |
-
|
458 |
// If a translation profile has targets set to copy then copy them
|
459 |
-
$targets_to_copy = $this->targets_to_be_copied($profile);
|
460 |
-
if (!empty($targets_to_copy) && $profile['upload']
|
461 |
-
foreach ($targets_to_copy as $target) {
|
462 |
-
$this->copy_term($term, $target, $taxonomy);
|
463 |
}
|
464 |
}
|
465 |
}
|
466 |
-
}
|
467 |
}
|
468 |
|
469 |
-
|
470 |
* uploads a strings group to Lingotek TMS
|
471 |
*
|
472 |
* @since 0.2
|
473 |
*
|
474 |
* @param string $group
|
475 |
*/
|
476 |
-
public function upload_strings($group) {
|
477 |
-
$type
|
478 |
-
$language = $this->pllm->get_language($this->pllm->options['default_lang']);
|
479 |
-
$profile
|
480 |
|
481 |
-
if ('disabled'
|
482 |
return;
|
|
|
483 |
|
484 |
-
if (is_numeric($group)) {
|
485 |
$strings = self::get_strings();
|
486 |
-
$group
|
487 |
}
|
488 |
|
489 |
// check that we have a valid string group
|
490 |
-
if (!in_array($group, wp_list_pluck(self::get_strings(), 'context')))
|
491 |
return;
|
|
|
492 |
|
493 |
-
$client
|
494 |
-
$content
|
495 |
-
$params
|
496 |
-
$filter_ids = $this->get_filter_ids($type, $language, null);
|
497 |
-
$params
|
498 |
|
499 |
-
if (($document = $this->get_group($type, $group)) && 'edited'
|
500 |
-
$document->patch($this->format_patch_params($params, $profile, $language));
|
501 |
-
}
|
502 |
-
|
503 |
-
$document_id = $client->upload_document($params, $group);
|
504 |
|
505 |
-
if ($document_id) {
|
506 |
-
Lingotek_Group_String::create($group, $language, $document_id);
|
507 |
}
|
508 |
}
|
509 |
}
|
510 |
|
511 |
-
|
512 |
* checks if the document can be upload to Lingotek
|
513 |
*
|
514 |
* @since 0.1
|
515 |
*
|
516 |
* @param string $type either 'post' or 'term'
|
517 |
-
* @param int
|
518 |
* @return bool
|
519 |
*/
|
520 |
-
|
521 |
-
|
522 |
-
$document = $this->get_group($type, $object_id);
|
523 |
-
if ($document && $document->status
|
524 |
return false;
|
525 |
}
|
526 |
-
switch ($type) {
|
527 |
case 'string':
|
528 |
-
if (empty($document))
|
529 |
return true;
|
530 |
-
|
531 |
-
|
|
|
532 |
$document->source_edited();
|
533 |
return true;
|
534 |
}
|
@@ -536,123 +591,123 @@ class Lingotek_Model {
|
|
536 |
return false;
|
537 |
|
538 |
case 'post':
|
539 |
-
$language
|
540 |
-
$allow_status = $document && 'edited'
|
541 |
-
return !empty($language) && (empty($document) ||
|
542 |
-
(isset($document) && $allow_status && $document->source == $object_id));
|
543 |
case 'term':
|
544 |
// first check that a language is associated to the object
|
545 |
-
$language = PLL()->model->term->get_language($object_id);
|
546 |
|
547 |
// FIXME how to get profile to check if disabled?
|
548 |
|
549 |
-
return !empty($language) && (empty($document) ||
|
550 |
-
|
551 |
-
(
|
552 |
-
|
|
|
553 |
}
|
554 |
|
555 |
-
|
556 |
* deletes a post
|
557 |
*
|
558 |
* @since 0.1
|
559 |
*
|
560 |
* @param int $object_id post id
|
561 |
*/
|
562 |
-
public function delete_post($object_id) {
|
563 |
-
if ($document = $this->get_group('post', $object_id)) {
|
564 |
$client = new Lingotek_API();
|
565 |
|
566 |
-
if ($document->source == $object_id) {
|
567 |
-
$client->cancel_document($document->document_id, $object_id);
|
568 |
-
}
|
569 |
-
|
570 |
-
PLL()->model->post->
|
571 |
-
$
|
572 |
-
$client->cancel_translation($document->document_id, $lang->lingotek_locale, $object_id);
|
573 |
}
|
574 |
}
|
575 |
}
|
576 |
|
577 |
-
public function cancel_post($object_id) {
|
578 |
-
if ($document = $this->get_group('post', $object_id)) {
|
579 |
$client = new Lingotek_API();
|
580 |
|
581 |
-
if($document->source == $object_id) {
|
582 |
-
$client->cancel_document($document->document_id, $object_id);
|
583 |
-
}
|
584 |
-
|
585 |
-
$lang = PLL()->model->post->get_language($object_id);
|
586 |
$locale = $lang->locale;
|
587 |
-
if(isset($document->desc_array['lingotek']['translations'][$locale])){
|
588 |
-
$document->desc_array['lingotek']['translations'][$locale] = 'cancelled';
|
589 |
}
|
590 |
$document->save();
|
591 |
-
$client->cancel_translation($document->document_id, $lang->lingotek_locale, $object_id);
|
592 |
}
|
593 |
}
|
594 |
}
|
595 |
|
596 |
-
|
597 |
* deletes a term
|
598 |
*
|
599 |
* @since 0.2
|
600 |
*
|
601 |
* @param int $object_id term id
|
602 |
*/
|
603 |
-
public function delete_term($object_id) {
|
604 |
-
if ($document = $this->get_group('term', $object_id)) {
|
605 |
$client = new Lingotek_API();
|
606 |
-
if ($document->source == $object_id) {
|
607 |
-
$client->cancel_document($document->document_id, $object_id);
|
608 |
-
}
|
609 |
-
|
610 |
-
|
611 |
-
PLL()->model->term->
|
612 |
-
|
613 |
-
$client->cancel_translation($document->document_id, $lang->lingotek_locale, $object_id);
|
614 |
}
|
615 |
}
|
616 |
}
|
617 |
|
618 |
-
public function cancel_term($object_id){
|
619 |
-
if ($document = $this->get_group('term', $object_id)){
|
620 |
$client = new Lingotek_API();
|
621 |
-
if($document->source == $object_id){
|
622 |
-
$client->cancel_document($document->document_id, $object_id);
|
623 |
} else {
|
624 |
-
$lang = PLL()->model->term->get_language($object_id);
|
625 |
-
PLL()->model->term->cancel_translation($object_id);
|
626 |
-
PLL()->model->term->delete_translation($object_id);
|
627 |
-
$client->cancel_translation($document->document_id, $lang->lingotek_locale, $object_id);
|
628 |
}
|
629 |
}
|
630 |
}
|
631 |
|
632 |
-
|
633 |
* counts the number of targets per language
|
634 |
*
|
635 |
* @since 0.2
|
636 |
*
|
637 |
-
* @param array $groups
|
638 |
* @return array number of targets per language
|
639 |
*/
|
640 |
-
protected function get_target_count($groups) {
|
641 |
-
$targets = array_fill_keys($this->pllm->get_languages_list(array('fields' => 'slug')), 0);
|
642 |
-
|
643 |
-
foreach ($groups as $group) {
|
644 |
-
$group = unserialize($group);
|
645 |
-
if (isset($group['lingotek']['translations'])) {
|
646 |
-
foreach ($group['lingotek']['translations'] as $locale => $status) {
|
647 |
-
|
648 |
-
|
|
|
|
|
649 |
}
|
650 |
}
|
651 |
}
|
652 |
return $targets;
|
653 |
}
|
654 |
|
655 |
-
|
656 |
* counts the number of sources and targets per language for a certain post type
|
657 |
*
|
658 |
* @since 0.2
|
@@ -660,101 +715,119 @@ class Lingotek_Model {
|
|
660 |
* @param string $post_type
|
661 |
* @return array
|
662 |
*/
|
663 |
-
public function count_posts($post_type) {
|
664 |
global $wpdb;
|
665 |
|
666 |
static $r = array();
|
667 |
-
if (!empty($r[$post_type]))
|
668 |
-
return $r[$post_type];
|
|
|
669 |
|
670 |
-
if (!post_type_exists($post_type))
|
671 |
return;
|
|
|
672 |
|
673 |
// gets all translations groups for the post type
|
674 |
-
$groups = $wpdb->get_col(
|
|
|
|
|
675 |
SELECT DISTINCT tt.description FROM $wpdb->term_taxonomy AS tt
|
676 |
INNER JOIN $wpdb->term_relationships AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
677 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
678 |
WHERE tt.taxonomy = %s
|
679 |
AND p.post_type = %s
|
680 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
|
|
|
686 |
|
687 |
$group_ids = array();
|
688 |
-
$disabled
|
689 |
|
690 |
-
foreach ($this->pllm->get_languages_list() as $language) {
|
691 |
// counts all the posts in one language
|
692 |
-
$n = $wpdb->get_var(
|
|
|
|
|
693 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
694 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
695 |
WHERE tr.term_taxonomy_id = %d
|
696 |
AND p.post_type = %s
|
697 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
|
|
|
|
|
|
|
|
702 |
SELECT object_id FROM $wpdb->term_relationships AS tr
|
703 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
704 |
WHERE tr.term_taxonomy_id = %d
|
705 |
AND p.post_type = %s
|
706 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
|
|
|
|
714 |
}
|
715 |
}
|
716 |
|
717 |
$count = 0;
|
718 |
-
foreach ($objects as $object) {
|
719 |
$id = $object;
|
720 |
-
if (!in_array($id, $group_ids)) {
|
721 |
-
$profile = self::get_profile($post_type, $language, $id);
|
722 |
-
if ($profile['profile']
|
723 |
-
|
724 |
}
|
725 |
}
|
726 |
}
|
727 |
-
$disabled[$language->slug] = $count;
|
728 |
|
729 |
// if a post is not a target, then it is source
|
730 |
-
$sources[$language->slug] = $n - $targets[$language->slug];
|
731 |
// $sources[$language->slug] -= $disabled[$language->slug];
|
732 |
-
}
|
733 |
|
734 |
// untranslated posts have no associated translation group in DB
|
735 |
// so let's count them indirectly
|
736 |
|
737 |
// counts the number of translated posts
|
738 |
-
$n_translated = $wpdb->get_var(
|
|
|
|
|
739 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
740 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
741 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
742 |
WHERE tt.taxonomy = %s
|
743 |
AND p.post_type = %s
|
744 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
745 |
-
|
746 |
-
|
|
|
|
|
747 |
|
748 |
// untranslated = total - translated
|
749 |
// total of posts translations groups = untranslated + number of translation groups stored in DB
|
750 |
-
$count_posts = (array) wp_count_posts($post_type);
|
751 |
-
|
752 |
-
$
|
|
|
753 |
|
754 |
-
return $r[$post_type] = compact('sources', 'targets', 'total');
|
755 |
}
|
756 |
|
757 |
-
|
758 |
* counts the number of sources and targets per language for a certain taxonomy
|
759 |
*
|
760 |
* @since 0.2
|
@@ -762,192 +835,206 @@ class Lingotek_Model {
|
|
762 |
* @param string $taxonomy
|
763 |
* @return array
|
764 |
*/
|
765 |
-
public function count_terms($taxonomy) {
|
766 |
global $wpdb;
|
767 |
|
768 |
static $r = array();
|
769 |
-
if (!empty($r[$taxonomy]))
|
770 |
-
return $r[$taxonomy];
|
|
|
771 |
|
772 |
-
if (!taxonomy_exists($taxonomy))
|
773 |
return;
|
|
|
774 |
|
775 |
// gets all translations groups for the taxonomy
|
776 |
-
$groups = $wpdb->get_col(
|
|
|
|
|
777 |
SELECT DISTINCT tt1.description FROM $wpdb->term_taxonomy AS tt1
|
778 |
INNER JOIN $wpdb->term_relationships AS tr ON tt1.term_taxonomy_id = tr.term_taxonomy_id
|
779 |
INNER JOIN $wpdb->term_taxonomy AS tt2 ON tt2.term_id = tr.object_id
|
780 |
WHERE tt1.taxonomy = %s
|
781 |
AND tt2.taxonomy = %s",
|
782 |
-
|
783 |
-
|
|
|
|
|
784 |
|
785 |
-
$targets = $this->get_target_count($groups);
|
786 |
|
787 |
$group_ids = array();
|
788 |
-
$disabled
|
789 |
|
790 |
-
foreach ($this->pllm->get_languages_list() as $language) {
|
791 |
// counts all the terms in one language
|
792 |
-
$n = $wpdb->get_var(
|
|
|
|
|
793 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
794 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = tr.object_id
|
795 |
WHERE tr.term_taxonomy_id = %d
|
796 |
AND tt.taxonomy = %s",
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
|
|
|
|
|
|
|
|
801 |
SELECT object_id FROM $wpdb->term_relationships AS tr
|
802 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = tr.object_id
|
803 |
WHERE tr.term_taxonomy_id = %d
|
804 |
AND tt.taxonomy = %s",
|
805 |
-
|
806 |
-
|
|
|
|
|
807 |
|
808 |
$count = 0;
|
809 |
-
foreach ($groups as $group) {
|
810 |
-
$group = unserialize($group);
|
811 |
-
if (array_key_exists($language->slug, $group)) {
|
812 |
-
$group_ids[] = $group[$language->slug];
|
813 |
-
$profile
|
814 |
-
if ($profile['profile']
|
815 |
-
|
816 |
}
|
817 |
}
|
818 |
}
|
819 |
|
820 |
-
|
821 |
-
$disabled[$language->slug] = $count;
|
822 |
|
823 |
// if a term is not a target, then it is a source
|
824 |
-
$sources[$language->slug] = $n - $targets[$language->slug];
|
825 |
// $sources[$language->slug] -= $disabled[$language->slug];
|
826 |
-
}
|
827 |
|
828 |
-
$total = count($groups);
|
829 |
|
830 |
// default categories are created by Polylang in all languages
|
831 |
// don't count them as sources if they are not associated to the TMS
|
832 |
-
if ('category' === $taxonomy) {
|
833 |
-
$term_id = get_option('default_category');
|
834 |
-
$group
|
835 |
-
foreach($this->pllm->get_languages_list() as $language) {
|
836 |
-
if (empty($group->source) || ($group->get_source_language()->slug
|
837 |
-
if ($language->slug
|
838 |
-
$sources[$language->slug]--;
|
839 |
}
|
840 |
}
|
841 |
}
|
842 |
// Remove category targets from being counted until they are downloaded. Fixed target categories being counted as source languages.
|
843 |
-
foreach ($groups as $group) {
|
844 |
-
$group = unserialize($group);
|
845 |
-
if (isset($group['lingotek']['translations'])) {
|
846 |
-
foreach ($group['lingotek']['translations'] as $locale => $status) {
|
847 |
-
|
848 |
-
|
849 |
-
|
|
|
850 |
}
|
851 |
}
|
852 |
}
|
853 |
}
|
854 |
}
|
855 |
-
if (count($sources)
|
856 |
-
$total = $sources[$this->pllm->options['default_lang']];
|
857 |
}
|
858 |
-
}
|
859 |
-
|
|
|
860 |
}
|
861 |
|
862 |
-
private function build_params($external_url, $title, $type, $content, $language, $profile, $wp_id, &$wp_target_locales = array()) {
|
863 |
-
|
864 |
-
|
865 |
-
if ($translation_workflow_id === 'project-default' || $translation_workflow_id === false) {
|
866 |
$translation_workflow_id = null;
|
867 |
}
|
868 |
|
869 |
$params = array(
|
870 |
-
'title'
|
871 |
-
'content'
|
872 |
-
'locale_code'
|
873 |
-
'project_id'
|
874 |
-
'external_url' => $external_url
|
875 |
);
|
876 |
|
877 |
-
$lingotek_metadata_keys = array(
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
|
|
|
|
900 |
$params['translation_workflow_id'] = $translation_workflow_id;
|
901 |
}
|
902 |
|
903 |
// Get target locales to send up from profile
|
904 |
$target_locales = array();
|
905 |
-
if (!empty($profile['target_locales'])) {
|
906 |
-
if (isset($profile['target_locales'][$language->slug])) {
|
907 |
-
unset($profile['target_locales'][$language->slug]);
|
908 |
}
|
909 |
-
if (isset($profile['custom']['workflow_id'][$language->slug])) {
|
910 |
-
unset($profile['custom']['workflow_id'][$language->slug]);
|
911 |
}
|
912 |
-
$target_locales['translation_locale_code'] = array_values($profile['target_locales']);
|
913 |
-
$wp_target_locales
|
914 |
|
915 |
// Add workflows
|
916 |
-
if (!empty($profile['custom']['workflow_id'])) {
|
917 |
-
$temp_workflow_ids =
|
918 |
-
$workflow_id
|
919 |
-
foreach ($wp_target_locales as $language_slug) {
|
920 |
-
if (isset($profile['custom']['workflow_id'][$language_slug])) {
|
921 |
-
$profile_override = $profile['custom']['workflow_id'][$language_slug];
|
922 |
-
$workflow_id
|
923 |
-
}
|
924 |
-
else {
|
925 |
$workflow_id = $translation_workflow_id;
|
926 |
}
|
927 |
-
if ($workflow_id) {
|
928 |
$temp_workflow_ids[] = $workflow_id;
|
929 |
}
|
930 |
}
|
931 |
$params['translation_workflow_id'] = $temp_workflow_ids;
|
932 |
}
|
933 |
-
}
|
934 |
-
else {
|
935 |
// No targets being sent up to TMS, unset the workflow
|
936 |
-
unset($params['translation_workflow_id']);
|
937 |
-
}
|
938 |
|
939 |
-
$params = array_merge($params, $target_locales);
|
940 |
|
941 |
return $params;
|
942 |
}
|
943 |
|
944 |
-
private function get_filter_ids($type, $language, $wp_id) {
|
945 |
$filter_ids = array();
|
946 |
-
if (self::get_profile_option('primary_filter_id', $type, $language, false, $wp_id)) {
|
947 |
-
$filter_ids['fprm_id'] = self::get_profile_option('primary_filter_id'
|
948 |
}
|
949 |
-
if (self::get_profile_option('secondary_filter_id', $type, $language, false, $wp_id)) {
|
950 |
-
$filter_ids['fprm_subfilter_id'] = self::get_profile_option('secondary_filter_id'
|
951 |
}
|
952 |
return $filter_ids;
|
953 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Manages interactions with database
|
5 |
* Factory for Lingotek_Group objects
|
6 |
*
|
7 |
* @since 0.1
|
8 |
*/
|
9 |
class Lingotek_Model {
|
|
|
|
|
|
|
10 |
|
11 |
+
/**
|
12 |
+
* Polylang model.
|
13 |
+
*
|
14 |
+
* @var obj
|
15 |
+
*/
|
16 |
+
public $pllm;
|
17 |
+
|
18 |
+
public static $copying_post;
|
19 |
+
public static $copying_term;
|
20 |
+
|
21 |
+
/**
|
22 |
* constructor
|
23 |
*
|
24 |
* @since 0.1
|
26 |
public function __construct() {
|
27 |
$this->pllm = $GLOBALS['polylang']->model;
|
28 |
|
29 |
+
register_taxonomy(
|
30 |
+
'lingotek_profile',
|
31 |
+
null,
|
32 |
+
array(
|
33 |
+
'label' => false,
|
34 |
+
'public' => false,
|
35 |
+
'query_var' => false,
|
36 |
+
'rewrite' => false,
|
37 |
+
)
|
38 |
+
);
|
39 |
+
register_taxonomy(
|
40 |
+
'lingotek_hash',
|
41 |
+
null,
|
42 |
+
array(
|
43 |
+
'label' => false,
|
44 |
+
'public' => false,
|
45 |
+
'query_var' => false,
|
46 |
+
'rewrite' => false,
|
47 |
+
)
|
48 |
+
);
|
49 |
}
|
50 |
|
51 |
+
/**
|
52 |
* get the strings groups as well as their count
|
53 |
*
|
54 |
* @since 0.2
|
57 |
*/
|
58 |
public static function get_strings() {
|
59 |
static $strings = array();
|
60 |
+
if ( empty( $strings ) ) {
|
61 |
+
// Enables sanitization filter.
|
62 |
+
PLL_Admin_Strings::init();
|
63 |
|
64 |
+
foreach ( PLL_Admin_Strings::get_strings() as $string ) {
|
65 |
+
$strings[ $string['context'] ]['context'] = $string['context'];
|
66 |
+
$strings[ $string['context'] ]['count'] = empty( $strings[ $string['context'] ]['count'] ) ? 1 : $strings[ $string['context'] ]['count'] + 1;
|
67 |
}
|
68 |
+
$strings = array_values( $strings );
|
69 |
}
|
70 |
return $strings;
|
71 |
}
|
72 |
|
73 |
+
/**
|
74 |
* create a translation group object from a translation term
|
75 |
*
|
76 |
* @since 0.2
|
78 |
* @param object $term
|
79 |
* @return object
|
80 |
*/
|
81 |
+
protected function convert_term( $term ) {
|
82 |
+
switch ( $term->taxonomy ) {
|
83 |
case 'term_translations':
|
84 |
+
return new Lingotek_Group_Term( $term, $this->pllm );
|
85 |
|
86 |
case 'post_translations':
|
87 |
+
$class = $term->name === $term->slug ? 'Lingotek_Group_Post' : 'Lingotek_Group_String';
|
88 |
+
return new $class( $term, $this->pllm );
|
89 |
}
|
90 |
}
|
91 |
|
92 |
+
/**
|
93 |
* get the translation term of an object
|
94 |
*
|
95 |
* @since 0.2
|
96 |
*
|
97 |
+
* @param string $type Either 'post' or 'term' or 'string'.
|
98 |
+
* @param int|string $id Post id or term id or strings translations group name.
|
99 |
+
* @return object Translation term.
|
100 |
*/
|
101 |
+
public function get_group( $type, $id ) {
|
102 |
+
switch ( $type ) {
|
103 |
case 'post':
|
104 |
+
return ( $post = PLL()->model->post->get_object_term( (int) $id, $type . '_translations' ) ) && ! empty( $post ) ? $this->convert_term( $post ) : false;
|
105 |
case 'term':
|
106 |
+
return ( $term = PLL()->model->term->get_object_term( (int) $id, $type . '_translations' ) ) && ! empty( $term ) ? $this->convert_term( $term ) : false;
|
107 |
case 'string':
|
108 |
+
if ( is_numeric( $id ) ) {
|
109 |
$strings = self::get_strings();
|
110 |
+
$id = $strings[ $id ]['context'];
|
111 |
}
|
112 |
+
return ( $term = get_term_by( 'name', $id, 'post_translations' ) ) && ! empty( $term ) ? $this->convert_term( $term ) : false;
|
113 |
default:
|
114 |
return false;
|
115 |
}
|
116 |
}
|
117 |
|
118 |
+
/**
|
119 |
+
* get document id of an object, false if it wasn't uploaded yet.
|
120 |
+
*
|
121 |
+
* @since 1.4.11
|
122 |
+
*
|
123 |
+
* @param string $type either 'post' or 'term' or 'string'
|
124 |
+
* @param int|string $id post id or term id or strings translations group name
|
125 |
+
* @return string|bool document id or false
|
126 |
+
*/
|
127 |
+
public function get_document_id( $type, $id ) {
|
128 |
+
$document_term = $this->get_group( $type, $id );
|
129 |
+
$document_id = $document_term != false ? $document_term->document_id : false;
|
130 |
+
return $document_id;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
* get the translation term of an object by its Lingotek document id
|
135 |
*
|
136 |
* @since 0.2
|
138 |
* @param string|object $document_id
|
139 |
* @return object translation term
|
140 |
*/
|
141 |
+
public function get_group_by_id( $document_id ) {
|
142 |
// we already passed a translation group object
|
143 |
+
if ( is_object( $document_id ) ) {
|
144 |
return $document_id;
|
145 |
+
}
|
146 |
|
147 |
+
$terms = get_terms( array( 'post_translations', 'term_translations' ), array( 'slug' => $document_id ) );
|
148 |
+
return is_wp_error( $terms ) || empty( $terms ) ? false : $this->convert_term( reset( $terms ) );
|
149 |
}
|
150 |
|
151 |
+
/**
|
152 |
* get a translation profile
|
153 |
*
|
154 |
* @since 0.2
|
157 |
* @param object $language
|
158 |
* @return array
|
159 |
*/
|
160 |
+
public static function get_profile( $type, $language, $post_id = null ) {
|
161 |
global $profileInformation, $ltk_profiles, $ltk_contentTypes;
|
162 |
|
163 |
+
if ( is_null( $ltk_profiles ) ) {
|
164 |
+
$ltk_profiles = get_option( 'lingotek_profiles' );
|
165 |
}
|
166 |
+
if ( $post_id && $profileInformation && isset( $profileInformation[ $type ] ) && isset( $profileInformation[ $type ][ $language->locale ] ) && isset( $profileInformation[ $type ][ $language->locale ][ $post_id ] ) ) {
|
167 |
+
return $ltk_profiles[ $profileInformation[ $type ][ $language->locale ][ $post_id ] ];
|
168 |
}
|
169 |
|
170 |
+
if ( is_null( $ltk_contentTypes ) ) {
|
171 |
+
$ltk_contentTypes = get_option( 'lingotek_content_type' );
|
172 |
}
|
173 |
|
174 |
// If a profile is set for a specific post/page get that first
|
175 |
+
if ( $post_id ) {
|
176 |
+
$profile_override = get_term_by( 'name', 'lingotek_profile_' . $post_id, 'lingotek_profile' );
|
177 |
+
if ( $profile_override ) {
|
178 |
+
if ( ! isset( $profileInformation ) ) {
|
179 |
+
$profileInformation = array(); }
|
180 |
+
if ( ! isset( $profileInformation[ $type ] ) ) {
|
181 |
+
$profileInformation[ $type ] = array(); }
|
182 |
+
if ( ! isset( $profileInformation[ $type ][ $language->locale ] ) ) {
|
183 |
+
$profileInformation[ $type ][ $language->locale ] = array(); }
|
184 |
+
$profileInformation[ $type ][ $language->locale ][ $post_id ] = $profile_override->description;
|
185 |
+
return $ltk_profiles[ $profile_override->description ];
|
186 |
}
|
187 |
}
|
188 |
|
189 |
+
// Default profile is manual for posts and pages, custom types are set to disabled by default.
|
190 |
$default = 'post' === $type || 'page' === $type ? 'manual' : 'disabled';
|
191 |
|
192 |
+
$profile = is_object( $language ) && isset( $content_types[ $type ]['sources'][ $language->slug ] ) ?
|
193 |
+
$ltk_contentTypes[ $type ]['sources'][ $language->slug ] :
|
194 |
+
( isset( $ltk_contentTypes[ $type ]['profile'] ) ? $ltk_contentTypes[ $type ]['profile'] : $default );
|
195 |
+
|
196 |
+
if ( $post_id ) {
|
197 |
+
if ( ! isset( $profileInformation ) ) {
|
198 |
+
$profileInformation = array(); }
|
199 |
+
if ( ! isset( $profileInformation[ $type ] ) ) {
|
200 |
+
$profileInformation[ $type ] = array(); }
|
201 |
+
if ( ! isset( $profileInformation[ $type ][ $language->locale ] ) ) {
|
202 |
+
$profileInformation[ $type ][ $language->locale ] = array(); }
|
203 |
+
$profileInformation[ $type ][ $language->locale ][ $post_id ] = $profile;
|
204 |
}
|
205 |
|
206 |
+
return $ltk_profiles[ $profile ];
|
207 |
}
|
208 |
|
209 |
+
public static function get_prefs() {
|
210 |
$default = array(
|
211 |
+
'download_post_status' => Lingotek_Group_Post::SAME_AS_SOURCE,
|
212 |
'auto_upload_post_statuses' => array(
|
213 |
+
// ignore auto-upload
|
214 |
+
'draft' => 0,
|
215 |
+
// auto-upload
|
216 |
+
'pending' => 1,
|
217 |
'publish' => 1,
|
218 |
+
'future' => 1,
|
219 |
'private' => 0,
|
220 |
),
|
221 |
+
'trash_linked_content' => array(),
|
222 |
+
'auto_update_status' => '10',
|
223 |
+
'enable_lingotek_logs' => 0,
|
|
|
|
|
224 |
);
|
225 |
+
// Ensure defaults are set for missing keys.
|
226 |
+
$prefs = array_merge( $default, get_option( 'lingotek_prefs', $default ) );
|
227 |
return $prefs;
|
228 |
}
|
229 |
|
230 |
+
/**
|
231 |
* get a profile option
|
232 |
*
|
233 |
* @since 0.2
|
234 |
*
|
235 |
+
* @param string $item 'project_id' | 'workflow_id' | 'upload' | 'download'.
|
236 |
+
* @param string $type Post type or taxonomy.
|
237 |
* @param object $source_language
|
238 |
+
* @param object $target_language Optional, needed to get custom target informations 'workflow_id' | 'download'.
|
239 |
+
* @return string | bool either the option or false if the translation is disabled.
|
240 |
*/
|
241 |
+
public static function get_profile_option( $item, $type, $source_language, $target_language = false, $post_id = null ) {
|
242 |
+
$profile = self::get_profile( $type, $source_language, $post_id );
|
243 |
+
if ( 'disabled' === $profile['profile'] || is_object( $target_language ) && isset( $profile['targets'][ $target_language->slug ] ) && 'disabled' === $profile['targets'][ $target_language->slug ] ) {
|
244 |
return false;
|
245 |
+
}
|
246 |
+
|
247 |
+
if ( ! empty( $target_language ) && isset( $profile['targets'][ $target_language->slug ] ) && ! empty( $profile['custom'][ $item ][ $target_language->slug ] ) ) {
|
248 |
+
return $profile['custom'][ $item ][ $target_language->slug ];
|
249 |
+
}
|
250 |
|
251 |
+
if ( ! empty( $profile[ $item ] ) ) {
|
252 |
+
return $profile[ $item ];
|
253 |
+
}
|
254 |
|
255 |
+
$defaults = get_option( 'lingotek_defaults', array() );
|
256 |
+
return isset( $defaults[ $item ] ) ? $defaults[ $item ] : null;
|
|
|
|
|
|
|
257 |
}
|
258 |
|
259 |
+
/**
|
260 |
* find targets that are set to copy in a profile
|
261 |
*
|
262 |
* @since 1.1.1
|
264 |
* @param array $profile (use get_profile to retrieve)
|
265 |
* @return array of targets that should be copied. if none exist returns empty array
|
266 |
*/
|
267 |
+
public function targets_to_be_copied( $profile ) {
|
268 |
+
if ( isset( $profile['targets'] ) && in_array( 'copy', $profile['targets'] ) ) {
|
269 |
+
$targets_to_copy = array_keys( $profile['targets'], 'copy' );
|
270 |
return $targets_to_copy;
|
271 |
+
} else {
|
|
|
272 |
return array();
|
273 |
}
|
274 |
}
|
275 |
|
276 |
+
/**
|
277 |
* copy a post from the source language to a target language
|
278 |
*
|
279 |
* @since 1.1.1
|
282 |
* @param string $target polylang language slug (ex: en, de, fr, etc)
|
283 |
* @return $new_post_id if copy of post is successful, false otherwise
|
284 |
*/
|
285 |
+
public function copy_post( $post, $target ) {
|
286 |
+
self::$copying_post = true;
|
287 |
+
$document = $this->get_group( 'post', $post->ID );
|
288 |
+
$prefs = self::get_prefs();
|
289 |
+
$cp_lang = $this->pllm->get_language( $target );
|
290 |
+
$cp_post = (array) $post;
|
291 |
+
$cp_post['post_status'] = ( $prefs['download_post_status'] === 'SAME_AS_SOURCE' ) ? $post->post_status : $prefs['download_post_status'];
|
292 |
+
$slug = $cp_post['post_name'];
|
293 |
+
unset( $cp_post['ID'] );
|
294 |
+
unset( $cp_post['post_name'] );
|
295 |
+
if ( ! isset( $document->desc_array[ $target ] ) ) {
|
296 |
+
$new_post_id = wp_insert_post( $cp_post, true );
|
297 |
+
if ( ! is_wp_error( $new_post_id ) ) {
|
298 |
+
PLL()->model->post->set_language( $new_post_id, $cp_lang );
|
299 |
+
wp_set_object_terms( $new_post_id, $document->term_id, 'post_translations' );
|
300 |
+
$GLOBALS['polylang']->sync->taxonomies->copy( $document->source, $new_post_id, $cp_lang->slug );
|
301 |
+
$GLOBALS['polylang']->sync->post_metas->copy( $document->source, $new_post_id, $cp_lang->slug );
|
302 |
+
Lingotek_Group_Post::copy_or_ignore_metas( $post->ID, $new_post_id );
|
303 |
+
$document->desc_array[ $target ] = $new_post_id;
|
304 |
$document->save();
|
305 |
+
if ( class_exists( 'PLL_Share_Post_Slug', true ) ) {
|
306 |
+
wp_update_post(
|
307 |
+
array(
|
308 |
+
'ID' => $new_post_id,
|
309 |
+
'post_name' => $slug,
|
310 |
+
)
|
311 |
+
);
|
312 |
}
|
313 |
}
|
314 |
}
|
315 |
self::$copying_post = false;
|
316 |
}
|
317 |
|
318 |
+
public function copy_term( $term, $target, $taxonomy ) {
|
319 |
self::$copying_term = true;
|
320 |
+
$document = $this->get_group( 'term', $term->term_id );
|
321 |
+
$cp_lang = $this->pllm->get_language( $target );
|
322 |
+
$cp_term = (array) $term;
|
|
|
323 |
|
324 |
+
if ( class_exists( 'PLL_Share_Term_Slug', true ) ) {
|
325 |
remove_action( 'create_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
326 |
remove_action( 'edit_term', array( PLL()->filters_term, 'save_term' ), 999, 3 );
|
327 |
+
remove_action( 'pre_post_update', array( PLL()->filters_term, 'pre_post_update' ) );
|
328 |
+
remove_filter( 'pre_term_name', array( PLL()->filters_term, 'pre_term_name' ) );
|
329 |
+
remove_filter( 'pre_term_slug', array( PLL()->filters_term, 'pre_term_slug' ), 10, 2 );
|
330 |
add_action( 'pre_post_update', array( PLL()->share_term_slug, 'pre_post_update' ) );
|
331 |
add_filter( 'pre_term_name', array( PLL()->share_term_slug, 'pre_term_name' ) );
|
332 |
add_filter( 'pre_term_slug', array( PLL()->share_term_slug, 'pre_term_slug' ), 10, 2 );
|
333 |
add_action( 'create_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
334 |
add_action( 'edit_term', array( PLL()->share_term_slug, 'save_term' ), 1, 3 );
|
335 |
$_POST['term_lang_choice'] = $cp_lang->slug;
|
336 |
+
} else {
|
337 |
+
if ( isset( $cp_term['slug'] ) && term_exists( $cp_term['slug'] ) ) {
|
|
|
338 |
$cp_term['slug'] .= '-' . $cp_lang->slug;
|
339 |
}
|
340 |
}
|
341 |
|
342 |
+
$new_term = wp_insert_term( $cp_term['name'], $taxonomy, $cp_term );
|
343 |
|
344 |
+
if ( ! is_wp_error( $new_term ) ) {
|
345 |
+
PLL()->model->term->set_language( $new_term['term_id'], $cp_lang );
|
346 |
+
wp_set_object_terms( $new_term['term_id'], $document->term_id, 'term_translations' );
|
347 |
+
$document->desc_array[ $target ] = $new_term['term_id'];
|
348 |
$document->save();
|
349 |
}
|
350 |
self::$copying_term = false;
|
351 |
}
|
352 |
|
353 |
+
private function format_patch_params( $params, $profile, $source_lang ) {
|
354 |
+
$params['translation_locale_code'] = array();
|
355 |
+
$params['translation_workflow_id'] = array();
|
356 |
|
357 |
+
foreach ( $this->pllm->get_languages_list() as $lang ) {
|
358 |
+
if ( $lang->lingotek_locale == $source_lang->lingotek_locale
|
359 |
+
|| ( isset( $profile['targets'][ $lang->slug ] ) && 'disabled' === $profile['targets'][ $lang->slug ] ) ) {
|
360 |
continue;
|
361 |
}
|
362 |
$params['translation_locale_code'][] = $lang->lingotek_locale;
|
363 |
+
if ( isset( $profile['custom']['workflow_id'][ $lang->slug ], $profile['targets'][ $lang->lingotek_locale ] ) ) {
|
364 |
+
$params['translation_workflow_id'][] = $profile['custom']['workflow_id'][ $lang->slug ];
|
365 |
+
} elseif ( ! isset( $profile['targets'][ $lang->lingotek_locale ] ) && isset( $profile['workflow_id'] ) && $profile['workflow_id'] !== 'project-default' ) {
|
366 |
+
// Target is not using a custom workflow so we use the default workflow.
|
367 |
+
$params['translation_workflow_id'][] = $profile['workflow_id'];
|
368 |
}
|
369 |
}
|
370 |
+
if ( empty( $params['translation_workflow_id'] ) ) {
|
371 |
+
unset( $params['translation_workflow_id'] );
|
372 |
}
|
373 |
return $params;
|
374 |
}
|
379 |
* @since 0.1
|
380 |
*
|
381 |
* @param int $post_id
|
382 |
+
* @return boolean|string false if post failed to upload
|
383 |
*/
|
384 |
+
public function upload_post( $post_id ) {
|
385 |
+
$post = get_post( $post_id );
|
386 |
+
$language = PLL()->model->post->get_language( $post_id );
|
387 |
+
$profile = self::get_profile( $post->post_type, $language, $post_id );
|
388 |
+
if ( 'disabled' === $profile['profile'] || empty( $post ) || empty( $language ) ) {
|
389 |
return;
|
390 |
}
|
391 |
+
// Returns type string or boolean
|
392 |
+
$document_id = self::get_document_id( 'post', $post_id );
|
393 |
+
// Slug can't be empty or duplicated, so we prefix `disassociated` to show the document id is no longer associated with this post
|
394 |
+
if ( is_string( $document_id ) && strpos( $document_id, 'disassociated_' ) === 0 ) {
|
395 |
+
$document_id = false;
|
396 |
+
}
|
397 |
$content = null;
|
398 |
// If we already uploaded this doc, check if it changed and prevent the upload if it didn't.
|
399 |
+
if ( $document_id ) {
|
400 |
+
$content = Lingotek_Group_Post::get_content( $post );
|
401 |
+
$hash_terms = wp_get_object_terms( $post->ID, 'lingotek_hash' );
|
402 |
+
$hash_term = array_pop( $hash_terms );
|
403 |
+
$new_hash = md5( $content );
|
404 |
+
if ( ! empty( $hash_term ) ) {
|
405 |
if ( $hash_term->description == $new_hash ) {
|
406 |
return;
|
407 |
}
|
408 |
}
|
409 |
}
|
410 |
+
$document = $this->get_group( 'post', $post_id );
|
411 |
// Customized workflows have the option to do any sort of pre-processing before a document
|
412 |
// is uploaded to lingotek.
|
413 |
+
if ( $document ) {
|
414 |
+
$document->pre_upload_to_lingotek( $post_id, $post->post_type, $language, 'post' );
|
415 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
+
$client = new Lingotek_API();
|
418 |
+
$external_url = get_page_link( $post_id );
|
419 |
+
if ( ! $content ) {
|
420 |
+
$content = Lingotek_Group_Post::get_content( $post );
|
421 |
+
}
|
422 |
+
$params = $this->build_params( $external_url, $post->post_title, $post->post_type, $content, $language, $profile, $post_id, $wp_target_locales );
|
423 |
+
$filter_ids = $this->get_filter_ids( $post->post_type, $language, $post_id );
|
424 |
+
$params = array_merge( $params, $filter_ids );
|
425 |
+
if ( $document && in_array( $document->status, array( 'edited', 'importing', 'current' ) ) && $document_id ) {
|
426 |
+
$response = $document->patch( $this->format_patch_params( $params, $profile, $language ) );
|
427 |
+
if ( $response ) {
|
428 |
+
// Only save the hash if the patch function is successful
|
429 |
+
// Re-establish hash relation if needed
|
430 |
+
if ( ! isset( $hash_term->term_id ) ) {
|
431 |
+
$hash_terms = wp_set_post_terms( $post->ID, 'lingotek_hash_' . $post->ID, 'lingotek_hash' );
|
432 |
+
$hash_term_id = array_pop( $hash_terms );
|
433 |
+
} else {
|
434 |
+
$hash_term_id = $hash_term->id;
|
435 |
+
}
|
436 |
+
wp_update_term( $hash_term_id, 'lingotek_hash', array( 'description' => $new_hash ) );
|
437 |
+
}
|
438 |
+
return $response;
|
439 |
+
} elseif ( ! Lingotek_Group::$creating_translation && ! self::$copying_post && ( ! $document || $document->status === 'cancelled' ) ) {
|
440 |
+
$document_id = $client->upload_document( $params, $post->ID );
|
441 |
+
if ( $document_id ) {
|
442 |
+
Lingotek_Group_Post::create( $post->ID, $language, $document_id );
|
443 |
$document = $this->get_group_by_id( $document_id );
|
444 |
+
if ( isset( $wp_target_locales ) ) {
|
445 |
+
foreach ( $wp_target_locales as $locale ) {
|
446 |
+
$document->translations[ $locale ] = 'pending';
|
447 |
}
|
448 |
}
|
449 |
$document->save();
|
450 |
// If a translation profile has targets set to copy then copy them
|
451 |
+
$targets_to_copy = $this->targets_to_be_copied( $profile );
|
452 |
+
$upload = self::get_profile_option( 'upload', $post->post_type, $language, false, $post_id );
|
453 |
+
if ( ! empty( $targets_to_copy ) && $upload === 'automatic' ) {
|
454 |
+
foreach ( $targets_to_copy as $target ) {
|
455 |
+
$this->copy_post( $post, $target );
|
456 |
}
|
457 |
}
|
458 |
+
return $document_id;
|
459 |
}
|
460 |
+
return false;
|
461 |
+
}//end if
|
462 |
}
|
463 |
|
464 |
/**
|
466 |
*
|
467 |
* @since 0.2
|
468 |
*
|
469 |
+
* @param int $term_id
|
470 |
* @param string $taxonomy
|
471 |
*/
|
472 |
+
public function upload_term( $term_id, $taxonomy ) {
|
473 |
+
$term = get_term( $term_id, $taxonomy );
|
474 |
+
$language = PLL()->model->term->get_language( $term_id );
|
475 |
+
if ( empty( $term ) || empty( $language ) ) {
|
476 |
return;
|
477 |
+
}
|
478 |
|
479 |
+
$profile = self::get_profile( $taxonomy, $language );
|
480 |
+
if ( 'disabled' === $profile['profile'] ) {
|
481 |
return;
|
482 |
+
}
|
483 |
|
484 |
/**
|
485 |
* Customized workflows have the option to do any sort of pre-processing before a document is uploaded to lingotek.
|
486 |
*/
|
487 |
+
$document = $this->get_group( 'term', $term_id );
|
488 |
+
if ( $document ) {
|
489 |
+
$document->pre_upload_to_lingotek( $term_id, $taxonomy, $language, 'term' );
|
490 |
}
|
491 |
|
492 |
+
$client = new Lingotek_API();
|
493 |
+
$content = Lingotek_Group_Term::get_content( $term );
|
494 |
+
$params = $this->build_params( get_term_link( $term_id, $taxonomy ), $term->name, $taxonomy, $content, $language, $profile, $term_id, $wp_target_locales );
|
495 |
+
$filter_ids = $this->get_filter_ids( $taxonomy, $language, $term_id );
|
496 |
+
$params = array_merge( $params, $filter_ids );
|
|
|
|
|
|
|
|
|
497 |
|
498 |
+
if ( ( $document = $this->get_group( 'term', $term_id ) ) && 'edited' === $document->status ) {
|
499 |
+
$document->patch( $this->format_patch_params( $params, $profile, $language ), $term->name, $term );
|
500 |
+
} elseif ( ! Lingotek_Group::$creating_translation && ! self::$copying_term ) {
|
501 |
+
$document_id = $client->upload_document( $params, $term_id );
|
502 |
|
503 |
+
if ( $document_id ) {
|
504 |
+
Lingotek_Group_Term::create( $term_id, $taxonomy, $language, $document_id );
|
505 |
$document = $this->get_group_by_id( $document_id );
|
506 |
+
foreach ( $wp_target_locales as $locale ) {
|
507 |
+
$document->translations[ $locale ] = 'pending';
|
508 |
}
|
509 |
$document->save();
|
510 |
+
|
511 |
// If a translation profile has targets set to copy then copy them
|
512 |
+
$targets_to_copy = $this->targets_to_be_copied( $profile );
|
513 |
+
if ( ! empty( $targets_to_copy ) && 'automatic' === $profile['upload'] ) {
|
514 |
+
foreach ( $targets_to_copy as $target ) {
|
515 |
+
$this->copy_term( $term, $target, $taxonomy );
|
516 |
}
|
517 |
}
|
518 |
}
|
519 |
+
}//end if
|
520 |
}
|
521 |
|
522 |
+
/**
|
523 |
* uploads a strings group to Lingotek TMS
|
524 |
*
|
525 |
* @since 0.2
|
526 |
*
|
527 |
* @param string $group
|
528 |
*/
|
529 |
+
public function upload_strings( $group ) {
|
530 |
+
$type = 'string';
|
531 |
+
$language = $this->pllm->get_language( $this->pllm->options['default_lang'] );
|
532 |
+
$profile = self::get_profile( $type, $language );
|
533 |
|
534 |
+
if ( 'disabled' === $profile['profile'] ) {
|
535 |
return;
|
536 |
+
}
|
537 |
|
538 |
+
if ( is_numeric( $group ) ) {
|
539 |
$strings = self::get_strings();
|
540 |
+
$group = $strings[ $group ]['context'];
|
541 |
}
|
542 |
|
543 |
// check that we have a valid string group
|
544 |
+
if ( ! in_array( $group, wp_list_pluck( self::get_strings(), 'context' ) ) ) {
|
545 |
return;
|
546 |
+
}
|
547 |
|
548 |
+
$client = new Lingotek_API();
|
549 |
+
$content = Lingotek_Group_String::get_content( $group );
|
550 |
+
$params = $this->build_params( '', $group, $type, $content, $language, $profile, null );
|
551 |
+
$filter_ids = $this->get_filter_ids( $type, $language, null );
|
552 |
+
$params = array_merge( $params, $filter_ids );
|
553 |
|
554 |
+
if ( ( $document = $this->get_group( $type, $group ) ) && 'edited' === $document->status ) {
|
555 |
+
$document->patch( $this->format_patch_params( $params, $profile, $language ) );
|
556 |
+
} else {
|
557 |
+
$document_id = $client->upload_document( $params, $group );
|
|
|
558 |
|
559 |
+
if ( $document_id ) {
|
560 |
+
Lingotek_Group_String::create( $group, $language, $document_id );
|
561 |
}
|
562 |
}
|
563 |
}
|
564 |
|
565 |
+
/**
|
566 |
* checks if the document can be upload to Lingotek
|
567 |
*
|
568 |
* @since 0.1
|
569 |
*
|
570 |
* @param string $type either 'post' or 'term'
|
571 |
+
* @param int $object_id post id or term id
|
572 |
* @return bool
|
573 |
*/
|
574 |
+
public function can_upload( $type, $object_id ) {
|
575 |
+
// FIXME should I check for disabled profile here?
|
576 |
+
$document = $this->get_group( $type, $object_id );
|
577 |
+
if ( $document && 'failed' === $document->status ) {
|
578 |
return false;
|
579 |
}
|
580 |
+
switch ( $type ) {
|
581 |
case 'string':
|
582 |
+
if ( empty( $document ) ) {
|
583 |
return true;
|
584 |
+
}
|
585 |
+
// Check if source strings have not been modified.
|
586 |
+
elseif ( $document->md5 !== md5( Lingotek_Group_String::get_content( $object_id ) ) ) {
|
587 |
$document->source_edited();
|
588 |
return true;
|
589 |
}
|
591 |
return false;
|
592 |
|
593 |
case 'post':
|
594 |
+
$language = PLL()->model->post->get_language( $object_id );
|
595 |
+
$allow_status = $document && 'edited' === $document->status ? true : ( $document && 'cancelled' === $document->status ? true : false );
|
596 |
+
return ! empty( $language ) && ( empty( $document ) ||
|
597 |
+
( isset( $document ) && $allow_status && $document->source == $object_id ) );
|
598 |
case 'term':
|
599 |
// first check that a language is associated to the object
|
600 |
+
$language = PLL()->model->term->get_language( $object_id );
|
601 |
|
602 |
// FIXME how to get profile to check if disabled?
|
603 |
|
604 |
+
return ! empty( $language ) && ( empty( $document ) ||
|
605 |
+
// Specific for terms as document is never empty.
|
606 |
+
( empty( $document->translations ) && empty( $document->source ) ) ||
|
607 |
+
( isset( $document ) && 'edited' == $document->status && $document->source == $object_id ) );
|
608 |
+
}//end switch
|
609 |
}
|
610 |
|
611 |
+
/**
|
612 |
* deletes a post
|
613 |
*
|
614 |
* @since 0.1
|
615 |
*
|
616 |
* @param int $object_id post id
|
617 |
*/
|
618 |
+
public function delete_post( $object_id ) {
|
619 |
+
if ( $document = $this->get_group( 'post', $object_id ) ) {
|
620 |
$client = new Lingotek_API();
|
621 |
|
622 |
+
if ( $document->source == $object_id ) {
|
623 |
+
$client->cancel_document( $document->document_id, $object_id );
|
624 |
+
} else {
|
625 |
+
PLL()->model->post->delete_translation( $object_id );
|
626 |
+
$lang = PLL()->model->post->get_language( $object_id );
|
627 |
+
$client->cancel_translation( $document->document_id, $lang->lingotek_locale, $object_id );
|
|
|
628 |
}
|
629 |
}
|
630 |
}
|
631 |
|
632 |
+
public function cancel_post( $object_id ) {
|
633 |
+
if ( $document = $this->get_group( 'post', $object_id ) ) {
|
634 |
$client = new Lingotek_API();
|
635 |
|
636 |
+
if ( $document->source == $object_id ) {
|
637 |
+
$client->cancel_document( $document->document_id, $object_id );
|
638 |
+
} else {
|
639 |
+
$lang = PLL()->model->post->get_language( $object_id );
|
|
|
640 |
$locale = $lang->locale;
|
641 |
+
if ( isset( $document->desc_array['lingotek']['translations'][ $locale ] ) ) {
|
642 |
+
$document->desc_array['lingotek']['translations'][ $locale ] = 'cancelled';
|
643 |
}
|
644 |
$document->save();
|
645 |
+
$client->cancel_translation( $document->document_id, $lang->lingotek_locale, $object_id );
|
646 |
}
|
647 |
}
|
648 |
}
|
649 |
|
650 |
+
/**
|
651 |
* deletes a term
|
652 |
*
|
653 |
* @since 0.2
|
654 |
*
|
655 |
* @param int $object_id term id
|
656 |
*/
|
657 |
+
public function delete_term( $object_id ) {
|
658 |
+
if ( $document = $this->get_group( 'term', $object_id ) ) {
|
659 |
$client = new Lingotek_API();
|
660 |
+
if ( $document->source == $object_id ) {
|
661 |
+
$client->cancel_document( $document->document_id, $object_id );
|
662 |
+
} else {
|
663 |
+
$lang = PLL()->model->term->get_language( $object_id );
|
664 |
+
PLL()->model->term->delete_language( $object_id );
|
665 |
+
PLL()->model->term->delete_translation( $object_id );
|
666 |
+
$client->cancel_translation( $document->document_id, $lang->lingotek_locale, $object_id );
|
|
|
667 |
}
|
668 |
}
|
669 |
}
|
670 |
|
671 |
+
public function cancel_term( $object_id ) {
|
672 |
+
if ( $document = $this->get_group( 'term', $object_id ) ) {
|
673 |
$client = new Lingotek_API();
|
674 |
+
if ( $document->source == $object_id ) {
|
675 |
+
$client->cancel_document( $document->document_id, $object_id );
|
676 |
} else {
|
677 |
+
$lang = PLL()->model->term->get_language( $object_id );
|
678 |
+
PLL()->model->term->cancel_translation( $object_id );
|
679 |
+
PLL()->model->term->delete_translation( $object_id );
|
680 |
+
$client->cancel_translation( $document->document_id, $lang->lingotek_locale, $object_id );
|
681 |
}
|
682 |
}
|
683 |
}
|
684 |
|
685 |
+
/**
|
686 |
* counts the number of targets per language
|
687 |
*
|
688 |
* @since 0.2
|
689 |
*
|
690 |
+
* @param array $groups Array of serialized 'post_translations' or 'term_translations' description.
|
691 |
* @return array number of targets per language
|
692 |
*/
|
693 |
+
protected function get_target_count( $groups ) {
|
694 |
+
$targets = array_fill_keys( $this->pllm->get_languages_list( array( 'fields' => 'slug' ) ), 0 );
|
695 |
+
|
696 |
+
foreach ( $groups as $group ) {
|
697 |
+
$group = unserialize( $group );
|
698 |
+
if ( isset( $group['lingotek']['translations'] ) ) {
|
699 |
+
foreach ( $group['lingotek']['translations'] as $locale => $status ) {
|
700 |
+
$language = $this->pllm->get_language( $locale );
|
701 |
+
if ( 'current' === $status && $language ) {
|
702 |
+
$targets[ $language->slug ]++;
|
703 |
+
}
|
704 |
}
|
705 |
}
|
706 |
}
|
707 |
return $targets;
|
708 |
}
|
709 |
|
710 |
+
/**
|
711 |
* counts the number of sources and targets per language for a certain post type
|
712 |
*
|
713 |
* @since 0.2
|
715 |
* @param string $post_type
|
716 |
* @return array
|
717 |
*/
|
718 |
+
public function count_posts( $post_type ) {
|
719 |
global $wpdb;
|
720 |
|
721 |
static $r = array();
|
722 |
+
if ( ! empty( $r[ $post_type ] ) ) {
|
723 |
+
return $r[ $post_type ];
|
724 |
+
}
|
725 |
|
726 |
+
if ( ! post_type_exists( $post_type ) ) {
|
727 |
return;
|
728 |
+
}
|
729 |
|
730 |
// gets all translations groups for the post type
|
731 |
+
$groups = $wpdb->get_col(
|
732 |
+
$wpdb->prepare(
|
733 |
+
"
|
734 |
SELECT DISTINCT tt.description FROM $wpdb->term_taxonomy AS tt
|
735 |
INNER JOIN $wpdb->term_relationships AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
736 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
737 |
WHERE tt.taxonomy = %s
|
738 |
AND p.post_type = %s
|
739 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
740 |
+
'post_translations',
|
741 |
+
$post_type
|
742 |
+
)
|
743 |
+
);
|
744 |
|
745 |
+
$targets = $this->get_target_count( $groups );
|
746 |
|
747 |
$group_ids = array();
|
748 |
+
$disabled = array();
|
749 |
|
750 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
751 |
// counts all the posts in one language
|
752 |
+
$n = $wpdb->get_var(
|
753 |
+
$wpdb->prepare(
|
754 |
+
"
|
755 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
756 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
757 |
WHERE tr.term_taxonomy_id = %d
|
758 |
AND p.post_type = %s
|
759 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
760 |
+
$language->term_taxonomy_id,
|
761 |
+
$post_type
|
762 |
+
)
|
763 |
+
);
|
764 |
+
|
765 |
+
$objects = $wpdb->get_col(
|
766 |
+
$wpdb->prepare(
|
767 |
+
"
|
768 |
SELECT object_id FROM $wpdb->term_relationships AS tr
|
769 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
770 |
WHERE tr.term_taxonomy_id = %d
|
771 |
AND p.post_type = %s
|
772 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
773 |
+
$language->term_taxonomy_id,
|
774 |
+
$post_type
|
775 |
+
)
|
776 |
+
);
|
777 |
+
|
778 |
+
foreach ( $groups as $group ) {
|
779 |
+
$group = unserialize( $group );
|
780 |
+
if ( array_key_exists( $language->slug, $group ) ) {
|
781 |
+
$group_ids[] = $group[ $language->slug ];
|
782 |
}
|
783 |
}
|
784 |
|
785 |
$count = 0;
|
786 |
+
foreach ( $objects as $object ) {
|
787 |
$id = $object;
|
788 |
+
if ( ! in_array( $id, $group_ids, true ) ) {
|
789 |
+
$profile = self::get_profile( $post_type, $language, $id );
|
790 |
+
if ( 'disabled' === $profile['profile'] && in_array( $id, $objects, true ) ) {
|
791 |
+
++$count;
|
792 |
}
|
793 |
}
|
794 |
}
|
795 |
+
$disabled[ $language->slug ] = $count;
|
796 |
|
797 |
// if a post is not a target, then it is source
|
798 |
+
$sources[ $language->slug ] = $n - $targets[ $language->slug ];
|
799 |
// $sources[$language->slug] -= $disabled[$language->slug];
|
800 |
+
}//end foreach
|
801 |
|
802 |
// untranslated posts have no associated translation group in DB
|
803 |
// so let's count them indirectly
|
804 |
|
805 |
// counts the number of translated posts
|
806 |
+
$n_translated = $wpdb->get_var(
|
807 |
+
$wpdb->prepare(
|
808 |
+
"
|
809 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
810 |
INNER JOIN $wpdb->posts AS p ON p.ID = tr.object_id
|
811 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
812 |
WHERE tt.taxonomy = %s
|
813 |
AND p.post_type = %s
|
814 |
AND p.post_status NOT IN ('trash', 'auto-draft')",
|
815 |
+
'post_translations',
|
816 |
+
$post_type
|
817 |
+
)
|
818 |
+
);
|
819 |
|
820 |
// untranslated = total - translated
|
821 |
// total of posts translations groups = untranslated + number of translation groups stored in DB
|
822 |
+
$count_posts = (array) wp_count_posts( $post_type );
|
823 |
+
// Don't count trash and auto-draft.
|
824 |
+
unset( $count_posts['trash'], $count_posts['auto-draft'] );
|
825 |
+
$total = array_sum( $count_posts ) - $n_translated + count( $groups );
|
826 |
|
827 |
+
return $r[ $post_type ] = compact( 'sources', 'targets', 'total' );
|
828 |
}
|
829 |
|
830 |
+
/**
|
831 |
* counts the number of sources and targets per language for a certain taxonomy
|
832 |
*
|
833 |
* @since 0.2
|
835 |
* @param string $taxonomy
|
836 |
* @return array
|
837 |
*/
|
838 |
+
public function count_terms( $taxonomy ) {
|
839 |
global $wpdb;
|
840 |
|
841 |
static $r = array();
|
842 |
+
if ( ! empty( $r[ $taxonomy ] ) ) {
|
843 |
+
return $r[ $taxonomy ];
|
844 |
+
}
|
845 |
|
846 |
+
if ( ! taxonomy_exists( $taxonomy ) ) {
|
847 |
return;
|
848 |
+
}
|
849 |
|
850 |
// gets all translations groups for the taxonomy
|
851 |
+
$groups = $wpdb->get_col(
|
852 |
+
$wpdb->prepare(
|
853 |
+
"
|
854 |
SELECT DISTINCT tt1.description FROM $wpdb->term_taxonomy AS tt1
|
855 |
INNER JOIN $wpdb->term_relationships AS tr ON tt1.term_taxonomy_id = tr.term_taxonomy_id
|
856 |
INNER JOIN $wpdb->term_taxonomy AS tt2 ON tt2.term_id = tr.object_id
|
857 |
WHERE tt1.taxonomy = %s
|
858 |
AND tt2.taxonomy = %s",
|
859 |
+
'term_translations',
|
860 |
+
$taxonomy
|
861 |
+
)
|
862 |
+
);
|
863 |
|
864 |
+
$targets = $this->get_target_count( $groups );
|
865 |
|
866 |
$group_ids = array();
|
867 |
+
$disabled = array();
|
868 |
|
869 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
870 |
// counts all the terms in one language
|
871 |
+
$n = $wpdb->get_var(
|
872 |
+
$wpdb->prepare(
|
873 |
+
"
|
874 |
SELECT COUNT(*) FROM $wpdb->term_relationships AS tr
|
875 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = tr.object_id
|
876 |
WHERE tr.term_taxonomy_id = %d
|
877 |
AND tt.taxonomy = %s",
|
878 |
+
$language->tl_term_taxonomy_id,
|
879 |
+
$taxonomy
|
880 |
+
)
|
881 |
+
);
|
882 |
+
|
883 |
+
$objects = $wpdb->get_col(
|
884 |
+
$wpdb->prepare(
|
885 |
+
"
|
886 |
SELECT object_id FROM $wpdb->term_relationships AS tr
|
887 |
INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = tr.object_id
|
888 |
WHERE tr.term_taxonomy_id = %d
|
889 |
AND tt.taxonomy = %s",
|
890 |
+
$language->tl_term_taxonomy_id,
|
891 |
+
$taxonomy
|
892 |
+
)
|
893 |
+
);
|
894 |
|
895 |
$count = 0;
|
896 |
+
foreach ( $groups as $group ) {
|
897 |
+
$group = unserialize( $group );
|
898 |
+
if ( array_key_exists( $language->slug, $group ) ) {
|
899 |
+
$group_ids[] = $group[ $language->slug ];
|
900 |
+
$profile = self::get_profile( $taxonomy, $language, $group[ $language->slug ] );
|
901 |
+
if ( 'disabled' === $profile['profile'] && ! isset( $group['lingotek'] ) ) {
|
902 |
+
++$count;
|
903 |
}
|
904 |
}
|
905 |
}
|
906 |
|
907 |
+
$disabled[ $language->slug ] = $count;
|
|
|
908 |
|
909 |
// if a term is not a target, then it is a source
|
910 |
+
$sources[ $language->slug ] = $n - $targets[ $language->slug ];
|
911 |
// $sources[$language->slug] -= $disabled[$language->slug];
|
912 |
+
}//end foreach
|
913 |
|
914 |
+
$total = count( $groups );
|
915 |
|
916 |
// default categories are created by Polylang in all languages
|
917 |
// don't count them as sources if they are not associated to the TMS
|
918 |
+
if ( 'category' === $taxonomy ) {
|
919 |
+
$term_id = get_option( 'default_category' );
|
920 |
+
$group = $this->get_group( 'term', $term_id );
|
921 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
922 |
+
if ( empty( $group->source ) || ( $group->get_source_language()->slug !== $language->slug && empty( $group->translations[ $language->locale ] ) ) ) {
|
923 |
+
if ( $language->slug !== $this->pllm->options['default_lang'] ) {
|
924 |
+
$sources[ $language->slug ]--;
|
925 |
}
|
926 |
}
|
927 |
}
|
928 |
// Remove category targets from being counted until they are downloaded. Fixed target categories being counted as source languages.
|
929 |
+
foreach ( $groups as $group ) {
|
930 |
+
$group = unserialize( $group );
|
931 |
+
if ( isset( $group['lingotek']['translations'] ) ) {
|
932 |
+
foreach ( $group['lingotek']['translations'] as $locale => $status ) {
|
933 |
+
$language = $this->pllm->get_language( $locale );
|
934 |
+
if ( ( 'pending' === $status || 'ready' === $status ) && $language ) {
|
935 |
+
if ( $sources[ $language->slug ] > 0 ) {
|
936 |
+
$sources[ $language->slug ]--;
|
937 |
}
|
938 |
}
|
939 |
}
|
940 |
}
|
941 |
}
|
942 |
+
if ( 1 === count( $sources ) && $total !== $sources[ $this->pllm->options['default_lang'] ] ) {
|
943 |
+
$total = $sources[ $this->pllm->options['default_lang'] ];
|
944 |
}
|
945 |
+
}//end if
|
946 |
+
$r[ $taxonomy ] = compact( 'sources', 'targets', 'total' );
|
947 |
+
return $r[ $taxonomy ];
|
948 |
}
|
949 |
|
950 |
+
private function build_params( $external_url, $title, $type, $content, $language, $profile, $wp_id, &$wp_target_locales = array() ) {
|
951 |
+
$translation_workflow_id = self::get_profile_option( 'workflow_id', $type, $language, false, $wp_id );
|
952 |
+
if ( 'project-default' === $translation_workflow_id || false === $translation_workflow_id ) {
|
|
|
953 |
$translation_workflow_id = null;
|
954 |
}
|
955 |
|
956 |
$params = array(
|
957 |
+
'title' => $title,
|
958 |
+
'content' => $content,
|
959 |
+
'locale_code' => $language->lingotek_locale,
|
960 |
+
'project_id' => self::get_profile_option( 'project_id', $type, $language, false, $wp_id ),
|
961 |
+
'external_url' => $external_url,
|
962 |
);
|
963 |
|
964 |
+
$lingotek_metadata_keys = array(
|
965 |
+
'author_email',
|
966 |
+
'author_name',
|
967 |
+
'division',
|
968 |
+
'unit',
|
969 |
+
'campaign_id',
|
970 |
+
'channel',
|
971 |
+
'contact_email',
|
972 |
+
'contact_name',
|
973 |
+
'description',
|
974 |
+
'domain',
|
975 |
+
'style_id',
|
976 |
+
'purchase_order',
|
977 |
+
'reference_url',
|
978 |
+
'region',
|
979 |
+
'require_review',
|
980 |
+
);
|
981 |
+
|
982 |
+
foreach ( $lingotek_metadata_keys as $key ) {
|
983 |
+
if ( isset( $profile[ $key ] ) ) {
|
984 |
+
$params[ $key ] = $profile[ $key ];
|
985 |
+
}
|
986 |
+
}
|
987 |
+
|
988 |
+
if ( null !== $translation_workflow_id ) {
|
989 |
$params['translation_workflow_id'] = $translation_workflow_id;
|
990 |
}
|
991 |
|
992 |
// Get target locales to send up from profile
|
993 |
$target_locales = array();
|
994 |
+
if ( ! empty( $profile['target_locales'] ) ) {
|
995 |
+
if ( isset( $profile['target_locales'][ $language->slug ] ) ) {
|
996 |
+
unset( $profile['target_locales'][ $language->slug ] );
|
997 |
}
|
998 |
+
if ( isset( $profile['custom']['workflow_id'][ $language->slug ] ) ) {
|
999 |
+
unset( $profile['custom']['workflow_id'][ $language->slug ] );
|
1000 |
}
|
1001 |
+
$target_locales['translation_locale_code'] = array_values( $profile['target_locales'] );
|
1002 |
+
$wp_target_locales = array_keys( $profile['target_locales'] );
|
1003 |
|
1004 |
// Add workflows
|
1005 |
+
if ( ! empty( $profile['custom']['workflow_id'] ) ) {
|
1006 |
+
$temp_workflow_ids = array();
|
1007 |
+
$workflow_id = null;
|
1008 |
+
foreach ( $wp_target_locales as $language_slug ) {
|
1009 |
+
if ( isset( $profile['custom']['workflow_id'][ $language_slug ] ) ) {
|
1010 |
+
$profile_override = $profile['custom']['workflow_id'][ $language_slug ];
|
1011 |
+
$workflow_id = 'project-default' === $profile_override ? $translation_workflow_id : $profile_override;
|
1012 |
+
} else {
|
|
|
1013 |
$workflow_id = $translation_workflow_id;
|
1014 |
}
|
1015 |
+
if ( $workflow_id ) {
|
1016 |
$temp_workflow_ids[] = $workflow_id;
|
1017 |
}
|
1018 |
}
|
1019 |
$params['translation_workflow_id'] = $temp_workflow_ids;
|
1020 |
}
|
1021 |
+
} else {
|
|
|
1022 |
// No targets being sent up to TMS, unset the workflow
|
1023 |
+
unset( $params['translation_workflow_id'] );
|
1024 |
+
}//end if
|
1025 |
|
1026 |
+
$params = array_merge( $params, $target_locales );
|
1027 |
|
1028 |
return $params;
|
1029 |
}
|
1030 |
|
1031 |
+
private function get_filter_ids( $type, $language, $wp_id ) {
|
1032 |
$filter_ids = array();
|
1033 |
+
if ( self::get_profile_option( 'primary_filter_id', $type, $language, false, $wp_id ) ) {
|
1034 |
+
$filter_ids['fprm_id'] = self::get_profile_option( 'primary_filter_id', $type, $language, false, $wp_id );
|
1035 |
}
|
1036 |
+
if ( self::get_profile_option( 'secondary_filter_id', $type, $language, false, $wp_id ) ) {
|
1037 |
+
$filter_ids['fprm_subfilter_id'] = self::get_profile_option( 'secondary_filter_id', $type, $language, false, $wp_id );
|
1038 |
}
|
1039 |
return $filter_ids;
|
1040 |
}
|
include/plugins-compat.php
CHANGED
@@ -8,33 +8,34 @@
|
|
8 |
* @since 1.0.6
|
9 |
*/
|
10 |
class Lingotek_Plugins_Compat {
|
11 |
-
static
|
12 |
|
13 |
protected function __construct() {
|
14 |
// WordPress Importer
|
15 |
-
add_action('init', array(&$this, 'lingotek_maybe_wordpress_importer'));
|
16 |
}
|
17 |
|
18 |
-
static
|
19 |
-
if (empty(self::$instance))
|
20 |
self::$instance = new self();
|
|
|
21 |
|
22 |
return self::$instance;
|
23 |
}
|
24 |
|
25 |
function lingotek_maybe_wordpress_importer() {
|
26 |
-
if (defined('WP_LOAD_IMPORTERS') && class_exists('WP_Import')) {
|
27 |
-
remove_action('admin_init', 'lingotek_wordpress_importer_init');
|
28 |
-
add_action('admin_init', array(&$this, 'lingotek_wordpress_importer_init'));
|
29 |
}
|
30 |
}
|
31 |
|
32 |
function lingotek_wordpress_importer_init() {
|
33 |
-
$class = new ReflectionClass('WP_Import');
|
34 |
-
load_plugin_textdomain( 'wordpress-importer', false, basename(dirname( $class->getFileName() )) . '/languages' );
|
35 |
|
36 |
$GLOBALS['wp_import'] = new Lingotek_WP_Import();
|
37 |
-
register_importer( '
|
38 |
}
|
39 |
}
|
40 |
-
|
8 |
* @since 1.0.6
|
9 |
*/
|
10 |
class Lingotek_Plugins_Compat {
|
11 |
+
protected static $instance;
|
12 |
|
13 |
protected function __construct() {
|
14 |
// WordPress Importer
|
15 |
+
add_action( 'init', array( &$this, 'lingotek_maybe_wordpress_importer' ) );
|
16 |
}
|
17 |
|
18 |
+
public static function instance() {
|
19 |
+
if ( empty( self::$instance ) ) {
|
20 |
self::$instance = new self();
|
21 |
+
}
|
22 |
|
23 |
return self::$instance;
|
24 |
}
|
25 |
|
26 |
function lingotek_maybe_wordpress_importer() {
|
27 |
+
if ( defined( 'WP_LOAD_IMPORTERS' ) && class_exists( 'WP_Import' ) ) {
|
28 |
+
remove_action( 'admin_init', 'lingotek_wordpress_importer_init' );
|
29 |
+
add_action( 'admin_init', array( &$this, 'lingotek_wordpress_importer_init' ) );
|
30 |
}
|
31 |
}
|
32 |
|
33 |
function lingotek_wordpress_importer_init() {
|
34 |
+
$class = new ReflectionClass( 'WP_Import' );
|
35 |
+
load_plugin_textdomain( 'wordpress-importer', false, basename( dirname( $class->getFileName() ) ) . '/languages' );
|
36 |
|
37 |
$GLOBALS['wp_import'] = new Lingotek_WP_Import();
|
38 |
+
register_importer( 'WordPress', 'WordPress', __( 'Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'wordpress-importer' ), array( $GLOBALS['wp_import'], 'dispatch' ) );
|
39 |
}
|
40 |
}
|
41 |
+
|
include/pointer.php
CHANGED
@@ -12,22 +12,22 @@ class Lingotek_Pointer {
|
|
12 |
* pointer => required, unique identifier of the pointer
|
13 |
* id => required, the pointer will be attached to this html id
|
14 |
* position => optional array, if used both sub parameters are required
|
15 |
-
*
|
16 |
-
*
|
17 |
* width => optional, the width in px
|
18 |
* title => required, title
|
19 |
* content => required, content
|
20 |
* buttons => optional array of arrays, by default the pointer uses the standard dismiss button offered by WP
|
21 |
-
*
|
22 |
-
*
|
23 |
*
|
24 |
* @since 1.0.1
|
25 |
*
|
26 |
* @param array $args
|
27 |
*/
|
28 |
-
public function __construct($args) {
|
29 |
$this->args = $args;
|
30 |
-
add_action('admin_enqueue_scripts', array(&$this, 'enqueue_scripts'));
|
31 |
}
|
32 |
|
33 |
/**
|
@@ -36,17 +36,18 @@ class Lingotek_Pointer {
|
|
36 |
* @since 1.0.1
|
37 |
*/
|
38 |
public function enqueue_scripts() {
|
39 |
-
$dismissed = explode(',', get_user_meta(get_current_user_id(), 'dismissed_wp_pointers', true));
|
40 |
|
41 |
// comment the two lines below to make the pointer non dismissable
|
42 |
-
if (in_array($this->args['pointer'], $dismissed) || !current_user_can('manage_options'))
|
43 |
return;
|
|
|
44 |
|
45 |
// Add pointer JavaScript
|
46 |
-
add_action('admin_print_footer_scripts', array(&$this, 'print_js'));
|
47 |
|
48 |
-
wp_enqueue_style('wp-pointer');
|
49 |
-
wp_enqueue_script('wp-pointer');
|
50 |
}
|
51 |
|
52 |
/**
|
@@ -57,15 +58,17 @@ class Lingotek_Pointer {
|
|
57 |
public function print_js() {
|
58 |
|
59 |
// add optional buttons
|
60 |
-
if (!empty($this->args['buttons'])) {
|
|
|
61 |
$b = "
|
62 |
var widget = pointer.pointer('widget');
|
63 |
var buttons = $('.wp-pointer-buttons', widget);
|
64 |
-
$('a.close', widget).remove();";
|
65 |
|
66 |
// all the buttons use the standard WP ajax action to remember the pointer has been dismissed
|
67 |
-
foreach ($this->args['buttons'] as $button) {
|
68 |
-
$b .= sprintf(
|
|
|
69 |
$('<a>').addClass('%s').html('%s').css('margin-left', '10px').click(function() {
|
70 |
$.post(ajaxurl, {
|
71 |
pointer: '%s',
|
@@ -74,15 +77,16 @@ class Lingotek_Pointer {
|
|
74 |
%s
|
75 |
});
|
76 |
}).appendTo(buttons);",
|
77 |
-
empty($button['link']) ? 'button' : 'button button-primary',
|
78 |
$button['label'],
|
79 |
$this->args['pointer'],
|
80 |
-
empty($button['link']) ? "pointer.pointer('close')" : sprintf("location.href = '%s'", $button['link'])
|
81 |
);
|
82 |
}
|
83 |
-
}
|
84 |
|
85 |
-
$js = sprintf(
|
|
|
86 |
//<![CDATA[
|
87 |
jQuery(document).ready(function($) {
|
88 |
var pointer = $('#%s').pointer({
|
@@ -95,13 +99,13 @@ class Lingotek_Pointer {
|
|
95 |
});
|
96 |
// ]]>",
|
97 |
$this->args['id'],
|
98 |
-
sprintf('<h3>%s</h3><p>%s</p>', $this->args['title'], $this->args['content']),
|
99 |
-
empty($this->args['position']) ? '' : sprintf('position: {edge: "%s", align: "%s",},', $this->args['position']['edge'], $this->args['position']['align']),
|
100 |
-
empty($this->args['width']) ? '' : sprintf('pointerWidth: %d,', $this->args['width']),
|
101 |
-
empty($b) ? '' : $b
|
102 |
);
|
103 |
-
echo "<script type='text/javascript'>"
|
104 |
}
|
105 |
}
|
106 |
|
107 |
-
|
12 |
* pointer => required, unique identifier of the pointer
|
13 |
* id => required, the pointer will be attached to this html id
|
14 |
* position => optional array, if used both sub parameters are required
|
15 |
+
* edge => 'top' or 'bottom'
|
16 |
+
* align => 'right' or 'left'
|
17 |
* width => optional, the width in px
|
18 |
* title => required, title
|
19 |
* content => required, content
|
20 |
* buttons => optional array of arrays, by default the pointer uses the standard dismiss button offered by WP
|
21 |
+
* label => the label of the button
|
22 |
+
* link => optional link for the button. By default, the button just dismisses the pointer
|
23 |
*
|
24 |
* @since 1.0.1
|
25 |
*
|
26 |
* @param array $args
|
27 |
*/
|
28 |
+
public function __construct( $args ) {
|
29 |
$this->args = $args;
|
30 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
|
31 |
}
|
32 |
|
33 |
/**
|
36 |
* @since 1.0.1
|
37 |
*/
|
38 |
public function enqueue_scripts() {
|
39 |
+
$dismissed = explode( ',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
40 |
|
41 |
// comment the two lines below to make the pointer non dismissable
|
42 |
+
if ( in_array( $this->args['pointer'], $dismissed ) || ! current_user_can( 'manage_options' ) ) {
|
43 |
return;
|
44 |
+
}
|
45 |
|
46 |
// Add pointer JavaScript
|
47 |
+
add_action( 'admin_print_footer_scripts', array( &$this, 'print_js' ) );
|
48 |
|
49 |
+
wp_enqueue_style( 'wp-pointer' );
|
50 |
+
wp_enqueue_script( 'wp-pointer' );
|
51 |
}
|
52 |
|
53 |
/**
|
58 |
public function print_js() {
|
59 |
|
60 |
// add optional buttons
|
61 |
+
if ( ! empty( $this->args['buttons'] ) ) {
|
62 |
+
// Removes the WordPress button.
|
63 |
$b = "
|
64 |
var widget = pointer.pointer('widget');
|
65 |
var buttons = $('.wp-pointer-buttons', widget);
|
66 |
+
$('a.close', widget).remove();";
|
67 |
|
68 |
// all the buttons use the standard WP ajax action to remember the pointer has been dismissed
|
69 |
+
foreach ( $this->args['buttons'] as $button ) {
|
70 |
+
$b .= sprintf(
|
71 |
+
"
|
72 |
$('<a>').addClass('%s').html('%s').css('margin-left', '10px').click(function() {
|
73 |
$.post(ajaxurl, {
|
74 |
pointer: '%s',
|
77 |
%s
|
78 |
});
|
79 |
}).appendTo(buttons);",
|
80 |
+
empty( $button['link'] ) ? 'button' : 'button button-primary',
|
81 |
$button['label'],
|
82 |
$this->args['pointer'],
|
83 |
+
empty( $button['link'] ) ? "pointer.pointer('close')" : sprintf( "location.href = '%s'", $button['link'] )
|
84 |
);
|
85 |
}
|
86 |
+
}//end if
|
87 |
|
88 |
+
$js = sprintf(
|
89 |
+
"
|
90 |
//<![CDATA[
|
91 |
jQuery(document).ready(function($) {
|
92 |
var pointer = $('#%s').pointer({
|
99 |
});
|
100 |
// ]]>",
|
101 |
$this->args['id'],
|
102 |
+
sprintf( '<h3>%s</h3><p>%s</p>', $this->args['title'], $this->args['content'] ),
|
103 |
+
empty( $this->args['position'] ) ? '' : sprintf( 'position: {edge: "%s", align: "%s",},', $this->args['position']['edge'], $this->args['position']['align'] ),
|
104 |
+
empty( $this->args['width'] ) ? '' : sprintf( 'pointerWidth: %d,', $this->args['width'] ),
|
105 |
+
empty( $b ) ? '' : $b
|
106 |
);
|
107 |
+
echo "<script type='text/javascript'>" . $js . '</script>';
|
108 |
}
|
109 |
}
|
110 |
|
111 |
+
|
js/updater.js
CHANGED
@@ -125,11 +125,13 @@ jQuery(document).ready(function($) {
|
|
125 |
var source = data[key]['source'];
|
126 |
if(locale === data[key]['source']){
|
127 |
$(td).find('.lingotek-color').remove();
|
|
|
128 |
$(td).find('.pll_icon_edit').remove();
|
129 |
updateUploadIndicator(td, data, key, locale);
|
130 |
}
|
131 |
else if (data[key][locale]['status'] === 'disabled' || data[key]['source'] === 'disabled') {
|
132 |
$(td).find('.lingotek-color').remove();
|
|
|
133 |
}
|
134 |
else if ($(td).find('.pll_icon_add').length > 0 && (data[key][data[key]['source']]['status'] === 'none' || data[key][data[key]['source']]['status'] === 'cancelled')){
|
135 |
break;
|
@@ -143,6 +145,7 @@ jQuery(document).ready(function($) {
|
|
143 |
$(td).find('.pll_icon_tick').remove();
|
144 |
$(td).find('.pll_icon_edit').remove();
|
145 |
$(td).find('.lingotek-color').remove();
|
|
|
146 |
updateIndicator(td, data, key, locale, 'request', 'Request a translation', 'plus');
|
147 |
updateGenericBulkLink(tr, data, key, 'request' , 'Request translations of this item to Lingotek TMS', 'Request translations');
|
148 |
}
|
@@ -151,6 +154,7 @@ jQuery(document).ready(function($) {
|
|
151 |
$(td).find('.pll_icon_tick').remove();
|
152 |
$(td).find('.pll_icon_edit').remove();
|
153 |
$(td).find('.lingotek-color').remove();
|
|
|
154 |
var indicator = $('<div></div>').addClass('lingotek-color dashicons dashicons-no');
|
155 |
$(td).prepend(indicator);
|
156 |
}
|
@@ -186,6 +190,7 @@ jQuery(document).ready(function($) {
|
|
186 |
}
|
187 |
$(td).find('.pll_icon_edit').remove();
|
188 |
$(td).find('.lingotek-color').remove();
|
|
|
189 |
var request_link = $('<a></a>').attr('href', data[key][locale]['workbench_link'])
|
190 |
.attr('title',title)
|
191 |
.attr('target','_blank')
|
@@ -194,6 +199,13 @@ jQuery(document).ready(function($) {
|
|
194 |
}
|
195 |
|
196 |
function updateInterimIcon(td, data, key, locale) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
$(td).find('.lingotek-professional-icon').remove();
|
198 |
var icon = 'edit';
|
199 |
$(td).find('.lingotek-interim-color').remove();
|
@@ -278,6 +290,7 @@ jQuery(document).ready(function($) {
|
|
278 |
|
279 |
function updateUploadIndicator(td, data, key, locale){
|
280 |
$(td).find('.lingotek-color').remove();
|
|
|
281 |
var request_link = $('<a></a>').attr('href', relative_url
|
282 |
+ page_params + 'post=' + key
|
283 |
+ '&locale=' + locale
|
@@ -291,6 +304,7 @@ jQuery(document).ready(function($) {
|
|
291 |
|
292 |
function updateFailedIndicator(td, data, key, locale) {
|
293 |
$(td).find('.lingotek-color').remove();
|
|
|
294 |
$(td).find('.lingotek-failed-color').remove();
|
295 |
var reupload_failed_doc = $('<a></a>').attr('title', 'Upload Failed. Click to re-upload')
|
296 |
.attr('href', relative_url
|
@@ -307,14 +321,15 @@ jQuery(document).ready(function($) {
|
|
307 |
$(td).find('.lingotek-professional-icon').remove();
|
308 |
}
|
309 |
$(td).find('.lingotek-color').remove();
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
|
|
318 |
$(td).prepend(request_link);
|
319 |
}
|
320 |
|
@@ -322,6 +337,7 @@ jQuery(document).ready(function($) {
|
|
322 |
$(td).find('.pll_icon_edit').remove();
|
323 |
if(locale === data[key]['source']){
|
324 |
$(td).find('.lingotek-color').remove();
|
|
|
325 |
if(post_data['terms_translations'] === true){
|
326 |
var request_link = $('<a></a>').attr('href', relative_url
|
327 |
+ '/edit-tags.php?action=edit'
|
125 |
var source = data[key]['source'];
|
126 |
if(locale === data[key]['source']){
|
127 |
$(td).find('.lingotek-color').remove();
|
128 |
+
$(td).find('.lingotek-interim-color').remove();
|
129 |
$(td).find('.pll_icon_edit').remove();
|
130 |
updateUploadIndicator(td, data, key, locale);
|
131 |
}
|
132 |
else if (data[key][locale]['status'] === 'disabled' || data[key]['source'] === 'disabled') {
|
133 |
$(td).find('.lingotek-color').remove();
|
134 |
+
$(td).find('.lingotek-interim-color').remove();
|
135 |
}
|
136 |
else if ($(td).find('.pll_icon_add').length > 0 && (data[key][data[key]['source']]['status'] === 'none' || data[key][data[key]['source']]['status'] === 'cancelled')){
|
137 |
break;
|
145 |
$(td).find('.pll_icon_tick').remove();
|
146 |
$(td).find('.pll_icon_edit').remove();
|
147 |
$(td).find('.lingotek-color').remove();
|
148 |
+
$(td).find('.lingotek-interim-color').remove();
|
149 |
updateIndicator(td, data, key, locale, 'request', 'Request a translation', 'plus');
|
150 |
updateGenericBulkLink(tr, data, key, 'request' , 'Request translations of this item to Lingotek TMS', 'Request translations');
|
151 |
}
|
154 |
$(td).find('.pll_icon_tick').remove();
|
155 |
$(td).find('.pll_icon_edit').remove();
|
156 |
$(td).find('.lingotek-color').remove();
|
157 |
+
$(td).find('.lingotek-interim-color').remove();
|
158 |
var indicator = $('<div></div>').addClass('lingotek-color dashicons dashicons-no');
|
159 |
$(td).prepend(indicator);
|
160 |
}
|
190 |
}
|
191 |
$(td).find('.pll_icon_edit').remove();
|
192 |
$(td).find('.lingotek-color').remove();
|
193 |
+
$(td).find('.lingotek-interim-color').remove();
|
194 |
var request_link = $('<a></a>').attr('href', data[key][locale]['workbench_link'])
|
195 |
.attr('title',title)
|
196 |
.attr('target','_blank')
|
199 |
}
|
200 |
|
201 |
function updateInterimIcon(td, data, key, locale) {
|
202 |
+
$(td).find('.lingotek-color').remove();
|
203 |
+
$(td).find('.lingotek-interim-color').remove();
|
204 |
+
if ($(td).find('dashicons-no').length > 0) {
|
205 |
+
$(td).find('.dashicons-no').remove();
|
206 |
+
} else if ($(td).find('.dashicons-clock').length > 0) {
|
207 |
+
$(td).find('.dashicons-clock').remove();
|
208 |
+
}
|
209 |
$(td).find('.lingotek-professional-icon').remove();
|
210 |
var icon = 'edit';
|
211 |
$(td).find('.lingotek-interim-color').remove();
|
290 |
|
291 |
function updateUploadIndicator(td, data, key, locale){
|
292 |
$(td).find('.lingotek-color').remove();
|
293 |
+
$(td).find('.lingotek-interim-color').remove();
|
294 |
var request_link = $('<a></a>').attr('href', relative_url
|
295 |
+ page_params + 'post=' + key
|
296 |
+ '&locale=' + locale
|
304 |
|
305 |
function updateFailedIndicator(td, data, key, locale) {
|
306 |
$(td).find('.lingotek-color').remove();
|
307 |
+
$(td).find('.lingotek-interim-color').remove();
|
308 |
$(td).find('.lingotek-failed-color').remove();
|
309 |
var reupload_failed_doc = $('<a></a>').attr('title', 'Upload Failed. Click to re-upload')
|
310 |
.attr('href', relative_url
|
321 |
$(td).find('.lingotek-professional-icon').remove();
|
322 |
}
|
323 |
$(td).find('.lingotek-color').remove();
|
324 |
+
$(td).find('.lingotek-interim-color').remove();
|
325 |
+
var request_link = $('<a></a>').attr('href', relative_url
|
326 |
+
+ page_params + 'document_id=' + data[key]['doc_id']
|
327 |
+
+ '&locale=' + locale
|
328 |
+
+ '&action=lingotek-' + action
|
329 |
+
+ '&noheader=1'
|
330 |
+
+ '&_wpnonce='+data[action + '_nonce'])
|
331 |
+
.attr('title', title)
|
332 |
+
.addClass('lingotek-color dashicons dashicons-' + dashicon + ' dashicons-' + dashicon + '-lingotek');
|
333 |
$(td).prepend(request_link);
|
334 |
}
|
335 |
|
337 |
$(td).find('.pll_icon_edit').remove();
|
338 |
if(locale === data[key]['source']){
|
339 |
$(td).find('.lingotek-color').remove();
|
340 |
+
$(td).find('.lingotek-interim-color').remove();
|
341 |
if(post_data['terms_translations'] === true){
|
342 |
var request_link = $('<a></a>').attr('href', relative_url
|
343 |
+ '/edit-tags.php?action=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.4.
|
6 |
Author: Lingotek and Frédéric Demarle
|
7 |
Author uri: http://lingotek.com
|
8 |
Description: Lingotek offers convenient cloud-based localization and translation.
|
@@ -16,218 +16,222 @@ if ( ! function_exists( 'add_action' ) ) {
|
|
16 |
exit();
|
17 |
}
|
18 |
|
19 |
-
|
|
|
20 |
define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
|
21 |
-
|
22 |
-
define( '
|
23 |
-
|
|
|
|
|
|
|
24 |
define( 'LINGOTEK_INC', LINGOTEK_DIR . '/include' );
|
25 |
-
define( 'LINGOTEK_ADMIN_INC',
|
26 |
-
define( 'LINGOTEK_WORKFLOWS',
|
27 |
define( 'LINGOTEK_URL', plugins_url( '', __FILE__ ) );
|
28 |
define( 'BRIDGE_URL', 'https://marketplace.lingotek.com' );
|
29 |
|
30 |
class Lingotek {
|
31 |
/**
|
32 |
-
*
|
33 |
*
|
34 |
-
*
|
35 |
*/
|
36 |
public $model;
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*
|
41 |
-
*
|
42 |
*/
|
43 |
public $callback;
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
-
*
|
48 |
*
|
49 |
* TODO: update this list!!!!
|
50 |
-
*
|
|
|
51 |
*/
|
52 |
public static $lingotek_locales = array(
|
53 |
-
'af'
|
54 |
-
'ak'
|
55 |
-
'am'
|
56 |
-
'ar'
|
57 |
-
'ar_AE'
|
58 |
-
'ar_AF'
|
59 |
-
'ar_BH'
|
60 |
-
'ar_DZ'
|
61 |
-
'ar_EG'
|
62 |
-
'ar_IQ'
|
63 |
-
'ar_JO'
|
64 |
-
'ar_LY'
|
65 |
-
'ar_MA'
|
66 |
-
'ar_MR'
|
67 |
-
'ar_OM'
|
68 |
-
'ar_SA'
|
69 |
-
'ar_SD'
|
70 |
-
'ar_SY'
|
71 |
-
'ar_TD'
|
72 |
-
'ar_TN'
|
73 |
-
'ar_UZ'
|
74 |
-
'ar_YE'
|
75 |
-
'as'
|
76 |
-
'az'
|
77 |
-
'ba'
|
78 |
-
'bel'
|
79 |
-
'bg_BG'
|
80 |
-
'bn_BD'
|
81 |
-
'bo'
|
82 |
-
'bs_BA'
|
83 |
-
'ca'
|
84 |
-
'ca_ES'
|
85 |
-
'co'
|
86 |
-
'cs_CZ'
|
87 |
-
'cy'
|
88 |
-
'cy_GB'
|
89 |
-
'de_AT'
|
90 |
-
'da_DK'
|
91 |
-
'de_CH'
|
92 |
-
'de_DE'
|
93 |
-
'dv'
|
94 |
-
'el'
|
95 |
-
'el_GR'
|
96 |
-
'en_AU'
|
97 |
-
'en_CA'
|
98 |
-
'en_GB'
|
99 |
-
'en_US'
|
100 |
-
'en_IE'
|
101 |
-
'en_IN'
|
102 |
-
'en_ZA'
|
103 |
-
'eo'
|
104 |
-
'es_419' => 'es-419',
|
105 |
-
'es_AR'
|
106 |
-
'es_BO'
|
107 |
-
'es_CL'
|
108 |
-
'es_CO'
|
109 |
-
'es_ES'
|
110 |
-
'es_MX'
|
111 |
-
'es_PE'
|
112 |
-
'es_PR'
|
113 |
-
'es_VE'
|
114 |
-
'es_HN'
|
115 |
-
'es_CR'
|
116 |
-
'es_CU'
|
117 |
-
'es_DO'
|
118 |
-
'es_EC'
|
119 |
-
'es_GT'
|
120 |
-
'es_NI'
|
121 |
-
'es_PA'
|
122 |
-
'es_PY'
|
123 |
-
'es_SV'
|
124 |
-
'es_UY'
|
125 |
-
'es_US'
|
126 |
-
'et'
|
127 |
-
'et_EE'
|
128 |
-
'eu'
|
129 |
-
'fa_IR'
|
130 |
-
'fi'
|
131 |
-
'fi_FI'
|
132 |
-
'fr_FR'
|
133 |
-
'fr_BE'
|
134 |
-
'fr_CA'
|
135 |
-
'fr_CH'
|
136 |
-
'fr_US'
|
137 |
-
'ga'
|
138 |
-
'gd'
|
139 |
-
'gl_ES'
|
140 |
-
'gn'
|
141 |
'haw_US' => 'haw-US',
|
142 |
-
'he_IL'
|
143 |
-
'hi_IN'
|
144 |
-
'hr'
|
145 |
-
'ht_HT'
|
146 |
-
'hu_HU'
|
147 |
-
'hy'
|
148 |
-
'id_ID'
|
149 |
-
'is_IS'
|
150 |
-
'it_IT'
|
151 |
-
'it_CH'
|
152 |
-
'ja'
|
153 |
-
'ja_JP'
|
154 |
-
'jv_ID'
|
155 |
-
'ka_GE'
|
156 |
-
'kin'
|
157 |
-
'kk'
|
158 |
-
'kn'
|
159 |
-
'ko_KR'
|
160 |
-
'ky_KY'
|
161 |
-
'lb_LU'
|
162 |
-
'lo'
|
163 |
-
'lt_LT'
|
164 |
-
'lv'
|
165 |
-
'lv_LV'
|
166 |
-
'mg_MG'
|
167 |
-
'mk_MK'
|
168 |
-
'ml_IN'
|
169 |
-
'mn'
|
170 |
-
'mr'
|
171 |
-
'ms_MY'
|
172 |
-
'mt_MT'
|
173 |
-
'my_MM'
|
174 |
-
'ne_NP'
|
175 |
-
'nl_BE'
|
176 |
-
'nl_NL'
|
177 |
-
'nn_NO'
|
178 |
-
'no_NO'
|
179 |
-
'pa_IN'
|
180 |
-
'pl_PL'
|
181 |
-
'ps'
|
182 |
-
'pt_BR'
|
183 |
-
'pt_PT'
|
184 |
-
'ro_RO'
|
185 |
-
'ru_RU'
|
186 |
-
'sa_IN'
|
187 |
-
'sd_PK'
|
188 |
-
'si_LK'
|
189 |
-
'sk_SK'
|
190 |
-
'sl_SI'
|
191 |
-
'so_SO'
|
192 |
-
'sq'
|
193 |
-
'sr_RS'
|
194 |
-
'su_ID'
|
195 |
-
'sv_SE'
|
196 |
-
'sw'
|
197 |
-
'sw_TZ'
|
198 |
-
'ta_IN'
|
199 |
-
'te'
|
200 |
-
'tg'
|
201 |
-
'th'
|
202 |
-
'th_TH'
|
203 |
-
'tir'
|
204 |
-
'tl'
|
205 |
-
'tr_TR'
|
206 |
-
'ug_CN'
|
207 |
-
'uk'
|
208 |
-
'uk_UA'
|
209 |
-
'ur'
|
210 |
-
'ur_PK'
|
211 |
-
'uz_UZ'
|
212 |
-
'vi'
|
213 |
-
'vi_VN'
|
214 |
-
'zh_CN'
|
215 |
-
'zh_HK'
|
216 |
-
'zh_TW'
|
217 |
-
'zh_SG'
|
218 |
);
|
219 |
|
220 |
|
221 |
/**
|
222 |
-
* Verifies that a lingotek-locale (ie. es-ES) is an allowed
|
223 |
* TMS locale.
|
224 |
*
|
225 |
* @param string $lingotek_locale
|
226 |
* @return boolean
|
227 |
*/
|
228 |
-
public static function is_allowed_tms_locale($lingotek_locale)
|
229 |
-
|
230 |
-
return isset(self::$lingotek_locales[$lingotek_locale]) || in_array($lingotek_locale, self::$lingotek_locales);
|
231 |
}
|
232 |
|
233 |
/**
|
@@ -277,11 +281,12 @@ class Lingotek {
|
|
277 |
// loads the admin side of Polylang for the dashboard.
|
278 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $action ) && 'lingotek_language' === $action ) {
|
279 |
define( 'PLL_AJAX_ON_FRONT', false );
|
280 |
-
|
281 |
add_filter( 'pll_model', array( &$this, 'PLL_Admin_Model' ) );
|
282 |
}
|
283 |
|
284 |
-
|
|
|
285 |
|
286 |
// init.
|
287 |
add_filter( 'pll_model', array( &$this, 'pll_model' ) );
|
@@ -325,94 +330,97 @@ class Lingotek {
|
|
325 |
// If any update happened, inform the user and update the version.
|
326 |
if ( $updatesHaveRun ) {
|
327 |
update_option( 'lingotek_plugin_version', LINGOTEK_VERSION, false );
|
328 |
-
add_action(
|
329 |
-
|
|
|
|
|
330 |
<p>' . __( 'Upgrades for the lingotek translation module have completed.', 'lingotek-translation' ) . '</p>
|
331 |
</div>';
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
334 |
}
|
335 |
|
336 |
-
|
337 |
-
* Check if we need to run these updates.
|
338 |
-
*
|
339 |
-
* It will check that the installed version is newer than the db one, even if we
|
340 |
-
* had skipped any version, and ensures we don't run any update if we already did.
|
341 |
-
*
|
342 |
-
* @param $versionUpdates
|
343 |
-
* The version where these updates were introduced.
|
344 |
-
* @return bool
|
345 |
-
* true if needs to run, false otherwise
|
346 |
-
*
|
347 |
-
* @since 1.4.11
|
348 |
-
*/
|
349 |
-
public function needs_to_run_updates($versionUpdates) {
|
350 |
-
$db_version = get_option('lingotek_plugin_version');
|
351 |
-
return (version_compare(LINGOTEK_VERSION, $versionUpdates, '>=') &&
|
352 |
-
version_compare($versionUpdates, $db_version, '>'));
|
353 |
-
}
|
354 |
-
|
355 |
-
/**
|
356 |
-
* As we already have the metas in the lingotek_custom_fields options, we can
|
357 |
-
* remove them from the lingotek_content_type option.
|
358 |
-
*
|
359 |
-
* @since 1.4.11
|
360 |
-
*/
|
361 |
-
public function update_1_4_11_for_removing_custom_fields_from_postTypes_settings() {
|
362 |
-
$settings = get_option('lingotek_content_type');
|
363 |
-
foreach ($settings as $postType => &$postTypeSettings) {
|
364 |
-
unset($postTypeSettings['fields']['metas']);
|
365 |
-
}
|
366 |
-
update_option('lingotek_content_type', $settings, false);
|
367 |
-
}
|
368 |
-
|
369 |
-
/**
|
370 |
-
* Set the lingotek_custom_fields option as not autoloaded.
|
371 |
-
*
|
372 |
-
* @since 1.4.11
|
373 |
-
*/
|
374 |
-
public function update_1_4_11_for_removing_custom_fields_autoload() {
|
375 |
-
$settings = get_option('lingotek_custom_fields');
|
376 |
-
update_option('lingotek_custom_fields', 'fakeValueSoWeForceAutoloadToFalse', false);
|
377 |
-
update_option('lingotek_custom_fields', $settings, false);
|
378 |
-
}
|
379 |
-
|
380 |
-
/**
|
381 |
-
* Set the lingotek_community_resources option as not autoloaded.
|
382 |
-
*
|
383 |
-
* @since 1.4.11
|
384 |
-
*/
|
385 |
-
public function update_1_4_11_for_removing_community_resources_autoload() {
|
386 |
-
$settings = get_option('lingotek_community_resources');
|
387 |
-
update_option('lingotek_community_resources', 'fakeValueSoWeForceAutoloadToFalse', false);
|
388 |
-
update_option('lingotek_community_resources', $settings, false);
|
389 |
-
}
|
390 |
-
|
391 |
-
/**
|
392 |
-
* Set the lingotek_custom_fields option as not autoloaded.
|
393 |
-
*
|
394 |
-
* @since 1.4.13
|
395 |
-
*/
|
396 |
-
public function update_1_4_13_for_disabling_autoload_for_all_wpoptions()
|
397 |
-
{
|
398 |
-
$wpoptions = array(
|
399 |
-
'lingotek_base_url',
|
400 |
-
'lingotek_plugin_version',
|
401 |
-
'lingotek_community',
|
402 |
-
'lingotek_defaults',
|
403 |
-
'lingotek_profiles',
|
404 |
-
'lingotek_token',
|
405 |
-
);
|
406 |
-
foreach ($wpoptions as $wpoption) {
|
407 |
-
$settings = get_option($wpoption);
|
408 |
-
if ($wpoption !== false) {
|
409 |
-
update_option($wpoption, 'fakeValueSoWeForceAutoloadToFalse', false);
|
410 |
-
update_option($wpoption, $settings, false);
|
411 |
-
}
|
412 |
-
}
|
413 |
-
}
|
414 |
-
|
415 |
-
/**
|
416 |
* Return the plugin slug.
|
417 |
*
|
418 |
* @since 0.1
|
@@ -434,7 +442,7 @@ class Lingotek {
|
|
434 |
|
435 |
// If the single instance hasn't been set, set it now.
|
436 |
if ( null === self::$instance ) {
|
437 |
-
self::$instance = new self;
|
438 |
}
|
439 |
|
440 |
return self::$instance;
|
@@ -460,7 +468,7 @@ class Lingotek {
|
|
460 |
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
461 |
}
|
462 |
restore_current_blog();
|
463 |
-
} //
|
464 |
else {
|
465 |
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
466 |
}
|
@@ -484,7 +492,8 @@ class Lingotek {
|
|
484 |
global $polylang;
|
485 |
|
486 |
if ( isset( $polylang ) ) {
|
487 |
-
|
|
|
488 |
}
|
489 |
|
490 |
// default profiles.
|
@@ -495,6 +504,12 @@ class Lingotek {
|
|
495 |
// for the end point for the Lingoteck callback in rewrite rules.
|
496 |
// don't use flush_rewrite_rules at network activation. See #32471.
|
497 |
delete_option( 'rewrite_rules' );
|
|
|
|
|
|
|
|
|
|
|
|
|
498 |
}
|
499 |
|
500 |
/**
|
@@ -506,7 +521,7 @@ class Lingotek {
|
|
506 |
*/
|
507 |
public static function get_profiles() {
|
508 |
$default_profiles = self::get_default_profiles();
|
509 |
-
$profiles
|
510 |
if ( is_array( $profiles ) ) {
|
511 |
$profiles = array_merge( $default_profiles, $profiles );
|
512 |
} else {
|
@@ -515,9 +530,10 @@ class Lingotek {
|
|
515 |
|
516 |
// localize canned profile names.
|
517 |
foreach ( $profiles as $k => $v ) {
|
518 |
-
if ( in_array( $k,array( 'automatic', 'manual', 'disabled' ), true ) ) {
|
519 |
$profile_name = $profiles[ $k ]['name'];
|
520 |
-
|
|
|
521 |
}
|
522 |
}
|
523 |
|
@@ -572,7 +588,7 @@ class Lingotek {
|
|
572 |
$class = self::convert_class_to_file( $class );
|
573 |
foreach ( array( LINGOTEK_WORKFLOWS, LINGOTEK_INC, LINGOTEK_ADMIN_INC ) as $path ) {
|
574 |
if ( file_exists( $file = "$path/$class.php" ) ) {
|
575 |
-
require_once
|
576 |
break;
|
577 |
}
|
578 |
}
|
@@ -620,24 +636,25 @@ class Lingotek {
|
|
620 |
foreach ( $classes as $class ) {
|
621 |
$method = "Lingotek_$class";
|
622 |
|
623 |
-
add_filter( 'pll_' . strtolower( $class )
|
624 |
}
|
625 |
|
626 |
// add actions to posts, media and terms list.
|
627 |
// no need to load this if there is no language yet.
|
628 |
if ( $GLOBALS['polylang']->model->get_languages_list() ) {
|
629 |
-
$this->post_actions
|
630 |
-
$this->term_actions
|
631 |
$this->string_actions = new Lingotek_String_actions();
|
632 |
-
|
|
|
633 |
}
|
634 |
|
635 |
$this->utilities = new Lingotek_Utilities();
|
636 |
-
} //
|
637 |
elseif ( ! PLL_ADMIN && ! PLL_AJAX_ON_FRONT ) {
|
638 |
$GLOBALS['wp']->add_query_var( 'lingotek' );
|
639 |
|
640 |
-
$this->model
|
641 |
$this->callback = new Lingotek_Callback( $this->model );
|
642 |
}
|
643 |
}
|
@@ -673,10 +690,8 @@ class Lingotek {
|
|
673 |
|
674 |
if ( ! defined( 'POLYLANG_VERSION' ) ) {
|
675 |
add_action( 'all_admin_notices', array( &$this, 'pll_inactive_notice' ) );
|
676 |
-
|
677 |
} elseif ( version_compare( POLYLANG_VERSION, LINGOTEK_MIN_PLL_VERSION, '<' ) ) {
|
678 |
add_action( 'all_admin_notices', array( &$this, 'pll_old_notice' ) );
|
679 |
-
|
680 |
} elseif ( isset( $GLOBALS['polylang'] ) && ! count( $GLOBALS['polylang']->model->get_languages_list() ) ) {
|
681 |
self::create_first_language();
|
682 |
}
|
@@ -691,20 +706,22 @@ class Lingotek {
|
|
691 |
*/
|
692 |
public function pll_inactive_notice() {
|
693 |
$action = 'install-plugin';
|
694 |
-
$slug
|
695 |
-
$url
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
);
|
705 |
printf(
|
706 |
'<div class="error" style="height:55px"><p style="font-size:1.5em">%s<a href="%s">%s</a></p></div>',
|
707 |
-
esc_html( __( 'Lingotek Translation requires Polylang to work. ', 'lingotek-translation' ) ),
|
|
|
|
|
708 |
);
|
709 |
}
|
710 |
|
@@ -721,7 +738,7 @@ class Lingotek {
|
|
721 |
'<div class="error"><p>%s</p></div>',
|
722 |
sprintf(
|
723 |
esc_html( __( 'Lingotek Translation requires Polylang %s to work. Please upgrade Polylang.', 'lingotek-translation' ) ),
|
724 |
-
wp_kses( '<strong>' . LINGOTEK_MIN_PLL_VERSION . '</strong>'
|
725 |
)
|
726 |
);
|
727 |
}
|
@@ -731,13 +748,12 @@ class Lingotek {
|
|
731 |
*
|
732 |
* @since 0.2
|
733 |
*/
|
734 |
-
static
|
735 |
global $polylang;
|
736 |
|
737 |
$language;
|
738 |
-
if (file_exists( PLL_ADMIN_INC . '/languages.php' ) )
|
739 |
-
|
740 |
-
include( PLL_ADMIN_INC . '/languages.php' );
|
741 |
$locale = get_locale();
|
742 |
|
743 |
// attempts to set the default language from the current locale.
|
@@ -747,21 +763,23 @@ class Lingotek {
|
|
747 |
}
|
748 |
}
|
749 |
}
|
750 |
-
|
751 |
|
752 |
// defaults to en_US.
|
753 |
if ( empty( $language ) ) {
|
754 |
$language = array( 'en', 'en_US', 'English' );
|
755 |
}
|
756 |
|
757 |
-
|
758 |
-
$pll_model->
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
|
|
|
|
|
|
765 |
}
|
766 |
|
767 |
/**
|
@@ -776,8 +794,10 @@ class Lingotek {
|
|
776 |
public function pre_set_languages_list( $languages ) {
|
777 |
foreach ( $languages as $key => $language ) {
|
778 |
if ( is_object( $language ) ) {
|
779 |
-
|
780 |
-
|
|
|
|
|
781 |
}
|
782 |
}
|
783 |
|
@@ -800,16 +820,15 @@ class Lingotek {
|
|
800 |
}
|
801 |
|
802 |
/**
|
803 |
-
*
|
804 |
-
*
|
805 |
-
* @param string $class the class name.
|
806 |
*/
|
807 |
public static function convert_class_to_file( $class ) {
|
808 |
return str_replace( '_', '-', strtolower( substr( $class, 9 ) ) );
|
809 |
}
|
810 |
|
811 |
/**
|
812 |
-
* Maps a
|
813 |
*
|
814 |
* @since 0.3
|
815 |
*
|
@@ -837,10 +856,10 @@ class Lingotek {
|
|
837 |
}
|
838 |
|
839 |
/**
|
840 |
-
*
|
841 |
*
|
842 |
-
*
|
843 |
-
*
|
844 |
*/
|
845 |
public static function log( $data, $label = null ) {
|
846 |
if ( self::$logging ) {
|
@@ -872,28 +891,27 @@ class Lingotek {
|
|
872 |
),
|
873 |
array(
|
874 |
'label' => __( 'Activate Account', 'lingotek-translation' ),
|
875 |
-
'link'
|
876 |
),
|
877 |
);
|
878 |
|
879 |
$args = array(
|
880 |
-
'pointer'
|
881 |
-
'id'
|
882 |
'position' => array(
|
883 |
-
'edge'
|
884 |
'align' => 'left',
|
885 |
),
|
886 |
-
'width'
|
887 |
-
'title'
|
888 |
-
'content'
|
889 |
-
'buttons'
|
890 |
);
|
891 |
|
892 |
new Lingotek_Pointer( $args );
|
893 |
}
|
894 |
|
895 |
-
public function lingotek_professional_translation_pointer()
|
896 |
-
{
|
897 |
$content = __( 'Lingotek Professional Translation is now available!', 'lingotek-translation' );
|
898 |
|
899 |
$buttons = array(
|
@@ -902,21 +920,21 @@ class Lingotek {
|
|
902 |
),
|
903 |
array(
|
904 |
'label' => __( 'Learn More', 'lingotek-translation' ),
|
905 |
-
'link'
|
906 |
),
|
907 |
);
|
908 |
|
909 |
$args = array(
|
910 |
-
'pointer'
|
911 |
-
'id'
|
912 |
'position' => array(
|
913 |
-
'edge'
|
914 |
'align' => 'left',
|
915 |
),
|
916 |
-
'width'
|
917 |
-
'title'
|
918 |
-
'content'
|
919 |
-
'buttons'
|
920 |
);
|
921 |
|
922 |
new Lingotek_Pointer( $args );
|
@@ -925,33 +943,32 @@ class Lingotek {
|
|
925 |
public static function get_default_profiles() {
|
926 |
$default_profiles = array();
|
927 |
|
928 |
-
if (/**get_option('lingotek_automatic_enabled')*/ true) {
|
929 |
$default_profiles['automatic'] = array(
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
}
|
936 |
|
937 |
$default_profiles['manual'] = array(
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
$default_profiles['disabled'] = array(
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
|
949 |
return $default_profiles;
|
950 |
}
|
951 |
-
public static function mylog($message = '')
|
952 |
-
|
953 |
-
|
954 |
-
}
|
955 |
}
|
956 |
|
957 |
$GLOBALS['wp_lingotek'] = Lingotek::get_instance();
|
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.4.14
|
6 |
Author: Lingotek and Frédéric Demarle
|
7 |
Author uri: http://lingotek.com
|
8 |
Description: Lingotek offers convenient cloud-based localization and translation.
|
16 |
exit();
|
17 |
}
|
18 |
|
19 |
+
// Plugin version (should match above meta).
|
20 |
+
define( 'LINGOTEK_VERSION', '1.4.14' );
|
21 |
define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
|
22 |
+
// Plugin name as known by WordPress.
|
23 |
+
define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) );
|
24 |
+
// plugin slug (should match above meta: Text Domain).
|
25 |
+
define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );
|
26 |
+
// our directory.
|
27 |
+
define( 'LINGOTEK_DIR', dirname( __FILE__ ) );
|
28 |
define( 'LINGOTEK_INC', LINGOTEK_DIR . '/include' );
|
29 |
+
define( 'LINGOTEK_ADMIN_INC', LINGOTEK_DIR . '/admin' );
|
30 |
+
define( 'LINGOTEK_WORKFLOWS', LINGOTEK_ADMIN_INC . '/workflows' );
|
31 |
define( 'LINGOTEK_URL', plugins_url( '', __FILE__ ) );
|
32 |
define( 'BRIDGE_URL', 'https://marketplace.lingotek.com' );
|
33 |
|
34 |
class Lingotek {
|
35 |
/**
|
36 |
+
* Lingotek model.
|
37 |
*
|
38 |
+
* @var object
|
39 |
*/
|
40 |
public $model;
|
41 |
|
42 |
/**
|
43 |
+
* Callback method
|
44 |
*
|
45 |
+
* @var method
|
46 |
*/
|
47 |
public $callback;
|
48 |
|
49 |
/**
|
50 |
+
* Array to map Lingotek locales to WP locales.
|
51 |
+
* map as 'WP locale' => 'Lingotek locale'.
|
52 |
*
|
53 |
* TODO: update this list!!!!
|
54 |
+
*
|
55 |
+
* @var array
|
56 |
*/
|
57 |
public static $lingotek_locales = array(
|
58 |
+
'af' => 'af-ZA',
|
59 |
+
'ak' => 'ak-GH',
|
60 |
+
'am' => 'am-ET',
|
61 |
+
'ar' => 'ar',
|
62 |
+
'ar_AE' => 'ar-AE',
|
63 |
+
'ar_AF' => 'ar-AF',
|
64 |
+
'ar_BH' => 'ar-BH',
|
65 |
+
'ar_DZ' => 'ar-DZ',
|
66 |
+
'ar_EG' => 'ar-EG',
|
67 |
+
'ar_IQ' => 'ar-IQ',
|
68 |
+
'ar_JO' => 'ar-JO',
|
69 |
+
'ar_LY' => 'ar-LY',
|
70 |
+
'ar_MA' => 'ar-MA',
|
71 |
+
'ar_MR' => 'ar-MR',
|
72 |
+
'ar_OM' => 'ar-OM',
|
73 |
+
'ar_SA' => 'ar-SA',
|
74 |
+
'ar_SD' => 'ar-SD',
|
75 |
+
'ar_SY' => 'ar-SY',
|
76 |
+
'ar_TD' => 'ar-TD',
|
77 |
+
'ar_TN' => 'ar-TN',
|
78 |
+
'ar_UZ' => 'ar-UZ',
|
79 |
+
'ar_YE' => 'ar-YE',
|
80 |
+
'as' => 'as-IN',
|
81 |
+
'az' => 'az-AZ',
|
82 |
+
'ba' => 'ba-RU',
|
83 |
+
'bel' => 'be-BY',
|
84 |
+
'bg_BG' => 'bg-BG',
|
85 |
+
'bn_BD' => 'bn-BD',
|
86 |
+
'bo' => 'bo-CN',
|
87 |
+
'bs_BA' => 'bs-BA',
|
88 |
+
'ca' => 'ca-ES',
|
89 |
+
'ca_ES' => 'ca-ES',
|
90 |
+
'co' => 'co-FR',
|
91 |
+
'cs_CZ' => 'cs-CZ',
|
92 |
+
'cy' => 'cy-GB',
|
93 |
+
'cy_GB' => 'cy-GB',
|
94 |
+
'de_AT' => 'de-AT',
|
95 |
+
'da_DK' => 'da-DK',
|
96 |
+
'de_CH' => 'de-CH',
|
97 |
+
'de_DE' => 'de-DE',
|
98 |
+
'dv' => 'dv-MV',
|
99 |
+
'el' => 'el-GR',
|
100 |
+
'el_GR' => 'el-GR',
|
101 |
+
'en_AU' => 'en-AU',
|
102 |
+
'en_CA' => 'en-CA',
|
103 |
+
'en_GB' => 'en-GB',
|
104 |
+
'en_US' => 'en-US',
|
105 |
+
'en_IE' => 'en-IE',
|
106 |
+
'en_IN' => 'en-IN',
|
107 |
+
'en_ZA' => 'en-ZA',
|
108 |
+
'eo' => 'eo-FR',
|
109 |
+
'es_419' => 'es-419',
|
110 |
+
'es_AR' => 'es-AR',
|
111 |
+
'es_BO' => 'es-BO',
|
112 |
+
'es_CL' => 'es-CL',
|
113 |
+
'es_CO' => 'es-CO',
|
114 |
+
'es_ES' => 'es-ES',
|
115 |
+
'es_MX' => 'es-MX',
|
116 |
+
'es_PE' => 'es-PE',
|
117 |
+
'es_PR' => 'es-PR',
|
118 |
+
'es_VE' => 'es-VE',
|
119 |
+
'es_HN' => 'es-HN',
|
120 |
+
'es_CR' => 'es-CR',
|
121 |
+
'es_CU' => 'es-CU',
|
122 |
+
'es_DO' => 'es-DO',
|
123 |
+
'es_EC' => 'es-EC',
|
124 |
+
'es_GT' => 'es-GT',
|
125 |
+
'es_NI' => 'es-NI',
|
126 |
+
'es_PA' => 'es-PA',
|
127 |
+
'es_PY' => 'es-PY',
|
128 |
+
'es_SV' => 'es-SV',
|
129 |
+
'es_UY' => 'es-UY',
|
130 |
+
'es_US' => 'es-US',
|
131 |
+
'et' => 'et-EE',
|
132 |
+
'et_EE' => 'et-EE',
|
133 |
+
'eu' => 'eu-ES',
|
134 |
+
'fa_IR' => 'fa-IR',
|
135 |
+
'fi' => 'fi-FI',
|
136 |
+
'fi_FI' => 'fi-FI',
|
137 |
+
'fr_FR' => 'fr-FR',
|
138 |
+
'fr_BE' => 'fr-BE',
|
139 |
+
'fr_CA' => 'fr-CA',
|
140 |
+
'fr_CH' => 'fr-CH',
|
141 |
+
'fr_US' => 'fr-US',
|
142 |
+
'ga' => 'ga-IE',
|
143 |
+
'gd' => 'gd-GB',
|
144 |
+
'gl_ES' => 'gl-ES',
|
145 |
+
'gn' => 'gn-BO',
|
146 |
'haw_US' => 'haw-US',
|
147 |
+
'he_IL' => 'he-IL',
|
148 |
+
'hi_IN' => 'hi-IN',
|
149 |
+
'hr' => 'hr-HR',
|
150 |
+
'ht_HT' => 'ht-HT',
|
151 |
+
'hu_HU' => 'hu-HU',
|
152 |
+
'hy' => 'hy-AM',
|
153 |
+
'id_ID' => 'id-ID',
|
154 |
+
'is_IS' => 'is-IS',
|
155 |
+
'it_IT' => 'it-IT',
|
156 |
+
'it_CH' => 'it-CH',
|
157 |
+
'ja' => 'ja-JP',
|
158 |
+
'ja_JP' => 'ja-JP',
|
159 |
+
'jv_ID' => 'jv-ID',
|
160 |
+
'ka_GE' => 'ka-GE',
|
161 |
+
'kin' => 'kin-RW',
|
162 |
+
'kk' => 'kk-KZ',
|
163 |
+
'kn' => 'kn-IN',
|
164 |
+
'ko_KR' => 'ko-KR',
|
165 |
+
'ky_KY' => 'ky-KG',
|
166 |
+
'lb_LU' => 'lb-LU',
|
167 |
+
'lo' => 'lo-LA',
|
168 |
+
'lt_LT' => 'lt-LT',
|
169 |
+
'lv' => 'lv-LV',
|
170 |
+
'lv_LV' => 'lv-LV',
|
171 |
+
'mg_MG' => 'mg-MG',
|
172 |
+
'mk_MK' => 'mk-MK',
|
173 |
+
'ml_IN' => 'ml-IN',
|
174 |
+
'mn' => 'mn-MN',
|
175 |
+
'mr' => 'mr-IN',
|
176 |
+
'ms_MY' => 'ms-MY',
|
177 |
+
'mt_MT' => 'mt-MT',
|
178 |
+
'my_MM' => 'my-MM',
|
179 |
+
'ne_NP' => 'ne-NP',
|
180 |
+
'nl_BE' => 'nl-BE',
|
181 |
+
'nl_NL' => 'nl-NL',
|
182 |
+
'nn_NO' => 'nn-NO',
|
183 |
+
'no_NO' => 'no-NO',
|
184 |
+
'pa_IN' => 'pa-IN',
|
185 |
+
'pl_PL' => 'pl-PL',
|
186 |
+
'ps' => 'ps-AF',
|
187 |
+
'pt_BR' => 'pt-BR',
|
188 |
+
'pt_PT' => 'pt-PT',
|
189 |
+
'ro_RO' => 'ro-RO',
|
190 |
+
'ru_RU' => 'ru-RU',
|
191 |
+
'sa_IN' => 'sa-IN',
|
192 |
+
'sd_PK' => 'sd-PK',
|
193 |
+
'si_LK' => 'si-LK',
|
194 |
+
'sk_SK' => 'sk-SK',
|
195 |
+
'sl_SI' => 'sl-SI',
|
196 |
+
'so_SO' => 'so-SO',
|
197 |
+
'sq' => 'sq-SQ',
|
198 |
+
'sr_RS' => 'sr-CS',
|
199 |
+
'su_ID' => 'su-ID',
|
200 |
+
'sv_SE' => 'sv-SE',
|
201 |
+
'sw' => 'sw-TZ',
|
202 |
+
'sw_TZ' => 'sw-TZ',
|
203 |
+
'ta_IN' => 'ta-IN',
|
204 |
+
'te' => 'te-IN',
|
205 |
+
'tg' => 'tg-TJ',
|
206 |
+
'th' => 'th-TH',
|
207 |
+
'th_TH' => 'th-TH',
|
208 |
+
'tir' => 'ti-ER',
|
209 |
+
'tl' => 'tl-PH',
|
210 |
+
'tr_TR' => 'tr-TR',
|
211 |
+
'ug_CN' => 'ug-CN',
|
212 |
+
'uk' => 'uk-UA',
|
213 |
+
'uk_UA' => 'uk-UA',
|
214 |
+
'ur' => 'ur-PK',
|
215 |
+
'ur_PK' => 'ur-PK',
|
216 |
+
'uz_UZ' => 'uz-UZ',
|
217 |
+
'vi' => 'vi-VN',
|
218 |
+
'vi_VN' => 'vi-VN',
|
219 |
+
'zh_CN' => 'zh-CN',
|
220 |
+
'zh_HK' => 'zh-HK',
|
221 |
+
'zh_TW' => 'zh-TW',
|
222 |
+
'zh_SG' => 'zh-SG',
|
223 |
);
|
224 |
|
225 |
|
226 |
/**
|
227 |
+
* Verifies that a lingotek-locale (ie. es-ES) is an allowed
|
228 |
* TMS locale.
|
229 |
*
|
230 |
* @param string $lingotek_locale
|
231 |
* @return boolean
|
232 |
*/
|
233 |
+
public static function is_allowed_tms_locale( $lingotek_locale ) {
|
234 |
+
return isset( self::$lingotek_locales[ $lingotek_locale ] ) || in_array( $lingotek_locale, self::$lingotek_locales );
|
|
|
235 |
}
|
236 |
|
237 |
/**
|
281 |
// loads the admin side of Polylang for the dashboard.
|
282 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $action ) && 'lingotek_language' === $action ) {
|
283 |
define( 'PLL_AJAX_ON_FRONT', false );
|
284 |
+
|
285 |
add_filter( 'pll_model', array( &$this, 'PLL_Admin_Model' ) );
|
286 |
}
|
287 |
|
288 |
+
// Autoload classes.
|
289 |
+
spl_autoload_register( array( &$this, 'autoload' ) );
|
290 |
|
291 |
// init.
|
292 |
add_filter( 'pll_model', array( &$this, 'pll_model' ) );
|
330 |
// If any update happened, inform the user and update the version.
|
331 |
if ( $updatesHaveRun ) {
|
332 |
update_option( 'lingotek_plugin_version', LINGOTEK_VERSION, false );
|
333 |
+
add_action(
|
334 |
+
'admin_notices',
|
335 |
+
function () {
|
336 |
+
echo '<div class="notice notice-success is-dismissible">
|
337 |
<p>' . __( 'Upgrades for the lingotek translation module have completed.', 'lingotek-translation' ) . '</p>
|
338 |
</div>';
|
339 |
+
}
|
340 |
+
);
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Check if we need to run these updates.
|
346 |
+
*
|
347 |
+
* It will check that the installed version is newer than the db one, even if we
|
348 |
+
* had skipped any version, and ensures we don't run any update if we already did.
|
349 |
+
*
|
350 |
+
* @param $versionUpdates
|
351 |
+
* The version where these updates were introduced.
|
352 |
+
* @return bool
|
353 |
+
* true if needs to run, false otherwise
|
354 |
+
*
|
355 |
+
* @since 1.4.11
|
356 |
+
*/
|
357 |
+
public function needs_to_run_updates( $versionUpdates ) {
|
358 |
+
$db_version = get_option( 'lingotek_plugin_version' );
|
359 |
+
return ( $db_version !== false &&
|
360 |
+
version_compare( LINGOTEK_VERSION, $versionUpdates, '>=' ) &&
|
361 |
+
version_compare( $versionUpdates, $db_version, '>' ) );
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* As we already have the metas in the lingotek_custom_fields options, we can
|
366 |
+
* remove them from the lingotek_content_type option.
|
367 |
+
*
|
368 |
+
* @since 1.4.11
|
369 |
+
*/
|
370 |
+
public function update_1_4_11_for_removing_custom_fields_from_postTypes_settings() {
|
371 |
+
$settings = get_option( 'lingotek_content_type' );
|
372 |
+
foreach ( $settings as $postType => &$postTypeSettings ) {
|
373 |
+
unset( $postTypeSettings['fields']['metas'] );
|
374 |
+
}
|
375 |
+
update_option( 'lingotek_content_type', $settings, false );
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Set the lingotek_custom_fields option as not autoloaded.
|
380 |
+
*
|
381 |
+
* @since 1.4.11
|
382 |
+
*/
|
383 |
+
public function update_1_4_11_for_removing_custom_fields_autoload() {
|
384 |
+
$settings = get_option( 'lingotek_custom_fields' );
|
385 |
+
update_option( 'lingotek_custom_fields', 'fakeValueSoWeForceAutoloadToFalse', false );
|
386 |
+
update_option( 'lingotek_custom_fields', $settings, false );
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Set the lingotek_community_resources option as not autoloaded.
|
391 |
+
*
|
392 |
+
* @since 1.4.11
|
393 |
+
*/
|
394 |
+
public function update_1_4_11_for_removing_community_resources_autoload() {
|
395 |
+
$settings = get_option( 'lingotek_community_resources' );
|
396 |
+
update_option( 'lingotek_community_resources', 'fakeValueSoWeForceAutoloadToFalse', false );
|
397 |
+
update_option( 'lingotek_community_resources', $settings, false );
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Set the lingotek_custom_fields option as not autoloaded.
|
402 |
+
*
|
403 |
+
* @since 1.4.13
|
404 |
+
*/
|
405 |
+
public function update_1_4_13_for_disabling_autoload_for_all_wpoptions() {
|
406 |
+
$wpoptions = array(
|
407 |
+
'lingotek_base_url',
|
408 |
+
'lingotek_plugin_version',
|
409 |
+
'lingotek_community',
|
410 |
+
'lingotek_defaults',
|
411 |
+
'lingotek_profiles',
|
412 |
+
'lingotek_token',
|
413 |
+
);
|
414 |
+
foreach ( $wpoptions as $wpoption ) {
|
415 |
+
$settings = get_option( $wpoption );
|
416 |
+
if ( $wpoption !== false ) {
|
417 |
+
update_option( $wpoption, 'fakeValueSoWeForceAutoloadToFalse', false );
|
418 |
+
update_option( $wpoption, $settings, false );
|
419 |
+
}
|
420 |
}
|
421 |
}
|
422 |
|
423 |
+
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
* Return the plugin slug.
|
425 |
*
|
426 |
* @since 0.1
|
442 |
|
443 |
// If the single instance hasn't been set, set it now.
|
444 |
if ( null === self::$instance ) {
|
445 |
+
self::$instance = new self();
|
446 |
}
|
447 |
|
448 |
return self::$instance;
|
468 |
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
469 |
}
|
470 |
restore_current_blog();
|
471 |
+
} //end if
|
472 |
else {
|
473 |
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
474 |
}
|
492 |
global $polylang;
|
493 |
|
494 |
if ( isset( $polylang ) ) {
|
495 |
+
// To add lingotek_locale property.
|
496 |
+
$polylang->model->clean_languages_cache();
|
497 |
}
|
498 |
|
499 |
// default profiles.
|
504 |
// for the end point for the Lingoteck callback in rewrite rules.
|
505 |
// don't use flush_rewrite_rules at network activation. See #32471.
|
506 |
delete_option( 'rewrite_rules' );
|
507 |
+
|
508 |
+
// Update the option for the installed version if it's the first time is activated,
|
509 |
+
// so updates are not attempted to run when they shouldn't.
|
510 |
+
if ( ! get_option( 'lingotek_plugin_version', false ) ) {
|
511 |
+
update_option( 'lingotek_plugin_version', LINGOTEK_VERSION );
|
512 |
+
}
|
513 |
}
|
514 |
|
515 |
/**
|
521 |
*/
|
522 |
public static function get_profiles() {
|
523 |
$default_profiles = self::get_default_profiles();
|
524 |
+
$profiles = get_option( 'lingotek_profiles' );
|
525 |
if ( is_array( $profiles ) ) {
|
526 |
$profiles = array_merge( $default_profiles, $profiles );
|
527 |
} else {
|
530 |
|
531 |
// localize canned profile names.
|
532 |
foreach ( $profiles as $k => $v ) {
|
533 |
+
if ( in_array( $k, array( 'automatic', 'manual', 'disabled' ), true ) ) {
|
534 |
$profile_name = $profiles[ $k ]['name'];
|
535 |
+
// Localize canned profile names.
|
536 |
+
$profiles[ $k ]['name'] = __( $profile_name, 'lingotek-translation' );
|
537 |
}
|
538 |
}
|
539 |
|
588 |
$class = self::convert_class_to_file( $class );
|
589 |
foreach ( array( LINGOTEK_WORKFLOWS, LINGOTEK_INC, LINGOTEK_ADMIN_INC ) as $path ) {
|
590 |
if ( file_exists( $file = "$path/$class.php" ) ) {
|
591 |
+
require_once $file;
|
592 |
break;
|
593 |
}
|
594 |
}
|
636 |
foreach ( $classes as $class ) {
|
637 |
$method = "Lingotek_$class";
|
638 |
|
639 |
+
add_filter( 'pll_' . strtolower( $class ), array( &$this, $method ) );
|
640 |
}
|
641 |
|
642 |
// add actions to posts, media and terms list.
|
643 |
// no need to load this if there is no language yet.
|
644 |
if ( $GLOBALS['polylang']->model->get_languages_list() ) {
|
645 |
+
$this->post_actions = new Lingotek_Post_Actions();
|
646 |
+
$this->term_actions = new Lingotek_Term_Actions();
|
647 |
$this->string_actions = new Lingotek_String_actions();
|
648 |
+
// Autoloads class.
|
649 |
+
new Lingotek_Workflow_Factory();
|
650 |
}
|
651 |
|
652 |
$this->utilities = new Lingotek_Utilities();
|
653 |
+
} //end if
|
654 |
elseif ( ! PLL_ADMIN && ! PLL_AJAX_ON_FRONT ) {
|
655 |
$GLOBALS['wp']->add_query_var( 'lingotek' );
|
656 |
|
657 |
+
$this->model = new Lingotek_Model();
|
658 |
$this->callback = new Lingotek_Callback( $this->model );
|
659 |
}
|
660 |
}
|
690 |
|
691 |
if ( ! defined( 'POLYLANG_VERSION' ) ) {
|
692 |
add_action( 'all_admin_notices', array( &$this, 'pll_inactive_notice' ) );
|
|
|
693 |
} elseif ( version_compare( POLYLANG_VERSION, LINGOTEK_MIN_PLL_VERSION, '<' ) ) {
|
694 |
add_action( 'all_admin_notices', array( &$this, 'pll_old_notice' ) );
|
|
|
695 |
} elseif ( isset( $GLOBALS['polylang'] ) && ! count( $GLOBALS['polylang']->model->get_languages_list() ) ) {
|
696 |
self::create_first_language();
|
697 |
}
|
706 |
*/
|
707 |
public function pll_inactive_notice() {
|
708 |
$action = 'install-plugin';
|
709 |
+
$slug = 'polylang';
|
710 |
+
$url = wp_nonce_url(
|
711 |
+
add_query_arg(
|
712 |
+
array(
|
713 |
+
'action' => $action,
|
714 |
+
'plugin' => $slug,
|
715 |
+
),
|
716 |
+
admin_url( 'update.php' )
|
717 |
+
),
|
718 |
+
$action . '_' . $slug
|
719 |
);
|
720 |
printf(
|
721 |
'<div class="error" style="height:55px"><p style="font-size:1.5em">%s<a href="%s">%s</a></p></div>',
|
722 |
+
esc_html( __( 'Lingotek Translation requires Polylang to work. ', 'lingotek-translation' ) ),
|
723 |
+
esc_url( $url ),
|
724 |
+
esc_html( __( 'Install Polylang', 'lingotek-translation' ) )
|
725 |
);
|
726 |
}
|
727 |
|
738 |
'<div class="error"><p>%s</p></div>',
|
739 |
sprintf(
|
740 |
esc_html( __( 'Lingotek Translation requires Polylang %s to work. Please upgrade Polylang.', 'lingotek-translation' ) ),
|
741 |
+
wp_kses( '<strong>' . LINGOTEK_MIN_PLL_VERSION . '</strong>', $allowed_html )
|
742 |
)
|
743 |
);
|
744 |
}
|
748 |
*
|
749 |
* @since 0.2
|
750 |
*/
|
751 |
+
protected static function create_first_language() {
|
752 |
global $polylang;
|
753 |
|
754 |
$language;
|
755 |
+
if ( file_exists( PLL_ADMIN_INC . '/languages.php' ) ) {
|
756 |
+
include PLL_ADMIN_INC . '/languages.php';
|
|
|
757 |
$locale = get_locale();
|
758 |
|
759 |
// attempts to set the default language from the current locale.
|
763 |
}
|
764 |
}
|
765 |
}
|
|
|
766 |
|
767 |
// defaults to en_US.
|
768 |
if ( empty( $language ) ) {
|
769 |
$language = array( 'en', 'en_US', 'English' );
|
770 |
}
|
771 |
|
772 |
+
// Need admin model.
|
773 |
+
$pll_model = new PLL_Admin_Model( $polylang->options );
|
774 |
+
$pll_model->add_language(
|
775 |
+
array(
|
776 |
+
'slug' => $language[0],
|
777 |
+
'locale' => $language[1],
|
778 |
+
'name' => $language[2],
|
779 |
+
'rtl' => isset( $language[3] ) ? 1 : 0,
|
780 |
+
'term_group' => 0,
|
781 |
+
)
|
782 |
+
);
|
783 |
}
|
784 |
|
785 |
/**
|
794 |
public function pre_set_languages_list( $languages ) {
|
795 |
foreach ( $languages as $key => $language ) {
|
796 |
if ( is_object( $language ) ) {
|
797 |
+
// Backward compatibility with Polylang < 1.7.3.
|
798 |
+
$languages[ $key ]->lingotek_locale = self::map_to_lingotek_locale( $language->locale );
|
799 |
+
} else {
|
800 |
+
$languages[ $key ]['lingotek_locale'] = self::map_to_lingotek_locale( $language['locale'] );
|
801 |
}
|
802 |
}
|
803 |
|
820 |
}
|
821 |
|
822 |
/**
|
823 |
+
* Converts the class name to the appropriate file name for class loading.
|
824 |
+
* @param string $class the class name.
|
|
|
825 |
*/
|
826 |
public static function convert_class_to_file( $class ) {
|
827 |
return str_replace( '_', '-', strtolower( substr( $class, 9 ) ) );
|
828 |
}
|
829 |
|
830 |
/**
|
831 |
+
* Maps a WordPress locale to a Lingotek locale
|
832 |
*
|
833 |
* @since 0.3
|
834 |
*
|
856 |
}
|
857 |
|
858 |
/**
|
859 |
+
* Writes data to a log.
|
860 |
*
|
861 |
+
* @param multiple $data the data to be written.
|
862 |
+
* @param string $label the label to identify the data.
|
863 |
*/
|
864 |
public static function log( $data, $label = null ) {
|
865 |
if ( self::$logging ) {
|
891 |
),
|
892 |
array(
|
893 |
'label' => __( 'Activate Account', 'lingotek-translation' ),
|
894 |
+
'link' => admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=new' ),
|
895 |
),
|
896 |
);
|
897 |
|
898 |
$args = array(
|
899 |
+
'pointer' => 'lingotek-translation',
|
900 |
+
'id' => 'toplevel_page_lingotek-translation',
|
901 |
'position' => array(
|
902 |
+
'edge' => 'bottom',
|
903 |
'align' => 'left',
|
904 |
),
|
905 |
+
'width' => 380,
|
906 |
+
'title' => __( 'Congratulations!', 'lingotek-translation' ),
|
907 |
+
'content' => $content,
|
908 |
+
'buttons' => $buttons,
|
909 |
);
|
910 |
|
911 |
new Lingotek_Pointer( $args );
|
912 |
}
|
913 |
|
914 |
+
public function lingotek_professional_translation_pointer() {
|
|
|
915 |
$content = __( 'Lingotek Professional Translation is now available!', 'lingotek-translation' );
|
916 |
|
917 |
$buttons = array(
|
920 |
),
|
921 |
array(
|
922 |
'label' => __( 'Learn More', 'lingotek-translation' ),
|
923 |
+
'link' => admin_url( 'admin.php?page=lingotek-translation_tutorial&sm=content&tutorial=ltk-prof#ltk-prof-trans-header' ),
|
924 |
),
|
925 |
);
|
926 |
|
927 |
$args = array(
|
928 |
+
'pointer' => 'lingotek-professional-translation',
|
929 |
+
'id' => 'toplevel_page_lingotek-translation',
|
930 |
'position' => array(
|
931 |
+
'edge' => 'bottom',
|
932 |
'align' => 'left',
|
933 |
),
|
934 |
+
'width' => 380,
|
935 |
+
'title' => __( 'New Feature', 'lingotek-translation' ),
|
936 |
+
'content' => $content,
|
937 |
+
'buttons' => $buttons,
|
938 |
);
|
939 |
|
940 |
new Lingotek_Pointer( $args );
|
943 |
public static function get_default_profiles() {
|
944 |
$default_profiles = array();
|
945 |
|
946 |
+
if ( /**get_option('lingotek_automatic_enabled')*/ true ) {
|
947 |
$default_profiles['automatic'] = array(
|
948 |
+
'profile' => 'automatic',
|
949 |
+
'name' => __( 'Automatic', 'lingotek-translation' ),
|
950 |
+
'upload' => 'automatic',
|
951 |
+
'download' => 'automatic',
|
952 |
+
);
|
953 |
}
|
954 |
|
955 |
$default_profiles['manual'] = array(
|
956 |
+
'profile' => 'manual',
|
957 |
+
'name' => __( 'Manual', 'lingotek-translation' ),
|
958 |
+
'upload' => 'manual',
|
959 |
+
'download' => 'manual',
|
960 |
+
);
|
961 |
+
|
962 |
$default_profiles['disabled'] = array(
|
963 |
+
'profile' => 'disabled',
|
964 |
+
'name' => __( 'Disabled', 'lingotek-translation' ),
|
965 |
+
);
|
966 |
|
967 |
return $default_profiles;
|
968 |
}
|
969 |
+
public static function mylog( $message = '' ) {
|
970 |
+
file_put_contents( 'php://stdout', "$message", FILE_APPEND );
|
971 |
+
}
|
|
|
972 |
}
|
973 |
|
974 |
$GLOBALS['wp_lingotek'] = Lingotek::get_instance();
|
phpcs.xml
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<ruleset name="WordPress Coding Standards based custom ruleset for your plugin">
|
3 |
+
<description>Generally-applicable sniffs for WordPress plugins.</description>
|
4 |
+
|
5 |
+
<!-- What to scan -->
|
6 |
+
<file>.</file>
|
7 |
+
<exclude-pattern>/vendor/</exclude-pattern>
|
8 |
+
<exclude-pattern>/node_modules/</exclude-pattern>
|
9 |
+
|
10 |
+
<!-- How to scan -->
|
11 |
+
<!-- Usage instructions: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage -->
|
12 |
+
<!-- Annotated ruleset: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml -->
|
13 |
+
<arg value="sp"/> <!-- Show sniff and progress -->
|
14 |
+
<arg name="basepath" value="./"/><!-- Strip the file paths down to the relevant bit -->
|
15 |
+
<arg name="colors"/>
|
16 |
+
<arg name="extensions" value="php"/>
|
17 |
+
<arg name="parallel" value="8"/><!-- Enables parallel processing when available for faster results. -->
|
18 |
+
|
19 |
+
<!-- Rules: Check PHP version compatibility -->
|
20 |
+
<!-- https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions -->
|
21 |
+
<config name="testVersion" value="5.6-"/>
|
22 |
+
<!-- https://github.com/PHPCompatibility/PHPCompatibilityWP -->
|
23 |
+
<rule ref="PHPCompatibilityWP"/>
|
24 |
+
|
25 |
+
<!-- Rules: WordPress Coding Standards -->
|
26 |
+
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards -->
|
27 |
+
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties -->
|
28 |
+
<config name="minimum_supported_wp_version" value="4.6"/>
|
29 |
+
<rule ref="WordPress"/>
|
30 |
+
<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
|
31 |
+
<properties>
|
32 |
+
<!-- Value: replace the function, class, and variable prefixes used. Separate multiple prefixes with a comma. -->
|
33 |
+
<property name="prefixes" type="array" value="lingotek"/>
|
34 |
+
</properties>
|
35 |
+
</rule>
|
36 |
+
<rule ref="WordPress.WP.I18n">
|
37 |
+
<properties>
|
38 |
+
<!-- Value: replace the text domain used. -->
|
39 |
+
<property name="text_domain" type="array" value="lingotek-translation"/>
|
40 |
+
</properties>
|
41 |
+
</rule>
|
42 |
+
<rule ref="WordPress.WhiteSpace.ControlStructureSpacing">
|
43 |
+
<properties>
|
44 |
+
<property name="blank_line_check" value="true"/>
|
45 |
+
</properties>
|
46 |
+
</rule>
|
47 |
+
|
48 |
+
<!-- ltk: Starting Lingotek customizations. We should include these rules, but let's go step by step. -->
|
49 |
+
<rule ref="Generic.Commenting">
|
50 |
+
<exclude name="Generic.Commenting.DocComment.ShortNotCapital"/>
|
51 |
+
</rule>
|
52 |
+
<rule ref="Squiz.Commenting">
|
53 |
+
<exclude name="Squiz.Commenting.FunctionComment.Missing" />
|
54 |
+
<exclude name="Squiz.Commenting.InlineComment" />
|
55 |
+
<exclude name="Squiz.Commenting.FunctionComment.MissingParamComment" />
|
56 |
+
<exclude name="Squiz.Commenting.FileComment.Missing"/>
|
57 |
+
<exclude name="Squiz.Commenting.FunctionComment.MissingParamTag"/>
|
58 |
+
</rule>
|
59 |
+
<rule ref="WordPress.Files.FileName">
|
60 |
+
<exclude name="WordPress.Files.FileName.InvalidClassFileName" />
|
61 |
+
</rule>
|
62 |
+
<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
|
63 |
+
<exclude name="WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound" />
|
64 |
+
<exclude name="WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound" />
|
65 |
+
</rule>
|
66 |
+
<!-- ltk: These are dangerous to change, as involve method renaming.' -->
|
67 |
+
<rule ref="PSR2.Methods.MethodDeclaration">
|
68 |
+
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
|
69 |
+
</rule>
|
70 |
+
<rule ref="WordPress.NamingConventions.ValidFunctionName">
|
71 |
+
<exclude name="WordPress.NamingConventions.ValidFunctionName" />
|
72 |
+
</rule>
|
73 |
+
<rule ref="WordPress.PHP.DisallowShortTernary.Found">
|
74 |
+
<type>warning</type>
|
75 |
+
</rule>
|
76 |
+
<rule ref="WordPress.PHP.StrictComparisons.LooseComparison">
|
77 |
+
<type>warning</type>
|
78 |
+
</rule>
|
79 |
+
</ruleset>
|
phpunit.xml
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<phpunit
|
3 |
+
bootstrap="tests/bootstrap.php"
|
4 |
+
backupGlobals="false"
|
5 |
+
colors="true"
|
6 |
+
convertErrorsToExceptions="true"
|
7 |
+
convertNoticesToExceptions="true"
|
8 |
+
convertWarningsToExceptions="true"
|
9 |
+
>
|
10 |
+
<testsuites>
|
11 |
+
<testsuite name="integration">
|
12 |
+
<directory prefix="test-" suffix=".php">./tests/</directory>
|
13 |
+
</testsuite>
|
14 |
+
</testsuites>
|
15 |
+
</phpunit>
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: chouby, smithworx, erichie, robertdhanna, ipoulsen, elliothanna, l
|
|
3 |
Donate link: http://lingotek.com/
|
4 |
Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
|
5 |
Requires at least: 3.8
|
6 |
-
Tested up to: 5.
|
7 |
-
Stable tag: 1.4.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -122,6 +122,9 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
|
|
122 |
5. The Lingotek Translation plugin provides the ability to Copy, Translate, and Ignore each specific custom field. Our plugin supports Wordpress custom fields and advanced custom fields.
|
123 |
|
124 |
== Changelog ==
|
|
|
|
|
|
|
125 |
= 1.4.13 (2021-6-14) =
|
126 |
* Updated code base to be compatible with PHP 8
|
127 |
* Updated cancel action behavior to be more consistent.
|
3 |
Donate link: http://lingotek.com/
|
4 |
Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
|
5 |
Requires at least: 3.8
|
6 |
+
Tested up to: 5.7
|
7 |
+
Stable tag: 1.4.14
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
122 |
5. The Lingotek Translation plugin provides the ability to Copy, Translate, and Ignore each specific custom field. Our plugin supports Wordpress custom fields and advanced custom fields.
|
123 |
|
124 |
== Changelog ==
|
125 |
+
= 1.4.14 (2021-07-07) =
|
126 |
+
* Fixed WordPress: consume the download_interim_translation callback
|
127 |
+
|
128 |
= 1.4.13 (2021-6-14) =
|
129 |
* Updated code base to be compatible with PHP 8
|
130 |
* Updated cancel action behavior to be more consistent.
|
tests/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Devs Quality Assurance
|
2 |
+
|
3 |
+
## PHPUnit Setup
|
4 |
+
|
5 |
+
Note: my setup is based on roots/bedrock, not a basic WordPress, so instructions might not be 100% accurate.
|
6 |
+
|
7 |
+
Warning: This runs on the host, not on ddev.
|
8 |
+
|
9 |
+
_TODO_: Adapt this so it runs on ddev.
|
10 |
+
|
11 |
+
_TODO_: Edit the release process. We don't want the /tests or /bin folder at all in the releases.
|
12 |
+
|
13 |
+
|
14 |
+
```
|
15 |
+
composer global require phpunit/phpunit:^7.3
|
16 |
+
|
17 |
+
bash bin/install-wp-tests.sh wordpress_test root 'mysql-pwd' localhost latest
|
18 |
+
```
|
19 |
+
|
20 |
+
## Running the tests
|
21 |
+
|
22 |
+
In a bedrocks setup is
|
23 |
+
```
|
24 |
+
../../../../vendor/bin/phpunit
|
25 |
+
```
|
26 |
+
|
27 |
+
# PHPCS
|
28 |
+
|
29 |
+
## Setup
|
30 |
+
|
31 |
+
```
|
32 |
+
composer global require wp-coding-standards/wpcs
|
33 |
+
composer global require phpcompatibility/php-compatibility
|
34 |
+
composer global require phpcompatibility/phpcompatibility-paragonie
|
35 |
+
composer global require phpcompatibility/phpcompatibility-wp
|
36 |
+
phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs,$HOME/.composer/vendor/phpcompatibility/php-compatibility,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-paragonie,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-wp
|
37 |
+
```
|
38 |
+
|
39 |
+
## Running checks
|
40 |
+
|
41 |
+
Just run `phpcs` from the plugin folder.
|
42 |
+
|
43 |
+
## Future work
|
44 |
+
|
45 |
+
Some rules from the _WP Standards_ have been disabled, as they involve renaming functions, files, etc that might
|
46 |
+
be dangerous.
|
tests/bootstrap.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* PHPUnit bootstrap file.
|
4 |
+
*
|
5 |
+
* @package Lingotek_Translation
|
6 |
+
*/
|
7 |
+
|
8 |
+
if ( PHP_MAJOR_VERSION >= 8 ) {
|
9 |
+
echo 'The scaffolded tests cannot currently be run on PHP 8.0+. See https://github.com/wp-cli/scaffold-command/issues/285' . PHP_EOL; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
10 |
+
exit( 1 );
|
11 |
+
}
|
12 |
+
|
13 |
+
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
14 |
+
|
15 |
+
if ( ! $_tests_dir ) {
|
16 |
+
$_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib';
|
17 |
+
}
|
18 |
+
|
19 |
+
if ( ! file_exists( "{$_tests_dir}/includes/functions.php" ) ) {
|
20 |
+
echo "Could not find {$_tests_dir}/includes/functions.php, have you run bin/install-wp-tests.sh ?" . PHP_EOL; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
21 |
+
exit( 1 );
|
22 |
+
}
|
23 |
+
|
24 |
+
// Give access to tests_add_filter() function.
|
25 |
+
require_once "{$_tests_dir}/includes/functions.php";
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Manually load the plugin being tested.
|
29 |
+
*/
|
30 |
+
function _manually_load_plugin() {
|
31 |
+
require dirname( dirname( __FILE__ ) ) . '/lingotek.php';
|
32 |
+
}
|
33 |
+
|
34 |
+
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
35 |
+
|
36 |
+
$GLOBALS['wp_tests_options'] = array(
|
37 |
+
'active_plugins' => array( 'lingotek-translation' ),
|
38 |
+
);
|
39 |
+
|
40 |
+
// Start up the WP testing environment.
|
41 |
+
require "{$_tests_dir}/includes/bootstrap.php";
|
42 |
+
|
tests/test-lingotek-installation.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class LingotekInstallationTest
|
4 |
+
*
|
5 |
+
* @package Lingotek_Translation
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Sample test case.
|
10 |
+
*/
|
11 |
+
class LingotekInstallationTest extends WP_UnitTestCase {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Tests the initial options are set on activation.
|
15 |
+
*
|
16 |
+
* @test
|
17 |
+
* @dataProvider getInitialOptions
|
18 |
+
*
|
19 |
+
* @param string $option The option name.
|
20 |
+
* @param mixed $value The expected value.
|
21 |
+
*/
|
22 |
+
public function InitialOptionsAreSet( $option, $value ) {
|
23 |
+
$this->ltk = new Lingotek();
|
24 |
+
$this->ltk->activate();
|
25 |
+
|
26 |
+
$this->assertSame( $value, get_option( $option ) );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Tests the initial profiles are created on activation.
|
31 |
+
*
|
32 |
+
* @test
|
33 |
+
*/
|
34 |
+
public function InitialProfilesAreCreated() {
|
35 |
+
$this->ltk = new Lingotek();
|
36 |
+
$this->ltk->activate();
|
37 |
+
|
38 |
+
$profiles = get_option( 'lingotek_profiles', false );
|
39 |
+
|
40 |
+
$this->assertEquals( 3, count( $profiles ) );
|
41 |
+
$this->assertTrue( isset( $profiles['automatic'] ) );
|
42 |
+
$this->assertTrue( isset( $profiles['manual'] ) );
|
43 |
+
$this->assertTrue( isset( $profiles['disabled'] ) );
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Data provider for initial options values.
|
48 |
+
*
|
49 |
+
* @see ::InitialOptionsAreSet
|
50 |
+
*/
|
51 |
+
public function getInitialOptions() {
|
52 |
+
yield 'lingotek_plugin_version' => array( 'lingotek_plugin_version', LINGOTEK_VERSION );
|
53 |
+
yield 'lingotek_profiles' => array(
|
54 |
+
'lingotek_profiles',
|
55 |
+
array(
|
56 |
+
'automatic' => array(
|
57 |
+
'profile' => 'automatic',
|
58 |
+
'name' => 'Automatic',
|
59 |
+
'upload' => 'automatic',
|
60 |
+
'download' => 'automatic',
|
61 |
+
),
|
62 |
+
'manual' => array(
|
63 |
+
'profile' => 'manual',
|
64 |
+
'name' => 'Manual',
|
65 |
+
'upload' => 'manual',
|
66 |
+
'download' => 'manual',
|
67 |
+
),
|
68 |
+
'disabled' => array(
|
69 |
+
'profile' => 'disabled',
|
70 |
+
'name' => 'Disabled',
|
71 |
+
),
|
72 |
+
),
|
73 |
+
);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Helper function for outputting data while running tests (debug purposes).
|
78 |
+
*
|
79 |
+
* @param mixed $data The data to be logged.
|
80 |
+
*/
|
81 |
+
public function log( $data ) {
|
82 |
+
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export,WordPress.WP.AlternativeFunctions.file_system_read_fwrite
|
83 |
+
fwrite( STDERR, var_export( $data, true ) );
|
84 |
+
}
|
85 |
+
|
86 |
+
}
|
uninstall.php
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
<?php
|
2 |
|
3 |
//if uninstall not called from WordPress exit
|
4 |
-
if (!defined('WP_UNINSTALL_PLUGIN'))
|
5 |
-
|
|
|
6 |
|
7 |
class Lingotek_Uninstall {
|
8 |
|
@@ -15,15 +16,15 @@ class Lingotek_Uninstall {
|
|
15 |
global $wpdb;
|
16 |
|
17 |
// check if it is a multisite uninstall - if so, run the uninstall function for each blog id
|
18 |
-
if (is_multisite()) {
|
19 |
-
foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $blog_id) {
|
20 |
-
switch_to_blog($blog_id);
|
21 |
$this->uninstall();
|
22 |
}
|
23 |
restore_current_blog();
|
24 |
-
}
|
25 |
-
else
|
26 |
$this->uninstall();
|
|
|
27 |
}
|
28 |
|
29 |
/*
|
@@ -34,15 +35,15 @@ class Lingotek_Uninstall {
|
|
34 |
* @since 0.1
|
35 |
*/
|
36 |
function uninstall() {
|
37 |
-
delete_option('lingotek_prefs');
|
38 |
-
delete_option('lingotek_content_type');
|
39 |
-
delete_option('lingotek_community');
|
40 |
-
delete_option('lingotek_defaults');
|
41 |
-
delete_option('lingotek_profiles');
|
42 |
-
delete_option('lingotek_token');
|
43 |
-
delete_option('lingotek_community_resources');
|
44 |
-
delete_option('lingotek_custom_fields');
|
45 |
-
delete_option('lingotek_log_errors');
|
46 |
}
|
47 |
}
|
48 |
|
1 |
<?php
|
2 |
|
3 |
//if uninstall not called from WordPress exit
|
4 |
+
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
5 |
+
exit();
|
6 |
+
}
|
7 |
|
8 |
class Lingotek_Uninstall {
|
9 |
|
16 |
global $wpdb;
|
17 |
|
18 |
// check if it is a multisite uninstall - if so, run the uninstall function for each blog id
|
19 |
+
if ( is_multisite() ) {
|
20 |
+
foreach ( $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ) as $blog_id ) {
|
21 |
+
switch_to_blog( $blog_id );
|
22 |
$this->uninstall();
|
23 |
}
|
24 |
restore_current_blog();
|
25 |
+
} else {
|
|
|
26 |
$this->uninstall();
|
27 |
+
}
|
28 |
}
|
29 |
|
30 |
/*
|
35 |
* @since 0.1
|
36 |
*/
|
37 |
function uninstall() {
|
38 |
+
delete_option( 'lingotek_prefs' );
|
39 |
+
delete_option( 'lingotek_content_type' );
|
40 |
+
delete_option( 'lingotek_community' );
|
41 |
+
delete_option( 'lingotek_defaults' );
|
42 |
+
delete_option( 'lingotek_profiles' );
|
43 |
+
delete_option( 'lingotek_token' );
|
44 |
+
delete_option( 'lingotek_community_resources' );
|
45 |
+
delete_option( 'lingotek_custom_fields' );
|
46 |
+
delete_option( 'lingotek_log_errors' );
|
47 |
}
|
48 |
}
|
49 |
|