Version Description
(2017-4-14) =
- Added Lingotek bulk actions to custom content types
- Fixed incorrect number display on the Translation Dashboard when content was disabled for translation
- Fixed a bug that created empty content if trying to download translations before they were finished
- Fixed the String Groups page
- Code refactoring to meet WordPress coding standards
Download this release
Release Info
Developer | erichie |
Plugin | Lingotek Translation |
Version | 1.2.7 |
Comparing to | |
See all releases |
Code changes from version 1.2.6 to 1.2.7
- admin/actions.php +263 -234
- admin/admin.php +429 -388
- admin/content-table.php +104 -86
- admin/custom-fields-table.php +118 -99
- admin/filters-columns.php +187 -151
- admin/filters-media.php +28 -21
- admin/filters-post.php +5 -3
- admin/filters-term.php +87 -62
- admin/manage/view-content.php +1 -1
- admin/manage/view-strings.php +2 -2
- admin/post-actions.php +209 -163
- admin/profiles-table.php +67 -54
- admin/settings.php +58 -60
- admin/settings/connect-account.php +36 -26
- admin/settings/view-account.php +108 -109
- admin/settings/view-defaults.php +115 -121
- admin/settings/view-preferences.php +92 -102
- admin/settings/view-utilities.php +22 -20
- admin/string-actions.php +66 -55
- admin/strings-table.php +125 -93
- admin/table-string.php +79 -74
- admin/workflows/professional-translation-workflow.php +105 -0
- admin/workflows/workflow-factory.php +66 -0
- admin/workflows/workflow.php +123 -0
- include/group-post.php +17 -5
- include/model.php +6 -6
- js/workflow/professional-workflow.js +29 -0
- js/workflow/workflow-defaults.js +19 -0
- js/workflow/workflow.js +19 -0
- lingotek.php +386 -248
- readme.txt +9 -1
admin/actions.php
CHANGED
@@ -1,108 +1,141 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Base class to add row and bulk actions to posts, media and terms list
|
5 |
* Bulk actions management is inspired by http://www.foxrunsoftware.net/articles/wordpress/add-custom-bulk-action/
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
abstract class Lingotek_Actions {
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
* Constructor
|
16 |
*
|
17 |
* @since 0.2
|
18 |
*/
|
19 |
-
public function __construct($type) {
|
20 |
-
// confirm message
|
21 |
-
self::$confirm_message = sprintf(' onclick = "return confirm(\'%s\');"', __('You are about to overwrite existing translations. Are you sure?', 'lingotek-translation'));
|
22 |
|
23 |
-
// row actions
|
24 |
self::$actions = array(
|
25 |
'upload' => array(
|
26 |
-
'action' => __('Upload to Lingotek', 'lingotek-translation'),
|
27 |
-
'progress' => __('Uploading...', 'lingotek-translation'),
|
28 |
-
'description' => __('Upload this item to Lingotek TMS', 'lingotek-translation' ),
|
29 |
),
|
30 |
|
31 |
'request' => array(
|
32 |
-
'action' => __('Request translations', 'lingotek-translation'),
|
33 |
-
'progress' => __('Requesting translations...', 'lingotek-translation'),
|
34 |
-
'description' => __('Request translations of this item to Lingotek TMS', 'lingotek-translation' ),
|
35 |
),
|
36 |
|
37 |
'status' => array(
|
38 |
-
'action' => __('Update translations status', 'lingotek-translation'),
|
39 |
-
'progress' => __('Updating translations status...', 'lingotek-translation'),
|
40 |
-
'description' => __('Update translations status of this item in Lingotek TMS', 'lingotek-translation' ),
|
41 |
),
|
42 |
|
43 |
'download' => array(
|
44 |
-
'action' => __('Download translations', 'lingotek-translation'),
|
45 |
-
'progress' => __('Downloading translations...', 'lingotek-translation'),
|
46 |
-
'description' => __('Download translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
47 |
),
|
48 |
|
49 |
'delete' => array(
|
50 |
-
'action' => __('Disassociate translations', 'lingotek-translation'),
|
51 |
-
'progress' => __('Disassociating translations...', 'lingotek-translation'),
|
52 |
-
'description' => __('Disassociate the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
53 |
),
|
54 |
);
|
55 |
|
56 |
// action icons
|
57 |
self::$icons = array(
|
58 |
'upload' => array(
|
59 |
-
'title' => __('Upload Now', 'lingotek-translation'),
|
60 |
-
'icon' => 'upload'
|
61 |
),
|
62 |
|
63 |
'importing' => array(
|
64 |
-
'title' => __('Importing source', 'lingotek-translation'),
|
65 |
-
'icon' => 'clock'
|
66 |
),
|
67 |
|
68 |
'uploaded' => array(
|
69 |
-
'title' => __('Source uploaded', 'lingotek-translation'),
|
70 |
-
'icon' => 'yes'
|
71 |
),
|
72 |
|
73 |
'request' => array(
|
74 |
-
'title' => __('Request a translation', 'lingotek-translation'),
|
75 |
-
'icon' => 'plus'
|
76 |
),
|
77 |
|
78 |
'pending' => array(
|
79 |
-
'title' => __('In Progress', 'lingotek-translation'),
|
80 |
-
'icon' => 'clock'
|
81 |
),
|
82 |
|
83 |
'ready' => array(
|
84 |
-
'title' => __('Ready to download', 'lingotek-translation'),
|
85 |
-
'icon' => 'download'
|
86 |
),
|
87 |
|
88 |
'current' => array(
|
89 |
-
'title' => __('Current', 'lingotek-translation'),
|
90 |
-
'icon' => 'edit'
|
91 |
),
|
92 |
|
93 |
'not-current' => array(
|
94 |
-
'title' => __('The target translation is no longer current as the source content has been updated', 'lingotek-translation'),
|
95 |
-
'icon' => 'edit'
|
96 |
),
|
97 |
|
98 |
'error' => array(
|
99 |
-
'title' => __('There was an error contacting Lingotek', 'lingotek-translation'),
|
100 |
-
'icon' => 'warning'
|
101 |
),
|
102 |
|
103 |
'copy' => array(
|
104 |
-
'title' => __('Copy source language', 'lingotek-translation'),
|
105 |
-
'icon' => 'welcome-add-page'
|
106 |
),
|
107 |
);
|
108 |
|
@@ -110,14 +143,15 @@ abstract class Lingotek_Actions {
|
|
110 |
$this->pllm = $GLOBALS['polylang']->model;
|
111 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
112 |
|
113 |
-
add_action('admin_enqueue_scripts', array(&$this, 'admin_enqueue_scripts'));
|
114 |
|
115 |
-
foreach (array_keys(self::$actions) as $action)
|
116 |
-
add_action('wp_ajax_lingotek_progress_' . $this->type . '_'. $action , array(&$this, 'ajax_' . $action));
|
|
|
117 |
}
|
118 |
|
119 |
-
|
120 |
-
*
|
121 |
*
|
122 |
* @since 0.1
|
123 |
*
|
@@ -125,13 +159,13 @@ abstract class Lingotek_Actions {
|
|
125 |
* @param string $locale Lingotek locale
|
126 |
* @return string workbench link
|
127 |
*/
|
128 |
-
public static function workbench_link($document_id, $locale) {
|
129 |
$client_id = Lingotek_API::CLIENT_ID;
|
130 |
-
$token_details = get_option('lingotek_token');
|
131 |
$user = wp_get_current_user();
|
132 |
-
$base_url = get_option('lingotek_base_url');
|
133 |
|
134 |
-
$acting_login_id = $user->user_email; //user_nicename;
|
135 |
|
136 |
return self::generate_workbench_link(
|
137 |
$document_id,
|
@@ -144,41 +178,41 @@ abstract class Lingotek_Actions {
|
|
144 |
);
|
145 |
}
|
146 |
|
147 |
-
|
148 |
-
*
|
149 |
* function provided by Matt Smith from Lingotek
|
150 |
*
|
151 |
* @since 0.1
|
152 |
*
|
153 |
-
* @param string
|
154 |
-
* @param string
|
155 |
-
* @param string
|
156 |
-
* @param string
|
157 |
-
* @param string
|
158 |
-
* @param string
|
159 |
-
* @param string
|
160 |
* @param int|null $expiration
|
161 |
* @return string workbench link
|
162 |
*/
|
163 |
-
public static function generate_workbench_link($document_id, $locale_code, $client_id, $access_token, $login_id, $acting_login_id =
|
164 |
$expiration_default = time() + (60 * 30); // 30-minute default, otherwise use $expiration as passed in
|
165 |
-
$expiration = is_null($expiration) ? $expiration_default : $expiration;
|
166 |
$data = array(
|
167 |
'document_id' => $document_id,
|
168 |
'locale_code' => $locale_code,
|
169 |
'client_id' => $client_id,
|
170 |
'login_id' => $login_id,
|
171 |
'acting_login_id' => $acting_login_id,
|
172 |
-
'expiration' => $expiration
|
173 |
);
|
174 |
-
$query_data = utf8_encode(http_build_query($data));
|
175 |
-
$hmac =
|
176 |
-
$workbench_url = $base_url . '/lingopoint/portal/wb.action?' . $query_data .
|
177 |
return $workbench_url;
|
178 |
}
|
179 |
|
180 |
-
|
181 |
-
*
|
182 |
*
|
183 |
* @since 0.2
|
184 |
*
|
@@ -186,275 +220,271 @@ abstract class Lingotek_Actions {
|
|
186 |
* @param string $link
|
187 |
* @param string $additional parameters to add (js, target)
|
188 |
*/
|
189 |
-
public static function display_icon($name, $link, $additional = '') {
|
190 |
return sprintf('<a class="lingotek-color dashicons dashicons-%s" title="%s" href="%s"%s></a>',
|
191 |
-
|
192 |
}
|
193 |
|
194 |
-
|
195 |
-
*
|
196 |
*
|
197 |
* @since 1.2
|
198 |
*
|
199 |
* @param string $name
|
200 |
* @param string $additional parameters to add (js, target)
|
201 |
*/
|
202 |
-
public static function display_error_icon($name, $api_error, $additional = '') {
|
203 |
return sprintf('<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
|
204 |
-
|
205 |
}
|
206 |
|
207 |
-
|
208 |
-
*
|
209 |
*
|
210 |
* @since 0.2
|
211 |
*
|
212 |
* @param int|string $object_id
|
213 |
-
* @param bool
|
214 |
*/
|
215 |
-
public function upload_icon($object_id, $confirm = false) {
|
216 |
-
$args = array($this->type => $object_id, 'action' => 'lingotek-upload', 'noheader' => true);
|
217 |
-
$link = wp_nonce_url(defined('DOING_AJAX') && DOING_AJAX ? add_query_arg($args, wp_get_referer()) : add_query_arg($args), 'lingotek-upload');
|
218 |
-
return self::display_icon('upload', $link, $confirm ? self::$confirm_message : '');
|
219 |
}
|
220 |
|
221 |
-
|
222 |
-
*
|
223 |
-
*
|
224 |
*
|
225 |
* @param int|string $object_id
|
226 |
-
* @param string
|
227 |
-
* @param bool
|
228 |
*/
|
229 |
-
public function copy_icon($object_id, $target, $confirm = false) {
|
230 |
-
$args = array($this->type => $object_id, 'target' => $target, 'action' => 'lingotek-copy', 'noheader' => true);
|
231 |
-
$link = wp_nonce_url(defined('DOING_AJAX') && DOING_AJAX ? add_query_arg($args, wp_get_referer()) : add_query_arg($args), 'lingotek-copy');
|
232 |
-
return self::display_icon('copy', $link, $confirm ? self::$confirm_message : '');
|
233 |
}
|
234 |
|
235 |
-
|
236 |
-
*
|
237 |
*
|
238 |
* @since 0.2
|
239 |
*
|
240 |
* @param object $document
|
241 |
*/
|
242 |
-
public static function importing_icon($document) {
|
243 |
-
$args = array('document_id' => $document->document_id, 'action' => 'lingotek-status', 'noheader' => true);
|
244 |
-
$link = wp_nonce_url(defined('DOING_AJAX') && DOING_AJAX ? add_query_arg($args, wp_get_referer()) : add_query_arg($args), 'lingotek-status');
|
245 |
-
return self::display_icon('importing', $link);
|
246 |
}
|
247 |
|
248 |
-
|
249 |
-
*
|
250 |
*
|
251 |
* @since 0.2
|
252 |
*
|
253 |
* @param object $document
|
254 |
* @param object $language
|
255 |
*/
|
256 |
-
public static function translation_icon($document, $language) {
|
257 |
-
if (isset($document->translations[$language->locale])) {
|
258 |
-
if ('ready'
|
259 |
-
$link = wp_nonce_url(add_query_arg(array('document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-download', 'noheader' => true)), 'lingotek-download');
|
260 |
-
return self::display_icon($document->translations[$language->locale], $link);
|
261 |
-
}
|
262 |
-
else if ('not-current' == $document->translations[$language->locale]) {
|
263 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
|
|
|
|
|
|
264 |
}
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
}
|
269 |
-
|
270 |
-
}
|
271 |
-
else {
|
272 |
-
$link = wp_nonce_url(add_query_arg(array('document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-request', 'noheader' => true)), 'lingotek-request');
|
273 |
-
return self::display_icon('request', $link);
|
274 |
}
|
275 |
}
|
276 |
|
277 |
-
|
278 |
-
*
|
279 |
*
|
280 |
* @since 0.2
|
281 |
*
|
282 |
* @param array $args parameters to add to the link
|
283 |
-
* @param bool
|
284 |
* @return string
|
285 |
*/
|
286 |
-
protected function get_action_link($args, $warning = false) {
|
287 |
$action = $args['action'];
|
288 |
$args['action'] = 'lingotek-' . $action;
|
289 |
$args['noheader'] = true;
|
290 |
|
291 |
return sprintf(
|
292 |
'<a class="lingotek-color" title="%s" href="%s"%s>%s</a>',
|
293 |
-
self::$actions[$action]['description'],
|
294 |
-
wp_nonce_url(defined('DOING_AJAX') && DOING_AJAX ? add_query_arg($args, wp_get_referer()) : add_query_arg($args), 'lingotek-'
|
295 |
-
empty($warning) ? '' : self::$confirm_message,
|
296 |
-
self::$actions[$action]['action']
|
297 |
);
|
298 |
}
|
299 |
|
300 |
-
|
301 |
-
*
|
302 |
*
|
303 |
* @since 0.2
|
304 |
*
|
305 |
-
* @param array
|
306 |
* @param $id object id
|
307 |
* @return array
|
308 |
*/
|
309 |
-
protected function _row_actions($actions, $id) {
|
310 |
// first check that a language is associated to this object
|
311 |
-
if (
|
312 |
return $actions;
|
|
|
313 |
|
314 |
-
$document = $this->lgtm->get_group($this->type, $id);
|
315 |
-
if ($this->type
|
316 |
$id = $document->desc_array['lingotek']['source'];
|
317 |
}
|
318 |
|
319 |
-
if ($this->lgtm->can_upload($this->type, $id) || (isset($document->source) && 'string'
|
320 |
-
if ($document) {
|
321 |
$desc_array = $document->desc_array;
|
322 |
-
unset($desc_array['lingotek']);
|
323 |
-
if (count($desc_array) >= 2) {
|
324 |
-
$actions['lingotek-upload'] = $this->get_action_link(array($this->type => $id, 'action' => 'upload'), true);
|
|
|
|
|
325 |
}
|
326 |
-
|
327 |
-
|
328 |
-
}
|
329 |
-
}
|
330 |
-
else {
|
331 |
-
$actions['lingotek-upload'] = $this->get_action_link(array($this->type => $id, 'action' => 'upload'));
|
332 |
}
|
333 |
-
}
|
334 |
-
|
335 |
-
elseif (isset($document->translations)) {
|
336 |
// translations to download ?
|
337 |
-
if ($document->has_translation_status('ready'))
|
338 |
-
$actions['lingotek-download'] = $this->get_action_link(array('document_id' => $document->document_id, 'action' => 'download'));
|
|
|
339 |
|
340 |
// need to request translations ?
|
341 |
-
$language = $this->get_language($document->source);
|
342 |
-
$all_locales = array_flip($this->pllm->get_languages_list(array('fields' => 'locale')));
|
343 |
-
if (!empty($language)) // in case a language has been deleted
|
344 |
-
unset($all_locales[$language->locale]);
|
345 |
-
|
|
|
346 |
|
347 |
// remove disabled target language from untranslated languages list
|
348 |
-
foreach ($untranslated as $k => $v) {
|
349 |
-
if ($this->type
|
350 |
-
if ($document->is_disabled_target($language, $this->pllm->get_language($k)))
|
351 |
-
|
352 |
-
|
353 |
-
else {
|
354 |
-
if ($document->is_disabled_target($language, $this->pllm->get_language($k)))
|
355 |
-
|
|
|
356 |
}
|
357 |
}
|
358 |
|
359 |
-
if ('current'
|
360 |
-
$actions['lingotek-request'] = $this->get_action_link(array('document_id' => $document->document_id, 'action' => 'request'));
|
|
|
361 |
|
362 |
// offers to update translations status
|
363 |
-
if ('importing'
|
364 |
-
$actions['lingotek-status'] = $this->get_action_link(array('document_id' => $document->document_id, 'action' => 'status'));
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
$actions['lingotek-upload'] = $this->get_action_link(array($this->type => $id, 'action' => 'upload'), true);
|
369 |
}
|
370 |
|
371 |
// offers to disassociate translations
|
372 |
-
if (isset($document->source))
|
373 |
-
$actions['lingotek-delete'] = $this->get_action_link(array('document_id' => $document->document_id, 'action' => 'delete'));
|
|
|
374 |
|
375 |
return $actions;
|
376 |
}
|
377 |
|
378 |
-
|
379 |
-
*
|
380 |
* as the existing filter does not allow to *add* actions
|
381 |
* also displays the progress dialog placeholder
|
382 |
*
|
383 |
* @since 0.2
|
384 |
*/
|
385 |
-
protected function _add_bulk_actions() {
|
386 |
-
$js = '';
|
387 |
-
|
388 |
-
foreach (self::$actions as $action => $strings) {
|
389 |
-
foreach (array('', '2') as $i)
|
390 |
-
$js .= sprintf('jQuery("<option>").val("bulk-lingotek-%s").text("%s").appendTo("select[name=\'action%s\']");', $action, $strings['action'], $i);
|
391 |
|
392 |
-
|
|
|
|
|
393 |
$text = $strings['progress'];
|
|
|
394 |
}
|
395 |
|
396 |
-
|
|
|
|
|
397 |
|
398 |
-
|
399 |
-
printf('<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', $text);
|
400 |
}
|
401 |
|
402 |
-
|
403 |
-
*
|
404 |
*
|
405 |
* @since 0.1
|
406 |
*/
|
407 |
public function admin_enqueue_scripts() {
|
408 |
-
foreach (array_keys(self::$actions) as $action) {
|
409 |
-
if (
|
410 |
wp_localize_script('lingotek_progress', 'lingotek_data', array(
|
411 |
-
'action' =>
|
412 |
-
'taxonomy' =>
|
413 |
-
'sendback' => remove_query_arg( array('bulk-lingotek-' . $action, 'ids', 'lingotek_warning'), wp_get_referer() ),
|
414 |
-
'ids' => array_map('intval', explode(',',
|
415 |
-
'warning' =>
|
416 |
-
'nonce' => wp_create_nonce('lingotek_progress')
|
417 |
));
|
418 |
return;
|
419 |
}
|
420 |
}
|
421 |
}
|
422 |
|
423 |
-
|
424 |
-
*
|
425 |
*
|
426 |
* @since 0.2
|
427 |
*
|
428 |
* @param string $action action name
|
429 |
* @return bool true if the action was managed, false otherwise
|
430 |
*/
|
431 |
-
protected function _manage_actions($action) {
|
432 |
-
if (
|
433 |
-
$document = $this->lgtm->get_group_by_id(
|
|
|
434 |
|
435 |
-
switch($action) {
|
436 |
case 'lingotek-status':
|
437 |
-
check_admin_referer('lingotek-status');
|
438 |
$document->source_status();
|
439 |
$document->translations_status();
|
440 |
break;
|
441 |
|
442 |
case 'lingotek-request':
|
443 |
-
check_admin_referer('lingotek-request');
|
444 |
-
|
445 |
break;
|
446 |
|
447 |
case 'lingotek-download':
|
448 |
-
check_admin_referer('lingotek-download');
|
449 |
-
|
450 |
break;
|
451 |
|
452 |
case 'lingotek-delete':
|
453 |
-
check_admin_referer('lingotek-delete');
|
454 |
$document->disassociate();
|
455 |
-
if (
|
456 |
$site_id = get_current_blog_id();
|
457 |
-
|
458 |
exit();
|
459 |
}
|
460 |
break;
|
@@ -466,83 +496,82 @@ abstract class Lingotek_Actions {
|
|
466 |
return true;
|
467 |
}
|
468 |
|
469 |
-
|
470 |
-
*
|
471 |
*
|
472 |
* @since 0.1
|
473 |
*/
|
474 |
public function ajax_download() {
|
475 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
476 |
|
477 |
-
if ($document = $this->lgtm->get_group($this->type,
|
478 |
-
foreach ($document->translations as $locale => $status) {
|
479 |
-
if ('pending'
|
480 |
-
$document->create_translation($locale);
|
481 |
}
|
482 |
}
|
483 |
}
|
484 |
die();
|
485 |
}
|
486 |
|
487 |
-
|
488 |
-
*
|
489 |
*
|
490 |
* @since 0.2
|
491 |
*/
|
492 |
public function ajax_request() {
|
493 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
494 |
-
if ($document = $this->lgtm->get_group($this->type,
|
495 |
$document->request_translations();
|
496 |
}
|
497 |
die();
|
498 |
}
|
499 |
|
500 |
-
|
501 |
-
*
|
502 |
*
|
503 |
* @since 0.1
|
504 |
*/
|
505 |
public function ajax_status() {
|
506 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
507 |
-
if ($document = $this->lgtm->get_group($this->type,
|
508 |
$document->source_status();
|
509 |
$document->translations_status();
|
510 |
}
|
511 |
die();
|
512 |
}
|
513 |
|
514 |
-
|
515 |
-
*
|
516 |
*
|
517 |
* @since 0.2
|
518 |
*/
|
519 |
public function ajax_delete() {
|
520 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
521 |
-
if ($document = $this->lgtm->get_group($this->type,
|
522 |
$document->disassociate();
|
523 |
}
|
524 |
die();
|
525 |
}
|
526 |
|
527 |
-
|
528 |
-
*
|
529 |
*
|
530 |
* @since 1.1
|
531 |
*
|
532 |
* @param string errors
|
533 |
*/
|
534 |
-
public static function retrieve_api_error($errors) {
|
535 |
$api_error = "\n";
|
536 |
|
537 |
-
foreach($errors as $error => $error_message) {
|
538 |
-
if (is_array($error_message)) {
|
539 |
-
if (!empty($error_message)) {
|
540 |
-
foreach ($error_message as $locale => $message) {
|
541 |
$api_error = $api_error . $message . "\n";
|
542 |
}
|
543 |
}
|
544 |
-
}
|
545 |
-
else {
|
546 |
$api_error = $api_error . $error_message . "\n";
|
547 |
}
|
548 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Base class to add row and bulk actions to posts, media and terms list
|
5 |
* Bulk actions management is inspired by http://www.foxrunsoftware.net/articles/wordpress/add-custom-bulk-action/
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
abstract class Lingotek_Actions {
|
10 |
+
/**
|
11 |
+
* Polylang model.
|
12 |
+
*
|
13 |
+
* @var obj
|
14 |
+
*/
|
15 |
+
public $pllm;
|
16 |
+
/**
|
17 |
+
* Lingotek model.
|
18 |
+
*
|
19 |
+
* @var object
|
20 |
+
*/
|
21 |
+
public $lgtm;
|
22 |
+
/**
|
23 |
+
* Must be defined in child class: 'post' or 'term'.
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
public $type;
|
28 |
+
/**
|
29 |
+
* Actions
|
30 |
+
*
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
public static $actions;
|
34 |
+
/**
|
35 |
+
* Icons
|
36 |
+
*
|
37 |
+
* @var list
|
38 |
+
*/
|
39 |
+
public static $icons;
|
40 |
+
/**
|
41 |
+
* Confirm_message
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
public static $confirm_message;
|
46 |
|
47 |
+
/**
|
48 |
* Constructor
|
49 |
*
|
50 |
* @since 0.2
|
51 |
*/
|
52 |
+
public function __construct( $type ) {
|
53 |
+
// confirm message.
|
54 |
+
self::$confirm_message = sprintf( ' onclick = "return confirm(\'%s\');"', __( 'You are about to overwrite existing translations. Are you sure?', 'lingotek-translation' ) );
|
55 |
|
56 |
+
// row actions.
|
57 |
self::$actions = array(
|
58 |
'upload' => array(
|
59 |
+
'action' => __( 'Upload to Lingotek', 'lingotek-translation' ),
|
60 |
+
'progress' => __( 'Uploading...', 'lingotek-translation' ),
|
61 |
+
'description' => __( 'Upload this item to Lingotek TMS', 'lingotek-translation' ),
|
62 |
),
|
63 |
|
64 |
'request' => array(
|
65 |
+
'action' => __( 'Request translations', 'lingotek-translation' ),
|
66 |
+
'progress' => __( 'Requesting translations...', 'lingotek-translation' ),
|
67 |
+
'description' => __( 'Request translations of this item to Lingotek TMS', 'lingotek-translation' ),
|
68 |
),
|
69 |
|
70 |
'status' => array(
|
71 |
+
'action' => __( 'Update translations status', 'lingotek-translation' ),
|
72 |
+
'progress' => __( 'Updating translations status...', 'lingotek-translation' ),
|
73 |
+
'description' => __( 'Update translations status of this item in Lingotek TMS', 'lingotek-translation' ),
|
74 |
),
|
75 |
|
76 |
'download' => array(
|
77 |
+
'action' => __( 'Download translations', 'lingotek-translation' ),
|
78 |
+
'progress' => __( 'Downloading translations...', 'lingotek-translation' ),
|
79 |
+
'description' => __( 'Download translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
80 |
),
|
81 |
|
82 |
'delete' => array(
|
83 |
+
'action' => __( 'Disassociate translations', 'lingotek-translation' ),
|
84 |
+
'progress' => __( 'Disassociating translations...', 'lingotek-translation' ),
|
85 |
+
'description' => __( 'Disassociate the translations of this item from Lingotek TMS', 'lingotek-translation' ),
|
86 |
),
|
87 |
);
|
88 |
|
89 |
// action icons
|
90 |
self::$icons = array(
|
91 |
'upload' => array(
|
92 |
+
'title' => __( 'Upload Now', 'lingotek-translation' ),
|
93 |
+
'icon' => 'upload',
|
94 |
),
|
95 |
|
96 |
'importing' => array(
|
97 |
+
'title' => __( 'Importing source', 'lingotek-translation' ),
|
98 |
+
'icon' => 'clock',
|
99 |
),
|
100 |
|
101 |
'uploaded' => array(
|
102 |
+
'title' => __( 'Source uploaded', 'lingotek-translation' ),
|
103 |
+
'icon' => 'yes',
|
104 |
),
|
105 |
|
106 |
'request' => array(
|
107 |
+
'title' => __( 'Request a translation', 'lingotek-translation' ),
|
108 |
+
'icon' => 'plus',
|
109 |
),
|
110 |
|
111 |
'pending' => array(
|
112 |
+
'title' => __( 'In Progress', 'lingotek-translation' ),
|
113 |
+
'icon' => 'clock',
|
114 |
),
|
115 |
|
116 |
'ready' => array(
|
117 |
+
'title' => __( 'Ready to download', 'lingotek-translation' ),
|
118 |
+
'icon' => 'download',
|
119 |
),
|
120 |
|
121 |
'current' => array(
|
122 |
+
'title' => __( 'Current', 'lingotek-translation' ),
|
123 |
+
'icon' => 'edit',
|
124 |
),
|
125 |
|
126 |
'not-current' => array(
|
127 |
+
'title' => __( 'The target translation is no longer current as the source content has been updated', 'lingotek-translation' ),
|
128 |
+
'icon' => 'edit',
|
129 |
),
|
130 |
|
131 |
'error' => array(
|
132 |
+
'title' => __( 'There was an error contacting Lingotek', 'lingotek-translation' ),
|
133 |
+
'icon' => 'warning',
|
134 |
),
|
135 |
|
136 |
'copy' => array(
|
137 |
+
'title' => __( 'Copy source language', 'lingotek-translation' ),
|
138 |
+
'icon' => 'welcome-add-page',
|
139 |
),
|
140 |
);
|
141 |
|
143 |
$this->pllm = $GLOBALS['polylang']->model;
|
144 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
145 |
|
146 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
|
147 |
|
148 |
+
foreach ( array_keys( self::$actions ) as $action ) {
|
149 |
+
add_action( 'wp_ajax_lingotek_progress_' . $this->type . '_' . $action , array( &$this, 'ajax_' . $action ) );
|
150 |
+
}
|
151 |
}
|
152 |
|
153 |
+
/**
|
154 |
+
* Generates a workbench link
|
155 |
*
|
156 |
* @since 0.1
|
157 |
*
|
159 |
* @param string $locale Lingotek locale
|
160 |
* @return string workbench link
|
161 |
*/
|
162 |
+
public static function workbench_link( $document_id, $locale ) {
|
163 |
$client_id = Lingotek_API::CLIENT_ID;
|
164 |
+
$token_details = get_option( 'lingotek_token' );
|
165 |
$user = wp_get_current_user();
|
166 |
+
$base_url = get_option( 'lingotek_base_url' );
|
167 |
|
168 |
+
$acting_login_id = $user->user_email; // user_nicename;
|
169 |
|
170 |
return self::generate_workbench_link(
|
171 |
$document_id,
|
178 |
);
|
179 |
}
|
180 |
|
181 |
+
/**
|
182 |
+
* Generates a workbench link
|
183 |
* function provided by Matt Smith from Lingotek
|
184 |
*
|
185 |
* @since 0.1
|
186 |
*
|
187 |
+
* @param string $document_id
|
188 |
+
* @param string $locale_code
|
189 |
+
* @param string $client_id
|
190 |
+
* @param string $access_token
|
191 |
+
* @param string $login_id
|
192 |
+
* @param string $acting_login_id
|
193 |
+
* @param string $base_url
|
194 |
* @param int|null $expiration
|
195 |
* @return string workbench link
|
196 |
*/
|
197 |
+
public static function generate_workbench_link( $document_id, $locale_code, $client_id, $access_token, $login_id, $acting_login_id = 'anonymous', $base_url = 'https://myaccount.lingotek.com', $expiration = null ) {
|
198 |
$expiration_default = time() + (60 * 30); // 30-minute default, otherwise use $expiration as passed in
|
199 |
+
$expiration = is_null( $expiration ) ? $expiration_default : $expiration;
|
200 |
$data = array(
|
201 |
'document_id' => $document_id,
|
202 |
'locale_code' => $locale_code,
|
203 |
'client_id' => $client_id,
|
204 |
'login_id' => $login_id,
|
205 |
'acting_login_id' => $acting_login_id,
|
206 |
+
'expiration' => $expiration,
|
207 |
);
|
208 |
+
$query_data = utf8_encode( http_build_query( $data ) );
|
209 |
+
$hmac = rawurlencode( base64_encode( hash_hmac( 'sha1', $query_data, $access_token, true ) ) );
|
210 |
+
$workbench_url = $base_url . '/lingopoint/portal/wb.action?' . $query_data . '&hmac=' . $hmac;
|
211 |
return $workbench_url;
|
212 |
}
|
213 |
|
214 |
+
/**
|
215 |
+
* Outputs an action icon
|
216 |
*
|
217 |
* @since 0.2
|
218 |
*
|
220 |
* @param string $link
|
221 |
* @param string $additional parameters to add (js, target)
|
222 |
*/
|
223 |
+
public static function display_icon( $name, $link, $additional = '' ) {
|
224 |
return sprintf('<a class="lingotek-color dashicons dashicons-%s" title="%s" href="%s"%s></a>',
|
225 |
+
self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'], esc_url( $link ), $additional);
|
226 |
}
|
227 |
|
228 |
+
/**
|
229 |
+
* Outputs an API error icon
|
230 |
*
|
231 |
* @since 1.2
|
232 |
*
|
233 |
* @param string $name
|
234 |
* @param string $additional parameters to add (js, target)
|
235 |
*/
|
236 |
+
public static function display_error_icon( $name, $api_error, $additional = '' ) {
|
237 |
return sprintf('<span class="lingotek-error dashicons dashicons-%s" title="%s"></span>',
|
238 |
+
self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'] . "\n" . $api_error, $additional);
|
239 |
}
|
240 |
|
241 |
+
/**
|
242 |
+
* Outputs an upload icon
|
243 |
*
|
244 |
* @since 0.2
|
245 |
*
|
246 |
* @param int|string $object_id
|
247 |
+
* @param bool $warning
|
248 |
*/
|
249 |
+
public function upload_icon( $object_id, $confirm = false ) {
|
250 |
+
$args = array( $this->type => $object_id, 'action' => 'lingotek-upload', 'noheader' => true );
|
251 |
+
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-upload' );
|
252 |
+
return self::display_icon( 'upload', $link, $confirm ? self::$confirm_message : '' );
|
253 |
}
|
254 |
|
255 |
+
/**
|
256 |
+
* Outputs a copy icon
|
|
|
257 |
*
|
258 |
* @param int|string $object_id
|
259 |
+
* @param string $target
|
260 |
+
* @param bool $warning
|
261 |
*/
|
262 |
+
public function copy_icon( $object_id, $target, $confirm = false ) {
|
263 |
+
$args = array( $this->type => $object_id, 'target' => $target, 'action' => 'lingotek-copy', 'noheader' => true );
|
264 |
+
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-copy' );
|
265 |
+
return self::display_icon( 'copy', $link, $confirm ? self::$confirm_message : '' );
|
266 |
}
|
267 |
|
268 |
+
/**
|
269 |
+
* Outputs an importing icon
|
270 |
*
|
271 |
* @since 0.2
|
272 |
*
|
273 |
* @param object $document
|
274 |
*/
|
275 |
+
public static function importing_icon( $document ) {
|
276 |
+
$args = array( 'document_id' => $document->document_id, 'action' => 'lingotek-status', 'noheader' => true );
|
277 |
+
$link = wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-status' );
|
278 |
+
return self::display_icon( 'importing', $link );
|
279 |
}
|
280 |
|
281 |
+
/**
|
282 |
+
* Outputs icons for translations
|
283 |
*
|
284 |
* @since 0.2
|
285 |
*
|
286 |
* @param object $document
|
287 |
* @param object $language
|
288 |
*/
|
289 |
+
public static function translation_icon( $document, $language ) {
|
290 |
+
if ( isset( $document->translations[ $language->locale ] ) ) {
|
291 |
+
if ( 'ready' === $document->translations[ $language->locale ] ) {
|
292 |
+
$link = wp_nonce_url( add_query_arg( array( 'document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-download', 'noheader' => true ) ), 'lingotek-download' );
|
293 |
+
return self::display_icon( $document->translations[ $language->locale ], $link );
|
294 |
+
} elseif ( 'not-current' === $document->translations[ $language->locale ] ) {
|
|
|
295 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
296 |
+
} else {
|
297 |
+
$link = self::workbench_link( $document->document_id, $language->lingotek_locale );
|
298 |
+
return self::display_icon( $document->translations[ $language->locale ], $link, ' target="_blank"' );
|
299 |
}
|
300 |
+
} else {
|
301 |
+
$link = wp_nonce_url( add_query_arg( array( 'document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-request', 'noheader' => true ) ), 'lingotek-request' );
|
302 |
+
return self::display_icon( 'request', $link );
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
}
|
304 |
}
|
305 |
|
306 |
+
/**
|
307 |
+
* Creates an html action link
|
308 |
*
|
309 |
* @since 0.2
|
310 |
*
|
311 |
* @param array $args parameters to add to the link
|
312 |
+
* @param bool $warning whether to display an alert or not, optional, defaults to false
|
313 |
* @return string
|
314 |
*/
|
315 |
+
protected function get_action_link( $args, $warning = false ) {
|
316 |
$action = $args['action'];
|
317 |
$args['action'] = 'lingotek-' . $action;
|
318 |
$args['noheader'] = true;
|
319 |
|
320 |
return sprintf(
|
321 |
'<a class="lingotek-color" title="%s" href="%s"%s>%s</a>',
|
322 |
+
self::$actions[ $action ]['description'],
|
323 |
+
wp_nonce_url( defined( 'DOING_AJAX' ) && DOING_AJAX ? add_query_arg( $args, wp_get_referer() ) : add_query_arg( $args ), 'lingotek-' . $action ),
|
324 |
+
empty( $warning ) ? '' : self::$confirm_message,
|
325 |
+
self::$actions[ $action ]['action']
|
326 |
);
|
327 |
}
|
328 |
|
329 |
+
/**
|
330 |
+
* Adds a row action link
|
331 |
*
|
332 |
* @since 0.2
|
333 |
*
|
334 |
+
* @param array $actions list of action links
|
335 |
* @param $id object id
|
336 |
* @return array
|
337 |
*/
|
338 |
+
protected function _row_actions( $actions, $id ) {
|
339 |
// first check that a language is associated to this object
|
340 |
+
if ( ! $this->get_language( $id ) ) {
|
341 |
return $actions;
|
342 |
+
}
|
343 |
|
344 |
+
$document = $this->lgtm->get_group( $this->type, $id );
|
345 |
+
if ( $this->type !== 'string' && isset( $document->desc_array['lingotek']['source'] ) ) {
|
346 |
$id = $document->desc_array['lingotek']['source'];
|
347 |
}
|
348 |
|
349 |
+
if ( $this->lgtm->can_upload( $this->type, $id ) || (isset( $document->source ) && 'string' !== $this->type && $this->lgtm->can_upload( $this->type, $document->source )) ) {
|
350 |
+
if ( $document ) {
|
351 |
$desc_array = $document->desc_array;
|
352 |
+
unset( $desc_array['lingotek'] );
|
353 |
+
if ( count( $desc_array ) >= 2 ) {
|
354 |
+
$actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ), true );
|
355 |
+
} else {
|
356 |
+
$actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
|
357 |
}
|
358 |
+
} else {
|
359 |
+
$actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
|
|
|
|
|
|
|
|
|
360 |
}
|
361 |
+
} elseif ( isset( $document->translations ) ) {
|
|
|
|
|
362 |
// translations to download ?
|
363 |
+
if ( $document->has_translation_status( 'ready' ) ) {
|
364 |
+
$actions['lingotek-download'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'download' ) );
|
365 |
+
}
|
366 |
|
367 |
// need to request translations ?
|
368 |
+
$language = $this->get_language( $document->source );
|
369 |
+
$all_locales = array_flip( $this->pllm->get_languages_list( array( 'fields' => 'locale' ) ) );
|
370 |
+
if ( ! empty( $language ) ) { // in case a language has been deleted
|
371 |
+
unset( $all_locales[ $language->locale ] );
|
372 |
+
}
|
373 |
+
$untranslated = array_diff_key( $all_locales, $document->translations );
|
374 |
|
375 |
// remove disabled target language from untranslated languages list
|
376 |
+
foreach ( $untranslated as $k => $v ) {
|
377 |
+
if ( $this->type === 'term' ) {
|
378 |
+
if ( $document->is_disabled_target( $language, $this->pllm->get_language( $k ) ) ) {
|
379 |
+
unset( $untranslated[ $k ] );
|
380 |
+
}
|
381 |
+
} else {
|
382 |
+
if ( $document->is_disabled_target( $language, $this->pllm->get_language( $k ) ) ) {
|
383 |
+
unset( $untranslated[ $k ] );
|
384 |
+
}
|
385 |
}
|
386 |
}
|
387 |
|
388 |
+
if ( 'current' === $document->status && ! empty( $untranslated ) ) {
|
389 |
+
$actions['lingotek-request'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'request' ) );
|
390 |
+
}
|
391 |
|
392 |
// offers to update translations status
|
393 |
+
if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
|
394 |
+
$actions['lingotek-status'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'status' ) );
|
395 |
+
}
|
396 |
+
} elseif ( empty( $document->source ) ) {
|
397 |
+
$actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ), true );
|
|
|
398 |
}
|
399 |
|
400 |
// offers to disassociate translations
|
401 |
+
if ( isset( $document->source ) ) {
|
402 |
+
$actions['lingotek-delete'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'delete' ) );
|
403 |
+
}
|
404 |
|
405 |
return $actions;
|
406 |
}
|
407 |
|
408 |
+
/**
|
409 |
+
* Adds actions to bulk dropdown list table using a javascript hack
|
410 |
* as the existing filter does not allow to *add* actions
|
411 |
* also displays the progress dialog placeholder
|
412 |
*
|
413 |
* @since 0.2
|
414 |
*/
|
415 |
+
protected function _add_bulk_actions( $bulk_actions ) {
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
+
foreach ( self::$actions as $action => $strings ) {
|
418 |
+
$bulk_actions[ 'bulk-lingotek-' . $action ] = __( $strings['action'], $action );
|
419 |
+
if ( null !== filter_input( INPUT_GET, 'bulk-lingotek-' . $action ) ) {
|
420 |
$text = $strings['progress'];
|
421 |
+
}
|
422 |
}
|
423 |
|
424 |
+
if ( ! empty( $text ) ) {
|
425 |
+
printf( '<div id="lingotek-progressdialog" style="display:none" title="%s"><div id="lingotek-progressbar"></div></div>', esc_html( $text ) );
|
426 |
+
}
|
427 |
|
428 |
+
return $bulk_actions;
|
|
|
429 |
}
|
430 |
|
431 |
+
/**
|
432 |
+
* Outputs javascript data for progress.js
|
433 |
*
|
434 |
* @since 0.1
|
435 |
*/
|
436 |
public function admin_enqueue_scripts() {
|
437 |
+
foreach ( array_keys( self::$actions ) as $action ) {
|
438 |
+
if ( null !== filter_input( INPUT_GET, 'bulk-lingotek-' . $action ) ) {
|
439 |
wp_localize_script('lingotek_progress', 'lingotek_data', array(
|
440 |
+
'action' => null === filter_input( INPUT_GET, 'page' ) ? (null === filter_input( INPUT_GET, 'taxonomy' ) ? 'post_' . $action : 'term_' . $action) : 'string_' . $action,
|
441 |
+
'taxonomy' => null === filter_input( INPUT_GET, 'taxonomy' ) || ! taxonomy_exists( wp_unslash( filter_input( INPUT_GET, 'taxonomy' ) ) ) ? '' : filter_input( INPUT_GET, 'taxonomy' ),
|
442 |
+
'sendback' => remove_query_arg( array( 'bulk-lingotek-' . $action, 'ids', 'lingotek_warning' ), wp_get_referer() ),
|
443 |
+
'ids' => array_map( 'intval', explode( ',', filter_input( INPUT_GET, 'ids' ) ) ),
|
444 |
+
'warning' => null === filter_input( INPUT_GET, 'lingotek_warning' ) ? '' : __( 'You are about to overwrite existing translations. Are you sure?', 'lingotek-translation' ),
|
445 |
+
'nonce' => wp_create_nonce( 'lingotek_progress' ),
|
446 |
));
|
447 |
return;
|
448 |
}
|
449 |
}
|
450 |
}
|
451 |
|
452 |
+
/**
|
453 |
+
* Manages actions driven by dcoument_id
|
454 |
*
|
455 |
* @since 0.2
|
456 |
*
|
457 |
* @param string $action action name
|
458 |
* @return bool true if the action was managed, false otherwise
|
459 |
*/
|
460 |
+
protected function _manage_actions( $action ) {
|
461 |
+
if ( null !== filter_input( INPUT_GET, 'document_id' ) ) {
|
462 |
+
$document = $this->lgtm->get_group_by_id( filter_input( INPUT_GET, 'document_id' ) );
|
463 |
+
}
|
464 |
|
465 |
+
switch ( $action ) {
|
466 |
case 'lingotek-status':
|
467 |
+
check_admin_referer( 'lingotek-status' );
|
468 |
$document->source_status();
|
469 |
$document->translations_status();
|
470 |
break;
|
471 |
|
472 |
case 'lingotek-request':
|
473 |
+
check_admin_referer( 'lingotek-request' );
|
474 |
+
null !== filter_input( INPUT_GET, 'locale' ) ? $document->request_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->request_translations();
|
475 |
break;
|
476 |
|
477 |
case 'lingotek-download':
|
478 |
+
check_admin_referer( 'lingotek-download' );
|
479 |
+
null !== filter_input( INPUT_GET, 'locale' ) ? $document->create_translation( filter_input( INPUT_GET, 'locale' ) ) : $document->create_translations();
|
480 |
break;
|
481 |
|
482 |
case 'lingotek-delete':
|
483 |
+
check_admin_referer( 'lingotek-delete' );
|
484 |
$document->disassociate();
|
485 |
+
if ( null !== filter_input( INPUT_GET, 'lingotek_redirect' ) && filter_input( INPUT_GET, 'lingotek_redirect' ) === true ) {
|
486 |
$site_id = get_current_blog_id();
|
487 |
+
wp_safe_redirect( get_site_url( $site_id, '/wp-admin/edit.php?post_type=page' ) );
|
488 |
exit();
|
489 |
}
|
490 |
break;
|
496 |
return true;
|
497 |
}
|
498 |
|
499 |
+
/**
|
500 |
+
* Ajax response to download translations and showing progress
|
501 |
*
|
502 |
* @since 0.1
|
503 |
*/
|
504 |
public function ajax_download() {
|
505 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
506 |
|
507 |
+
if ( $document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) ) ) {
|
508 |
+
foreach ( $document->translations as $locale => $status ) {
|
509 |
+
if ( 'pending' === $status || 'ready' === $status ) {
|
510 |
+
$document->create_translation( $locale );
|
511 |
}
|
512 |
}
|
513 |
}
|
514 |
die();
|
515 |
}
|
516 |
|
517 |
+
/**
|
518 |
+
* Ajax response to request translations and showing progress
|
519 |
*
|
520 |
* @since 0.2
|
521 |
*/
|
522 |
public function ajax_request() {
|
523 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
524 |
+
if ( $document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) ) ) {
|
525 |
$document->request_translations();
|
526 |
}
|
527 |
die();
|
528 |
}
|
529 |
|
530 |
+
/**
|
531 |
+
* Ajax response to check translation status and showing progress
|
532 |
*
|
533 |
* @since 0.1
|
534 |
*/
|
535 |
public function ajax_status() {
|
536 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
537 |
+
if ( $document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) ) ) {
|
538 |
$document->source_status();
|
539 |
$document->translations_status();
|
540 |
}
|
541 |
die();
|
542 |
}
|
543 |
|
544 |
+
/**
|
545 |
+
* Ajax response disassociate translations and showing progress
|
546 |
*
|
547 |
* @since 0.2
|
548 |
*/
|
549 |
public function ajax_delete() {
|
550 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
551 |
+
if ( $document = $this->lgtm->get_group( $this->type, filter_input( INPUT_POST, 'id' ) ) ) {
|
552 |
$document->disassociate();
|
553 |
}
|
554 |
die();
|
555 |
}
|
556 |
|
557 |
+
/**
|
558 |
+
* Collects and returns all API errors
|
559 |
*
|
560 |
* @since 1.1
|
561 |
*
|
562 |
* @param string errors
|
563 |
*/
|
564 |
+
public static function retrieve_api_error( $errors ) {
|
565 |
$api_error = "\n";
|
566 |
|
567 |
+
foreach ( $errors as $error => $error_message ) {
|
568 |
+
if ( is_array( $error_message ) ) {
|
569 |
+
if ( ! empty( $error_message ) ) {
|
570 |
+
foreach ( $error_message as $locale => $message ) {
|
571 |
$api_error = $api_error . $message . "\n";
|
572 |
}
|
573 |
}
|
574 |
+
} else {
|
|
|
575 |
$api_error = $api_error . $error_message . "\n";
|
576 |
}
|
577 |
}
|
admin/admin.php
CHANGED
@@ -1,415 +1,453 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
3 |
class Lingotek_Admin {
|
4 |
-
|
5 |
-
|
6 |
-
*
|
|
|
|
|
|
|
|
|
|
|
7 |
*
|
8 |
* @since 0.1
|
9 |
*/
|
10 |
public function __construct() {
|
11 |
$plugin = Lingotek::get_instance();
|
12 |
$this->plugin_slug = $plugin->get_plugin_slug();
|
13 |
-
$this->dashboard = new Lingotek_Dashboard($plugin);
|
14 |
|
15 |
$this->pllm = $GLOBALS['polylang']->model;
|
16 |
|
17 |
-
add_action('admin_enqueue_scripts', array(&$this, 'admin_enqueue_scripts'));
|
18 |
|
19 |
-
// adds a 'settings' link in the plugins table
|
20 |
-
add_filter('plugin_action_links_' . LINGOTEK_BASENAME, array(&$this, 'plugin_action_links'));
|
21 |
|
22 |
-
// adds the link to the languages panel in the wordpress admin menu
|
23 |
-
add_action('admin_menu', array(&$this, 'add_menus'));
|
24 |
|
25 |
-
add_action('load-translation_page_lingotek-translation_manage', array(&$this, 'load_manage_page'));
|
26 |
-
add_filter('set-screen-option', array($this, 'set_screen_option'), 10, 3);
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
//Network admin menu
|
31 |
-
add_action('network_admin_menu', array($this, 'add_network_admin_menu'));
|
32 |
}
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
//ids and nonces. Each id has a source language, languages with statuses, and a workbench link
|
45 |
-
$content_metadata = array();
|
46 |
-
foreach($object_ids as $object_id) {
|
47 |
-
$id = $object_id;
|
48 |
-
$type = $terms ? 'term' : 'post';
|
49 |
-
if (isset($_POST['taxonomy'])) {
|
50 |
-
$taxonomy = $_POST['taxonomy'];
|
51 |
-
if (strpos($_POST['taxonomy'], '&')) {
|
52 |
-
$taxonomy = strstr($_POST['taxonomy'], '&', true);
|
53 |
-
}
|
54 |
-
}
|
55 |
-
else {
|
56 |
-
$taxonomy = get_post_type($id);
|
57 |
-
}
|
58 |
-
$content_metadata[$id] = array(
|
59 |
-
'existing_trans' => false,
|
60 |
-
'source' => false,
|
61 |
-
'doc_id' => null,
|
62 |
-
'source_id' => null,
|
63 |
-
'source_status' => null,
|
64 |
-
);
|
65 |
-
|
66 |
-
$document = $lgtm->get_group($type, $object_id);
|
67 |
-
if($document && !isset($document->source) && count($document->desc_array) >= 3) {
|
68 |
-
$content_metadata[$id]['existing_trans'] = true;
|
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 |
-
$
|
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 |
-
public function lingotek_get_matching_nonce($action){
|
135 |
-
$upload_link = wp_nonce_url(add_query_arg(array(
|
136 |
-
'action' => $action)),
|
137 |
-
$action);
|
138 |
-
$nonce_begin = strpos($upload_link, 'wpnonce=') + 8;
|
139 |
-
$nonce = substr($upload_link,$nonce_begin);
|
140 |
-
return $nonce;
|
141 |
-
}
|
142 |
-
|
143 |
-
public function lingotek_get_placeholders($items){
|
144 |
-
foreach($items as $item){
|
145 |
-
$placeholders .= '%s,';
|
146 |
-
}
|
147 |
-
$placeholders = rtrim($placeholders, ',');
|
148 |
-
return $placeholders;
|
149 |
-
}
|
150 |
-
|
151 |
-
public function get_dashboard_endpoint(){
|
152 |
-
return site_url("wp-admin/admin-ajax.php?action=".$this->ajax_dashboard_language_endpoint);
|
153 |
}
|
154 |
|
155 |
-
|
156 |
-
*
|
157 |
*
|
158 |
* @since 0.1
|
159 |
*/
|
160 |
public function admin_enqueue_scripts() {
|
161 |
$screen = get_current_screen();
|
162 |
|
163 |
-
// FIXME no minified file for now
|
164 |
$suffix = '';
|
165 |
-
//
|
166 |
-
|
167 |
-
//
|
168 |
-
//
|
169 |
-
//
|
170 |
-
//
|
171 |
-
// FIXME: check if I can load more scripts in footer
|
172 |
$scripts = array(
|
173 |
-
'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),
|
174 |
-
'updater' => array(array('edit', 'upload', 'edit-tags'), array('jquery-ui-progressbar', 'jquery-ui-dialog', 'wp-ajax-response'), 1),
|
175 |
);
|
176 |
|
177 |
$styles = array(
|
178 |
-
'admin' => array(array('edit', 'upload', 'edit-tags', 'translation_page_lingotek-translation_manage', 'translation_page_lingotek-translation_settings'), array('wp-jquery-ui-dialog')),
|
179 |
);
|
180 |
|
181 |
-
foreach ($scripts as $script => $v)
|
182 |
-
if (in_array($screen->base, $v[0]))
|
183 |
-
wp_enqueue_script('lingotek_'
|
|
|
|
|
184 |
|
185 |
-
foreach ($styles as $style => $v)
|
186 |
-
if (in_array($screen->base, $v[0]))
|
187 |
-
wp_enqueue_style('lingotek_'
|
|
|
|
|
188 |
}
|
189 |
|
190 |
-
|
191 |
-
*
|
192 |
*
|
193 |
* @since 0.1
|
194 |
*
|
195 |
-
* @param array $links list of links associated to the plugin
|
196 |
* @return array modified list of links
|
197 |
*/
|
198 |
-
public function plugin_action_links($links) {
|
199 |
-
array_unshift($links, '<a href="admin.php?page=lingotek-translation">' . __('Settings', 'lingotek-translation') . '</a>');
|
200 |
return $links;
|
201 |
}
|
202 |
|
203 |
-
|
204 |
-
*
|
205 |
*
|
206 |
* @since 0.0.1
|
207 |
*/
|
208 |
public function add_menus() {
|
209 |
add_menu_page(
|
210 |
-
$title = __('Translation', 'lingotek-translation'),
|
211 |
$title,
|
212 |
'manage_options',
|
213 |
$this->plugin_slug,
|
214 |
-
array($this, 'display_dashboard_page'), 'dashicons-translation'
|
215 |
);
|
216 |
|
217 |
-
|
218 |
-
add_submenu_page($this->plugin_slug, __('Translation
|
219 |
-
add_submenu_page($this->plugin_slug, __('Translation
|
220 |
-
add_submenu_page($this->plugin_slug, __('
|
221 |
-
add_submenu_page($this->plugin_slug, __('Lingotek Tutorial', 'lingotek-translation'), __('Tutorial', 'lingotek-translation'), 'manage_options', $this->plugin_slug . '_tutorial', array($this, 'display_tutorial_page'));
|
222 |
|
223 |
$selected_options = Lingotek_Model::get_prefs();
|
224 |
-
if (isset($selected_options['import_enabled']) && $selected_options['import_enabled']['enabled']
|
225 |
-
add_submenu_page($this->plugin_slug, __('Lingotek Import', 'lingotek-translation'), __('Import', 'lingotek-translation'), 'manage_options', $this->plugin_slug . '_import', array($this, 'display_import_page')); }
|
226 |
-
|
227 |
-
|
228 |
-
*
|
229 |
*
|
230 |
* @since 0.0.1
|
231 |
*/
|
232 |
public function display_settings_page() {
|
233 |
|
234 |
-
// disconnect Lingotek account
|
235 |
-
if (
|
236 |
-
delete_option('lingotek_token');
|
237 |
-
delete_option('lingotek_community');
|
238 |
-
delete_option('lingotek_defaults');
|
239 |
}
|
240 |
|
241 |
-
// connect Lingotek account
|
242 |
-
if (
|
243 |
-
// set and get token details
|
244 |
$client = new Lingotek_API();
|
245 |
-
$token_details = $client->get_token_details(
|
246 |
-
if ($token_details && strlen($token_details->login_id)) {
|
247 |
-
update_option('lingotek_token', array('access_token' =>
|
248 |
-
add_settings_error( 'lingotek_token', 'account-connection', __('Your Lingotek account has been successfully connected.', 'lingotek-translation'), 'updated' );
|
249 |
-
}
|
250 |
-
|
251 |
-
add_settings_error('lingotek_token', 'account-connection', __('Your Lingotek account was not connected. The Access Token received was invalid.', 'lingotek-translation'), 'error');
|
252 |
}
|
253 |
}
|
254 |
|
255 |
-
// set page key primarily used for form submissions
|
256 |
-
$page_key = $this->plugin_slug.'_settings';
|
257 |
-
if(
|
258 |
-
$page_key .= '&sm='.sanitize_text_field(
|
259 |
}
|
260 |
|
261 |
-
// set community
|
262 |
-
if (!empty(
|
263 |
-
check_admin_referer($page_key, '_wpnonce_' . $page_key);
|
264 |
-
update_option('lingotek_community',
|
265 |
-
add_settings_error('lingotek_community', 'update', __('Your community has been successfully saved.', 'lingotek-translation'), 'updated');
|
266 |
-
$this->set_community_resources(
|
267 |
}
|
268 |
-
$community_id = get_option('lingotek_community');
|
269 |
-
if (
|
270 |
-
add_settings_error('lingotek_community', 'error', __('Select and save the community that you would like to use.', 'lingotek-translation'), 'error');
|
271 |
}
|
272 |
|
273 |
$token_details = self::has_token_details();
|
274 |
-
$redirect_url = admin_url('admin.php?page=' . $this->plugin_slug . '_settings&sm=account');
|
275 |
|
276 |
-
if($token_details){
|
277 |
$access_token = $token_details['access_token'];
|
278 |
$login_id = $token_details['login_id'];
|
279 |
-
$base_url = get_option('lingotek_base_url');
|
280 |
-
include(LINGOTEK_ADMIN_INC . '/settings.php');
|
281 |
-
}
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
else {
|
291 |
-
update_option('lingotek_base_url', Lingotek_API::PRODUCTION_URL);
|
292 |
}
|
293 |
$client = new Lingotek_API();
|
294 |
-
echo '<div class="wrap"><p class="description">'.__(
|
295 |
|
296 |
-
$connect_url = (strcasecmp(
|
297 |
}
|
298 |
-
$connect_account_cloak_url_new = admin_url('admin.php?page=' . $this->plugin_slug . '_settings&connect=new');
|
299 |
-
$connect_account_cloak_url_test = admin_url('admin.php?page=' . $this->plugin_slug . '_settings&connect=sandbox');
|
300 |
-
$connect_account_cloak_url_prod = admin_url('admin.php?page=' . $this->plugin_slug . '_settings&connect=production');
|
301 |
-
include(LINGOTEK_ADMIN_INC . '/settings/connect-account.php');
|
302 |
}
|
303 |
}
|
304 |
|
305 |
-
|
306 |
-
*
|
307 |
*
|
308 |
* @since 0.2
|
309 |
*
|
|
|
310 |
* @return array
|
311 |
*/
|
312 |
-
public function get_profiles_settings($defaults = false) {
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
$options = array(
|
315 |
-
'manual' => __('Manual', 'lingotek-translation'),
|
316 |
-
'automatic' => __('Automatic', 'lingotek-translation')
|
317 |
);
|
318 |
|
319 |
return array(
|
320 |
'upload' => array(
|
321 |
-
'label' => __('Upload content', 'lingotek-translation'),
|
322 |
'options' => $options,
|
323 |
-
'description' => __('How should new and modified content be uploaded to Lingotek?', 'lingotek-translation')
|
324 |
),
|
325 |
'download' => array(
|
326 |
-
'label' => __('Download translations', 'lingotek-translation'),
|
327 |
'options' => $options,
|
328 |
-
'description' => __('How should completed translations be downloaded to WordPress?', 'lingotek-translation')
|
329 |
),
|
330 |
'project_id' => array(
|
331 |
-
'label' => $defaults ? __('Default Project', 'lingotek-translation') : __('Project', 'lingotek-translation'),
|
332 |
'options' => $resources['projects'],
|
333 |
-
'description' => __('Changes will affect new entities only', 'lingotek-translation')
|
334 |
),
|
335 |
'workflow_id' => array(
|
336 |
-
'label' => $defaults ? __('Default Workflow', 'lingotek-translation') : __('Workflow', 'lingotek-translation'),
|
337 |
'options' => $resources['workflows'],
|
338 |
-
'description' => __('Changes will affect new entities only', 'lingotek-translation')
|
339 |
),
|
340 |
'primary_filter_id' => array(
|
341 |
-
'label' => $defaults ? __('Primary Filter', 'lingotek-translation') : __('Primary Filter', 'lingotek-translation'),
|
342 |
'options' => $resources['filters'],
|
343 |
-
'description' => __('Changes will affect new entities only', 'lingotek-translation')
|
344 |
),
|
345 |
'secondary_filter_id' => array(
|
346 |
-
'label' => $defaults ? __('Secondary Filter', 'lingotek-translation') : __('Secondary Filter', 'lingotek-translation'),
|
347 |
'options' => $resources['filters'],
|
348 |
-
'description' => __('Changes will affect new entities only', 'lingotek-translation')
|
349 |
),
|
350 |
);
|
351 |
}
|
352 |
|
353 |
-
|
354 |
-
*
|
355 |
*
|
356 |
* @since 0.2
|
357 |
*
|
358 |
-
* @param arry $profiles
|
359 |
* @return array profiles with added usage column
|
360 |
*/
|
361 |
-
public function get_profiles_usage($profiles) {
|
362 |
-
$content_types = get_option('lingotek_content_type');
|
363 |
-
|
364 |
-
// initialize usage column
|
365 |
-
foreach ($profiles as $key => $profile)
|
366 |
-
$profiles[$key]['usage'] = 0;
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
|
|
373 |
$profiles['automatic']['usage'] += 1;
|
374 |
-
else
|
375 |
-
|
376 |
|
377 |
-
if (isset($content_types[$type]['sources'])) {
|
378 |
-
foreach ($content_types[$type]['sources'] as $profile)
|
379 |
-
$profiles[$profile]['usage'] +=1;
|
|
|
380 |
}
|
381 |
}
|
382 |
return $profiles;
|
383 |
}
|
384 |
|
385 |
-
|
386 |
-
*
|
387 |
*
|
388 |
* @since 0.1.0
|
|
|
|
|
|
|
389 |
*/
|
390 |
-
public function set_community_resources($community_id, $update_first_project_callback =
|
391 |
$client = new Lingotek_API();
|
392 |
$refresh_success = array(
|
393 |
-
'projects' =>
|
394 |
-
'workflows' =>
|
395 |
);
|
396 |
|
397 |
-
$api_data = $client->get_projects($community_id);
|
398 |
$projects = array();
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
$api_data = $client->get_workflows($community_id);
|
413 |
$default_workflows = array(
|
414 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
415 |
'ddf6e3c0-0688-11e2-892e-0800200c9a66' => 'Machine Translation + Post-Edit',
|
@@ -417,39 +455,42 @@ class Lingotek_Admin {
|
|
417 |
'2b5498e0-f3c7-4c49-9afa-cca4b3345af7' => 'Translation + 1 review',
|
418 |
'814172a6-3744-4da7-b932-5857c1c20976' => 'Translation + 2 reviews',
|
419 |
'2210b148-0c44-4ae2-91d0-ca2ee47c069e' => 'Translation + 3 reviews',
|
420 |
-
'7993b4d7-4ada-46d0-93d5-858db46c4c7d' => 'Translation Only'
|
421 |
);
|
422 |
$workflows = array();
|
423 |
-
if ($api_data) {
|
424 |
-
foreach ($api_data->entities as $workflow) {
|
425 |
-
$workflows[$workflow->properties->id] = $workflow->properties->title;
|
426 |
}
|
427 |
-
$diff = array_diff_key($workflows, $default_workflows);
|
428 |
-
if (empty($diff)) {
|
429 |
-
$workflows =
|
|
|
|
|
|
|
430 |
}
|
431 |
-
natcasesort($workflows); //order by title (case-insensitive)
|
432 |
-
$refresh_success['workflows'] =
|
433 |
}
|
434 |
|
435 |
$api_data = $client->get_filters();
|
436 |
$filters = array();
|
437 |
-
if ($api_data && $api_data->properties->total > 0) {
|
438 |
-
foreach ($api_data->entities as $filter) {
|
439 |
-
if (
|
440 |
-
$filters[$filter->properties->id] = $filter->properties->title;
|
441 |
}
|
442 |
-
if (
|
443 |
-
$filters[$filter->properties->id] = $filter->properties->title;
|
444 |
}
|
445 |
}
|
446 |
-
$primary_filter_id = array_search('okf_json@with-html-subfilter.fprm', $filters);
|
447 |
-
$secondary_filter_id = array_search('okf_html@wordpress.fprm', $filters);
|
448 |
-
$defaults = get_option('lingotek_defaults');
|
449 |
-
if($defaults
|
450 |
$defaults['primary_filter_id'] = $primary_filter_id;
|
451 |
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
452 |
-
update_option('lingotek_defaults', $defaults);
|
453 |
}
|
454 |
}
|
455 |
|
@@ -459,188 +500,188 @@ class Lingotek_Admin {
|
|
459 |
'filters' => $filters,
|
460 |
);
|
461 |
|
462 |
-
if ($refresh_success['projects']
|
463 |
-
update_option('lingotek_community_resources', $resources);
|
464 |
$this->ensure_valid_defaults();
|
465 |
}
|
466 |
return $refresh_success;
|
467 |
}
|
468 |
|
|
|
|
|
|
|
469 |
public function ensure_valid_defaults() {
|
470 |
-
$resources = get_option('lingotek_community_resources');
|
471 |
-
$defaults = get_option('lingotek_defaults');
|
472 |
$valid_default = array();
|
473 |
-
foreach ($resources as $resource_key => $options) {
|
474 |
-
$key = substr($resource_key,0,strlen($resource_key)-1).
|
475 |
-
$valid_default[$key] = 0;
|
476 |
-
if(!is_array($defaults)) {
|
477 |
continue;
|
478 |
}
|
479 |
-
foreach ($options as $option_key => $option_val) {
|
480 |
-
if(!array_key_exists($key, $defaults)){
|
481 |
continue;
|
482 |
}
|
483 |
-
if ($option_key === $defaults[$key]) {
|
484 |
-
$valid_default[$key] = 1;
|
485 |
break;
|
486 |
}
|
487 |
}
|
488 |
}
|
489 |
-
foreach ($valid_default as $key => $valid) {
|
490 |
-
$resource_key = substr($key,0,strpos($key,'_')).
|
491 |
-
if ($valid) {
|
492 |
continue;
|
493 |
-
}
|
494 |
-
|
495 |
-
$defaults[$key] = current(array_keys($resources[$resource_key]));
|
496 |
}
|
497 |
}
|
498 |
-
$num_valid_defaults = array_sum($valid_default);
|
499 |
|
500 |
-
if($num_valid_defaults < count($valid_default)){
|
501 |
-
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' );
|
502 |
}
|
503 |
-
unset($defaults['filter_id']);
|
504 |
-
update_option('lingotek_defaults', $defaults);
|
505 |
}
|
506 |
|
507 |
-
|
508 |
-
*
|
509 |
*
|
510 |
* @since 0.1.0
|
511 |
*/
|
512 |
public function display_manage_page() {
|
513 |
-
if (self::has_token_details()) {
|
514 |
-
include(LINGOTEK_ADMIN_INC . '/view-manage.php');
|
515 |
-
}
|
516 |
-
else {
|
517 |
$this->display_settings_page();
|
518 |
}
|
519 |
}
|
520 |
|
521 |
-
|
522 |
-
*
|
523 |
*
|
524 |
* @since 0.2
|
525 |
*/
|
526 |
public function load_manage_page() {
|
527 |
add_screen_option('per_page', array(
|
528 |
-
'label' => __('Strings groups', 'lingotek-translation'),
|
529 |
'default' => 10,
|
530 |
-
'option' => 'lingotek_strings_per_page'
|
531 |
));
|
532 |
}
|
533 |
|
534 |
-
|
535 |
-
*
|
536 |
*
|
537 |
* @since 0.2
|
|
|
|
|
|
|
|
|
538 |
*/
|
539 |
-
public function set_screen_option($status, $option, $value) {
|
540 |
-
if ('lingotek_strings_per_page'
|
541 |
return $value;
|
542 |
-
|
543 |
return $status;
|
544 |
}
|
545 |
|
546 |
-
|
547 |
-
*
|
548 |
*
|
549 |
* @since 0.1.0
|
550 |
*/
|
551 |
public function display_dashboard_page() {
|
552 |
$token_details = self::has_token_details();
|
553 |
-
if ($token_details) {
|
554 |
-
$community_id = get_option('lingotek_community');
|
555 |
-
$defaults = get_option('lingotek_defaults');
|
556 |
$user = wp_get_current_user();
|
557 |
|
558 |
-
// The data that will be passed to the Lingotek GMC dashboard
|
559 |
$cms_data = array(
|
560 |
-
// lingotek
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
"endpoint_url" => $this->get_dashboard_endpoint()
|
579 |
);
|
580 |
-
include(LINGOTEK_ADMIN_INC . '/view-dashboard.php');
|
581 |
-
}
|
582 |
-
else {
|
583 |
$this->display_settings_page();
|
584 |
}
|
585 |
}
|
586 |
|
587 |
-
|
588 |
-
*
|
589 |
*
|
590 |
* @since 0.1.0
|
591 |
*/
|
592 |
public static function has_token_details() {
|
593 |
-
$token_details = get_option('lingotek_token');
|
594 |
-
$has_token =
|
595 |
-
if (
|
596 |
-
$has_token =
|
597 |
return $token_details;
|
598 |
}
|
599 |
return $has_token;
|
600 |
}
|
601 |
|
|
|
|
|
|
|
602 |
public function display_network_settings_page() {
|
603 |
-
if (is_multisite() && self::has_token_details()) {
|
604 |
-
include(LINGOTEK_ADMIN_INC . '/view-network.php');
|
605 |
-
}
|
606 |
-
else {
|
607 |
$this->display_settings_page();
|
608 |
}
|
609 |
}
|
610 |
|
611 |
-
|
612 |
-
*
|
613 |
*
|
614 |
* @since 0.1.0
|
615 |
*/
|
616 |
public function add_network_admin_menu() {
|
617 |
-
add_submenu_page('settings.php', __('Lingotek Settings', 'lingotek-translation'), __('Lingotek Settings', 'lingotek-translation'), 'manage_network_options', $this->plugin_slug . '_network', array($this, 'display_network_settings_page'), 'dashicons-translation');
|
618 |
}
|
619 |
|
|
|
|
|
|
|
620 |
public function display_tutorial_page() {
|
621 |
-
if (self::has_token_details()) {
|
622 |
-
include(LINGOTEK_ADMIN_INC . '/view-tutorial.php');
|
623 |
-
}
|
624 |
-
else {
|
625 |
$this->display_settings_page();
|
626 |
}
|
627 |
}
|
628 |
|
|
|
|
|
|
|
629 |
public function display_import_page() {
|
630 |
-
if (self::has_token_details()) {
|
631 |
-
// $client = new Lingotek_API();
|
632 |
-
// $docs = $client->get_documents(array('limit'=>5000));
|
633 |
-
// //$community_id = get_option('lingotek_community');
|
634 |
-
// $communities = $client->get_communities();
|
635 |
-
// var_dump($communities->entities);
|
636 |
-
// die();
|
637 |
-
// $projects = $client->get_projects($community_id)->entities;
|
638 |
-
// var_dump($projects);
|
639 |
-
// die();
|
640 |
settings_errors();
|
641 |
-
include(LINGOTEK_ADMIN_INC) . '/import.php';
|
642 |
-
}
|
643 |
-
else {
|
644 |
$this->display_settings_page();
|
645 |
}
|
646 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Lingotek Admin Class
|
4 |
+
*/
|
5 |
class Lingotek_Admin {
|
6 |
+
/**
|
7 |
+
* Ajax dashboard language endpoint.
|
8 |
+
*
|
9 |
+
* @var string
|
10 |
+
*/
|
11 |
+
private $ajax_dashboard_language_endpoint = 'lingotek_language';
|
12 |
+
/**
|
13 |
+
* Setups filters and action needed on all admin pages and on plugins page
|
14 |
*
|
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 |
|
24 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
|
25 |
|
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 |
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Gets current status.
|
43 |
+
*/
|
44 |
+
public function ajax_get_current_status() {
|
45 |
+
$lgtm = &$GLOBALS['wp_lingotek']->model;
|
46 |
+
$pllm = $GLOBALS['polylang']->model;
|
47 |
+
$languages = pll_languages_list( array( 'fields' => 'locale' ) );
|
48 |
+
$object_ids = filter_input( INPUT_POST, 'check_ids' );
|
49 |
+
if ( null === $object_ids ) {
|
50 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
+
$terms = ! empty( filter_input( INPUT_POST, 'terms_translations' ) );
|
53 |
+
|
54 |
+
// The main array consists of ids and nonces. Each id has a source language, languages with statuses, and a workbench link.
|
55 |
+
$content_metadata = array();
|
56 |
+
foreach ( $object_ids as $object_id ) {
|
57 |
+
$id = $object_id;
|
58 |
+
$type = $terms ? 'term' : 'post';
|
59 |
+
if ( ! empty( filter_input( INPUT_POST, 'taxonomy' ) ) ) {
|
60 |
+
$taxonomy = filter_input( INPUT_POST, 'taxonomy' );
|
61 |
+
if ( strpos( filter_input( INPUT_POST, 'taxonomy' ), '&' ) ) {
|
62 |
+
$taxonomy = strstr( filter_input( INPUT_POST, 'taxonomy' ), '&', true );
|
63 |
+
}
|
64 |
+
} else {
|
65 |
+
$taxonomy = get_post_type( $id );
|
66 |
+
}
|
67 |
+
$content_metadata[ $id ] = array(
|
68 |
+
'existing_trans' => false,
|
69 |
+
'source' => false,
|
70 |
+
'doc_id' => null,
|
71 |
+
'source_id' => null,
|
72 |
+
'source_status' => null,
|
73 |
+
);
|
74 |
+
|
75 |
+
$document = $lgtm->get_group( $type, $object_id );
|
76 |
+
if ( $document && ! isset( $document->source ) && count( $document->desc_array ) >= 3 ) {
|
77 |
+
$content_metadata[ $id ]['existing_trans'] = true;
|
78 |
+
}
|
79 |
+
if ( $document && isset( $document->source ) && isset( $document->document_id ) && isset( $document->status ) && isset( $document->translations ) ) {
|
80 |
+
if ( $document->source !== (int) $object_id ) {
|
81 |
+
$document = $lgtm->get_group( $type, $document->source );
|
82 |
+
}
|
83 |
+
$source_id = null !== $document->source ? $document->source : $object_id;
|
84 |
+
$source_language = $terms ? pll_get_term_language( $document->source, 'locale' )
|
85 |
+
: pll_get_post_language( $document->source, 'locale' );
|
86 |
+
$existing_translations = $type = 'term' ? PLL()->model->term->get_translations( $source_id ) : PLL()->model->post->get_translations( $source_id );
|
87 |
+
|
88 |
+
if ( count( $existing_translations ) > 1 ) {
|
89 |
+
$content_metadata[ $id ]['existing_trans'] = true;
|
90 |
+
}
|
91 |
+
$content_metadata[ $id ]['source'] = $source_language;
|
92 |
+
$content_metadata[ $id ]['doc_id'] = $document->document_id;
|
93 |
+
$content_metadata[ $id ]['source_id'] = $document->source;
|
94 |
+
$content_metadata[ $id ]['source_status'] = $document->status;
|
95 |
+
$target_status = 'edited' === $document->status || null === $document->status ? 'edited' : 'current';
|
96 |
+
$content_metadata[ $id ][ $source_language ]['status'] = $document->source === $object_id ? $document->status : $target_status;
|
97 |
+
|
98 |
+
if ( is_array( $document->translations ) ) {
|
99 |
+
foreach ( $document->translations as $locale => $translation_status ) {
|
100 |
+
$content_metadata[ $id ][ $locale ]['status'] = $translation_status;
|
101 |
+
$workbench_link = Lingotek_Actions::workbench_link( $document->document_id, $locale );
|
102 |
+
$content_metadata[ $id ][ $locale ]['workbench_link'] = $workbench_link;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
// fills in missing languages, makes life easier for the updater.
|
107 |
+
foreach ( $languages as $language ) {
|
108 |
+
foreach ( $content_metadata as $group => $status ) {
|
109 |
+
$language_obj = $pllm->get_language( $source_language );
|
110 |
+
$target_lang_obj = $pllm->get_language( $language );
|
111 |
+
$profile = Lingotek_Model::get_profile( $taxonomy, $language_obj, $group );
|
112 |
+
if ( 'disabled' !== $profile['profile'] && false !== $status['source'] ) {
|
113 |
+
if ( ! isset( $status[ $language ] ) ) {
|
114 |
+
$content_metadata[ $group ][ $language ]['status'] = 'none';
|
115 |
+
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 )) ) {
|
116 |
+
$content_metadata[ $group ][ $language ]['status'] = 'disabled';
|
117 |
+
}
|
118 |
}
|
119 |
}
|
120 |
}
|
121 |
}
|
122 |
}
|
123 |
+
|
124 |
+
$language = 'post' === $type ? pll_get_post_language( $id ) : pll_get_term_language( $id );
|
125 |
+
$language = $pllm->get_language( $language );
|
126 |
+
if ( $language ) {
|
127 |
+
$profile = Lingotek_Model::get_profile( $taxonomy, $language, $id );
|
128 |
+
if ( 'disabled' === $profile['profile'] && false === $content_metadata[ $id ]['source'] ) {
|
129 |
+
$content_metadata[ $id ]['source'] = 'disabled';
|
130 |
+
}
|
131 |
+
}
|
132 |
}
|
133 |
|
134 |
+
// get the nonces associated with the different actions.
|
135 |
+
$content_metadata['request_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-request' );
|
136 |
+
$content_metadata['download_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-download' );
|
137 |
+
$content_metadata['upload_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-upload' );
|
138 |
+
$content_metadata['status_nonce'] = $this->lingotek_get_matching_nonce( 'lingotek-status' );
|
139 |
+
|
140 |
+
wp_send_json( $content_metadata );
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Gets the matching nonce.
|
145 |
+
*
|
146 |
+
* @param string $action action.
|
147 |
+
* @return string nonce.
|
148 |
+
*/
|
149 |
+
public function lingotek_get_matching_nonce( $action ) {
|
150 |
+
$upload_link = wp_nonce_url( add_query_arg( array( 'action' => $action ) ), $action );
|
151 |
+
$nonce_begin = strpos( $upload_link, 'wpnonce=' ) + 8;
|
152 |
+
$nonce = substr( $upload_link,$nonce_begin );
|
153 |
+
return $nonce;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Gets placeholder string.
|
158 |
+
*
|
159 |
+
* @param array $items list of items.
|
160 |
+
* @return string string of placeholders.
|
161 |
+
*/
|
162 |
+
public function lingotek_get_placeholders( $items ) {
|
163 |
+
foreach ( $items as $item ) {
|
164 |
+
$placeholders .= '%s,';
|
165 |
}
|
166 |
+
$placeholders = rtrim( $placeholders, ',' );
|
167 |
+
return $placeholders;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Gets dashboard endpoint.
|
172 |
+
*
|
173 |
+
* @return url endpoint.
|
174 |
+
*/
|
175 |
+
public function get_dashboard_endpoint() {
|
176 |
+
return site_url( 'wp-admin/admin-ajax.php?action=' . $this->ajax_dashboard_language_endpoint );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
}
|
178 |
|
179 |
+
/**
|
180 |
+
* Setup js scripts & css styles (only on the relevant pages)
|
181 |
*
|
182 |
* @since 0.1
|
183 |
*/
|
184 |
public function admin_enqueue_scripts() {
|
185 |
$screen = get_current_screen();
|
186 |
|
187 |
+
// FIXME no minified file for now.
|
188 |
$suffix = '';
|
189 |
+
// $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';.
|
190 |
+
// for each script:.
|
191 |
+
// 0 => the pages on which to load the script.
|
192 |
+
// 1 => the scripts it needs to work.
|
193 |
+
// 2 => 1 if loaded in footer.
|
194 |
+
// FIXME: check if I can load more scripts in footer.
|
|
|
195 |
$scripts = array(
|
196 |
+
'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 ),
|
197 |
+
'updater' => array( array( 'edit', 'upload', 'edit-tags' ), array( 'jquery-ui-progressbar', 'jquery-ui-dialog', 'wp-ajax-response' ), 1 ),
|
198 |
);
|
199 |
|
200 |
$styles = array(
|
201 |
+
'admin' => array( array( 'edit', 'upload', 'edit-tags', 'translation_page_lingotek-translation_manage', 'translation_page_lingotek-translation_settings' ), array( 'wp-jquery-ui-dialog' ) ),
|
202 |
);
|
203 |
|
204 |
+
foreach ( $scripts as $script => $v ) {
|
205 |
+
if ( in_array( $screen->base, $v[0], true ) ) {
|
206 |
+
wp_enqueue_script( 'lingotek_' . $script, LINGOTEK_URL . '/js/' . $script . $suffix . '.js', $v[1], LINGOTEK_VERSION, $v[2] );
|
207 |
+
}
|
208 |
+
}
|
209 |
|
210 |
+
foreach ( $styles as $style => $v ) {
|
211 |
+
if ( in_array( $screen->base, $v[0], true ) ) {
|
212 |
+
wp_enqueue_style( 'lingotek_' . $style, LINGOTEK_URL . '/css/' . $style . $suffix . '.css', $v[1], LINGOTEK_VERSION );
|
213 |
+
}
|
214 |
+
}
|
215 |
}
|
216 |
|
217 |
+
/**
|
218 |
+
* Adds a 'settings' link in the plugins table
|
219 |
*
|
220 |
* @since 0.1
|
221 |
*
|
222 |
+
* @param array $links list of links associated to the plugin.
|
223 |
* @return array modified list of links
|
224 |
*/
|
225 |
+
public function plugin_action_links( $links ) {
|
226 |
+
array_unshift( $links, '<a href="admin.php?page=lingotek-translation">' . __( 'Settings', 'lingotek-translation' ) . '</a>' );
|
227 |
return $links;
|
228 |
}
|
229 |
|
230 |
+
/**
|
231 |
+
* Adds the links to the Lingotek panels in the wordpress admin menu
|
232 |
*
|
233 |
* @since 0.0.1
|
234 |
*/
|
235 |
public function add_menus() {
|
236 |
add_menu_page(
|
237 |
+
$title = __( 'Translation', 'lingotek-translation' ),
|
238 |
$title,
|
239 |
'manage_options',
|
240 |
$this->plugin_slug,
|
241 |
+
array( $this, 'display_dashboard_page' ), 'dashicons-translation'
|
242 |
);
|
243 |
|
244 |
+
add_submenu_page( $this->plugin_slug, __( 'Translation Dashboard', 'lingotek-translation' ), __( 'Dashboard', 'lingotek-translation' ), 'manage_options', $this->plugin_slug, array( $this, 'display_dashboard_page' ) );
|
245 |
+
add_submenu_page( $this->plugin_slug, __( 'Translation Management', 'lingotek-translation' ), __( 'Manage', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_manage', array( $this, 'display_manage_page' ) );
|
246 |
+
add_submenu_page( $this->plugin_slug, __( 'Translation Settings', 'lingotek-translation' ), __( 'Settings', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_settings', array( $this, 'display_settings_page' ) );
|
247 |
+
add_submenu_page( $this->plugin_slug, __( 'Lingotek Tutorial', 'lingotek-translation' ), __( 'Tutorial', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_tutorial', array( $this, 'display_tutorial_page' ) );
|
|
|
248 |
|
249 |
$selected_options = Lingotek_Model::get_prefs();
|
250 |
+
if ( isset( $selected_options['import_enabled'] ) && '1' === $selected_options['import_enabled']['enabled'] ) {
|
251 |
+
add_submenu_page( $this->plugin_slug, __( 'Lingotek Import', 'lingotek-translation' ), __( 'Import', 'lingotek-translation' ), 'manage_options', $this->plugin_slug . '_import', array( $this, 'display_import_page' ) ); }
|
252 |
+
}
|
253 |
+
/**
|
254 |
+
* Displays the settings page
|
255 |
*
|
256 |
* @since 0.0.1
|
257 |
*/
|
258 |
public function display_settings_page() {
|
259 |
|
260 |
+
// disconnect Lingotek account.
|
261 |
+
if ( ! empty( filter_input( INPUT_GET, 'delete_access_token' ) ) ) {
|
262 |
+
delete_option( 'lingotek_token' );
|
263 |
+
delete_option( 'lingotek_community' );
|
264 |
+
delete_option( 'lingotek_defaults' );
|
265 |
}
|
266 |
|
267 |
+
// connect Lingotek account.
|
268 |
+
if ( ! empty( filter_input( INPUT_GET, 'access_token' ) ) ) {
|
269 |
+
// set and get token details.
|
270 |
$client = new Lingotek_API();
|
271 |
+
$token_details = $client->get_token_details( filter_input( INPUT_GET, 'access_token' ) );
|
272 |
+
if ( $token_details && strlen( $token_details->login_id ) ) {
|
273 |
+
update_option( 'lingotek_token', array( 'access_token' => filter_input( INPUT_GET, 'access_token' ), 'login_id' => $token_details->login_id ) );
|
274 |
+
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account has been successfully connected.', 'lingotek-translation' ), 'updated' );
|
275 |
+
} else {
|
276 |
+
add_settings_error( 'lingotek_token', 'account-connection', __( 'Your Lingotek account was not connected. The Access Token received was invalid.', 'lingotek-translation' ), 'error' );
|
|
|
277 |
}
|
278 |
}
|
279 |
|
280 |
+
// set page key primarily used for form submissions.
|
281 |
+
$page_key = $this->plugin_slug . '_settings';
|
282 |
+
if ( ! empty( filter_input( INPUT_GET, 'sm' ) ) ) {
|
283 |
+
$page_key .= '&sm=' . sanitize_text_field( filter_input( INPUT_GET, 'sm' ) );
|
284 |
}
|
285 |
|
286 |
+
// set community.
|
287 |
+
if ( ! empty( filter_input( INPUT_POST, 'lingotek_community' ) ) && strlen( filter_input( INPUT_POST, 'lingotek_community' ) ) ) {
|
288 |
+
check_admin_referer( $page_key, '_wpnonce_' . $page_key );
|
289 |
+
update_option( 'lingotek_community', filter_input( INPUT_POST, 'lingotek_community' ) );
|
290 |
+
add_settings_error( 'lingotek_community', 'update', __( 'Your community has been successfully saved.', 'lingotek-translation' ), 'updated' );
|
291 |
+
$this->set_community_resources( filter_input( INPUT_POST, 'lingotek_community' ) );
|
292 |
}
|
293 |
+
$community_id = get_option( 'lingotek_community' );
|
294 |
+
if ( ! $community_id ) {
|
295 |
+
add_settings_error( 'lingotek_community', 'error', __( 'Select and save the community that you would like to use.', 'lingotek-translation' ), 'error' );
|
296 |
}
|
297 |
|
298 |
$token_details = self::has_token_details();
|
299 |
+
$redirect_url = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&sm=account' );
|
300 |
|
301 |
+
if ( $token_details ) {
|
302 |
$access_token = $token_details['access_token'];
|
303 |
$login_id = $token_details['login_id'];
|
304 |
+
$base_url = get_option( 'lingotek_base_url' );
|
305 |
+
include( LINGOTEK_ADMIN_INC . '/settings.php' );
|
306 |
+
} else {
|
307 |
+
$connect_url = '';
|
308 |
+
// connect cloak redirect.
|
309 |
+
if ( ! empty( filter_input( INPUT_GET, 'connect' ) ) ) {
|
310 |
+
// set sandbox or production (after button clicked).
|
311 |
+
if ( 0 === strcasecmp( filter_input( INPUT_GET, 'connect' ),'sandbox' ) ) {
|
312 |
+
update_option( 'lingotek_base_url', Lingotek_API::SANDBOX_URL );
|
313 |
+
} else {
|
314 |
+
update_option( 'lingotek_base_url', Lingotek_API::PRODUCTION_URL );
|
|
|
|
|
315 |
}
|
316 |
$client = new Lingotek_API();
|
317 |
+
echo '<div class="wrap"><p class="description">' . esc_html( __( 'Redirecting to Lingotek to connect your account...','lingotek-translation' ) ) . '</p></div>';
|
318 |
|
319 |
+
$connect_url = (0 === strcasecmp( filter_input( INPUT_GET, 'connect' ),'new' )) ? $client->get_new_url( $redirect_url ) : $client->get_connect_url( $redirect_url );
|
320 |
}
|
321 |
+
$connect_account_cloak_url_new = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=new' );
|
322 |
+
$connect_account_cloak_url_test = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=sandbox' );
|
323 |
+
$connect_account_cloak_url_prod = admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=production' );
|
324 |
+
include( LINGOTEK_ADMIN_INC . '/settings/connect-account.php' );
|
325 |
}
|
326 |
}
|
327 |
|
328 |
+
/**
|
329 |
+
* Get possible settings for defaults or translation profiles
|
330 |
*
|
331 |
* @since 0.2
|
332 |
*
|
333 |
+
* @param bool $defaults defaults flag.
|
334 |
* @return array
|
335 |
*/
|
336 |
+
public function get_profiles_settings( $defaults = false ) {
|
337 |
+
|
338 |
+
/**
|
339 |
+
* All specialized modals are echo'd to the page.
|
340 |
+
* a .js file is loaded that attaches listeners to each of the specialized workflows
|
341 |
+
* and launches a modal when one of them is selected in the default list.
|
342 |
+
*/
|
343 |
+
Lingotek_Workflow_Factory::echo_info_modals();
|
344 |
+
wp_enqueue_script( 'lingotek_workflow_defaults', LINGOTEK_URL . '/js/workflow/workflow-defaults.js' );
|
345 |
+
|
346 |
+
$resources = get_option( 'lingotek_community_resources' );
|
347 |
$options = array(
|
348 |
+
'manual' => __( 'Manual', 'lingotek-translation' ),
|
349 |
+
'automatic' => __( 'Automatic', 'lingotek-translation' ),
|
350 |
);
|
351 |
|
352 |
return array(
|
353 |
'upload' => array(
|
354 |
+
'label' => __( 'Upload content', 'lingotek-translation' ),
|
355 |
'options' => $options,
|
356 |
+
'description' => __( 'How should new and modified content be uploaded to Lingotek?', 'lingotek-translation' ),
|
357 |
),
|
358 |
'download' => array(
|
359 |
+
'label' => __( 'Download translations', 'lingotek-translation' ),
|
360 |
'options' => $options,
|
361 |
+
'description' => __( 'How should completed translations be downloaded to WordPress?', 'lingotek-translation' ),
|
362 |
),
|
363 |
'project_id' => array(
|
364 |
+
'label' => $defaults ? __( 'Default Project', 'lingotek-translation' ) : __( 'Project', 'lingotek-translation' ),
|
365 |
'options' => $resources['projects'],
|
366 |
+
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
367 |
),
|
368 |
'workflow_id' => array(
|
369 |
+
'label' => $defaults ? __( 'Default Workflow', 'lingotek-translation' ) : __( 'Workflow', 'lingotek-translation' ),
|
370 |
'options' => $resources['workflows'],
|
371 |
+
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
372 |
),
|
373 |
'primary_filter_id' => array(
|
374 |
+
'label' => $defaults ? __( 'Primary Filter', 'lingotek-translation' ) : __( 'Primary Filter', 'lingotek-translation' ),
|
375 |
'options' => $resources['filters'],
|
376 |
+
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
377 |
),
|
378 |
'secondary_filter_id' => array(
|
379 |
+
'label' => $defaults ? __( 'Secondary Filter', 'lingotek-translation' ) : __( 'Secondary Filter', 'lingotek-translation' ),
|
380 |
'options' => $resources['filters'],
|
381 |
+
'description' => __( 'Changes will affect new entities only', 'lingotek-translation' ),
|
382 |
),
|
383 |
);
|
384 |
}
|
385 |
|
386 |
+
/**
|
387 |
+
* Get usage for all profiles
|
388 |
*
|
389 |
* @since 0.2
|
390 |
*
|
391 |
+
* @param arry $profiles profiles.
|
392 |
* @return array profiles with added usage column
|
393 |
*/
|
394 |
+
public function get_profiles_usage( $profiles ) {
|
395 |
+
$content_types = get_option( 'lingotek_content_type' );
|
396 |
+
|
397 |
+
// initialize usage column.
|
398 |
+
foreach ( $profiles as $key => $profile ) {
|
399 |
+
$profiles[ $key ]['usage'] = 0;
|
400 |
+
}
|
401 |
+
|
402 |
+
// fill usage column.
|
403 |
+
foreach ( array_merge( $this->pllm->get_translated_post_types(), $this->pllm->get_translated_taxonomies(), array( 'string' ) ) as $type ) {
|
404 |
+
if ( isset( $content_types[ $type ]['profile'] ) ) {
|
405 |
+
$profiles[ $content_types[ $type ]['profile'] ]['usage'] += 1;
|
406 |
+
} elseif ( 'post' === $type ) {
|
407 |
$profiles['automatic']['usage'] += 1;
|
408 |
+
} else { $profiles['manual']['usage'] += 1;
|
409 |
+
}
|
410 |
|
411 |
+
if ( isset( $content_types[ $type ]['sources'] ) ) {
|
412 |
+
foreach ( $content_types[ $type ]['sources'] as $profile ) {
|
413 |
+
$profiles[ $profile ]['usage'] += 1;
|
414 |
+
}
|
415 |
}
|
416 |
}
|
417 |
return $profiles;
|
418 |
}
|
419 |
|
420 |
+
/**
|
421 |
+
* Store community options and set any missing defaults to the first available option
|
422 |
*
|
423 |
* @since 0.1.0
|
424 |
+
*
|
425 |
+
* @param string $community_id communit id.
|
426 |
+
* @param bool $update_first_project_callback boolean flag.
|
427 |
*/
|
428 |
+
public function set_community_resources( $community_id, $update_first_project_callback = false ) {
|
429 |
$client = new Lingotek_API();
|
430 |
$refresh_success = array(
|
431 |
+
'projects' => false,
|
432 |
+
'workflows' => false,
|
433 |
);
|
434 |
|
435 |
+
$api_data = $client->get_projects( $community_id );
|
436 |
$projects = array();
|
437 |
+
if ( false !== $api_data ) {
|
438 |
+
foreach ( $api_data->entities as $project ) {
|
439 |
+
$projects[ $project->properties->id ] = $project->properties->title;
|
440 |
+
}
|
441 |
+
if ( 1 === $api_data->properties->total ) {
|
442 |
+
if ( ! $project->properties->callback_url ) {
|
443 |
+
$client->update_callback_url( $project->properties->id );
|
444 |
+
}
|
445 |
+
}
|
446 |
+
natcasesort( $projects ); // order by title (case-insensitive).
|
447 |
+
$refresh_success['projects'] = true;
|
448 |
+
}
|
449 |
+
|
450 |
+
$api_data = $client->get_workflows( $community_id );
|
451 |
$default_workflows = array(
|
452 |
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
453 |
'ddf6e3c0-0688-11e2-892e-0800200c9a66' => 'Machine Translation + Post-Edit',
|
455 |
'2b5498e0-f3c7-4c49-9afa-cca4b3345af7' => 'Translation + 1 review',
|
456 |
'814172a6-3744-4da7-b932-5857c1c20976' => 'Translation + 2 reviews',
|
457 |
'2210b148-0c44-4ae2-91d0-ca2ee47c069e' => 'Translation + 3 reviews',
|
458 |
+
'7993b4d7-4ada-46d0-93d5-858db46c4c7d' => 'Translation Only',
|
459 |
);
|
460 |
$workflows = array();
|
461 |
+
if ( $api_data ) {
|
462 |
+
foreach ( $api_data->entities as $workflow ) {
|
463 |
+
$workflows[ $workflow->properties->id ] = $workflow->properties->title;
|
464 |
}
|
465 |
+
$diff = array_diff_key( $workflows, $default_workflows );
|
466 |
+
if ( empty( $diff ) ) {
|
467 |
+
$workflows = [
|
468 |
+
'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
|
469 |
+
// 'professional-translation' => 'Professional Translation',
|
470 |
+
];
|
471 |
}
|
472 |
+
natcasesort( $workflows ); // order by title (case-insensitive).
|
473 |
+
$refresh_success['workflows'] = true;
|
474 |
}
|
475 |
|
476 |
$api_data = $client->get_filters();
|
477 |
$filters = array();
|
478 |
+
if ( $api_data && $api_data->properties->total > 0 ) {
|
479 |
+
foreach ( $api_data->entities as $filter ) {
|
480 |
+
if ( ! $filter->properties->is_public ) {
|
481 |
+
$filters[ $filter->properties->id ] = $filter->properties->title;
|
482 |
}
|
483 |
+
if ( 'okf_json@with-html-subfilter.fprm' === $filter->properties->title || 'okf_html@wordpress.fprm' === $filter->properties->title ) {
|
484 |
+
$filters[ $filter->properties->id ] = $filter->properties->title;
|
485 |
}
|
486 |
}
|
487 |
+
$primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $filters, true );
|
488 |
+
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $filters, true );
|
489 |
+
$defaults = get_option( 'lingotek_defaults' );
|
490 |
+
if ( null === $defaults ) {
|
491 |
$defaults['primary_filter_id'] = $primary_filter_id;
|
492 |
$defaults['secondary_filter_id'] = $secondary_filter_id;
|
493 |
+
update_option( 'lingotek_defaults', $defaults );
|
494 |
}
|
495 |
}
|
496 |
|
500 |
'filters' => $filters,
|
501 |
);
|
502 |
|
503 |
+
if ( true === $refresh_success['projects'] || true === $refresh_success['workflows'] ) {
|
504 |
+
update_option( 'lingotek_community_resources', $resources );
|
505 |
$this->ensure_valid_defaults();
|
506 |
}
|
507 |
return $refresh_success;
|
508 |
}
|
509 |
|
510 |
+
/**
|
511 |
+
* Ensures valid defaults.
|
512 |
+
*/
|
513 |
public function ensure_valid_defaults() {
|
514 |
+
$resources = get_option( 'lingotek_community_resources' );
|
515 |
+
$defaults = get_option( 'lingotek_defaults' );
|
516 |
$valid_default = array();
|
517 |
+
foreach ( $resources as $resource_key => $options ) {
|
518 |
+
$key = substr( $resource_key,0,strlen( $resource_key ) -1 ) . '_id';
|
519 |
+
$valid_default[ $key ] = 0;
|
520 |
+
if ( ! is_array( $defaults ) ) {
|
521 |
continue;
|
522 |
}
|
523 |
+
foreach ( $options as $option_key => $option_val ) {
|
524 |
+
if ( ! array_key_exists( $key, $defaults ) ) {
|
525 |
continue;
|
526 |
}
|
527 |
+
if ( $option_key === $defaults[ $key ] ) {
|
528 |
+
$valid_default[ $key ] = 1;
|
529 |
break;
|
530 |
}
|
531 |
}
|
532 |
}
|
533 |
+
foreach ( $valid_default as $key => $valid ) {
|
534 |
+
$resource_key = substr( $key,0,strpos( $key,'_' ) ) . 's';
|
535 |
+
if ( $valid ) {
|
536 |
continue;
|
537 |
+
} else {
|
538 |
+
$defaults[ $key ] = current( array_keys( $resources[ $resource_key ] ) );
|
|
|
539 |
}
|
540 |
}
|
541 |
+
$num_valid_defaults = array_sum( $valid_default );
|
542 |
|
543 |
+
if ( $num_valid_defaults < count( $valid_default ) ) {
|
544 |
+
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' );
|
545 |
}
|
546 |
+
unset( $defaults['filter_id'] );
|
547 |
+
update_option( 'lingotek_defaults', $defaults );
|
548 |
}
|
549 |
|
550 |
+
/**
|
551 |
+
* Displays the admin manage page
|
552 |
*
|
553 |
* @since 0.1.0
|
554 |
*/
|
555 |
public function display_manage_page() {
|
556 |
+
if ( self::has_token_details() ) {
|
557 |
+
include( LINGOTEK_ADMIN_INC . '/view-manage.php' );
|
558 |
+
} else {
|
|
|
559 |
$this->display_settings_page();
|
560 |
}
|
561 |
}
|
562 |
|
563 |
+
/**
|
564 |
+
* Add screen option on translations->manage page
|
565 |
*
|
566 |
* @since 0.2
|
567 |
*/
|
568 |
public function load_manage_page() {
|
569 |
add_screen_option('per_page', array(
|
570 |
+
'label' => __( 'Strings groups', 'lingotek-translation' ),
|
571 |
'default' => 10,
|
572 |
+
'option' => 'lingotek_strings_per_page',
|
573 |
));
|
574 |
}
|
575 |
|
576 |
+
/**
|
577 |
+
* Save screen option from translations->manage page
|
578 |
*
|
579 |
* @since 0.2
|
580 |
+
*
|
581 |
+
* @param item $status status.
|
582 |
+
* @param string $option option.
|
583 |
+
* @param item $value value.
|
584 |
*/
|
585 |
+
public function set_screen_option( $status, $option, $value ) {
|
586 |
+
if ( 'lingotek_strings_per_page' === $option ) {
|
587 |
return $value;
|
588 |
+
}
|
589 |
return $status;
|
590 |
}
|
591 |
|
592 |
+
/**
|
593 |
+
* Displays the admin manage page
|
594 |
*
|
595 |
* @since 0.1.0
|
596 |
*/
|
597 |
public function display_dashboard_page() {
|
598 |
$token_details = self::has_token_details();
|
599 |
+
if ( $token_details ) {
|
600 |
+
$community_id = get_option( 'lingotek_community' );
|
601 |
+
$defaults = get_option( 'lingotek_defaults' );
|
602 |
$user = wp_get_current_user();
|
603 |
|
604 |
+
// The data that will be passed to the Lingotek GMC dashboard.
|
605 |
$cms_data = array(
|
606 |
+
// lingotek.
|
607 |
+
'community_id' => $community_id,
|
608 |
+
'external_id' => $token_details['login_id'],
|
609 |
+
'workflow_id' => $defaults['workflow_id'],
|
610 |
+
'project_id' => $defaults['project_id'],
|
611 |
+
'first_name' => $user->display_name,
|
612 |
+
'last_name' => '',
|
613 |
+
'email' => get_bloginfo( 'admin_email' ),
|
614 |
+
// cms.
|
615 |
+
'cms_site_id' => site_url(),
|
616 |
+
'cms_site_key' => site_url(),
|
617 |
+
'cms_site_name' => get_bloginfo( 'name' ),
|
618 |
+
'cms_type' => 'Wordpress',
|
619 |
+
'cms_version' => get_bloginfo( 'version' ),
|
620 |
+
'cms_tag' => LINGOTEK_PLUGIN_SLUG,
|
621 |
+
'locale' => pll_current_language( 'lingotek_locale' ),
|
622 |
+
'module_version' => LINGOTEK_VERSION,
|
623 |
+
'endpoint_url' => $this->get_dashboard_endpoint(),
|
|
|
624 |
);
|
625 |
+
include( LINGOTEK_ADMIN_INC . '/view-dashboard.php' );
|
626 |
+
} else {
|
|
|
627 |
$this->display_settings_page();
|
628 |
}
|
629 |
}
|
630 |
|
631 |
+
/**
|
632 |
+
* Returns the access token when present, otherwise returns FALSE
|
633 |
*
|
634 |
* @since 0.1.0
|
635 |
*/
|
636 |
public static function has_token_details() {
|
637 |
+
$token_details = get_option( 'lingotek_token' );
|
638 |
+
$has_token = false;
|
639 |
+
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'] ) ) {
|
640 |
+
$has_token = true;
|
641 |
return $token_details;
|
642 |
}
|
643 |
return $has_token;
|
644 |
}
|
645 |
|
646 |
+
/**
|
647 |
+
* Displays network settings page.
|
648 |
+
*/
|
649 |
public function display_network_settings_page() {
|
650 |
+
if ( is_multisite() && self::has_token_details() ) {
|
651 |
+
include( LINGOTEK_ADMIN_INC . '/view-network.php' );
|
652 |
+
} else {
|
|
|
653 |
$this->display_settings_page();
|
654 |
}
|
655 |
}
|
656 |
|
657 |
+
/**
|
658 |
+
* Adds a Lingotek settings option in the network admin page
|
659 |
*
|
660 |
* @since 0.1.0
|
661 |
*/
|
662 |
public function add_network_admin_menu() {
|
663 |
+
add_submenu_page( 'settings.php', __( 'Lingotek Settings', 'lingotek-translation' ), __( 'Lingotek Settings', 'lingotek-translation' ), 'manage_network_options', $this->plugin_slug . '_network', array( $this, 'display_network_settings_page' ), 'dashicons-translation' );
|
664 |
}
|
665 |
|
666 |
+
/**
|
667 |
+
* Displays tutorial page.
|
668 |
+
*/
|
669 |
public function display_tutorial_page() {
|
670 |
+
if ( self::has_token_details() ) {
|
671 |
+
include( LINGOTEK_ADMIN_INC . '/view-tutorial.php' );
|
672 |
+
} else {
|
|
|
673 |
$this->display_settings_page();
|
674 |
}
|
675 |
}
|
676 |
|
677 |
+
/**
|
678 |
+
* Displays import page.
|
679 |
+
*/
|
680 |
public function display_import_page() {
|
681 |
+
if ( self::has_token_details() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
682 |
settings_errors();
|
683 |
+
include( LINGOTEK_ADMIN_INC ) . '/import.php';
|
684 |
+
} else {
|
|
|
685 |
$this->display_settings_page();
|
686 |
}
|
687 |
}
|
admin/content-table.php
CHANGED
@@ -1,48 +1,61 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if(!class_exists('WP_List_Table')){
|
4 |
-
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1
|
5 |
}
|
6 |
|
|
|
|
|
|
|
7 |
class Lingotek_Content_Table extends WP_List_Table {
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
|
11 |
-
*
|
12 |
*
|
|
|
13 |
* @since 0.2
|
14 |
*/
|
15 |
-
function __construct($content_types) {
|
16 |
parent::__construct(array(
|
17 |
-
'plural' => 'lingotek-content', // do not translate (used for css class)
|
18 |
-
'ajax' => false
|
19 |
));
|
20 |
|
21 |
$this->profiles = Lingotek::get_profiles();
|
22 |
$this->content_types = $content_types;
|
23 |
}
|
24 |
|
25 |
-
|
26 |
-
*
|
27 |
*
|
28 |
* @since 0.2
|
29 |
*
|
30 |
-
* @param array $item
|
31 |
-
* @param string $column_name
|
32 |
-
* @return string
|
33 |
*/
|
34 |
-
function column_name($item) {
|
35 |
global $polylang;
|
36 |
|
37 |
-
printf('<span class="content-type-name">%s</span>', esc_html($item['name']));
|
38 |
|
39 |
-
// the source language for strings is always the default language
|
40 |
-
if ('string'
|
41 |
printf('<a id="id[%s]" class="dashicons dashicons-arrow-right" onclick="%s" href="#"></a>',
|
42 |
-
esc_attr($item['type']),
|
43 |
"
|
44 |
-
d1 = document.getElementById('sources-name[
|
45 |
-
d2 = document.getElementById('sources-profile[
|
46 |
c = 'dashicons dashicons-arrow-';
|
47 |
if (c+'right' == this.className) {
|
48 |
this.className = c+'down';
|
@@ -56,42 +69,41 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
56 |
"
|
57 |
);
|
58 |
|
59 |
-
printf('<ul class="sources-name" id="sources-name[%s]" style="display:none;">', $item['type']);
|
60 |
-
foreach ($polylang->model->get_languages_list() as $language) {
|
61 |
-
printf('<li>%s</li>', sprintf(__('%s source', 'lingotek-translation'), esc_html($language->name)));
|
62 |
}
|
63 |
echo '</ul>';
|
64 |
}
|
65 |
}
|
66 |
|
67 |
-
|
68 |
-
*
|
69 |
*
|
70 |
* @since 0.2
|
71 |
*
|
72 |
-
* @param array $item
|
73 |
-
* @return string
|
74 |
*/
|
75 |
-
function column_profile($item) {
|
76 |
global $polylang;
|
77 |
|
78 |
-
printf('<select class="content-type-profile" name="%1$s" id="%1$s">', $item['type'] . '[profile]');
|
79 |
-
foreach ($this->profiles as $key => $profile) {
|
80 |
-
$selected = (isset($item['profile']) && $key
|
81 |
-
echo "\n\t<option value='" . esc_attr($key) . "' $selected>
|
82 |
}
|
83 |
echo '</select>';
|
84 |
|
85 |
-
$options = array_merge(array('default' => array('name' => __('Use content type default', 'lingotek-translation'))), $this->profiles);
|
86 |
|
87 |
-
// the source language for strings is always the default language
|
88 |
-
if ('string'
|
89 |
-
printf('<ul class="sources-profile" id="sources-profile[%s]" style="display:none;">', $item['type']);
|
90 |
-
foreach ($polylang->model->get_languages_list() as $language) {
|
91 |
-
printf('<li><select name="%1$s" id="%1$s">', $item['type'] . '[sources][' . $language->slug . ']' );
|
92 |
-
foreach ($options as $key => $profile) {
|
93 |
-
$selected = (isset($item['sources'][$language->slug]) && $key
|
94 |
-
echo "\n\t<option value='" . esc_attr($key) . "' $selected>
|
95 |
}
|
96 |
echo '</select></li>';
|
97 |
}
|
@@ -99,53 +111,51 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
99 |
}
|
100 |
}
|
101 |
|
102 |
-
|
103 |
-
*
|
104 |
* can handle fields with one or two keys
|
105 |
*
|
106 |
* @since 0.2
|
107 |
*
|
108 |
-
* @param array
|
109 |
-
* @param array
|
110 |
-
* @param string $
|
111 |
*/
|
112 |
-
protected function display_fields($labels, $values, $name) {
|
113 |
-
foreach ($labels as $key => $str) {
|
114 |
-
if (is_array($str)) {
|
115 |
-
if (
|
116 |
continue;
|
117 |
}
|
118 |
-
$this->display_fields($str, isset($values[$key]) ? $values[$key] : array(), $name . "[$key]");
|
119 |
-
}
|
120 |
-
else {
|
121 |
printf(
|
122 |
'<li><label><input name="%s" type="checkbox" value="1" %s /> %s</label></li>',
|
123 |
-
esc_attr($name . "[$key]"),
|
124 |
-
empty($values[$key]) ? 'checked="checked"' : '',
|
125 |
-
esc_html($str)
|
126 |
);
|
127 |
}
|
128 |
}
|
129 |
}
|
130 |
|
131 |
-
|
132 |
-
*
|
133 |
*
|
134 |
* @since 0.2
|
135 |
*
|
136 |
-
* @param array $item
|
137 |
-
* @return string
|
138 |
*/
|
139 |
-
function column_fields($item) {
|
140 |
-
if (!empty($item['fields'])) {
|
141 |
echo '<ul class="content-type-fields">';
|
142 |
-
$this->display_fields($item['fields']['label'], isset($item['fields']['value']) ? $item['fields']['value'] : array() , $item['type'] . '[fields]');
|
143 |
echo '</ul>';
|
144 |
}
|
145 |
}
|
146 |
|
147 |
-
|
148 |
-
*
|
149 |
*
|
150 |
* @since 0.2
|
151 |
*
|
@@ -153,14 +163,14 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
153 |
*/
|
154 |
function get_columns() {
|
155 |
return array(
|
156 |
-
'name' => __('Content Type', 'lingotek-translation'),
|
157 |
-
'profile' => __('Profile', 'lingotek-translation'),
|
158 |
-
'fields' => __('Fields', 'lingotek-translation'),
|
159 |
);
|
160 |
}
|
161 |
|
162 |
-
|
163 |
-
*
|
164 |
*
|
165 |
* @since 0.2
|
166 |
*
|
@@ -168,36 +178,44 @@ class Lingotek_Content_Table extends WP_List_Table {
|
|
168 |
*/
|
169 |
function get_sortable_columns() {
|
170 |
return array(
|
171 |
-
'name' => array('name', false),
|
172 |
);
|
173 |
}
|
174 |
|
175 |
-
|
176 |
-
*
|
177 |
*
|
178 |
* @since 0.2
|
179 |
*
|
180 |
-
* @param array $data
|
181 |
*/
|
182 |
-
function prepare_items($data = array()) {
|
183 |
-
$per_page = $this->get_items_per_page('lingotek_content_per_page');
|
184 |
-
$this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
};
|
190 |
|
191 |
-
if (!empty(
|
192 |
-
usort($data, 'usort_reorder');
|
|
|
193 |
|
194 |
-
$total_items = count($data);
|
195 |
-
$this->items = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
196 |
|
197 |
$this->set_pagination_args(array(
|
198 |
'total_items' => $total_items,
|
199 |
'per_page' => $per_page,
|
200 |
-
'total_pages' => ceil($total_items
|
201 |
));
|
202 |
}
|
203 |
}
|
1 |
<?php
|
2 |
|
3 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1.
|
5 |
}
|
6 |
|
7 |
+
/**
|
8 |
+
* Lingotek Content Table class.
|
9 |
+
*/
|
10 |
class Lingotek_Content_Table extends WP_List_Table {
|
11 |
+
/**
|
12 |
+
* Profiles.
|
13 |
+
*
|
14 |
+
* @var array
|
15 |
+
*/
|
16 |
+
protected $profiles;
|
17 |
+
/**
|
18 |
+
* Content types.
|
19 |
+
*
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
protected $content_types;
|
23 |
|
24 |
+
/**
|
25 |
+
* Constructor
|
26 |
*
|
27 |
+
* @param array $content_types array of content types.
|
28 |
* @since 0.2
|
29 |
*/
|
30 |
+
function __construct( $content_types ) {
|
31 |
parent::__construct(array(
|
32 |
+
'plural' => 'lingotek-content', // do not translate (used for css class).
|
33 |
+
'ajax' => false,
|
34 |
));
|
35 |
|
36 |
$this->profiles = Lingotek::get_profiles();
|
37 |
$this->content_types = $content_types;
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* Displays the item information in a column (default case)
|
42 |
*
|
43 |
* @since 0.2
|
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('<a id="id[%s]" class="dashicons dashicons-arrow-right" onclick="%s" href="#"></a>',
|
55 |
+
esc_attr( $item['type'] ),
|
56 |
"
|
57 |
+
d1 = document.getElementById('sources-name[" . esc_html( $item['type'] ) . "]');
|
58 |
+
d2 = document.getElementById('sources-profile[" . esc_html( $item['type'] ) . "]');
|
59 |
c = 'dashicons dashicons-arrow-';
|
60 |
if (c+'right' == this.className) {
|
61 |
this.className = c+'down';
|
69 |
"
|
70 |
);
|
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 |
+
/**
|
81 |
+
* Displays the item profile dropdown list
|
82 |
*
|
83 |
* @since 0.2
|
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>';
|
96 |
|
97 |
+
$options = array_merge( array( 'default' => array( 'name' => __( 'Use content type default', 'lingotek-translation' ) ) ), $this->profiles );
|
98 |
|
99 |
+
// the source language for strings is always the default language.
|
100 |
+
if ( 'string' !== $item['type'] ) {
|
101 |
+
printf( '<ul class="sources-profile" id="sources-profile[%s]" style="display:none;">', esc_html( $item['type'] ) );
|
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>';
|
109 |
}
|
111 |
}
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* Displays checkboxes in fields columns
|
116 |
* can handle fields with one or two keys
|
117 |
*
|
118 |
* @since 0.2
|
119 |
*
|
120 |
+
* @param array $labels labels.
|
121 |
+
* @param array $values values.
|
122 |
+
* @param string $name name.
|
123 |
*/
|
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]" );
|
131 |
+
} else {
|
|
|
132 |
printf(
|
133 |
'<li><label><input name="%s" type="checkbox" value="1" %s /> %s</label></li>',
|
134 |
+
esc_attr( $name . "[$key]" ),
|
135 |
+
empty( $values[ $key ] ) ? 'checked="checked"' : '',
|
136 |
+
esc_html( $str )
|
137 |
);
|
138 |
}
|
139 |
}
|
140 |
}
|
141 |
|
142 |
+
/**
|
143 |
+
* Displays the item fields checkboxes
|
144 |
*
|
145 |
* @since 0.2
|
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() , $item['type'] . '[fields]' );
|
153 |
echo '</ul>';
|
154 |
}
|
155 |
}
|
156 |
|
157 |
+
/**
|
158 |
+
* Gets the list of columns
|
159 |
*
|
160 |
* @since 0.2
|
161 |
*
|
163 |
*/
|
164 |
function get_columns() {
|
165 |
return array(
|
166 |
+
'name' => __( 'Content Type', 'lingotek-translation' ),
|
167 |
+
'profile' => __( 'Profile', 'lingotek-translation' ),
|
168 |
+
'fields' => __( 'Fields', 'lingotek-translation' ),
|
169 |
);
|
170 |
}
|
171 |
|
172 |
+
/**
|
173 |
+
* Gets the list of sortable columns
|
174 |
*
|
175 |
* @since 0.2
|
176 |
*
|
178 |
*/
|
179 |
function get_sortable_columns() {
|
180 |
return array(
|
181 |
+
'name' => array( 'name', false ),
|
182 |
);
|
183 |
}
|
184 |
|
185 |
+
/**
|
186 |
+
* Prepares the list of items ofr displaying
|
187 |
*
|
188 |
* @since 0.2
|
189 |
*
|
190 |
+
* @param array $data data.
|
191 |
*/
|
192 |
+
function prepare_items( $data = array() ) {
|
193 |
+
$per_page = $this->get_items_per_page( 'lingotek_content_per_page' );
|
194 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Custom sorting comparator.
|
198 |
+
*
|
199 |
+
* @param array $a array of strings.
|
200 |
+
* @param array $b array of strings.
|
201 |
+
* @return int sort direction.
|
202 |
+
*/
|
203 |
+
function usort_reorder( $a, $b ) {
|
204 |
+
$result = strcmp( $a[ filter_input( INPUT_GET, 'orderby' ) ], $b[ filter_input( INPUT_GET, 'orderby' ) ] ); // determine sort order.
|
205 |
+
return (empty( filter_input( INPUT_GET, 'order' ) ) || filter_input( INPUT_GET, 'order' ) === 'asc') ? $result : -$result; // send final sort direction to usort.
|
206 |
};
|
207 |
|
208 |
+
if ( ! empty( filter_input( INPUT_GET, 'orderby' ) ) ) { // no sort by default.
|
209 |
+
usort( $data, 'usort_reorder' );
|
210 |
+
}
|
211 |
|
212 |
+
$total_items = count( $data );
|
213 |
+
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
214 |
|
215 |
$this->set_pagination_args(array(
|
216 |
'total_items' => $total_items,
|
217 |
'per_page' => $per_page,
|
218 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
219 |
));
|
220 |
}
|
221 |
}
|
admin/custom-fields-table.php
CHANGED
@@ -1,115 +1,134 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if(!class_exists('WP_List_Table')){
|
4 |
-
|
5 |
}
|
6 |
|
|
|
|
|
|
|
7 |
class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
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 |
-
$settings = array('translate', 'copy', 'ignore');
|
45 |
-
$custom_field_choices = get_option('lingotek_custom_fields', array());
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
// select the option from the lingotek_custom_fields option
|
50 |
-
foreach ($settings as $setting) {
|
51 |
-
if ($setting === $custom_field_choices[$item['meta_key']]) {
|
52 |
-
$selected = 'selected="selected"';
|
53 |
-
}
|
54 |
-
else {
|
55 |
-
$selected = '';
|
56 |
-
}
|
57 |
-
echo "\n\t<option value='" . esc_attr($setting) . "' $selected>" . esc_attr(ucwords($setting)) . '</option>';
|
58 |
-
}
|
59 |
-
echo '</select>';
|
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 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
98 |
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
-
|
108 |
-
|
|
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
1 |
<?php
|
2 |
|
3 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1.
|
5 |
}
|
6 |
|
7 |
+
/**
|
8 |
+
* Lingotek Custom Fields Table class.
|
9 |
+
*/
|
10 |
class Lingotek_Custom_Fields_Table extends WP_List_Table {
|
11 |
+
/**
|
12 |
+
* List of profiles.
|
13 |
+
*
|
14 |
+
* @var array
|
15 |
+
*/
|
16 |
+
protected $profiles;
|
17 |
+
/**
|
18 |
+
* List of content types.
|
19 |
+
*
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
protected $content_types;
|
23 |
|
24 |
+
/**
|
25 |
+
* Constructor
|
26 |
+
*
|
27 |
+
* @since 0.2
|
28 |
+
*/
|
29 |
+
function __construct() {
|
30 |
+
parent::__construct(array(
|
31 |
+
'plural' => 'lingotek-custom-fields', // do not translate (used for css class).
|
32 |
+
'ajax' => false,
|
33 |
+
));
|
34 |
+
}
|
35 |
|
36 |
+
/**
|
37 |
+
* Displays the item's meta_key
|
38 |
+
*
|
39 |
+
* @since 0.2
|
40 |
+
*
|
41 |
+
* @param array $item item.
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
function column_meta_key( $item ) {
|
45 |
+
return isset( $item['meta_key'] ) ? esc_html( $item['meta_key'] ) : '';
|
46 |
+
}
|
47 |
|
48 |
+
/**
|
49 |
+
* Displays the item setting
|
50 |
+
*
|
51 |
+
* @since 0.2
|
52 |
+
*
|
53 |
+
* @param array $item item.
|
54 |
+
*/
|
55 |
+
function column_setting( $item ) {
|
56 |
+
$settings = array( 'translate', 'copy', 'ignore' );
|
57 |
+
$custom_field_choices = get_option( 'lingotek_custom_fields', array() );
|
|
|
|
|
58 |
|
59 |
+
printf( '<select class="custom-field-setting" name="%1$s" id="%1$s">', 'settings[' . esc_html( $item['meta_key'] ) . ']' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
+
// select the option from the lingotek_custom_fields option.
|
62 |
+
foreach ( $settings as $setting ) {
|
63 |
+
if ( $setting === $custom_field_choices[ $item['meta_key'] ] ) {
|
64 |
+
$selected = 'selected="selected"';
|
65 |
+
} else {
|
66 |
+
$selected = '';
|
67 |
+
}
|
68 |
+
echo "\n\t<option value='" . esc_attr( $setting ) . "' " . esc_html( $selected ) . '>' . esc_attr( ucwords( $setting ) ) . '</option>';
|
69 |
+
}
|
70 |
+
echo '</select>';
|
71 |
+
}
|
|
|
|
|
72 |
|
73 |
+
/**
|
74 |
+
* Gets the list of columns
|
75 |
+
*
|
76 |
+
* @since 0.2
|
77 |
+
*
|
78 |
+
* @return array the list of column titles
|
79 |
+
*/
|
80 |
+
function get_columns() {
|
81 |
+
return array(
|
82 |
+
'meta_key' => __( 'Custom Field Key', 'lingotek-translation' ),
|
83 |
+
'setting' => __( 'Action', 'lingotek-translation' ),
|
84 |
+
);
|
85 |
+
}
|
86 |
|
87 |
+
/**
|
88 |
+
* Gets the list of sortable columns
|
89 |
+
*
|
90 |
+
* @since 0.2
|
91 |
+
*
|
92 |
+
* @return array
|
93 |
+
*/
|
94 |
+
function get_sortable_columns() {
|
95 |
+
return array(
|
96 |
+
'meta_key' => array( 'meta_key', false ),
|
97 |
+
);
|
98 |
+
}
|
99 |
|
100 |
+
/**
|
101 |
+
* Prepares the list of items for displaying
|
102 |
+
*
|
103 |
+
* @since 0.2
|
104 |
+
*
|
105 |
+
* @param array $data data.
|
106 |
+
*/
|
107 |
+
function prepare_items( $data = array() ) {
|
108 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
109 |
|
110 |
+
/**
|
111 |
+
* Custom sorting comparator.
|
112 |
+
*
|
113 |
+
* @param array $a array of strings.
|
114 |
+
* @param array $b array of strings.
|
115 |
+
* @return int sort direction.
|
116 |
+
*/
|
117 |
+
function usort_reorder( $a, $b ) {
|
118 |
+
$result = strcmp( $a[ filter_input( INPUT_GET, 'orderby' ) ], $b[ filter_input( INPUT_GET, 'orderby' ) ] ); // determine sort order.
|
119 |
+
return (empty( filter_input( INPUT_GET, 'order' ) ) || 'asc' === filter_input( INPUT_GET, 'order' ) ) ? $result : -$result; // send final sort direction to usort.
|
120 |
+
};
|
121 |
|
122 |
+
if ( ! empty( filter_input( INPUT_GET, 'orderby' ) ) ) { // no sort by default.
|
123 |
+
usort( $data, 'usort_reorder' );
|
124 |
+
}
|
125 |
|
126 |
+
$total_items = count( $data );
|
127 |
+
$this->items = $data;
|
128 |
+
|
129 |
+
$this->set_pagination_args(array(
|
130 |
+
'total_items' => $total_items,
|
131 |
+
'per_page' => count( $data ),
|
132 |
+
));
|
133 |
+
}
|
134 |
+
}
|
admin/filters-columns.php
CHANGED
@@ -1,241 +1,277 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Modifies Polylang filters
|
5 |
*
|
6 |
* @since 0.1
|
7 |
*/
|
8 |
class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
12 |
-
*
|
13 |
*
|
14 |
* @since 0.1
|
15 |
*
|
16 |
-
* @param object $polylang Polylang object
|
17 |
*/
|
18 |
-
public function __construct(&$polylang) {
|
19 |
-
parent::__construct($polylang);
|
20 |
|
21 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
22 |
|
23 |
-
// FIXME remove quick edit and bulk edit for now waiting for a solution to remove it only for uploaded documents
|
24 |
-
remove_filter('quick_edit_custom_box', array(&$this, 'quick_edit_custom_box'), 10, 2);
|
25 |
-
remove_filter('bulk_edit_custom_box', array(&$this, 'quick_edit_custom_box'), 10, 2);
|
26 |
}
|
27 |
|
28 |
-
|
29 |
-
*
|
30 |
* overrides Polylang method to display all languages including the filtered one
|
31 |
* as well as displaying a tooltip with the language name and locale when there is no flag
|
32 |
*
|
33 |
* @since 0.2
|
34 |
*
|
35 |
-
* @param array
|
36 |
-
* @param string $before the column before which we want to add our languages
|
37 |
* @return array modified list of columns
|
38 |
*/
|
39 |
-
protected function add_column($columns, $before) {
|
40 |
-
$n = array_search($before, array_keys($columns));
|
41 |
-
if ($n) {
|
42 |
-
$end = array_slice($columns, $n);
|
43 |
-
$columns = array_slice($columns, 0, $n);
|
44 |
}
|
45 |
|
46 |
-
foreach ($this->model->get_languages_list() as $language) {
|
47 |
-
$columns['language_'
|
48 |
sprintf('<a href="" title="%s">%s</a>',
|
49 |
-
esc_html("$language->name ($language->locale)"),
|
50 |
-
esc_html($language->slug)
|
51 |
);
|
52 |
}
|
53 |
|
54 |
-
return isset($end) ? array_merge($columns, $end) : $columns;
|
55 |
}
|
56 |
|
57 |
-
|
58 |
-
*
|
59 |
* take care that when doing ajax inline edit, the post or term may not be updated in database yet
|
60 |
*
|
61 |
* @since 0.2
|
62 |
*
|
63 |
-
* @param string $type 'post' or 'term'
|
64 |
-
* @param string $column column name
|
65 |
-
* @param int
|
|
|
66 |
*/
|
67 |
-
protected function _column($type, $column, $object_id, $custom_data =
|
68 |
-
$action = 'post'
|
69 |
-
$inline = defined('DOING_AJAX') &&
|
70 |
$lang = $inline ?
|
71 |
-
$this->model->get_language(
|
72 |
-
|
73 |
|
74 |
-
if (false === strpos($column, 'language_') ||
|
75 |
-
if ($custom_data) {
|
76 |
return $custom_data;
|
77 |
-
}
|
78 |
-
else {
|
79 |
return '';
|
80 |
}
|
81 |
}
|
82 |
|
83 |
-
$language = $this->model->get_language(substr($column, 9));
|
84 |
|
85 |
-
// FIXME should I suppress quick edit
|
86 |
-
// yes for uploaded posts, but I will need js as the field is built for all posts
|
87 |
-
// /!\ also take care not add this field two times when translations are managed by Polylang
|
88 |
-
// hidden field containing the post language for quick edit (used to filter categories since Polylang 1.7)
|
89 |
-
if ($column
|
90 |
-
printf('<div class="hidden" id="lang_%d">%s</div>', esc_attr($object_id), esc_html($lang->slug));
|
91 |
}
|
92 |
|
93 |
-
$id = ($inline && $lang->slug
|
94 |
-
($language->slug
|
95 |
-
|
96 |
|
97 |
-
$document = $this->lgtm->get_group($type, $object_id);
|
98 |
-
if (isset($document->source)) {
|
99 |
-
$source_language =
|
100 |
-
$source_profile = Lingotek_Model::get_profile($this->content_type, $source_language, $document->source);
|
101 |
-
}
|
102 |
-
else {
|
103 |
$source_language = $lang;
|
104 |
}
|
105 |
|
106 |
-
// FIXME not very clean
|
107 |
-
$actions = 'post'
|
108 |
-
|
109 |
-
$profile = Lingotek_Model::get_profile($this->content_type, $language, $object_id);
|
110 |
-
$disabled = 'disabled' == $profile['profile'];
|
111 |
|
112 |
-
|
113 |
-
|
114 |
-
return $disabled ? ('post' == $type ? parent::post_column($column, $object_id) : parent::term_column('', $column, $object_id))
|
115 |
-
: ($document && (count($document->desc_array) >= 3) ? $actions->upload_icon($object_id, true) : $actions->upload_icon($object_id));
|
116 |
-
}
|
117 |
|
118 |
-
//
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
return $actions->copy_icon($
|
|
|
|
|
129 |
}
|
130 |
}
|
131 |
-
}
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
elseif (isset($document->source) && $document->source == $id) {
|
140 |
-
// source ready for upload
|
141 |
-
if ($this->lgtm->can_upload($type, $id)) {
|
142 |
-
return $actions->upload_icon($id);
|
143 |
}
|
144 |
|
145 |
-
// importing source
|
146 |
-
if ($id
|
147 |
-
return Lingotek_Actions::importing_icon($document);
|
148 |
}
|
149 |
|
150 |
-
// uploaded
|
151 |
-
return 'post'
|
152 |
-
}
|
153 |
-
|
154 |
-
|
155 |
-
elseif (isset($document->translations[$language->locale])
|
156 |
-
return
|
157 |
-
}
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
}
|
162 |
-
|
163 |
-
// translations exist but are not managed by Lingotek TMS
|
164 |
-
elseif (empty($document->source)) {
|
165 |
-
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));
|
166 |
-
}
|
167 |
-
|
168 |
-
// no translation
|
169 |
else {
|
170 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
171 |
}
|
172 |
}
|
173 |
|
174 |
-
|
175 |
-
*
|
176 |
* take care that when doing ajax inline edit, the post may not be updated in database yet
|
177 |
*
|
178 |
* @since 0.1
|
179 |
*
|
180 |
-
* @param string $column column name
|
181 |
-
* @param int
|
182 |
*/
|
183 |
-
public function post_column($column, $post_id) {
|
184 |
-
$this->content_type = get_post_type($post_id);
|
185 |
|
186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
}
|
197 |
}
|
198 |
|
199 |
-
|
200 |
-
*
|
201 |
* take care that when doing ajax inline edit, the term may not be updated in database yet
|
202 |
*
|
203 |
* @since 0.2
|
204 |
*
|
205 |
-
* @param string $
|
206 |
-
* @param string $column column name
|
207 |
-
* @param int
|
208 |
*/
|
209 |
-
public function term_column($custom_data, $column, $term_id) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
$this->content_type = $GLOBALS['taxonomy'];
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
}
|
217 |
-
// checking for api errors
|
218 |
-
$this->error_icon_html($column, $term_id);
|
219 |
}
|
220 |
|
221 |
-
|
222 |
-
*
|
223 |
*
|
224 |
* @since 1.2
|
225 |
*
|
226 |
-
* @param string $column
|
227 |
-
* @param string $object_id
|
|
|
228 |
*/
|
229 |
-
protected function error_icon_html($column, $object_id, $source_locale = null) {
|
230 |
-
// checking for api errors
|
231 |
-
$source_column = substr($column, 9);
|
232 |
-
$column_language_only = substr($column, 0, 11);
|
233 |
-
$errors = get_option('lingotek_log_errors');
|
234 |
-
|
235 |
-
if ($source_column
|
236 |
-
if (isset($errors[$object_id])) {
|
237 |
-
$api_error = Lingotek_Actions::retrieve_api_error($errors[$object_id]);
|
238 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
}
|
240 |
}
|
241 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Modifies Polylang filters
|
5 |
*
|
6 |
* @since 0.1
|
7 |
*/
|
8 |
class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
|
9 |
+
/**
|
10 |
+
* Lingotek model.
|
11 |
+
*
|
12 |
+
* @var object
|
13 |
+
*/
|
14 |
+
public $lgtm;
|
15 |
|
16 |
+
/**
|
17 |
+
* Constructor
|
18 |
*
|
19 |
* @since 0.1
|
20 |
*
|
21 |
+
* @param object $polylang Polylang object.
|
22 |
*/
|
23 |
+
public function __construct( &$polylang ) {
|
24 |
+
parent::__construct( $polylang );
|
25 |
|
26 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
27 |
|
28 |
+
// FIXME remove quick edit and bulk edit for now waiting for a solution to remove it only for uploaded documents.
|
29 |
+
remove_filter( 'quick_edit_custom_box', array( &$this, 'quick_edit_custom_box' ), 10, 2 );
|
30 |
+
remove_filter( 'bulk_edit_custom_box', array( &$this, 'quick_edit_custom_box' ), 10, 2 );
|
31 |
}
|
32 |
|
33 |
+
/**
|
34 |
+
* Adds languages and translations columns in posts, pages, media, categories and tags tables
|
35 |
* overrides Polylang method to display all languages including the filtered one
|
36 |
* as well as displaying a tooltip with the language name and locale when there is no flag
|
37 |
*
|
38 |
* @since 0.2
|
39 |
*
|
40 |
+
* @param array $columns list of table columns.
|
41 |
+
* @param string $before the column before which we want to add our languages.
|
42 |
* @return array modified list of columns
|
43 |
*/
|
44 |
+
protected function add_column( $columns, $before ) {
|
45 |
+
$n = array_search( $before, array_keys( $columns ), true );
|
46 |
+
if ( $n ) {
|
47 |
+
$end = array_slice( $columns, $n );
|
48 |
+
$columns = array_slice( $columns, 0, $n );
|
49 |
}
|
50 |
|
51 |
+
foreach ( $this->model->get_languages_list() as $language ) {
|
52 |
+
$columns[ 'language_' . $language->locale ] = $language->flag ? $language->flag :
|
53 |
sprintf('<a href="" title="%s">%s</a>',
|
54 |
+
esc_html( "$language->name ($language->locale)" ),
|
55 |
+
esc_html( $language->slug )
|
56 |
);
|
57 |
}
|
58 |
|
59 |
+
return isset( $end ) ? array_merge( $columns, $end ) : $columns;
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* Fills the language and translations columns in the posts and taxonomies lists tables
|
64 |
* take care that when doing ajax inline edit, the post or term may not be updated in database yet
|
65 |
*
|
66 |
* @since 0.2
|
67 |
*
|
68 |
+
* @param string $type 'post' or 'term'.
|
69 |
+
* @param string $column column name.
|
70 |
+
* @param int $object_id id of the current object in row.
|
71 |
+
* @param item $custom_data data.
|
72 |
*/
|
73 |
+
protected function _column( $type, $column, $object_id, $custom_data = null ) {
|
74 |
+
$action = 'post' === $type ? 'inline-save' : 'inline-save-tax';
|
75 |
+
$inline = defined( 'DOING_AJAX' ) && filter_input( INPUT_GET, 'action' ) === $action && ! empty( filter_input( INPUT_POST, 'inline_lang_choice' ) );
|
76 |
$lang = $inline ?
|
77 |
+
$this->model->get_language( filter_input( INPUT_POST, 'inline_lang_choice' ) ) :
|
78 |
+
'post' === $type ? PLL()->model->post->get_language( $object_id ) : PLL()->model->term->get_language( $object_id );
|
79 |
|
80 |
+
if ( false === strpos( $column, 'language_' ) || ! $lang ) {
|
81 |
+
if ( $custom_data ) {
|
82 |
return $custom_data;
|
83 |
+
} else {
|
|
|
84 |
return '';
|
85 |
}
|
86 |
}
|
87 |
|
88 |
+
$language = $this->model->get_language( substr( $column, 9 ) );
|
89 |
|
90 |
+
// FIXME should I suppress quick edit?.
|
91 |
+
// yes for uploaded posts, but I will need js as the field is built for all posts.
|
92 |
+
// /!\ also take care not add this field two times when translations are managed by Polylang.
|
93 |
+
// hidden field containing the post language for quick edit (used to filter categories since Polylang 1.7).
|
94 |
+
if ( $column === $this->get_first_language_column() ) {
|
95 |
+
printf( '<div class="hidden" id="lang_%d">%s</div>', esc_attr( $object_id ), esc_html( $lang->slug ) );
|
96 |
}
|
97 |
|
98 |
+
$id = ($inline && $lang->slug !== $this->model->get_language( filter_input( INPUT_POST, 'old_lang' ) )->slug) ?
|
99 |
+
($language->slug === $lang->slug ? $object_id : 0) :
|
100 |
+
'post' === $type ? PLL()->model->post->get( $object_id, $language ) : PLL()->model->term->get( $object_id, $language );
|
101 |
|
102 |
+
$document = $this->lgtm->get_group( $type, $object_id );
|
103 |
+
if ( isset( $document->source ) ) {
|
104 |
+
$source_language = 'post' === $type ? PLL()->model->post->get_language( $document->source ) : PLL()->model->term->get_language( $document->source );
|
105 |
+
$source_profile = Lingotek_Model::get_profile( $this->content_type, $source_language, $document->source );
|
106 |
+
} else {
|
|
|
107 |
$source_language = $lang;
|
108 |
}
|
109 |
|
110 |
+
// FIXME not very clean.
|
111 |
+
$actions = 'post' === $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
|
|
|
|
|
|
|
112 |
|
113 |
+
$profile = Lingotek_Model::get_profile( $this->content_type, $language, $object_id );
|
114 |
+
$disabled = 'disabled' === $profile['profile'];
|
|
|
|
|
|
|
115 |
|
116 |
+
// post ready for upload.
|
117 |
+
if ( $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
|
118 |
+
return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
|
119 |
+
: ($document && (count( $document->desc_array ) >= 3) ? $actions->upload_icon( $object_id, true ) : $actions->upload_icon( $object_id ));
|
120 |
+
} // if language is set to copy and profile is manual.
|
121 |
+
elseif ( ('post' === $type) && ((isset( $source_profile['targets'][ $language->slug ] ) && 'copy' === $source_profile['targets'][ $language->slug ]) || (isset( $profile['targets'][ $language->slug ] ) && 'copy' === $profile['targets'][ $language->slug ] ) && isset( $document->source )) ) {
|
122 |
+
if ( isset( $document->desc_array[ $language->slug ] ) ) {
|
123 |
+
return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
|
124 |
+
} else {
|
125 |
+
if ( $document ) {
|
126 |
+
return $actions->copy_icon( $document->source, $language->slug );
|
127 |
+
} else {
|
128 |
+
return $actions->copy_icon( $object_id, $language->slug );
|
129 |
}
|
130 |
}
|
131 |
+
} // translation disabled.
|
132 |
+
elseif ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) && ! isset( $document->translations[ $language->locale ] ) ) {
|
133 |
+
return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
|
134 |
+
} // source post is uploaded.
|
135 |
+
elseif ( isset( $document->source ) && $document->source === $id ) {
|
136 |
+
// source ready for upload.
|
137 |
+
if ( $this->lgtm->can_upload( $type, $id ) ) {
|
138 |
+
return $actions->upload_icon( $id );
|
|
|
|
|
|
|
|
|
139 |
}
|
140 |
|
141 |
+
// importing source.
|
142 |
+
if ( $id === $object_id && 'importing' === $document->status ) {
|
143 |
+
return Lingotek_Actions::importing_icon( $document );
|
144 |
}
|
145 |
|
146 |
+
// uploaded.
|
147 |
+
return 'post' === $type ? Lingotek_Post_actions::uploaded_icon( $id ) : Lingotek_Term_actions::uploaded_icon( $id );
|
148 |
+
} // translations.
|
149 |
+
elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
|
150 |
+
return Lingotek_Actions::translation_icon( $document, $language );
|
151 |
+
} elseif ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) {
|
152 |
+
return parent::term_column( '', $column, $object_id );
|
153 |
+
} // translations exist but are not managed by Lingotek TMS.
|
154 |
+
elseif ( empty( $document->source ) ) {
|
155 |
+
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 ));
|
156 |
+
} // no translation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
else {
|
158 |
return '<div class="lingotek-color dashicons dashicons-no"></div>';
|
159 |
}
|
160 |
}
|
161 |
|
162 |
+
/**
|
163 |
+
* Fills the language and translations columns in the posts, pages and media library tables
|
164 |
* take care that when doing ajax inline edit, the post may not be updated in database yet
|
165 |
*
|
166 |
* @since 0.1
|
167 |
*
|
168 |
+
* @param string $column column name.
|
169 |
+
* @param int $post_id post id.
|
170 |
*/
|
171 |
+
public function post_column( $column, $post_id ) {
|
172 |
+
$this->content_type = get_post_type( $post_id );
|
173 |
|
174 |
+
$allowed_html = [
|
175 |
+
'a' => [
|
176 |
+
'href' => [],
|
177 |
+
'class' => [],
|
178 |
+
'title' => [],
|
179 |
+
],
|
180 |
+
'div' => [
|
181 |
+
'class' => [],
|
182 |
+
],
|
183 |
+
];
|
184 |
+
echo wp_kses( $this->_column( 'post', $column, $post_id ), $allowed_html );
|
185 |
|
186 |
+
/**
|
187 |
+
* Setup workflow specific logic for posts.
|
188 |
+
*/
|
189 |
+
$post = get_post( $post_id );
|
190 |
+
$language = PLL()->model->post->get_language( $post_id );
|
191 |
+
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $language, false, $post_id );
|
192 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id ); // TODO: put workflow_id here. It is currently not set up.
|
193 |
+
$workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
194 |
+
$workflow->echo_posts_modal( $workflow_id ); // adds modal html to page.
|
195 |
+
|
196 |
+
// checking for api errors.
|
197 |
+
$document = $this->lgtm->get_group( 'post', $post_id );
|
198 |
+
if ( isset( $document->source ) ) {
|
199 |
+
$source_language = PLL()->model->post->get_language( $document->source );
|
200 |
+
$this->error_icon_html( $column, $post_id, $source_language->locale );
|
201 |
+
} else {
|
202 |
+
$this->error_icon_html( $column, $post_id );
|
203 |
}
|
204 |
}
|
205 |
|
206 |
+
/**
|
207 |
+
* Fills the language and translations columns in the categories and post tags tables
|
208 |
* take care that when doing ajax inline edit, the term may not be updated in database yet
|
209 |
*
|
210 |
* @since 0.2
|
211 |
*
|
212 |
+
* @param string $custom_data data.
|
213 |
+
* @param string $column column name.
|
214 |
+
* @param int $term_id term id.
|
215 |
*/
|
216 |
+
public function term_column( $custom_data, $column, $term_id ) {
|
217 |
+
$allowed_html = [
|
218 |
+
'a' => [
|
219 |
+
'href' => [],
|
220 |
+
'class' => [],
|
221 |
+
'title' => [],
|
222 |
+
],
|
223 |
+
'div' => [
|
224 |
+
'class' => [],
|
225 |
+
],
|
226 |
+
'span' => [
|
227 |
+
'class' => [],
|
228 |
+
],
|
229 |
+
];
|
230 |
$this->content_type = $GLOBALS['taxonomy'];
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Setup workflow specific logic for terms.
|
234 |
+
*/
|
235 |
+
$workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $this->content_type, PLL()->model->term->get_language( $term_id ) );
|
236 |
+
$workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id ); // TODO: put workflow_id here. It is currently not set up.
|
237 |
+
$workflow->override_events( $workflow_id ); // Loads appropriate .js file.
|
238 |
+
$workflow->echo_terms_modal( $workflow_id ); // adds modal html to page.
|
239 |
+
|
240 |
+
if ( ! $custom_data ) {
|
241 |
+
echo wp_kses( $this->_column( 'term', $column, $term_id ), $allowed_html );
|
242 |
+
} else {
|
243 |
+
echo wp_kses( $this->_column( 'term', $column, $term_id, $custom_data ), $allowed_html );
|
244 |
}
|
245 |
+
// checking for api errors.
|
246 |
+
$this->error_icon_html( $column, $term_id );
|
247 |
}
|
248 |
|
249 |
+
/**
|
250 |
+
* Checks for errors in the lingotek_log_errors option and displays an icon
|
251 |
*
|
252 |
* @since 1.2
|
253 |
*
|
254 |
+
* @param string $column column.
|
255 |
+
* @param string $object_id id.
|
256 |
+
* @param item $source_locale locale.
|
257 |
*/
|
258 |
+
protected function error_icon_html( $column, $object_id, $source_locale = null ) {
|
259 |
+
// checking for api errors.
|
260 |
+
$source_column = substr( $column, 9 );
|
261 |
+
$column_language_only = substr( $column, 0, 11 );
|
262 |
+
$errors = get_option( 'lingotek_log_errors' );
|
263 |
+
|
264 |
+
if ( $source_column === $source_locale ) {
|
265 |
+
if ( isset( $errors[ $object_id ] ) ) {
|
266 |
+
$api_error = Lingotek_Actions::retrieve_api_error( $errors[ $object_id ] );
|
267 |
+
$allowed_html = [
|
268 |
+
'a' => [
|
269 |
+
'href' => [],
|
270 |
+
'class' => [],
|
271 |
+
'title' => [],
|
272 |
+
],
|
273 |
+
];
|
274 |
+
echo wp_kses( Lingotek_Actions::display_error_icon( 'error', $api_error ), $allowed_html );
|
275 |
}
|
276 |
}
|
277 |
}
|
admin/filters-media.php
CHANGED
@@ -1,56 +1,63 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Manages automatic upload
|
5 |
*
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
class Lingotek_Filters_Media extends PLL_Admin_Filters_Media {
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
12 |
* Constructor
|
13 |
*
|
14 |
* @since 0.2
|
|
|
15 |
*/
|
16 |
-
public function __construct(&$polylang) {
|
17 |
-
parent::__construct($polylang);
|
18 |
|
19 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
20 |
|
21 |
-
add_action('edit_attachment', array(&$this, 'edit_attachment'));
|
22 |
-
add_action('add_attachment', array(&$this, 'add_attachment'), 11); // after Polylang
|
23 |
}
|
24 |
|
25 |
-
|
26 |
-
*
|
27 |
*
|
28 |
* @since 0.2
|
29 |
*
|
30 |
-
* @param int $post_id
|
31 |
*/
|
32 |
-
public function edit_attachment($post_id) {
|
33 |
-
$document = $this->lgtm->get_group('post', $post_id);
|
34 |
|
35 |
// FIXME how to check if the attachment is really modified?
|
36 |
-
if ($document && $post_id
|
37 |
$document->source_edited();
|
38 |
|
39 |
-
if ($document->is_automatic_upload()) {
|
40 |
-
$this->lgtm->upload_post($post_id);
|
41 |
}
|
42 |
}
|
43 |
}
|
44 |
|
45 |
-
|
46 |
-
*
|
47 |
*
|
48 |
* @since 0.2
|
49 |
|
50 |
-
* @param int $post_id
|
51 |
*/
|
52 |
-
public function add_attachment($post_id) {
|
53 |
-
if ($this->model->is_translated_post_type('attachment') && 'automatic'
|
54 |
-
$this->lgtm->upload_post($post_id);
|
|
|
55 |
}
|
56 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Manages automatic upload
|
5 |
*
|
6 |
* @since 0.2
|
7 |
*/
|
8 |
class Lingotek_Filters_Media extends PLL_Admin_Filters_Media {
|
9 |
+
/**
|
10 |
+
* Lingotek model.
|
11 |
+
*
|
12 |
+
* @var object
|
13 |
+
*/
|
14 |
+
public $lgtm;
|
15 |
|
16 |
+
/**
|
17 |
* Constructor
|
18 |
*
|
19 |
* @since 0.2
|
20 |
+
* @param model $polylang polylang.
|
21 |
*/
|
22 |
+
public function __construct( &$polylang ) {
|
23 |
+
parent::__construct( $polylang );
|
24 |
|
25 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
26 |
|
27 |
+
add_action( 'edit_attachment', array( &$this, 'edit_attachment' ) );
|
28 |
+
add_action( 'add_attachment', array( &$this, 'add_attachment' ), 11 ); // after Polylang.
|
29 |
}
|
30 |
|
31 |
+
/**
|
32 |
+
* Marks the attachment as edited if needed
|
33 |
*
|
34 |
* @since 0.2
|
35 |
*
|
36 |
+
* @param int $post_id post id.
|
37 |
*/
|
38 |
+
public function edit_attachment( $post_id ) {
|
39 |
+
$document = $this->lgtm->get_group( 'post', $post_id );
|
40 |
|
41 |
// FIXME how to check if the attachment is really modified?
|
42 |
+
if ( $document && $post_id === $document->source ) {
|
43 |
$document->source_edited();
|
44 |
|
45 |
+
if ( $document->is_automatic_upload() ) {
|
46 |
+
$this->lgtm->upload_post( $post_id );
|
47 |
}
|
48 |
}
|
49 |
}
|
50 |
|
51 |
+
/**
|
52 |
+
* Uploads an attachment when saved for the first time
|
53 |
*
|
54 |
* @since 0.2
|
55 |
|
56 |
+
* @param int $post_id post id.
|
57 |
*/
|
58 |
+
public function add_attachment( $post_id ) {
|
59 |
+
if ( $this->model->is_translated_post_type( 'attachment' ) && 'automatic' === Lingotek_Model::get_profile_option( 'upload', 'attachment', PLL()->model->post->get_language( $post_id ) ) && $this->lgtm->can_upload( 'post', $post_id ) ) {
|
60 |
+
$this->lgtm->upload_post( $post_id );
|
61 |
+
}
|
62 |
}
|
63 |
}
|
admin/filters-post.php
CHANGED
@@ -99,6 +99,10 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
99 |
$profile = $content_profiles[$post_type]['sources'][$post_language->slug];
|
100 |
echo $profiles[$profile]['name'];
|
101 |
}
|
|
|
|
|
|
|
|
|
102 |
else if (!empty($content_profiles)) {
|
103 |
echo $profiles[$content_profiles[$post_type]['profile']]['name'];
|
104 |
}
|
@@ -139,7 +143,6 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
139 |
// updated post
|
140 |
if ($document && $post_id == $document->source && $this->post_hash_has_changed($post)) {
|
141 |
$document->source_edited();
|
142 |
-
|
143 |
if ($document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status)) {
|
144 |
$this->lgtm->upload_post($post_id);
|
145 |
}
|
@@ -151,8 +154,7 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
|
|
151 |
// new post
|
152 |
if (!isset($_REQUEST['import'])) {
|
153 |
parent::save_post($post_id, $post, $update);
|
154 |
-
|
155 |
-
if (!wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, PLL()->model->post->get_language($post_id), false, $post_id) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
|
156 |
$this->lgtm->upload_post($post_id);
|
157 |
}
|
158 |
}
|
99 |
$profile = $content_profiles[$post_type]['sources'][$post_language->slug];
|
100 |
echo $profiles[$profile]['name'];
|
101 |
}
|
102 |
+
else if (!empty($content_profiles) && !isset($profiles[$content_profiles[$post_type]['profile']]['name']))
|
103 |
+
{
|
104 |
+
echo esc_html( __('Disabled', 'lingotek-translation') );
|
105 |
+
}
|
106 |
else if (!empty($content_profiles)) {
|
107 |
echo $profiles[$content_profiles[$post_type]['profile']]['name'];
|
108 |
}
|
143 |
// updated post
|
144 |
if ($document && $post_id == $document->source && $this->post_hash_has_changed($post)) {
|
145 |
$document->source_edited();
|
|
|
146 |
if ($document->is_automatic_upload() && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status)) {
|
147 |
$this->lgtm->upload_post($post_id);
|
148 |
}
|
154 |
// new post
|
155 |
if (!isset($_REQUEST['import'])) {
|
156 |
parent::save_post($post_id, $post, $update);
|
157 |
+
if (!wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, PLL()->model->post->get_language($post_id), false, $post_id) && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
|
|
|
158 |
$this->lgtm->upload_post($post_id);
|
159 |
}
|
160 |
}
|
admin/filters-term.php
CHANGED
@@ -1,134 +1,159 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Modifies Polylang filters
|
5 |
* Manages automatic upload
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
|
14 |
* Constructor
|
15 |
*
|
16 |
* @since 0.2
|
|
|
17 |
*/
|
18 |
-
public function __construct(&$polylang) {
|
19 |
-
parent::__construct($polylang);
|
20 |
|
21 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
22 |
|
23 |
-
add_action('edit_terms', array(&$this, 'save_old_term'), 10, 2);
|
24 |
-
add_action('edited_term', array(&$this, 'edited_term'), 10, 3);
|
25 |
}
|
26 |
|
27 |
-
|
28 |
-
*
|
29 |
*
|
30 |
* @since 0.2
|
|
|
31 |
*/
|
32 |
-
public function edit_term_form($tag) {
|
33 |
-
if ($this->model->is_translated_taxonomy($tag->taxonomy)) {
|
34 |
-
$document = $this->lgtm->get_group('term', $tag->term_id);
|
35 |
-
if (empty($document->source))
|
36 |
-
parent::edit_term_form($tag);
|
|
|
37 |
}
|
38 |
}
|
39 |
|
40 |
-
|
41 |
-
*
|
42 |
*
|
43 |
* @since 0.2
|
44 |
|
45 |
-
* @param int
|
46 |
-
* @param int
|
47 |
-
* @param string $taxonomy
|
48 |
*/
|
49 |
-
public function save_term($term_id, $tt_id, $taxonomy) {
|
50 |
-
if (
|
51 |
return;
|
|
|
52 |
|
53 |
-
if (
|
54 |
-
parent::save_term($term_id, $tt_id, $taxonomy);
|
55 |
|
56 |
-
if ('automatic'
|
57 |
-
$this->lgtm->upload_term($term_id, $taxonomy);
|
|
|
58 |
}
|
59 |
}
|
60 |
}
|
61 |
|
62 |
-
|
63 |
-
*
|
64 |
*
|
65 |
* @since 0.2
|
66 |
*
|
67 |
-
* @param int
|
68 |
-
* @param string $taxonomy
|
69 |
*/
|
70 |
-
public function save_old_term($term_id, $taxonomy) {
|
71 |
-
if (pll_is_translated_taxonomy($taxonomy))
|
72 |
-
$this->old_term = md5(Lingotek_Group_Term::get_content(get_term($term_id, $taxonomy)));
|
|
|
73 |
}
|
74 |
|
75 |
-
|
76 |
-
*
|
77 |
*
|
78 |
* @since 0.2
|
79 |
*
|
80 |
-
* @param int
|
81 |
-
* @param int
|
82 |
-
* @param string $taxonomy
|
83 |
*/
|
84 |
-
public function edited_term($term_id, $tt_id, $taxonomy) {
|
85 |
-
if (pll_is_translated_taxonomy($taxonomy)) {
|
86 |
-
$document = $this->lgtm->get_group('term', $term_id);
|
87 |
|
88 |
-
if ($document && $term_id
|
89 |
$document->source_edited();
|
90 |
|
91 |
-
if ($document->is_automatic_upload()) {
|
92 |
-
$this->lgtm->upload_term($term_id, $taxonomy);
|
93 |
}
|
94 |
}
|
95 |
}
|
96 |
}
|
97 |
|
98 |
-
|
99 |
-
*
|
100 |
* since we can't sync all translations as we get conflicts when attempting to act two times on the same
|
101 |
*
|
102 |
* @since 0.2
|
103 |
*
|
104 |
-
* @param int $term_id
|
105 |
* @return array
|
106 |
*/
|
107 |
-
protected function get_translations_to_sync($term_id) {
|
108 |
-
// don't synchronize disassociated terms
|
109 |
-
$group = $this->lgtm->get_group('term', $term_id);
|
110 |
-
if (empty($group->source))
|
111 |
return array();
|
|
|
112 |
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
$term_ids[] = $term_id;
|
117 |
-
return array_diff(PLL()->model->term->get_translations($term_id), $term_ids);
|
118 |
}
|
119 |
|
120 |
-
|
121 |
-
*
|
122 |
*
|
123 |
* @since 0.2
|
124 |
*
|
125 |
-
* @param int $term_id
|
126 |
*/
|
127 |
-
public function delete_term($term_id) {
|
128 |
-
$taxonomy = substr(current_filter(), 7);
|
129 |
-
foreach ($this->get_translations_to_sync($term_id) as $tr_id) {
|
130 |
-
wp_delete_term($tr_id, $taxonomy); // forces deletion for the translations which are not already in the list
|
131 |
}
|
132 |
-
$this->lgtm->delete_term($term_id);
|
133 |
}
|
134 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Modifies Polylang filters
|
5 |
* Manages automatic upload
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
|
10 |
+
/**
|
11 |
+
* Lingotek model.
|
12 |
+
*
|
13 |
+
* @var object
|
14 |
+
*/
|
15 |
+
public $lgtm;
|
16 |
+
/**
|
17 |
+
* Old term.
|
18 |
+
*
|
19 |
+
* @var string.
|
20 |
+
*/
|
21 |
+
protected $old_term;
|
22 |
|
23 |
+
/**
|
24 |
* Constructor
|
25 |
*
|
26 |
* @since 0.2
|
27 |
+
* @param object $polylang polylang model.
|
28 |
*/
|
29 |
+
public function __construct( &$polylang ) {
|
30 |
+
parent::__construct( $polylang );
|
31 |
|
32 |
$this->lgtm = &$GLOBALS['wp_lingotek']->model;
|
33 |
|
34 |
+
add_action( 'edit_terms', array( &$this, 'save_old_term' ), 10, 2 );
|
35 |
+
add_action( 'edited_term', array( &$this, 'edited_term' ), 10, 3 );
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* Controls whether to display the language metabox or not
|
40 |
*
|
41 |
* @since 0.2
|
42 |
+
* @param object $tag tag object.
|
43 |
*/
|
44 |
+
public function edit_term_form( $tag ) {
|
45 |
+
if ( $this->model->is_translated_taxonomy( $tag->taxonomy ) ) {
|
46 |
+
$document = $this->lgtm->get_group( 'term', $tag->term_id );
|
47 |
+
if ( empty( $document->source ) ) {
|
48 |
+
parent::edit_term_form( $tag );
|
49 |
+
}
|
50 |
}
|
51 |
}
|
52 |
|
53 |
+
/**
|
54 |
+
* Uploads a term when saved for the first time
|
55 |
*
|
56 |
* @since 0.2
|
57 |
|
58 |
+
* @param int $term_id id.
|
59 |
+
* @param int $tt_id term taxononomy id.
|
60 |
+
* @param string $taxonomy taxonomy.
|
61 |
*/
|
62 |
+
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
63 |
+
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
64 |
return;
|
65 |
+
}
|
66 |
|
67 |
+
if ( empty( filter_input( INPUT_GET, 'import' ) ) && empty( filter_input( INPUT_POST, 'import' ) ) ) {
|
68 |
+
parent::save_term( $term_id, $tt_id, $taxonomy );
|
69 |
|
70 |
+
if ( 'automatic' === Lingotek_Model::get_profile_option( 'upload', $taxonomy, PLL()->model->term->get_language( $term_id ) ) && $this->lgtm->can_upload( 'term', $term_id ) ) {
|
71 |
+
$this->lgtm->upload_term( $term_id, $taxonomy );
|
72 |
+
} {
|
73 |
}
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
+
* Saves the md5sum of a term before it is edited
|
79 |
*
|
80 |
* @since 0.2
|
81 |
*
|
82 |
+
* @param int $term_id term id.
|
83 |
+
* @param string $taxonomy taxonomy.
|
84 |
*/
|
85 |
+
public function save_old_term( $term_id, $taxonomy ) {
|
86 |
+
if ( pll_is_translated_taxonomy( $taxonomy ) ) {
|
87 |
+
$this->old_term = md5( Lingotek_Group_Term::get_content( get_term( $term_id, $taxonomy ) ) );
|
88 |
+
}
|
89 |
}
|
90 |
|
91 |
+
/**
|
92 |
+
* Marks the term as edited if needed
|
93 |
*
|
94 |
* @since 0.2
|
95 |
*
|
96 |
+
* @param int $term_id term id.
|
97 |
+
* @param int $tt_id not used.
|
98 |
+
* @param string $taxonomy taxonomy.
|
99 |
*/
|
100 |
+
public function edited_term( $term_id, $tt_id, $taxonomy ) {
|
101 |
+
if ( pll_is_translated_taxonomy( $taxonomy ) ) {
|
102 |
+
$document = $this->lgtm->get_group( 'term', $term_id );
|
103 |
|
104 |
+
if ( $document && $term_id === $document->source && md5( Lingotek_Group_Term::get_content( get_term( $term_id, $taxonomy ) ) ) !== $this->old_term ) {
|
105 |
$document->source_edited();
|
106 |
|
107 |
+
if ( $document->is_automatic_upload() ) {
|
108 |
+
$this->lgtm->upload_term( $term_id, $taxonomy );
|
109 |
}
|
110 |
}
|
111 |
}
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* Get translations ids to sync for delete
|
116 |
* since we can't sync all translations as we get conflicts when attempting to act two times on the same
|
117 |
*
|
118 |
* @since 0.2
|
119 |
*
|
120 |
+
* @param int $term_id term id.
|
121 |
* @return array
|
122 |
*/
|
123 |
+
protected function get_translations_to_sync( $term_id ) {
|
124 |
+
// don't synchronize disassociated terms.
|
125 |
+
$group = $this->lgtm->get_group( 'term', $term_id );
|
126 |
+
if ( empty( $group->source ) ) {
|
127 |
return array();
|
128 |
+
}
|
129 |
|
130 |
+
$delete_tags = null;
|
131 |
+
if ( ! empty( filter_input( INPUT_GET, 'delete_tags' ) ) ) {
|
132 |
+
$delete_tags = filter_input( INPUT_GET, 'delete_tags' );
|
133 |
+
} elseif ( ! empty( filter_input( INPUT_POST, 'delete_tags' ) ) ) {
|
134 |
+
$delete_tags = filter_input( INPUT_POST, 'delete_tags' );
|
135 |
+
}
|
136 |
+
|
137 |
+
if ( isset( $delete_tags ) && is_array( $delete_tags ) ) {
|
138 |
+
$term_ids = array_map( 'intval', $delete_tags );
|
139 |
+
}
|
140 |
|
141 |
$term_ids[] = $term_id;
|
142 |
+
return array_diff( PLL()->model->term->get_translations( $term_id ), $term_ids );
|
143 |
}
|
144 |
|
145 |
+
/**
|
146 |
+
* Deletes the Lingotek document when a source document is deleted
|
147 |
*
|
148 |
* @since 0.2
|
149 |
*
|
150 |
+
* @param int $term_id term id.
|
151 |
*/
|
152 |
+
public function delete_term( $term_id ) {
|
153 |
+
$taxonomy = substr( current_filter(), 7 );
|
154 |
+
foreach ( $this->get_translations_to_sync( $term_id ) as $tr_id ) {
|
155 |
+
wp_delete_term( $tr_id, $taxonomy ); // forces deletion for the translations which are not already in the list.
|
156 |
}
|
157 |
+
$this->lgtm->delete_term( $term_id );
|
158 |
}
|
159 |
}
|
admin/manage/view-content.php
CHANGED
@@ -78,7 +78,7 @@ else {
|
|
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'
|
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'];
|
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 ? 'automatic' : ('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'];
|
admin/manage/view-strings.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<h3 style="padding-top:
|
2 |
|
3 |
<?php
|
4 |
$listlanguages = $GLOBALS['polylang']->model->get_languages_list();
|
@@ -40,7 +40,7 @@ $string_table = new Lingotek_Table_String(compact('languages', 'groups', 'select
|
|
40 |
$string_table->prepare_items($data); ?>
|
41 |
|
42 |
<div class="form-wrap">
|
43 |
-
<form id="string-translation" method="post" action="admin.php?page=
|
44 |
<input type="hidden" name="pll_action" value="string-translation" /><?php
|
45 |
$string_table->search_box(__('Search translations', 'lingotek-translation'), 'translations' );
|
46 |
wp_nonce_field('string-translation', '_wpnonce_string-translation');
|
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();
|
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" /><?php
|
45 |
$string_table->search_box(__('Search translations', 'lingotek-translation'), 'translations' );
|
46 |
wp_nonce_field('string-translation', '_wpnonce_string-translation');
|
admin/post-actions.php
CHANGED
@@ -1,151 +1,163 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
* Adds row and bulk actions to posts, pages and media list
|
5 |
* Manages actions which trigger communication with Lingotek TMS
|
6 |
-
|
7 |
*
|
8 |
* @since 0.2
|
9 |
*/
|
10 |
class Lingotek_Post_actions extends Lingotek_Actions {
|
11 |
|
12 |
-
|
13 |
* Constructor
|
14 |
*
|
15 |
* @since 0.2
|
16 |
*/
|
17 |
public function __construct() {
|
18 |
-
parent::__construct('post');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
add_filter('media_row_actions', array(&$this, 'post_row_actions'), 10, 2);
|
24 |
|
25 |
-
|
26 |
-
add_action('admin_footer-edit.php', array(&$this, 'add_bulk_actions')); // FIXME admin_print_footer_scripts instead?
|
27 |
-
add_action('admin_footer-upload.php', array(&$this, 'add_bulk_actions'));
|
28 |
|
29 |
-
// manage bulk actions, row actions and icon actions
|
30 |
-
add_action('load-edit.php', array(&$this, 'manage_actions'));
|
31 |
-
add_action('load-upload.php', array(&$this, 'manage_actions'));
|
32 |
|
33 |
-
// add meta box on post and page edit pages, and hook on save
|
34 |
-
add_action('add_meta_boxes', array(&$this, 'lingotek_add_meta_boxes'));
|
35 |
-
add_action('save_post', array(&$this, 'lingotek_save_meta_boxes'));
|
36 |
}
|
37 |
|
38 |
-
|
39 |
-
*
|
40 |
*
|
41 |
* @since 0.2
|
42 |
*
|
43 |
* @param int $post_id
|
44 |
* @return object
|
45 |
*/
|
46 |
-
protected function get_language($post_id) {
|
47 |
-
return PLL()->model->post->get_language($post_id);
|
48 |
}
|
49 |
|
50 |
-
|
51 |
-
*
|
52 |
*
|
53 |
* @since 0.2
|
54 |
*
|
55 |
* @param int $id
|
56 |
*/
|
57 |
-
public static function uploaded_icon($id) {
|
58 |
-
return self::display_icon('uploaded', get_edit_post_link($id));
|
59 |
}
|
60 |
|
61 |
-
|
62 |
-
*
|
63 |
*
|
64 |
* @since 0.1
|
65 |
*
|
66 |
-
* @param array
|
67 |
-
* @param object $post
|
68 |
* @return array
|
69 |
*/
|
70 |
-
public function post_row_actions($actions, $post) {
|
71 |
-
if ($this->pllm->is_translated_post_type($post->post_type)) {
|
72 |
-
$actions = $this->_row_actions($actions, $post->ID);
|
73 |
-
|
74 |
-
$language = PLL()->model->post->get_language($post->ID);
|
75 |
-
if (!empty($language)) {
|
76 |
-
$profile = Lingotek_Model::get_profile($post->post_type, $language, $post->ID);
|
77 |
-
if ('disabled'
|
78 |
-
unset($actions['lingotek-upload']);
|
|
|
79 |
}
|
80 |
}
|
81 |
return $actions;
|
82 |
}
|
83 |
|
84 |
-
|
85 |
-
*
|
86 |
*
|
87 |
* @since 0.1
|
88 |
*/
|
89 |
-
public function add_bulk_actions() {
|
90 |
-
if (isset($GLOBALS['post_type']) && $this->pllm->is_translated_post_type($GLOBALS['post_type']))
|
91 |
-
$this->_add_bulk_actions();
|
|
|
92 |
}
|
93 |
|
94 |
-
|
95 |
-
*
|
96 |
*
|
97 |
* @since 0.1
|
98 |
*/
|
99 |
public function manage_actions() {
|
100 |
global $typenow;
|
101 |
-
$post_type = 'load-upload.php'
|
102 |
|
103 |
-
if (
|
104 |
return;
|
|
|
105 |
|
106 |
-
// get the action
|
107 |
-
// $typenow is empty for media
|
108 |
-
$wp_list_table = _get_list_table(empty($typenow) ? 'WP_Media_List_Table' : 'WP_Posts_List_Table');
|
109 |
$action = $wp_list_table->current_action();
|
110 |
|
111 |
-
if (empty($action))
|
112 |
return;
|
|
|
113 |
|
114 |
-
$redirect = remove_query_arg( array('action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), wp_get_referer() );
|
115 |
-
if (
|
116 |
-
$redirect = admin_url("edit.php?post_type=$typenow");
|
|
|
117 |
|
118 |
-
switch($action) {
|
119 |
case 'bulk-lingotek-upload':
|
120 |
-
$type = empty($typenow) ? 'media' : 'post';
|
121 |
-
|
|
|
122 |
return;
|
|
|
123 |
|
124 |
$post_ids = array();
|
125 |
|
126 |
-
foreach (array_map('intval', $
|
127 |
-
// safe upload
|
128 |
-
if ($this->lgtm->can_upload('post', $post_id))
|
129 |
$post_ids[] = $post_id;
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
if (empty($intersect)) {
|
136 |
$post_ids[] = $post_id;
|
137 |
-
$redirect = add_query_arg('lingotek_warning', 1, $redirect);
|
138 |
}
|
139 |
}
|
140 |
}
|
141 |
|
142 |
-
// check if translation is disabled
|
143 |
-
if (!empty($post_ids)) {
|
144 |
-
foreach ($post_ids as $key => $post_id) {
|
145 |
-
$language = PLL()->model->post->get_language($post_id);
|
146 |
-
$profile = Lingotek_Model::get_profile($post_type, $language);
|
147 |
-
if ('disabled'
|
148 |
-
unset($post_ids[$key]);
|
|
|
149 |
}
|
150 |
}
|
151 |
|
@@ -153,192 +165,226 @@ class Lingotek_Post_actions extends Lingotek_Actions {
|
|
153 |
case 'bulk-lingotek-download':
|
154 |
case 'bulk-lingotek-status':
|
155 |
case 'bulk-lingotek-delete':
|
156 |
-
if (empty($post_ids)) {
|
157 |
-
$type = empty($typenow) ? 'media' : 'post';
|
158 |
-
|
|
|
159 |
return;
|
|
|
160 |
|
161 |
-
$post_ids = array_map('intval', $
|
162 |
}
|
163 |
|
164 |
-
empty($typenow) ? check_admin_referer('bulk-media') : check_admin_referer('bulk-posts');
|
165 |
|
166 |
-
$redirect = add_query_arg($action, 1, $redirect);
|
167 |
-
$redirect = add_query_arg('ids', implode(',', $post_ids), $redirect);
|
168 |
|
169 |
break;
|
170 |
|
171 |
case 'lingotek-upload':
|
172 |
-
check_admin_referer('lingotek-upload');
|
173 |
-
$this->lgtm->upload_post((int)
|
174 |
break;
|
175 |
|
176 |
case 'lingotek-copy':
|
177 |
-
check_admin_referer('lingotek-copy');
|
178 |
-
$
|
179 |
-
$target =
|
180 |
-
$this->lgtm->copy_post($
|
181 |
break;
|
182 |
|
183 |
default:
|
184 |
-
if (
|
185 |
-
return; // do not redirect if this is not one of our actions
|
186 |
-
|
187 |
}
|
188 |
|
189 |
-
|
190 |
exit();
|
191 |
|
192 |
}
|
193 |
|
194 |
-
|
195 |
-
*
|
196 |
*
|
197 |
* @since 0.1
|
198 |
*/
|
199 |
public function ajax_upload() {
|
200 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
201 |
-
$this->lgtm->upload_post((int)
|
202 |
die();
|
203 |
}
|
204 |
|
205 |
-
|
206 |
-
*
|
207 |
-
|
208 |
* @since 0.1
|
209 |
-
|
210 |
public function lingotek_add_meta_boxes() {
|
211 |
global $post;
|
212 |
$lgtm = new Lingotek_Model();
|
213 |
-
$group = $lgtm->get_group($post->post_type, $post->ID);
|
214 |
|
215 |
-
// if it's a new page, $group will be null, so don't check if it's a source page
|
216 |
-
if ($group) {
|
217 |
$desc_array = $group->desc_array;
|
218 |
$source_id = $desc_array['lingotek']['source'];
|
219 |
-
// only display the meta box if it's a source
|
220 |
-
if (isset($desc_array['lingotek']['source']) && $post->ID
|
221 |
return;
|
222 |
}
|
223 |
}
|
224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'post', 'side', 'default');
|
226 |
add_meta_box('lingotek_page_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'page', 'side', 'default');
|
227 |
}
|
228 |
|
229 |
-
|
230 |
-
*
|
231 |
*
|
232 |
* @since 0.1
|
233 |
*/
|
234 |
public static function lingotek_edit_meta_box_html() {
|
235 |
-
wp_enqueue_script('lingotek_defaults', LINGOTEK_URL .'/js/defaults.js');
|
236 |
|
237 |
global $post;
|
238 |
-
$post_type = get_post_type($post->ID);
|
239 |
$lgtm = new Lingotek_Model();
|
240 |
-
$group = $lgtm->get_group('post', $post->ID);
|
241 |
$profiles = Lingotek::get_profiles();
|
242 |
$content_profiles = get_option('lingotek_content_type');
|
243 |
$language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
|
244 |
$default_name = empty($content_profiles) == false ? $profiles[$content_profiles[$post->post_type]['profile']]['name'] : ($post_type == 'page' ? __('Manual', 'lingotek-translation') : __('Automatic', 'lingotek-translation'));
|
|
|
|
|
|
|
|
|
|
|
245 |
$content_default_profile = array('default' => array(
|
246 |
'name' => __('Content Default', 'lingotek-translation') . ' (' . $default_name . ')', // Adds in the name of the content type default profile
|
247 |
));
|
|
|
248 |
$language_profiles['defaults'] = array(
|
249 |
'content_default' => $default_name,
|
250 |
-
'title' => __('Content Default', 'lingotek-translation'),
|
251 |
);
|
252 |
-
$profiles = array_merge($content_default_profile, $profiles);
|
253 |
-
$post_profile = self::get_post_profile($post->ID);
|
254 |
-
if (isset($post_profile)) {
|
255 |
-
$selected[$post_profile->description] = $profiles[$post_profile->description];
|
256 |
-
unset($profiles[$post_profile->description]);
|
257 |
-
$profiles = array_merge($selected, $profiles);
|
258 |
}
|
259 |
|
260 |
-
if (isset($group->source)) { // Disables selection of a different profile if content has been uploaded to Lingotek
|
261 |
$args = array(
|
262 |
'document_id' => $group->document_id,
|
263 |
'action' => 'lingotek-delete',
|
264 |
'noheader' => true,
|
265 |
);
|
266 |
-
if ($post_type
|
267 |
$args['lingotek_redirect'] = true;
|
268 |
}
|
269 |
$site_id = get_current_blog_id();
|
270 |
-
$url = $post_type
|
271 |
-
$disassociate_url = wp_nonce_url(add_query_arg($args, $url), 'lingotek-delete');
|
272 |
$remove_post = 'post=' . $post->ID;
|
273 |
-
$disassociate_url = str_replace($remove_post, '', $disassociate_url);
|
274 |
$prefs = Lingotek_Model::get_prefs();
|
275 |
-
$confirm_message = isset($prefs['delete_document_from_tms']) === false ? __('Are you sure you want to do this?', 'lingotek-translation') : __('Are you sure you want to do this? The document will be deleted from Lingotek TMS.', 'lingotek-translation');
|
276 |
-
$confirm_message = sprintf(' onclick = "return confirm(\'%s\');"', $confirm_message);
|
277 |
-
printf('<strong>%s</strong><br><br>', __('Translation Profile', 'lingotek-translation'));
|
278 |
-
printf('<em>%s</em><br>', __('Disassociate this content to change the Translation Profile', 'lingotek-translation'));
|
279 |
-
printf(('<a class="button button-small" href="%s" %s>%s</a><br><br>'), esc_url($disassociate_url), $confirm_message, __('Disassociate', 'lingotek-translation'));
|
280 |
-
printf('<select disabled class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
|
281 |
-
}
|
282 |
-
|
283 |
-
printf('<
|
284 |
-
printf('<select class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta');
|
285 |
}
|
286 |
|
287 |
-
foreach ($profiles as $key => $profile) {
|
288 |
-
echo "\n\t<option value=" . esc_attr($key) .
|
289 |
}
|
290 |
echo '</select>';
|
291 |
-
echo '<div id="lingotek-language-profiles" style="display: none;">'.
|
292 |
}
|
293 |
|
294 |
public function lingotek_save_meta_boxes() {
|
295 |
-
if (
|
296 |
return;
|
297 |
}
|
298 |
|
299 |
global $post;
|
300 |
-
$profile_choice =
|
301 |
$document_id = 'lingotek_profile_' . $post->ID;
|
302 |
-
$term = self::get_post_profile($post->ID);
|
303 |
-
$post_language = $this->get_language($post->ID);
|
304 |
-
$content_profiles = get_option('lingotek_content_type');
|
305 |
-
|
306 |
-
if ($profile_choice
|
307 |
-
wp_delete_term((int) $term->term_id, 'lingotek_profile');
|
308 |
-
}
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
else {
|
314 |
-
wp_update_term((int) $term->term_id, 'lingotek_profile', array('description' => $profile_choice));
|
315 |
}
|
316 |
|
317 |
-
wp_set_object_terms($post->ID, $document_id, 'lingotek_profile');
|
318 |
}
|
319 |
}
|
320 |
|
321 |
-
public static function get_post_profile($post_id) {
|
322 |
-
if (taxonomy_exists('lingotek_profile')) {
|
323 |
-
$terms =
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
|
|
328 |
return 'false';
|
329 |
}
|
330 |
}
|
331 |
|
332 |
-
public static function retrieve_lang_Profiles($post_type, $profiles, $content_profiles) {
|
333 |
$language_profiles = array();
|
334 |
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
}
|
341 |
|
342 |
return $language_profiles;
|
343 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
* Adds row and bulk actions to posts, pages and media list
|
5 |
* Manages actions which trigger communication with Lingotek TMS
|
|
|
6 |
*
|
7 |
* @since 0.2
|
8 |
*/
|
9 |
class Lingotek_Post_actions extends Lingotek_Actions {
|
10 |
|
11 |
+
/**
|
12 |
* Constructor
|
13 |
*
|
14 |
* @since 0.2
|
15 |
*/
|
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 |
+
add_filter( 'page_row_actions', array( &$this, 'post_row_actions' ), 10, 2 ); // hierarchical post types.
|
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 |
+
$add_bulk_actions_to_custom_post_types = function($type) {
|
29 |
+
add_filter( "bulk_actions-edit-$type", array( &$this, 'add_bulk_actions' ) );
|
30 |
+
};
|
|
|
31 |
|
32 |
+
$this->iterate_custom_post_types($add_bulk_actions_to_custom_post_types);
|
|
|
|
|
33 |
|
34 |
+
// manage bulk actions, row actions and icon actions.
|
35 |
+
add_action( 'load-edit.php', array( &$this, 'manage_actions' ) );
|
36 |
+
add_action( 'load-upload.php', array( &$this, 'manage_actions' ) );
|
37 |
|
38 |
+
// add meta box on post and page edit pages, and hook on save.
|
39 |
+
add_action( 'add_meta_boxes', array( &$this, 'lingotek_add_meta_boxes' ) );
|
40 |
+
add_action( 'save_post', array( &$this, 'lingotek_save_meta_boxes' ) );
|
41 |
}
|
42 |
|
43 |
+
/**
|
44 |
+
* Get the language of a post
|
45 |
*
|
46 |
* @since 0.2
|
47 |
*
|
48 |
* @param int $post_id
|
49 |
* @return object
|
50 |
*/
|
51 |
+
protected function get_language( $post_id ) {
|
52 |
+
return PLL()->model->post->get_language( $post_id );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* Displays the icon of an uploaded post with the relevant link
|
57 |
*
|
58 |
* @since 0.2
|
59 |
*
|
60 |
* @param int $id
|
61 |
*/
|
62 |
+
public static function uploaded_icon( $id ) {
|
63 |
+
return self::display_icon( 'uploaded', get_edit_post_link( $id ) );
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
* Adds a row action link
|
68 |
*
|
69 |
* @since 0.1
|
70 |
*
|
71 |
+
* @param array $actions list of action links.
|
72 |
+
* @param object $post post object.
|
73 |
* @return array
|
74 |
*/
|
75 |
+
public function post_row_actions( $actions, $post ) {
|
76 |
+
if ( $this->pllm->is_translated_post_type( $post->post_type ) ) {
|
77 |
+
$actions = $this->_row_actions( $actions, $post->ID );
|
78 |
+
|
79 |
+
$language = PLL()->model->post->get_language( $post->ID );
|
80 |
+
if ( ! empty( $language ) ) {
|
81 |
+
$profile = Lingotek_Model::get_profile( $post->post_type, $language, $post->ID );
|
82 |
+
if ( 'disabled' === $profile['profile'] ) {
|
83 |
+
unset( $actions['lingotek-upload'] );
|
84 |
+
}
|
85 |
}
|
86 |
}
|
87 |
return $actions;
|
88 |
}
|
89 |
|
90 |
+
/**
|
91 |
+
* Adds actions to bulk dropdown in posts list table
|
92 |
*
|
93 |
* @since 0.1
|
94 |
*/
|
95 |
+
public function add_bulk_actions( $bulk_actions ) {
|
96 |
+
if ( isset( $GLOBALS['post_type'] ) && $this->pllm->is_translated_post_type( $GLOBALS['post_type'] ) ) {
|
97 |
+
return $this->_add_bulk_actions( $bulk_actions );
|
98 |
+
}
|
99 |
}
|
100 |
|
101 |
+
/**
|
102 |
+
* Manages Lingotek specific actions before WordPress acts
|
103 |
*
|
104 |
* @since 0.1
|
105 |
*/
|
106 |
public function manage_actions() {
|
107 |
global $typenow;
|
108 |
+
$post_type = 'load-upload.php' === current_filter() ? 'attachment' : $typenow;
|
109 |
|
110 |
+
if ( ! $this->pllm->is_translated_post_type( $post_type ) ) {
|
111 |
return;
|
112 |
+
}
|
113 |
|
114 |
+
// get the action.
|
115 |
+
// $typenow is empty for media.
|
116 |
+
$wp_list_table = _get_list_table( empty( $typenow ) ? 'WP_Media_List_Table' : 'WP_Posts_List_Table' );
|
117 |
$action = $wp_list_table->current_action();
|
118 |
|
119 |
+
if ( empty( $action ) ) {
|
120 |
return;
|
121 |
+
}
|
122 |
|
123 |
+
$redirect = remove_query_arg( array( 'action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view' ), wp_get_referer() );
|
124 |
+
if ( ! $redirect ) {
|
125 |
+
$redirect = admin_url( "edit.php?post_type=$typenow" );
|
126 |
+
}
|
127 |
|
128 |
+
switch ( $action ) {
|
129 |
case 'bulk-lingotek-upload':
|
130 |
+
$type = empty( $typenow ) ? 'media' : 'post';
|
131 |
+
$filtered_get = filter_input_array( INPUT_GET );
|
132 |
+
if ( ! isset( $filtered_get[ $type ] ) ) {
|
133 |
return;
|
134 |
+
}
|
135 |
|
136 |
$post_ids = array();
|
137 |
|
138 |
+
foreach ( array_map( 'intval', $filtered_get[ $type ] ) as $post_id ) {
|
139 |
+
// safe upload.
|
140 |
+
if ( $this->lgtm->can_upload( 'post', $post_id ) ) {
|
141 |
$post_ids[] = $post_id;
|
142 |
+
} // the document is already translated so will be overwritten.
|
143 |
+
elseif ( ($document = $this->lgtm->get_group( 'post', $post_id )) && empty( $document->source ) ) {
|
144 |
+
// take care to upload only one post in a translation group.
|
145 |
+
$intersect = array_intersect( $post_ids, PLL()->model->post->get_translations( $post_id ) );
|
146 |
+
if ( empty( $intersect ) ) {
|
|
|
147 |
$post_ids[] = $post_id;
|
148 |
+
$redirect = add_query_arg( 'lingotek_warning', 1, $redirect );
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
|
153 |
+
// check if translation is disabled.
|
154 |
+
if ( ! empty( $post_ids ) ) {
|
155 |
+
foreach ( $post_ids as $key => $post_id ) {
|
156 |
+
$language = PLL()->model->post->get_language( $post_id );
|
157 |
+
$profile = Lingotek_Model::get_profile( $post_type, $language );
|
158 |
+
if ( 'disabled' === $profile['profile'] ) {
|
159 |
+
unset( $post_ids[ $key ] );
|
160 |
+
}
|
161 |
}
|
162 |
}
|
163 |
|
165 |
case 'bulk-lingotek-download':
|
166 |
case 'bulk-lingotek-status':
|
167 |
case 'bulk-lingotek-delete':
|
168 |
+
if ( empty( $post_ids ) ) {
|
169 |
+
$type = empty( $typenow ) ? 'media' : 'post';
|
170 |
+
$filtered_get = filter_input_array( INPUT_GET );
|
171 |
+
if ( ! isset( $filtered_get[ $type ] ) ) {
|
172 |
return;
|
173 |
+
}
|
174 |
|
175 |
+
$post_ids = array_map( 'intval', $filtered_get[ $type ] );
|
176 |
}
|
177 |
|
178 |
+
empty( $typenow ) ? check_admin_referer( 'bulk-media' ) : check_admin_referer( 'bulk-posts' );
|
179 |
|
180 |
+
$redirect = add_query_arg( $action, 1, $redirect );
|
181 |
+
$redirect = add_query_arg( 'ids', implode( ',', $post_ids ), $redirect );
|
182 |
|
183 |
break;
|
184 |
|
185 |
case 'lingotek-upload':
|
186 |
+
check_admin_referer( 'lingotek-upload' );
|
187 |
+
$this->lgtm->upload_post( (int) filter_input( INPUT_GET, 'post' ) );
|
188 |
break;
|
189 |
|
190 |
case 'lingotek-copy':
|
191 |
+
check_admin_referer( 'lingotek-copy' );
|
192 |
+
$post_to_copy = get_post( (int) filter_input( INPUT_GET, 'post' ) );
|
193 |
+
$target = filter_input( INPUT_GET, 'target' );
|
194 |
+
$this->lgtm->copy_post( $post_to_copy, $target );
|
195 |
break;
|
196 |
|
197 |
default:
|
198 |
+
if ( ! $this->_manage_actions( $action ) ) {
|
199 |
+
return; // do not redirect if this is not one of our actions.
|
200 |
+
}
|
201 |
}
|
202 |
|
203 |
+
wp_safe_redirect( $redirect );
|
204 |
exit();
|
205 |
|
206 |
}
|
207 |
|
208 |
+
/**
|
209 |
+
* Ajax response to upload documents and showing progress
|
210 |
*
|
211 |
* @since 0.1
|
212 |
*/
|
213 |
public function ajax_upload() {
|
214 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
215 |
+
$this->lgtm->upload_post( (int) filter_input( INPUT_POST, 'id' ) );
|
216 |
die();
|
217 |
}
|
218 |
|
219 |
+
/**
|
220 |
+
* Adds the lingotek profile meta box on edit pages
|
221 |
+
*
|
222 |
* @since 0.1
|
223 |
+
*/
|
224 |
public function lingotek_add_meta_boxes() {
|
225 |
global $post;
|
226 |
$lgtm = new Lingotek_Model();
|
227 |
+
$group = $lgtm->get_group( $post->post_type, $post->ID );
|
228 |
|
229 |
+
// if it's a new page, $group will be null, so don't check if it's a source page.
|
230 |
+
if ( $group ) {
|
231 |
$desc_array = $group->desc_array;
|
232 |
$source_id = $desc_array['lingotek']['source'];
|
233 |
+
// only display the meta box if it's a source.
|
234 |
+
if ( isset( $desc_array['lingotek']['source'] ) && $post->ID !== $source_id ) {
|
235 |
return;
|
236 |
}
|
237 |
}
|
238 |
|
239 |
+
$add_meta_box_to_custom_post_types = function($type) {
|
240 |
+
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), $type, 'side', 'default');
|
241 |
+
};
|
242 |
+
|
243 |
+
$this->iterate_custom_post_types($add_meta_box_to_custom_post_types);
|
244 |
+
|
245 |
add_meta_box('lingotek_post_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'post', 'side', 'default');
|
246 |
add_meta_box('lingotek_page_meta_box', __('Lingotek Translation', 'lingotek-translation'), array( __CLASS__, 'lingotek_edit_meta_box_html'), 'page', 'side', 'default');
|
247 |
}
|
248 |
|
249 |
+
/**
|
250 |
+
* Builds the html for the edit post and edit page meta boxes.
|
251 |
*
|
252 |
* @since 0.1
|
253 |
*/
|
254 |
public static function lingotek_edit_meta_box_html() {
|
255 |
+
wp_enqueue_script( 'lingotek_defaults', LINGOTEK_URL . '/js/defaults.js' );
|
256 |
|
257 |
global $post;
|
258 |
+
$post_type = get_post_type( $post->ID );
|
259 |
$lgtm = new Lingotek_Model();
|
260 |
+
$group = $lgtm->get_group( 'post', $post->ID );
|
261 |
$profiles = Lingotek::get_profiles();
|
262 |
$content_profiles = get_option('lingotek_content_type');
|
263 |
$language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
|
264 |
$default_name = empty($content_profiles) == false ? $profiles[$content_profiles[$post->post_type]['profile']]['name'] : ($post_type == 'page' ? __('Manual', 'lingotek-translation') : __('Automatic', 'lingotek-translation'));
|
265 |
+
if ( ! isset( $default_name ) || 'disabled' === $default_name )
|
266 |
+
{
|
267 |
+
echo esc_html( __('You must enable translation for this content type in Lingotek\'s Content Type Configuration to enable Translation Profiles.', 'lingotek-translation') );
|
268 |
+
return;
|
269 |
+
}
|
270 |
$content_default_profile = array('default' => array(
|
271 |
'name' => __('Content Default', 'lingotek-translation') . ' (' . $default_name . ')', // Adds in the name of the content type default profile
|
272 |
));
|
273 |
+
|
274 |
$language_profiles['defaults'] = array(
|
275 |
'content_default' => $default_name,
|
276 |
+
'title' => __( 'Content Default', 'lingotek-translation' ),
|
277 |
);
|
278 |
+
$profiles = array_merge( $content_default_profile, $profiles );
|
279 |
+
$post_profile = self::get_post_profile( $post->ID );
|
280 |
+
if ( isset( $post_profile ) ) {
|
281 |
+
$selected[ $post_profile->description ] = $profiles[ $post_profile->description ];
|
282 |
+
unset( $profiles[ $post_profile->description ] );
|
283 |
+
$profiles = array_merge( $selected, $profiles );
|
284 |
}
|
285 |
|
286 |
+
if ( isset( $group->source ) ) { // Disables selection of a different profile if content has been uploaded to Lingotek.
|
287 |
$args = array(
|
288 |
'document_id' => $group->document_id,
|
289 |
'action' => 'lingotek-delete',
|
290 |
'noheader' => true,
|
291 |
);
|
292 |
+
if ( $post_type === 'page' ) {
|
293 |
$args['lingotek_redirect'] = true;
|
294 |
}
|
295 |
$site_id = get_current_blog_id();
|
296 |
+
$url = $post_type === 'page' ? get_site_url( $site_id, '/wp-admin/edit.php?post_type=page' ) : get_site_url( $site_id, '/wp-admin/edit.php' );
|
297 |
+
$disassociate_url = wp_nonce_url( add_query_arg( $args, $url ), 'lingotek-delete' );
|
298 |
$remove_post = 'post=' . $post->ID;
|
299 |
+
$disassociate_url = str_replace( $remove_post, '', $disassociate_url );
|
300 |
$prefs = Lingotek_Model::get_prefs();
|
301 |
+
$confirm_message = isset( $prefs['delete_document_from_tms'] ) === false ? __( 'Are you sure you want to do this?', 'lingotek-translation' ) : __( 'Are you sure you want to do this? The document will be deleted from Lingotek TMS.', 'lingotek-translation' );
|
302 |
+
$confirm_message = sprintf( ' onclick = "return confirm(\'%s\');"', esc_html( $confirm_message ) );
|
303 |
+
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
304 |
+
printf( '<em>%s</em><br>', esc_html( __( 'Disassociate this content to change the Translation Profile', 'lingotek-translation' ) ) );
|
305 |
+
printf( ('<a class="button button-small" href="%s" %s>%s</a><br><br>'), esc_url( $disassociate_url ), esc_html( $confirm_message ), esc_html( __( 'Disassociate', 'lingotek-translation' ) ) );
|
306 |
+
printf( '<select disabled class="lingotek-profile-setting" name="%1$s" id="%1$s">', esc_html( 'lingotek_profile_meta' ) );
|
307 |
+
} else {
|
308 |
+
printf( '<strong>%s</strong><br><br>', esc_html( __( 'Translation Profile', 'lingotek-translation' ) ) );
|
309 |
+
printf( '<select class="lingotek-profile-setting" name="%1$s" id="%1$s">', 'lingotek_profile_meta' );
|
|
|
310 |
}
|
311 |
|
312 |
+
foreach ( $profiles as $key => $profile ) {
|
313 |
+
echo "\n\t<option value=" . esc_attr( $key ) . '>' . esc_attr( $profile['name'] ) . '</option>';
|
314 |
}
|
315 |
echo '</select>';
|
316 |
+
echo '<div id="lingotek-language-profiles" style="display: none;">' . wp_json_encode( $language_profiles ) . '</div>';
|
317 |
}
|
318 |
|
319 |
public function lingotek_save_meta_boxes() {
|
320 |
+
if ( null === filter_input( INPUT_POST, 'lingotek_profile_meta' ) ) {
|
321 |
return;
|
322 |
}
|
323 |
|
324 |
global $post;
|
325 |
+
$profile_choice = filter_input( INPUT_POST, 'lingotek_profile_meta' );
|
326 |
$document_id = 'lingotek_profile_' . $post->ID;
|
327 |
+
$term = self::get_post_profile( $post->ID );
|
328 |
+
$post_language = $this->get_language( $post->ID );
|
329 |
+
$content_profiles = get_option( 'lingotek_content_type' );
|
330 |
+
|
331 |
+
if ( $profile_choice === 'default' && ! empty( $term ) ) {
|
332 |
+
wp_delete_term( (int) $term->term_id, 'lingotek_profile' );
|
333 |
+
} elseif ( $profile_choice !== 'default' ) {
|
334 |
+
if ( empty( $term ) ) {
|
335 |
+
wp_insert_term( $document_id, 'lingotek_profile', array( 'description' => $profile_choice ) );
|
336 |
+
} else {
|
337 |
+
wp_update_term( (int) $term->term_id, 'lingotek_profile', array( 'description' => $profile_choice ) );
|
|
|
|
|
338 |
}
|
339 |
|
340 |
+
wp_set_object_terms( $post->ID, $document_id, 'lingotek_profile' );
|
341 |
}
|
342 |
}
|
343 |
|
344 |
+
public static function get_post_profile( $post_id ) {
|
345 |
+
if ( taxonomy_exists( 'lingotek_profile' ) ) {
|
346 |
+
$terms = get_the_terms( $post_id, 'lingotek_profile' );
|
347 |
+
if ( is_array( $terms ) ) {
|
348 |
+
return array_pop( $terms );
|
349 |
+
} else {
|
350 |
+
return null;
|
351 |
+
}
|
352 |
+
} else {
|
353 |
return 'false';
|
354 |
}
|
355 |
}
|
356 |
|
357 |
+
public static function retrieve_lang_Profiles( $post_type, $profiles, $content_profiles ) {
|
358 |
$language_profiles = array();
|
359 |
|
360 |
+
if ( isset( $content_profiles[ $post_type ]['sources'] ) ) {
|
361 |
+
$sources = $content_profiles[ $post_type ]['sources'];
|
362 |
+
foreach ( $sources as $lang_code => $profile ) {
|
363 |
+
$language_profiles[ $lang_code ] = $profiles[ $profile ]['name'];
|
364 |
+
}
|
365 |
}
|
366 |
|
367 |
return $language_profiles;
|
368 |
}
|
369 |
+
|
370 |
+
/**
|
371 |
+
* Iterates through the enabled custom post types and passes in the type to a provided anonymous method.
|
372 |
+
* The provided method is only called if the custom post type has been enabled by Polylong.
|
373 |
+
*
|
374 |
+
* @param function $method the method to be called. Must take in a single parameter (type)
|
375 |
+
*/
|
376 |
+
private function iterate_custom_post_types($method)
|
377 |
+
{
|
378 |
+
$polylang_enabled = PLL()->model->get_translated_post_types();
|
379 |
+
$custom_post_types = get_post_types( [ '_builtin' => false ] );
|
380 |
+
unset( $custom_post_types[ 'polylang_mo' ] );
|
381 |
+
|
382 |
+
foreach ( $custom_post_types as $type )
|
383 |
+
{
|
384 |
+
if (isset($polylang_enabled[$type]))
|
385 |
+
{
|
386 |
+
$method($type);
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
}
|
admin/profiles-table.php
CHANGED
@@ -1,81 +1,86 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if(!class_exists('WP_List_Table')){
|
4 |
-
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1
|
5 |
}
|
6 |
|
|
|
|
|
|
|
7 |
class Lingotek_Profiles_Table extends WP_List_Table {
|
8 |
|
9 |
-
|
10 |
-
*
|
11 |
*
|
12 |
* @since 0.2
|
13 |
*/
|
14 |
function __construct() {
|
15 |
parent::__construct(array(
|
16 |
-
'plural' => 'lingotek-profiles', // do not translate (used for css class)
|
17 |
-
'ajax' => false
|
18 |
));
|
19 |
}
|
20 |
|
21 |
-
|
22 |
-
*
|
23 |
*
|
24 |
* @since 0.2
|
25 |
*
|
26 |
-
* @param array
|
27 |
-
* @param string $column_name
|
28 |
* @return string
|
29 |
*/
|
30 |
-
function column_default($item, $column_name) {
|
31 |
-
return isset($item[$column_name]) ? esc_html($item[$column_name]) : '';
|
32 |
}
|
33 |
|
34 |
-
|
35 |
-
*
|
36 |
*
|
37 |
* @since 0.2
|
38 |
*
|
39 |
-
* @param array $item
|
40 |
* @return string
|
41 |
*/
|
42 |
-
function column_usage($item){
|
43 |
-
return empty($item['usage']) ?
|
44 |
-
__('No content types', 'lingotek-translation') :
|
45 |
-
sprintf(_n('
|
46 |
}
|
47 |
|
48 |
-
|
49 |
-
*
|
50 |
*
|
51 |
* @since 0.2
|
52 |
*
|
53 |
-
* @param array $item
|
54 |
* @return string
|
55 |
*/
|
56 |
-
function column_actions($item){
|
57 |
$actions = array();
|
58 |
|
59 |
-
if ('disabled'
|
60 |
$actions[] = sprintf(
|
61 |
'<a href=%s>%s</a>',
|
62 |
-
esc_url(admin_url('admin.php?page=lingotek-translation_manage&sm=edit-profile&profile='
|
63 |
-
__('Edit', 'lingotek-translation')
|
64 |
);
|
|
|
65 |
|
66 |
-
if (!in_array($item['profile'], array('automatic', 'manual', 'disabled')) && empty($item['usage']))
|
67 |
$actions[] = sprintf(
|
68 |
'<a href="%s" onclick = "return confirm(\'%s\');">%s</a>',
|
69 |
-
esc_url(wp_nonce_url('admin.php?page=lingotek-translation_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile='
|
70 |
-
__('You are about to permanently delete this profile. Are you sure?', 'lingotek-translation'),
|
71 |
-
__('Delete', 'lingotek-translation')
|
72 |
);
|
|
|
73 |
|
74 |
-
return implode(' | ', $actions);
|
75 |
}
|
76 |
|
77 |
-
|
78 |
-
*
|
79 |
*
|
80 |
* @since 0.2
|
81 |
*
|
@@ -83,14 +88,14 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
83 |
*/
|
84 |
function get_columns() {
|
85 |
return array(
|
86 |
-
'name' => __('Profile name', 'lingotek-translation'),
|
87 |
-
'usage' => __('Usage', 'lingotek-translation'),
|
88 |
-
'actions' => __('Actions', 'lingotek-translation'),
|
89 |
);
|
90 |
}
|
91 |
|
92 |
-
|
93 |
-
*
|
94 |
*
|
95 |
* @since 0.2
|
96 |
*
|
@@ -98,36 +103,44 @@ class Lingotek_Profiles_Table extends WP_List_Table {
|
|
98 |
*/
|
99 |
function get_sortable_columns() {
|
100 |
return array(
|
101 |
-
'name' => array('name', false),
|
102 |
);
|
103 |
}
|
104 |
|
105 |
-
|
106 |
-
*
|
107 |
*
|
108 |
* @since 0.2
|
109 |
*
|
110 |
-
* @param array $data
|
111 |
*/
|
112 |
-
function prepare_items($data = array()) {
|
113 |
-
$per_page = $this->get_items_per_page('lingotek_profiles_per_page');
|
114 |
-
$this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
};
|
120 |
|
121 |
-
if (!empty(
|
122 |
-
usort($data, 'usort_reorder');
|
|
|
123 |
|
124 |
-
$total_items = count($data);
|
125 |
-
$this->items = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
126 |
|
127 |
$this->set_pagination_args(array(
|
128 |
'total_items' => $total_items,
|
129 |
'per_page' => $per_page,
|
130 |
-
'total_pages' => ceil($total_items
|
131 |
));
|
132 |
}
|
133 |
}
|
1 |
<?php
|
2 |
|
3 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1.
|
5 |
}
|
6 |
|
7 |
+
/**
|
8 |
+
* Lingotek Profiles Table Class.
|
9 |
+
*/
|
10 |
class Lingotek_Profiles_Table extends WP_List_Table {
|
11 |
|
12 |
+
/**
|
13 |
+
* Constructor
|
14 |
*
|
15 |
* @since 0.2
|
16 |
*/
|
17 |
function __construct() {
|
18 |
parent::__construct(array(
|
19 |
+
'plural' => 'lingotek-profiles', // do not translate (used for css class).
|
20 |
+
'ajax' => false,
|
21 |
));
|
22 |
}
|
23 |
|
24 |
+
/**
|
25 |
+
* Displays the item information in a column (default case)
|
26 |
*
|
27 |
* @since 0.2
|
28 |
*
|
29 |
+
* @param array $item item.
|
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 |
|
37 |
+
/**
|
38 |
+
* Displays the edit link in actions column
|
39 |
*
|
40 |
* @since 0.2
|
41 |
*
|
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 |
|
51 |
+
/**
|
52 |
+
* Displays the edit link in actions column
|
53 |
*
|
54 |
* @since 0.2
|
55 |
*
|
56 |
+
* @param array $item item.
|
57 |
* @return string
|
58 |
*/
|
59 |
+
function column_actions( $item ) {
|
60 |
$actions = array();
|
61 |
|
62 |
+
if ( 'disabled' !== $item['profile'] ) {
|
63 |
$actions[] = sprintf(
|
64 |
'<a href=%s>%s</a>',
|
65 |
+
esc_url( admin_url( 'admin.php?page=lingotek-translation_manage&sm=edit-profile&profile=' . $item['profile'] ) ),
|
66 |
+
__( 'Edit', 'lingotek-translation' )
|
67 |
);
|
68 |
+
}
|
69 |
|
70 |
+
if ( ! in_array( $item['profile'], array( 'automatic', 'manual', 'disabled' ), true ) && empty( $item['usage'] ) ) {
|
71 |
$actions[] = sprintf(
|
72 |
'<a href="%s" onclick = "return confirm(\'%s\');">%s</a>',
|
73 |
+
esc_url( wp_nonce_url( 'admin.php?page=lingotek-translation_manage&sm=profiles&lingotek_action=delete-profile&noheader=true&profile=' . $item['profile'], 'delete-profile' ) ),
|
74 |
+
__( 'You are about to permanently delete this profile. Are you sure?', 'lingotek-translation' ),
|
75 |
+
__( 'Delete', 'lingotek-translation' )
|
76 |
);
|
77 |
+
}
|
78 |
|
79 |
+
return implode( ' | ', $actions );
|
80 |
}
|
81 |
|
82 |
+
/**
|
83 |
+
* Gets the list of columns
|
84 |
*
|
85 |
* @since 0.2
|
86 |
*
|
88 |
*/
|
89 |
function get_columns() {
|
90 |
return array(
|
91 |
+
'name' => __( 'Profile name', 'lingotek-translation' ),
|
92 |
+
'usage' => __( 'Usage', 'lingotek-translation' ),
|
93 |
+
'actions' => __( 'Actions', 'lingotek-translation' ),
|
94 |
);
|
95 |
}
|
96 |
|
97 |
+
/**
|
98 |
+
* Gets the list of sortable columns
|
99 |
*
|
100 |
* @since 0.2
|
101 |
*
|
103 |
*/
|
104 |
function get_sortable_columns() {
|
105 |
return array(
|
106 |
+
'name' => array( 'name', false ),
|
107 |
);
|
108 |
}
|
109 |
|
110 |
+
/**
|
111 |
+
* Prepares the list of items ofr displaying
|
112 |
*
|
113 |
* @since 0.2
|
114 |
*
|
115 |
+
* @param array $data data.
|
116 |
*/
|
117 |
+
function prepare_items( $data = array() ) {
|
118 |
+
$per_page = $this->get_items_per_page( 'lingotek_profiles_per_page' );
|
119 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Custom sort comparator.
|
123 |
+
*
|
124 |
+
* @param array $a assoc. array representing a profile.
|
125 |
+
* @param array $b assoc. array representing a profile.
|
126 |
+
* @return int sort direction.
|
127 |
+
*/
|
128 |
+
function usort_reorder( $a, $b ) {
|
129 |
+
$result = strcmp( $a[ filter_input( INPUT_GET, 'orderby' ) ], $b[ filter_input( INPUT_GET, 'orderby' ) ] ); // determine sort order.
|
130 |
+
return (empty( filter_input( INPUT_GET, 'order' ) ) || 'asc' === filter_input( INPUT_GET, 'order' ) ) ? $result : -$result; // send final sort direction to usort.
|
131 |
};
|
132 |
|
133 |
+
if ( ! empty( filter_input( INPUT_GET, 'orderby' ) ) ) { // no sort by default.
|
134 |
+
usort( $data, 'usort_reorder' );
|
135 |
+
}
|
136 |
|
137 |
+
$total_items = count( $data );
|
138 |
+
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
139 |
|
140 |
$this->set_pagination_args(array(
|
141 |
'total_items' => $total_items,
|
142 |
'per_page' => $per_page,
|
143 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
144 |
));
|
145 |
}
|
146 |
}
|
admin/settings.php
CHANGED
@@ -1,62 +1,60 @@
|
|
1 |
<div class="wrap">
|
2 |
-
<h2><?php
|
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 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
}
|
61 |
-
?>
|
62 |
</div>
|
1 |
<div class="wrap">
|
2 |
+
<h2><?php esc_html_e( 'Settings', 'lingotek-translation' ); ?></h2>
|
3 |
+
|
4 |
+
<?php
|
5 |
+
if ( strlen( $access_token ) ) {
|
6 |
+
?>
|
7 |
+
|
8 |
+
<?php
|
9 |
+
|
10 |
+
$menu_items = array(
|
11 |
+
'account' => __( 'Account', 'lingotek-translation' ),
|
12 |
+
);
|
13 |
+
|
14 |
+
$community_required_menu_items = array(
|
15 |
+
'defaults' => __( 'Defaults', 'lingotek-translation' ),
|
16 |
+
'preferences' => __( 'Preferences', 'lingotek-translation' ),
|
17 |
+
'utilities' => __( 'Utilities', 'lingotek-translation' ),
|
18 |
+
);
|
19 |
+
|
20 |
+
if ( false !== $community_id ) {
|
21 |
+
$menu_items = array_merge( $menu_items, $community_required_menu_items );
|
22 |
+
}
|
23 |
+
|
24 |
+
?>
|
25 |
+
|
26 |
+
<h3 class="nav-tab-wrapper">
|
27 |
+
<?php
|
28 |
+
$menu_item_index = 0;
|
29 |
+
foreach ( $menu_items as $menu_item_key => $menu_item_label ) {
|
30 |
+
$use_as_default = (0 === $menu_item_index && empty( filter_input( INPUT_GET, 'sm' ) )) ? true : false;
|
31 |
+
$alias = null;
|
32 |
+
// custom sub sub-menus.
|
33 |
+
if ( ! empty( filter_input( INPUT_GET, 'sm' ) ) && 'edit-profile' === filter_input( INPUT_GET, 'sm' ) ) {
|
34 |
+
$alias = 'profiles';
|
35 |
+
}
|
36 |
+
?>
|
37 |
+
|
38 |
+
<a class="nav-tab <?php if ( $use_as_default || ( ! empty( filter_input( INPUT_GET, 'sm' ) ) && filter_input( INPUT_GET, 'sm' ) === $menu_item_key) || $alias === $menu_item_key ) : ?> nav-tab-active<?php endif; ?>"
|
39 |
+
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>
|
40 |
+
<?php
|
41 |
+
$menu_item_index++;
|
42 |
+
}
|
43 |
+
?>
|
44 |
+
</h3>
|
45 |
+
|
46 |
+
<?php
|
47 |
+
settings_errors();
|
48 |
+
$submenu = ! empty( filter_input( INPUT_GET, 'sm' ) ) ? sanitize_text_field( filter_input( INPUT_GET, 'sm' ) ) : 'account';
|
49 |
+
$dir = dirname( __FILE__ ) . '/settings/';
|
50 |
+
$filename = $dir . 'view-' . $submenu . '.php';
|
51 |
+
if ( file_exists( $filename ) ) {
|
52 |
+
include $filename;
|
53 |
+
} else { echo 'TO-DO: create <i>settings/view-' . esc_html( $submenu ) . '.php</i>';
|
54 |
+
}
|
55 |
+
?>
|
56 |
+
|
57 |
+
<?php
|
58 |
+
}
|
59 |
+
?>
|
|
|
|
|
60 |
</div>
|
admin/settings/connect-account.php
CHANGED
@@ -1,29 +1,39 @@
|
|
1 |
-
|
2 |
<script>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
</script>
|
12 |
-
|
13 |
<div class="wrap">
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!-- Redirect Access Token -->
|
2 |
<script>
|
3 |
+
var hash = window.location.hash;
|
4 |
+
if (hash.length && hash.indexOf("access_token") !== -1) {
|
5 |
+
var url_with_access_token = window.location.origin + window.location.pathname + window.location.search + '&' + hash.substr(1);
|
6 |
+
window.location.href = url_with_access_token;
|
7 |
+
}
|
8 |
+
else if (window.location.search.indexOf("connect") != -1) {
|
9 |
+
window.location.href = "<?php echo esc_url_raw( $connect_url ) ?>";
|
10 |
+
}
|
11 |
</script>
|
12 |
+
<!-- Connect Your Account Button -->
|
13 |
<div class="wrap">
|
14 |
+
<h2><?php esc_html_e( 'Connect Your Account', 'lingotek-translation' ) ?></h2>
|
15 |
+
<div>
|
16 |
+
<p class="description">
|
17 |
+
<?php esc_html_e( 'Get started by clicking the button below to connect your Lingotek account to this Wordpress installation.', 'lingotek-translation' ) ?>
|
18 |
+
</p>
|
19 |
+
<hr/>
|
20 |
+
<p>
|
21 |
+
<a class="button button-large button-hero" href="<?php echo esc_url_raw( $connect_account_cloak_url_new ) ?>">
|
22 |
+
<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' ) ?>
|
23 |
+
</a>
|
24 |
+
</p>
|
25 |
+
<hr/>
|
26 |
+
<p class="description">
|
27 |
+
<?php
|
28 |
+
$allowed_html = [
|
29 |
+
'a' => [
|
30 |
+
'href' => [],
|
31 |
+
],
|
32 |
+
];
|
33 |
+
|
34 |
+
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 ) )
|
35 |
+
?>
|
36 |
+
</p>
|
37 |
+
<p class="description"><?php echo sprintf( wp_kses( __( 'Do you have a Lingotek sandbox account? <a href="%s">Connect Sandbox Account</a>', 'lingotek-translation' ), $allowed_html ), esc_attr( $connect_account_cloak_url_test ) ) ?></p>
|
38 |
+
</div>
|
39 |
+
</div>
|
admin/settings/view-account.php
CHANGED
@@ -1,126 +1,125 @@
|
|
1 |
<?php
|
2 |
$client = new Lingotek_API();
|
3 |
$api_communities = $client->get_communities();
|
4 |
-
if (!isset($api_communities->entities)) {
|
5 |
-
|
6 |
-
|
7 |
}
|
8 |
-
if (
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
}
|
18 |
?>
|
19 |
|
20 |
-
<h3><?php
|
21 |
-
<p class="description"><?php
|
22 |
|
23 |
<table class="form-table">
|
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 |
</table>
|
85 |
|
86 |
<hr/>
|
87 |
|
88 |
-
<form method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate">
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
-
|
108 |
-
|
109 |
-
update_option('lingotek_community', current(array_keys($communities)));
|
110 |
-
}
|
111 |
-
if(!$community_id && $num_communities > 1) {
|
112 |
-
echo "\n\t" . '<option value="">'.__('Select', 'lingotek-translation').'...</option>';
|
113 |
-
}
|
114 |
-
foreach ($communities as $community_id_option => $community_title) {
|
115 |
-
$selected = ($default_community_id == $community_id_option) ? 'selected="selected"' : '';
|
116 |
-
echo "\n\t" . '<option value="' . esc_attr($community_id_option) . '" '.$selected.'>' . $community_title . '</option>';
|
117 |
-
}
|
118 |
-
}
|
119 |
-
?>
|
120 |
-
</select>
|
121 |
-
</td>
|
122 |
-
</tr>
|
123 |
-
</table>
|
124 |
-
|
125 |
-
<?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
|
126 |
-
</form>
|
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;
|
14 |
+
$this->set_community_resources( $ltk_community_id );
|
15 |
+
echo '<script type="text/javascript">document.body.innerHTML = ""; window.location = "admin.php?page=lingotek-translation_tutorial";</script>';
|
16 |
+
}
|
17 |
}
|
18 |
?>
|
19 |
|
20 |
+
<h3><?php esc_html_e( 'Account', 'lingotek-translation' ); ?></h3>
|
21 |
+
<p class="description"><?php esc_html_e( 'Lingotek account connection and community selection.', 'lingotek-translation' ); ?></p>
|
22 |
|
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" />', 'login_id', esc_html( $token_details['login_id'] )
|
42 |
+
);
|
43 |
+
?>
|
44 |
+
</label>
|
45 |
+
</td>
|
46 |
+
</tr>
|
47 |
+
<tr>
|
48 |
+
<th scope="row"><?php echo esc_html( __( 'Access Token', 'lingotek-translation' ) ) ?></th>
|
49 |
+
<td>
|
50 |
+
<label>
|
51 |
+
<?php
|
52 |
+
printf(
|
53 |
+
'<input name="%s" class="regular-text" type="password" value="%s" disabled="disabled" style="display: none;" />', 'access_token', esc_html( $token_details['access_token'] )
|
54 |
+
);
|
55 |
+
printf(
|
56 |
+
'<input name="%s" class="regular-text" type="text" value="%s" disabled="disabled" />', 'access_token', esc_html( $token_details['access_token'] )
|
57 |
+
);
|
58 |
+
?>
|
59 |
+
</label>
|
60 |
+
</td>
|
61 |
+
</tr>
|
62 |
+
<tr>
|
63 |
+
<th scope="row"><?php echo esc_html( __( 'API Endpoint', 'lingotek-translation' ) ) ?></th>
|
64 |
+
<td>
|
65 |
+
<label>
|
66 |
+
<?php
|
67 |
+
printf(
|
68 |
+
'<input name="%s" class="regular-text" type="text" value="%s" disabled="disabled" />', 'base_url', esc_html( $base_url )
|
69 |
+
);
|
70 |
+
?>
|
71 |
+
</label>
|
72 |
+
</td>
|
73 |
+
</tr>
|
74 |
+
<tr>
|
75 |
+
<th></th>
|
76 |
+
<td>
|
77 |
+
<?php
|
78 |
+
$confirm_message = __( 'Are you sure you would like to disconnect your Lingotek account? \n\nAfter disconnecting, you will need to re-connect an account to continue using Lingotek.', 'lingotek-translation' );
|
79 |
+
echo '<a class="button" href="' . esc_html( $redirect_url ) . '&delete_access_token=true" onclick="return confirm(\'' . esc_html( $confirm_message ) . '\')">' . esc_html( __( 'Disconnect', 'lingotek-translation' ) ) . '</a>';
|
80 |
+
?>
|
81 |
+
</td>
|
82 |
+
</tr>
|
83 |
+
</tbody>
|
84 |
</table>
|
85 |
|
86 |
<hr/>
|
87 |
|
88 |
+
<form method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
89 |
+
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
90 |
|
91 |
+
<table class="form-table">
|
92 |
+
<tr>
|
93 |
+
<th scope="row"><label for="lingotek_community"><?php esc_html_e( 'Community', 'lingotek-translation' ) ?></label></th>
|
94 |
+
<td>
|
95 |
+
<select name="lingotek_community" id="lingotek_community">
|
96 |
+
<?php
|
97 |
+
$default_community_id = $community_id;
|
98 |
|
99 |
+
// Community.
|
100 |
+
$communities = array();
|
101 |
+
if ( isset( $api_communities->entities ) ) {
|
102 |
+
foreach ( $api_communities->entities as $community ) {
|
103 |
+
$communities[ $community->properties->id ] = $community->properties->title;
|
104 |
+
}
|
105 |
|
106 |
+
$num_communities = count( $communities );
|
107 |
+
if ( 1 === $num_communities && ! $community_id ) {
|
108 |
+
update_option( 'lingotek_community', current( array_keys( $communities ) ) );
|
109 |
+
}
|
110 |
+
if ( ! $community_id && $num_communities > 1 ) {
|
111 |
+
echo "\n\t" . '<option value="">' . esc_html( __( 'Select', 'lingotek-translation' ) ) . '...</option>';
|
112 |
+
}
|
113 |
+
foreach ( $communities as $community_id_option => $community_title ) {
|
114 |
+
$selected = ($default_community_id === $community_id_option) ? 'selected="selected"' : '';
|
115 |
+
echo "\n\t" . '<option value="' . esc_attr( $community_id_option ) . '" ' . esc_html( $selected ) . '>' . esc_html( $community_title ) . '</option>';
|
116 |
+
}
|
117 |
+
}
|
118 |
+
?>
|
119 |
+
</select>
|
120 |
+
</td>
|
121 |
+
</tr>
|
122 |
+
</table>
|
123 |
|
124 |
+
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
125 |
+
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/settings/view-defaults.php
CHANGED
@@ -2,141 +2,135 @@
|
|
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);
|
9 |
-
if (
|
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 |
-
update_option('lingotek_defaults', $options);
|
51 |
-
}
|
52 |
-
}
|
53 |
}
|
54 |
settings_errors();
|
55 |
}
|
56 |
-
$settings = $this->get_profiles_settings(true);
|
57 |
-
$options = get_option('lingotek_defaults');
|
58 |
-
|
59 |
-
// Code to determine which filter scenario will be displayed (Not configured, defaults, custom filters)
|
60 |
-
$primary_filter_id = array_search('okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options']);
|
61 |
-
$secondary_filter_id = array_search('okf_html@wordpress.fprm', $settings['secondary_filter_id']['options']);
|
62 |
-
$default_filters = array($primary_filter_id => 'okf_json@with-html-subfilter.fprm', $secondary_filter_id => 'okf_html@wordpress.fprm');
|
63 |
-
$default_filters_exist =
|
64 |
-
$extra_filters_exist =
|
65 |
-
$no_filters_exist =
|
66 |
-
|
67 |
-
if ($settings['primary_filter_id']['options']
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
}
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
$no_filters_exist = TRUE;
|
83 |
-
}
|
84 |
}
|
85 |
-
unset($settings['primary_filter_id']['options'][$secondary_filter_id]);
|
86 |
-
unset($settings['secondary_filter_id']['options'][$primary_filter_id]);
|
87 |
?>
|
88 |
|
89 |
-
<h3><?php
|
90 |
-
<p class="description"><?php
|
91 |
|
92 |
|
93 |
-
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate">
|
94 |
-
<?php wp_nonce_field($page_key, '_wpnonce_' . $page_key); ?>
|
95 |
|
96 |
-
<table class="form-table"><?php foreach ($settings as $key => $setting) { ?>
|
97 |
-
<tr id="<?php echo $key.'_row'?>">
|
98 |
-
<th scope="row"><label for="<?php echo $key; ?>"><?php echo $setting['label'] ?></label></th>
|
99 |
<td>
|
100 |
-
<select name="<?php echo $key ?>" id="<?php echo $key ?>"><?php
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
</select><?php
|
106 |
-
if ('project_id'
|
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 |
-
<!-- End of filter code -->
|
135 |
</tr><?php } ?>
|
136 |
</table>
|
137 |
|
138 |
<p>
|
139 |
-
<?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
|
140 |
-
<?php submit_button(__( 'Refresh Resources', 'lingotek-translation'), 'secondary', 'refresh', false ); ?>
|
141 |
</p>
|
142 |
</form>
|
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 );
|
9 |
+
if ( ! empty( filter_input( INPUT_POST, 'refresh' ) ) ) {
|
10 |
+
$refresh_success = $this->set_community_resources( $community_id );
|
11 |
+
if ( true === $refresh_success['projects'] && true === $refresh_success['workflows'] ) {
|
12 |
+
add_settings_error( 'lingotek_community_resources', 'options', __( 'Resources from Lingotek were successfully updated for projects and workflows.', 'lingotek-translation' ), 'updated' );
|
13 |
+
} elseif ( true === $refresh_success['projects'] ) {
|
14 |
+
add_settings_error( 'lingotek_community_resources', 'error', __( 'Resources from Lingotek were successfully updated for projects.', 'lingotek-translation' ), 'updated' );
|
15 |
+
} elseif ( true === $refresh_success['workflows'] ) {
|
16 |
+
add_settings_error( 'lingotek_community_resources', 'error', __( 'Resources from Lingotek were successfully updated for workflows.', 'lingotek-translation' ), 'updated' );
|
17 |
+
} elseif ( false === $refresh_success['workflows'] || false === $refresh_success['projects'] ) {
|
18 |
+
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' );
|
19 |
+
}
|
20 |
+
} else {
|
21 |
+
$options = array();
|
22 |
+
$settings = $this->get_profiles_settings( true );
|
23 |
+
foreach ( $settings as $key => $setting ) {
|
24 |
+
if ( ! empty( filter_input( INPUT_POST, $key ) ) ) {
|
25 |
+
$options[ $key ] = filter_input( INPUT_POST, $key );
|
26 |
+
}
|
27 |
+
}
|
28 |
+
update_option( 'lingotek_defaults', $options );
|
29 |
+
add_settings_error( 'lingotek_defaults', 'defaultgs', __( 'Your <i>Defaults</i> were sucessfully saved.', 'lingotek-translation' ), 'updated' );
|
30 |
+
|
31 |
+
if ( ! empty( filter_input( INPUT_POST, 'update_callback' ) ) ) {
|
32 |
+
$client = new Lingotek_API();
|
33 |
+
if ( $client->update_callback_url( $options['project_id'] ) ) {
|
34 |
+
add_settings_error( 'lingotek_defaults', 'defaultgs', __( 'Your callback url was successfully updated.', 'lingotek-translation' ), 'updated' );
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
// adds new project if text box is filled out.
|
39 |
+
if ( ! empty( filter_input( INPUT_POST, 'new_project' ) ) ) {
|
40 |
+
$client = new Lingotek_API();
|
41 |
+
$title = stripslashes( filter_input( INPUT_POST, 'new_project' ) );
|
42 |
+
|
43 |
+
if ( $new_id = $client->create_project( $title, $community_id ) ) {
|
44 |
+
add_settings_error( 'lingotek_defaults', 'defaultgs', __( 'Your new project was successfully created.', 'lingotek-translation' ), 'updated' );
|
45 |
+
$this->set_community_resources( $community_id );// updates the cache to include the newly created project.
|
46 |
+
$options['project_id'] = $new_id;
|
47 |
+
update_option( 'lingotek_defaults', $options );
|
48 |
+
}
|
49 |
+
}
|
|
|
|
|
|
|
50 |
}
|
51 |
settings_errors();
|
52 |
}
|
53 |
+
$settings = $this->get_profiles_settings( true );
|
54 |
+
$options = get_option( 'lingotek_defaults' );
|
55 |
+
|
56 |
+
// Code to determine which filter scenario will be displayed (Not configured, defaults, custom filters).
|
57 |
+
$primary_filter_id = array_search( 'okf_json@with-html-subfilter.fprm', $settings['primary_filter_id']['options'], true );
|
58 |
+
$secondary_filter_id = array_search( 'okf_html@wordpress.fprm', $settings['secondary_filter_id']['options'], true );
|
59 |
+
$default_filters = array( $primary_filter_id => 'okf_json@with-html-subfilter.fprm', $secondary_filter_id => 'okf_html@wordpress.fprm' );
|
60 |
+
$default_filters_exist = false;
|
61 |
+
$extra_filters_exist = false;
|
62 |
+
$no_filters_exist = false;
|
63 |
+
|
64 |
+
if ( $settings['primary_filter_id']['options'] === $default_filters ) {
|
65 |
+
$default_filters_exist = true;
|
66 |
+
$options['primary_filter_id'] = $primary_filter_id;
|
67 |
+
$options['secondary_filter_id'] = $secondary_filter_id;
|
68 |
+
update_option( 'lingotek_defaults', $options );
|
69 |
+
} else {
|
70 |
+
$num = count( array_diff_assoc( $settings['primary_filter_id']['options'], $default_filters ) );
|
71 |
+
if ( $num > 0 ) {
|
72 |
+
$extra_filters_exist = true;
|
73 |
+
} else {
|
74 |
+
$options['primary_filter_id'] = '';
|
75 |
+
$options['secondary_filter_id'] = '';
|
76 |
+
update_option( 'lingotek_defaults', $options );
|
77 |
+
$no_filters_exist = true;
|
78 |
+
}
|
|
|
|
|
79 |
}
|
80 |
+
unset( $settings['primary_filter_id']['options'][ $secondary_filter_id ] );
|
81 |
+
unset( $settings['secondary_filter_id']['options'][ $primary_filter_id ] );
|
82 |
?>
|
83 |
|
84 |
+
<h3><?php esc_html_e( 'Defaults', 'lingotek-translation' ); ?></h3>
|
85 |
+
<p class="description"><?php esc_html_e( 'The default automation settings and resources that should be used for this site. These settings can be overriden using translation profiles and content type configuration.', 'lingotek-translation' ); ?></p>
|
86 |
|
87 |
|
88 |
+
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
89 |
+
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
90 |
|
91 |
+
<table class="form-table"><?php foreach ( $settings as $key => $setting ) { ?>
|
92 |
+
<tr id="<?php echo esc_html( $key ) . '_row'?>">
|
93 |
+
<th scope="row"><label for="<?php echo esc_html( $key ); ?>"><?php echo esc_html( $setting['label'] ) ?></label></th>
|
94 |
<td>
|
95 |
+
<select name="<?php echo esc_html( $key ) ?>" id="<?php echo esc_html( $key ) ?>"><?php
|
96 |
+
foreach ( $setting['options'] as $id => $title ) {
|
97 |
+
$selected = array_key_exists( $key, $options ) && ($options[ $key ] === $id) ? 'selected="selected"' : '';
|
98 |
+
echo "\n\t<option value='" . esc_attr( $id ) . "' " . esc_html( $selected ) . '>' . esc_html( $title ) . '</option>';
|
99 |
+
} ?>
|
100 |
</select><?php
|
101 |
+
if ( 'project_id' === $key ) { ?>
|
102 |
+
<?php
|
103 |
+
|
104 |
+
if ( empty( $setting['options'] ) ) { ?>
|
105 |
+
<script> document.getElementById('project_id').style.display = 'none';</script>
|
106 |
+
<input type="text" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ) ?>" />
|
107 |
+
<?php } else { ?>
|
108 |
+
|
109 |
+
<input type="text" style="display:none" name="new_project" id="new_project" placeholder="<?php esc_html_e( 'Enter new project name', 'lingotek-translation' ) ?>" />
|
110 |
+
<input type="checkbox" name="update_callback" id="update_callback"/>
|
111 |
+
<label for="update_callback" id="callback_label"><?php esc_html_e( 'Update the callback url for this project.', 'lingotek-translation' ) ?></label>
|
112 |
+
|
113 |
+
<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>
|
114 |
+
<?php } ?>
|
115 |
+
<?php } ?>
|
116 |
+
<!-- Code to handle displaying of Primary and Secondary Filters. -->
|
117 |
+
<?php if ( $no_filters_exist ) { ?>
|
118 |
+
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
119 |
+
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script> <?php
|
120 |
+
if ( 'primary_filter_id' === $key ) { ?>
|
121 |
+
<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>
|
122 |
+
<?php }
|
123 |
+
}
|
124 |
+
if ( $default_filters_exist ) { ?>
|
125 |
+
<script> document.getElementById("primary_filter_id_row").style.display = "none";</script>
|
126 |
+
<script> document.getElementById("secondary_filter_id_row").style.display = "none";</script>
|
127 |
+
<?php } ?>
|
128 |
+
<!-- End of filter code. -->
|
|
|
129 |
</tr><?php } ?>
|
130 |
</table>
|
131 |
|
132 |
<p>
|
133 |
+
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
134 |
+
<?php submit_button( __( 'Refresh Resources', 'lingotek-translation' ), 'secondary', 'refresh', false ); ?>
|
135 |
</p>
|
136 |
</form>
|
admin/settings/view-preferences.php
CHANGED
@@ -1,121 +1,111 @@
|
|
1 |
<?php
|
2 |
|
3 |
$setting_details = 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 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
);
|
51 |
|
52 |
$page_key = $this->plugin_slug . '_settings&sm=preferences';
|
53 |
|
54 |
-
if (!empty($_POST)) {
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
update_option('lingotek_prefs', $options);
|
66 |
|
67 |
-
|
68 |
-
|
69 |
}
|
70 |
-
// else {
|
71 |
-
// $selected_options = Lingotek_Model::get_prefs();
|
72 |
-
//
|
73 |
-
// $options = array();
|
74 |
-
// if (!isset($selected_options['import_enabled'])){
|
75 |
-
// $options['import_enabled'] = 'enabled';
|
76 |
-
// }
|
77 |
-
//
|
78 |
-
// update_option('lingotek_prefs', $options);
|
79 |
-
// }
|
80 |
-
|
81 |
$selected_options = Lingotek_Model::get_prefs();
|
82 |
|
83 |
?>
|
84 |
|
85 |
-
<h3><?php
|
86 |
-
<p class="description"><?php
|
87 |
|
88 |
|
89 |
-
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate">
|
90 |
-
<?php wp_nonce_field($page_key, '_wpnonce_' . $page_key); ?>
|
91 |
|
92 |
-
|
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 |
|
120 |
-
<?php submit_button(__('Save Changes', 'lingotek-translation'), 'primary', 'submit', false); ?>
|
121 |
</form>
|
1 |
<?php
|
2 |
|
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 |
+
'draft' => __( 'Draft', 'lingotek-translation' ),
|
11 |
+
'pending' => __( 'Pending Review', 'lingotek-translation' ),
|
12 |
+
'publish' => __( 'Published', 'lingotek-translation' ),
|
13 |
+
'private' => __( 'Privately Published', 'lingotek-translation' ),
|
14 |
+
),
|
15 |
+
),
|
16 |
+
'auto_upload_post_statuses' => array( // blacklist.
|
17 |
+
'type' => 'checkboxes',
|
18 |
+
'label' => __( 'Auto upload statuses', 'lingotek-translation' ),
|
19 |
+
'description' => __( 'The post statuses checked above are enabled for automatic upload (when using automatic uploading translation profiles).', 'lingotek-translation' ),
|
20 |
+
'values' => array(
|
21 |
+
'draft' => __( 'Draft', 'lingotek-translation' ),
|
22 |
+
'pending' => __( 'Pending Review', 'lingotek-translation' ),
|
23 |
+
'publish' => __( 'Published', 'lingotek-translation' ),
|
24 |
+
'future' => __( 'Scheduled', 'lingotek-translation' ),
|
25 |
+
'private' => __( 'Privately Published', 'lingotek-translation' ),
|
26 |
+
),
|
27 |
+
),
|
28 |
+
'delete_document_from_tms' => array(
|
29 |
+
'type' => 'checkboxes',
|
30 |
+
'label' => __( 'Disassociation', 'lingotek-translation' ),
|
31 |
+
'description' => __( 'Your documents will remain in your WordPress site but will be deleted from the Lingotek TMS if this option is checked.', 'lingotek-translation' ),
|
32 |
+
'values' => array(
|
33 |
+
'delete' => __( 'Delete documents from Lingotek TMS when disassociating.', 'lingotek-translation' ),
|
34 |
+
),
|
35 |
+
),
|
36 |
+
'delete_linked_content' => array(
|
37 |
+
'type' => 'checkboxes',
|
38 |
+
'label' => __( 'Deleting Content', 'wp-lingotek' ),
|
39 |
+
'description' => __( 'When enabled, deleting source or target content will also delete all linked content.', 'wp-lingotek' ),
|
40 |
+
'values' => array(
|
41 |
+
'enabled' => __( 'Delete linked content', 'wp-lingotek' ),
|
42 |
+
),
|
43 |
+
),
|
44 |
+
'import_enabled' => array(
|
45 |
+
'type' => 'checkboxes',
|
46 |
+
'label' => __( 'Import', 'wp-lingotek' ),
|
47 |
+
'description' => __( 'When checked, an "Import" submenu will appear.', 'wp-lingotek' ),
|
48 |
+
'values' => array(
|
49 |
+
'enabled' => __( 'Enable importing from Lingotek Content Cloud. (beta)', 'wp-lingotek' ),
|
50 |
+
),
|
51 |
+
),
|
52 |
);
|
53 |
|
54 |
$page_key = $this->plugin_slug . '_settings&sm=preferences';
|
55 |
|
56 |
+
if ( ! empty( $_POST ) ) {
|
57 |
+
check_admin_referer( $page_key, '_wpnonce_' . $page_key );
|
58 |
+
$options = array();
|
59 |
+
foreach ( $setting_details as $key => $setting ) {
|
60 |
+
if ( ! empty( filter_input( INPUT_POST, $key ) ) ) {
|
61 |
+
$options[ $key ] = filter_input( INPUT_POST, $key );
|
62 |
+
} else {
|
63 |
+
$options[ $key ] = null;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
update_option( 'lingotek_prefs', $options );
|
|
|
67 |
|
68 |
+
add_settings_error( 'lingotek_prefs', 'prefs', __( 'Your preferences were successfully updated.', 'lingotek-translation' ), 'updated' );
|
69 |
+
settings_errors();
|
70 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
$selected_options = Lingotek_Model::get_prefs();
|
72 |
|
73 |
?>
|
74 |
|
75 |
+
<h3><?php esc_html_e( 'Preferences', 'lingotek-translation' ); ?></h3>
|
76 |
+
<p class="description"><?php esc_html_e( 'These are your preferred settings.', 'lingotek-translation' ); ?></p>
|
77 |
|
78 |
|
79 |
+
<form id="lingotek-settings" method="post" action="admin.php?page=<?php echo esc_html( $page_key ); ?>" class="validate">
|
80 |
+
<?php wp_nonce_field( $page_key, '_wpnonce_' . $page_key ); ?>
|
81 |
|
82 |
+
<table class="form-table"><?php foreach ( $setting_details as $key => $setting ) { ?>
|
83 |
|
84 |
+
<tr>
|
85 |
+
<th scope="row"><label for="<?php echo esc_html( $key ); ?>"><?php echo esc_html( $setting['label'] ) ?></label></th>
|
86 |
+
<td>
|
87 |
+
<?php if ( 'dropdown' === $setting['type'] ) { ?>
|
88 |
+
<select name="<?php echo esc_html( $key ); ?>" id="<?php echo esc_html( $key ); ?>">
|
89 |
+
<?php
|
90 |
+
foreach ( $setting['values'] as $id => $title ) {
|
91 |
+
echo "\n\t" . '<option value="' . esc_attr( $id ) . '" ' . selected( $selected_options[ $key ], $id ) . '>' . esc_html( $title ) . '</option>';
|
92 |
+
}
|
93 |
+
?>
|
94 |
+
</select>
|
95 |
+
<?php } elseif ( 'checkboxes' === $setting['type'] ) {
|
96 |
+
echo '<ul class="pref-statuses">';
|
97 |
+
foreach ( $setting['values'] as $id => $title ) {
|
98 |
+
$cb_name = $key . '[' . esc_attr( $id ) . ']';
|
99 |
+
$checked = checked( '1', (isset( $selected_options[ $key ][ $id ] ) && $selected_options[ $key ][ $id ]), false );
|
100 |
+
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>';
|
101 |
+
}
|
102 |
+
echo '</ul>';
|
103 |
+
} ?>
|
104 |
+
<p class="description">
|
105 |
+
<?php echo esc_html( $setting['description'] ); ?>
|
106 |
+
</p>
|
107 |
+
</tr><?php } ?>
|
108 |
+
</table>
|
109 |
|
110 |
+
<?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
|
111 |
</form>
|
admin/settings/view-utilities.php
CHANGED
@@ -1,51 +1,55 @@
|
|
1 |
<?php
|
2 |
$page_key = $this->plugin_slug . '_settings&sm=utilities';
|
3 |
|
4 |
-
if (!empty($_POST)) {
|
5 |
-
check_admin_referer($page_key, '_wpnonce_' . $page_key);
|
6 |
|
7 |
-
// progress dialog placeholder
|
8 |
-
if (!empty(
|
9 |
$ids = Lingotek_Utilities::get_all_document_ids();
|
10 |
-
if (!empty($ids))
|
11 |
-
printf('<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', __('Disassociating content...', 'lingotek-translation'));
|
|
|
12 |
}
|
13 |
|
14 |
$utilities = array();
|
15 |
-
if(
|
16 |
$utilities[] = 'utility_set_default_language';
|
17 |
}
|
18 |
|
19 |
-
$GLOBALS['wp_lingotek']->utilities->run_utilities($utilities);
|
20 |
|
21 |
settings_errors();
|
22 |
}
|
23 |
|
24 |
?>
|
25 |
-
<h3><?php
|
26 |
-
<p class="description"><?php
|
27 |
|
28 |
-
<h4><?php
|
29 |
-
<form id="lingotek-utilities" method="post" action="admin.php?page=<?php echo $page_key; ?>" class="validate"><?php
|
30 |
-
wp_nonce_field($page_key, '_wpnonce_' . $page_key);
|
31 |
|
|
|
|
|
|
|
32 |
printf(
|
33 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
34 |
'utility_set_default_language',
|
35 |
-
__('Set <i>default language</i> as the language for all content that has not been assigned a language.', 'lingotek-translation')
|
36 |
);
|
37 |
|
38 |
?>
|
39 |
-
<h4><?php
|
40 |
<?php
|
41 |
|
42 |
printf(
|
43 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
44 |
'utility_disassociate',
|
45 |
-
__('Disassociate all the content from Lingotek TMS.', 'lingotek-translation')
|
46 |
);
|
47 |
|
48 |
-
$confirm_disassociate = __('You are about to disassociate all your content from Lingotek TMS. Are you sure ?', 'lingotek-translation');
|
49 |
|
50 |
$confirm_js = "
|
51 |
d = document.getElementById('utility_disassociate');
|
@@ -53,7 +57,5 @@ if (!empty($_POST)) {
|
|
53 |
return confirm('$confirm_disassociate');
|
54 |
}";
|
55 |
|
56 |
-
submit_button(__('Run Utilities', 'lingotek-translation'), 'primary', 'submit', true, sprintf('onclick="%s"', $confirm_js)); ?>
|
57 |
</form><?php
|
58 |
-
|
59 |
-
|
1 |
<?php
|
2 |
$page_key = $this->plugin_slug . '_settings&sm=utilities';
|
3 |
|
4 |
+
if ( ! empty( $_POST ) ) {
|
5 |
+
check_admin_referer( $page_key, '_wpnonce_' . $page_key );
|
6 |
|
7 |
+
// progress dialog placeholder.
|
8 |
+
if ( ! empty( filter_input( INPUT_POST, 'utility_disassociate' ) ) ) {
|
9 |
$ids = Lingotek_Utilities::get_all_document_ids();
|
10 |
+
if ( ! empty( $ids ) ) {
|
11 |
+
printf( '<div id="lingotek-progressdialog" title="%s"><div id="lingotek-progressbar"></div></div>', esc_html( __( 'Disassociating content...', 'lingotek-translation' ) ) );
|
12 |
+
}
|
13 |
}
|
14 |
|
15 |
$utilities = array();
|
16 |
+
if ( 'on' === filter_input( INPUT_POST, 'utility_set_default_language' ) ) {
|
17 |
$utilities[] = 'utility_set_default_language';
|
18 |
}
|
19 |
|
20 |
+
$GLOBALS['wp_lingotek']->utilities->run_utilities( $utilities );
|
21 |
|
22 |
settings_errors();
|
23 |
}
|
24 |
|
25 |
?>
|
26 |
+
<h3><?php esc_html_e( 'Utilities', 'lingotek-translation' ); ?></h3>
|
27 |
+
<p class="description"><?php esc_html_e( 'These utilities are designed to help you prepare and maintain your multilingual content.', 'lingotek-translation' ); ?></p>
|
28 |
|
29 |
+
<h4><?php esc_html_e( 'Language', 'lingotek-translation' ); ?></h4>
|
30 |
+
<form id="lingotek-utilities" method="post" action="admin.php?page=<?php echo esc_attr( $page_key ); ?>" class="validate"><?php
|
31 |
+
wp_nonce_field( $page_key, '_wpnonce_' . $page_key );
|
32 |
|
33 |
+
$allowed_html = [
|
34 |
+
'i' => [],
|
35 |
+
];
|
36 |
printf(
|
37 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
38 |
'utility_set_default_language',
|
39 |
+
wp_kses( __( 'Set <i>default language</i> as the language for all content that has not been assigned a language.', 'lingotek-translation' ), $allowed_html )
|
40 |
);
|
41 |
|
42 |
?>
|
43 |
+
<h4><?php esc_html_e( 'Disassociation', 'lingotek-translation' ); ?></h4>
|
44 |
<?php
|
45 |
|
46 |
printf(
|
47 |
'<p><input type="checkbox" name="%1$s" id="%1$s"/><label for="%1$s">%2$s</label></p>',
|
48 |
'utility_disassociate',
|
49 |
+
esc_html( __( 'Disassociate all the content from Lingotek TMS.', 'lingotek-translation' ) )
|
50 |
);
|
51 |
|
52 |
+
$confirm_disassociate = __( 'You are about to disassociate all your content from Lingotek TMS. Are you sure ?', 'lingotek-translation' );
|
53 |
|
54 |
$confirm_js = "
|
55 |
d = document.getElementById('utility_disassociate');
|
57 |
return confirm('$confirm_disassociate');
|
58 |
}";
|
59 |
|
60 |
+
submit_button( __( 'Run Utilities', 'lingotek-translation' ), 'primary', 'submit', true, sprintf( 'onclick="%s"', $confirm_js ) ); ?>
|
61 |
</form><?php
|
|
|
|
admin/string-actions.php
CHANGED
@@ -1,144 +1,155 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
3 |
class Lingotek_String_actions extends Lingotek_Actions {
|
4 |
|
5 |
-
|
6 |
* Constructor
|
7 |
*
|
8 |
* @since 0.2
|
9 |
*/
|
10 |
public function __construct() {
|
11 |
-
parent::__construct('string');
|
12 |
|
13 |
-
if (isset($this->pllm->options['default_lang']) && 'automatic'
|
14 |
-
add_action('updated_option', array(&$this, 'updated_option'));
|
|
|
15 |
}
|
16 |
|
17 |
-
|
18 |
-
*
|
19 |
*
|
20 |
* @since 0.2
|
21 |
*
|
22 |
-
* @param string $name
|
23 |
* @return object
|
24 |
*/
|
25 |
-
protected function get_language($name) {
|
26 |
-
return $this->pllm->get_language($this->pllm->options['default_lang'])
|
|
|
27 |
}
|
28 |
|
29 |
|
30 |
-
|
31 |
-
*
|
32 |
*
|
33 |
* @since 0.2
|
34 |
*
|
35 |
-
* @param int $id
|
36 |
*/
|
37 |
-
public static function uploaded_icon($id) {
|
38 |
-
return self::display_icon('uploaded', '#');
|
39 |
}
|
40 |
|
41 |
-
|
42 |
-
*
|
43 |
*
|
44 |
* @since 0.2
|
45 |
*
|
46 |
-
* @param array $args parameters to add to the link
|
47 |
-
* @param bool
|
48 |
* @return string
|
49 |
*/
|
50 |
-
protected function get_action_link($args, $warning = false) {
|
51 |
$args['page'] = 'lingotek-translation_manage';
|
52 |
$args['noheader'] = true;
|
53 |
-
return parent::get_action_link($args, $warning);
|
54 |
}
|
55 |
|
56 |
-
|
57 |
-
*
|
58 |
*
|
59 |
* @since 0.2
|
60 |
*
|
61 |
-
* @param string $name strings group name
|
62 |
* @return array
|
63 |
*/
|
64 |
-
public function row_actions($name) {
|
65 |
-
return $this->_row_actions(array(), $name);
|
66 |
}
|
67 |
|
68 |
-
|
69 |
-
*
|
70 |
*
|
71 |
* @since 0.2
|
|
|
|
|
72 |
*/
|
73 |
-
public function manage_actions($action) {
|
74 |
|
75 |
-
$redirect = remove_query_arg( array('action', 'action2'), wp_get_referer() );
|
76 |
-
if (
|
77 |
-
$redirect = admin_url(
|
|
|
78 |
|
79 |
-
switch($action) {
|
80 |
case 'bulk-lingotek-upload':
|
81 |
$ids = array();
|
82 |
|
83 |
-
foreach ($_REQUEST['strings'] as $id) {
|
84 |
-
// safe upload
|
85 |
-
if ($this->lgtm->can_upload('string', $id))
|
86 |
$ids[] = $id;
|
|
|
87 |
}
|
88 |
|
89 |
case 'bulk-lingotek-request':
|
90 |
case 'bulk-lingotek-download':
|
91 |
case 'bulk-lingotek-status':
|
92 |
case 'bulk-lingotek-delete':
|
93 |
-
if (empty($ids)) {
|
94 |
-
if (empty($_REQUEST['strings']))
|
95 |
return;
|
|
|
96 |
|
97 |
$ids = $_REQUEST['strings'];
|
98 |
}
|
99 |
|
100 |
-
check_admin_referer('bulk-lingotek-strings-translations');
|
101 |
-
$redirect = add_query_arg($action, 1, $redirect);
|
102 |
-
$redirect = add_query_arg('ids', implode(',', array_map('intval', $ids)), $redirect);
|
103 |
|
104 |
break;
|
105 |
|
106 |
case 'lingotek-upload':
|
107 |
-
check_admin_referer('lingotek-upload');
|
108 |
-
$this->lgtm->upload_strings($_GET['string']);
|
109 |
break;
|
110 |
|
111 |
default:
|
112 |
-
if (
|
113 |
-
return; // do not redirect if this is not one of our actions
|
114 |
-
|
115 |
}
|
116 |
|
117 |
-
wp_redirect($redirect);
|
118 |
exit();
|
119 |
|
120 |
}
|
121 |
|
122 |
-
|
123 |
-
*
|
124 |
*
|
125 |
* @since 0.2
|
126 |
*/
|
127 |
public function ajax_upload() {
|
128 |
-
check_ajax_referer('lingotek_progress', '_lingotek_nonce');
|
129 |
-
$this->lgtm->upload_strings(
|
130 |
die();
|
131 |
}
|
132 |
|
133 |
-
|
134 |
-
*
|
135 |
*
|
136 |
* @since 0.2
|
137 |
*/
|
138 |
public function updated_option() {
|
139 |
-
foreach (Lingotek_Model::get_strings() as $id) {
|
140 |
-
if ($this->lgtm->can_upload('string', $id['context']))
|
141 |
-
$this->lgtm->upload_strings($id['context']);
|
|
|
142 |
}
|
143 |
}
|
144 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
+
* Lingotek String Actions class.
|
5 |
+
*/
|
6 |
class Lingotek_String_actions extends Lingotek_Actions {
|
7 |
|
8 |
+
/**
|
9 |
* Constructor
|
10 |
*
|
11 |
* @since 0.2
|
12 |
*/
|
13 |
public function __construct() {
|
14 |
+
parent::__construct( 'string' );
|
15 |
|
16 |
+
if ( isset( $this->pllm->options['default_lang'] ) && 'automatic' === Lingotek_Model::get_profile_option( 'upload', 'string', $this->pllm->get_language( $this->pllm->options['default_lang'] ) ) ) {
|
17 |
+
add_action( 'updated_option', array( &$this, 'updated_option' ) );
|
18 |
+
}
|
19 |
}
|
20 |
|
21 |
+
/**
|
22 |
+
* Get the language of strings sources
|
23 |
*
|
24 |
* @since 0.2
|
25 |
*
|
26 |
+
* @param string $name name.
|
27 |
* @return object
|
28 |
*/
|
29 |
+
protected function get_language( $name ) {
|
30 |
+
return $this->pllm->get_language( $this->pllm->options['default_lang'] );
|
31 |
+
;
|
32 |
}
|
33 |
|
34 |
|
35 |
+
/**
|
36 |
+
* Displays the icon of an uploaded strings group (no link)
|
37 |
*
|
38 |
* @since 0.2
|
39 |
*
|
40 |
+
* @param int $id id.
|
41 |
*/
|
42 |
+
public static function uploaded_icon( $id ) {
|
43 |
+
return self::display_icon( 'uploaded', '#' );
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* Creates an html action link
|
48 |
*
|
49 |
* @since 0.2
|
50 |
*
|
51 |
+
* @param array $args parameters to add to the link.
|
52 |
+
* @param bool $warning whether to display an alert or not, optional, defaults to false.
|
53 |
* @return string
|
54 |
*/
|
55 |
+
protected function get_action_link( $args, $warning = false ) {
|
56 |
$args['page'] = 'lingotek-translation_manage';
|
57 |
$args['noheader'] = true;
|
58 |
+
return parent::get_action_link( $args, $warning );
|
59 |
}
|
60 |
|
61 |
+
/**
|
62 |
+
* Adds a row actions links.
|
63 |
*
|
64 |
* @since 0.2
|
65 |
*
|
66 |
+
* @param string $name strings group name.
|
67 |
* @return array
|
68 |
*/
|
69 |
+
public function row_actions( $name ) {
|
70 |
+
return $this->_row_actions( array(), $name );
|
71 |
}
|
72 |
|
73 |
+
/**
|
74 |
+
* Manages Lingotek actions
|
75 |
*
|
76 |
* @since 0.2
|
77 |
+
*
|
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' );
|
85 |
+
}
|
86 |
|
87 |
+
switch ( $action ) {
|
88 |
case 'bulk-lingotek-upload':
|
89 |
$ids = array();
|
90 |
|
91 |
+
foreach ( $_REQUEST['strings'] as $id ) {
|
92 |
+
// safe upload.
|
93 |
+
if ( $this->lgtm->can_upload( 'string', $id ) ) {
|
94 |
$ids[] = $id;
|
95 |
+
}
|
96 |
}
|
97 |
|
98 |
case 'bulk-lingotek-request':
|
99 |
case 'bulk-lingotek-download':
|
100 |
case 'bulk-lingotek-status':
|
101 |
case 'bulk-lingotek-delete':
|
102 |
+
if ( empty( $ids ) ) {
|
103 |
+
if ( empty( $_REQUEST['strings'] ) ) {
|
104 |
return;
|
105 |
+
}
|
106 |
|
107 |
$ids = $_REQUEST['strings'];
|
108 |
}
|
109 |
|
110 |
+
check_admin_referer( 'bulk-lingotek-strings-translations' );
|
111 |
+
$redirect = add_query_arg( $action, 1, $redirect );
|
112 |
+
$redirect = add_query_arg( 'ids', implode( ',', array_map( 'intval', $ids ) ), $redirect );
|
113 |
|
114 |
break;
|
115 |
|
116 |
case 'lingotek-upload':
|
117 |
+
check_admin_referer( 'lingotek-upload' );
|
118 |
+
$this->lgtm->upload_strings( $_GET['string'] );
|
119 |
break;
|
120 |
|
121 |
default:
|
122 |
+
if ( ! $this->_manage_actions( $action ) ) {
|
123 |
+
return; // do not redirect if this is not one of our actions.
|
124 |
+
}
|
125 |
}
|
126 |
|
127 |
+
wp_redirect( $redirect );
|
128 |
exit();
|
129 |
|
130 |
}
|
131 |
|
132 |
+
/**
|
133 |
+
* Ajax response to upload documents and showing progress
|
134 |
*
|
135 |
* @since 0.2
|
136 |
*/
|
137 |
public function ajax_upload() {
|
138 |
+
check_ajax_referer( 'lingotek_progress', '_lingotek_nonce' );
|
139 |
+
$this->lgtm->upload_strings( filter_input( INPUT_POST, 'id' ) );
|
140 |
die();
|
141 |
}
|
142 |
|
143 |
+
/**
|
144 |
+
* Automatic upload of strings when an option is updated
|
145 |
*
|
146 |
* @since 0.2
|
147 |
*/
|
148 |
public function updated_option() {
|
149 |
+
foreach ( Lingotek_Model::get_strings() as $id ) {
|
150 |
+
if ( $this->lgtm->can_upload( 'string', $id['context'] ) ) {
|
151 |
+
$this->lgtm->upload_strings( $id['context'] );
|
152 |
+
}
|
153 |
}
|
154 |
}
|
155 |
}
|
admin/strings-table.php
CHANGED
@@ -1,102 +1,126 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if(!class_exists('WP_List_Table')){
|
4 |
-
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1
|
5 |
}
|
6 |
|
|
|
|
|
|
|
7 |
class Lingotek_Strings_Table extends WP_List_Table {
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
|
11 |
-
*
|
12 |
*
|
13 |
* @since 0.2
|
|
|
14 |
*/
|
15 |
-
function __construct($string_actions) {
|
16 |
parent::__construct(array(
|
17 |
-
'plural' => 'lingotek-strings-translations', // do not translate (used for css class)
|
18 |
-
'ajax' => false
|
19 |
));
|
20 |
$this->pllm = $GLOBALS['polylang']->model;
|
21 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
22 |
$this->string_actions = $string_actions;
|
23 |
}
|
24 |
|
25 |
-
|
26 |
-
*
|
27 |
*
|
28 |
* @since 0.2
|
29 |
*
|
30 |
-
* @param array
|
31 |
-
* @param string $column_name
|
32 |
-
* @return string
|
33 |
*/
|
34 |
-
function column_default($item, $column_name) {
|
35 |
-
// generic case (count)
|
36 |
-
if (false === strpos($column_name, 'language_'))
|
37 |
-
return $item[$column_name];
|
38 |
-
|
39 |
-
// language column
|
40 |
-
$language = $this->pllm->get_language(substr($column_name, 9));
|
41 |
-
$document = $this->lgtm->get_group('string', $item['context']); // FIXME
|
42 |
-
|
43 |
-
// post ready for upload
|
44 |
-
if ($this->lgtm->can_upload('string', $item['context']) && $language->slug == $this->pllm->options['default_lang'])
|
45 |
-
echo $this->string_actions->upload_icon($item['context']);
|
46 |
-
|
47 |
-
// translation disabled
|
48 |
-
elseif (isset($document->source) && $document->is_disabled_target($language))
|
49 |
-
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
50 |
-
|
51 |
-
// source post is uploaded
|
52 |
-
elseif (isset($document->source) && $document->source == $language->mo_id)
|
53 |
-
echo 'importing' == $document->status ? Lingotek_Actions::importing_icon($document) : Lingotek_String_actions::uploaded_icon($item['context']);
|
54 |
-
|
55 |
-
// translations
|
56 |
-
elseif (isset($document->translations[$language->locale]) || (isset($document->source) && 'current' == $document->status))
|
57 |
-
echo Lingotek_Actions::translation_icon($document, $language);
|
58 |
|
59 |
-
//
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
$language_only = 'language_' . $language->slug;
|
64 |
-
$errors = get_option('lingotek_log_errors');
|
65 |
-
if ($language_only
|
66 |
-
if (isset($errors[$item['context']])) {
|
67 |
-
$api_error = Lingotek_Actions::retrieve_api_error($errors[$item['context']]);
|
68 |
-
echo Lingotek_Actions::display_error_icon('error', $api_error);
|
69 |
}
|
70 |
}
|
71 |
}
|
72 |
|
73 |
-
|
74 |
-
*
|
75 |
*
|
76 |
* @since 0.2
|
77 |
*
|
78 |
-
* @param array $item
|
79 |
* @return string
|
80 |
*/
|
81 |
-
function column_cb($item){
|
82 |
-
return sprintf('<input type="checkbox" name="strings[]" value="%d" />', esc_attr($item['row']));
|
83 |
}
|
84 |
|
85 |
-
|
86 |
-
*
|
87 |
* displays the row actions links
|
88 |
*
|
89 |
* @since 0.2
|
90 |
*
|
91 |
-
* @param object $item
|
92 |
* @return string
|
93 |
*/
|
94 |
-
function column_context($item) {
|
95 |
-
return $item['context'] . $this->row_actions($this->string_actions->row_actions($item['context']));
|
96 |
}
|
97 |
|
98 |
-
|
99 |
-
*
|
100 |
*
|
101 |
* @since 0.2
|
102 |
*
|
@@ -104,25 +128,24 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
104 |
*/
|
105 |
function get_columns() {
|
106 |
$columns = array(
|
107 |
-
'cb' => '<input type="checkbox" />', //checkbox
|
108 |
-
'context' => __('Group', 'lingotek-translation'),
|
109 |
-
'count' => __('Count', 'lingotek-translation'),
|
110 |
);
|
111 |
|
112 |
-
foreach ($GLOBALS['polylang']->model->get_languages_list() as $lang) {
|
113 |
-
if (
|
114 |
-
$columns['language_' . $lang->slug] = $lang->slug;
|
115 |
-
}
|
116 |
-
|
117 |
-
$columns['language_' . $lang->slug] = $lang->flag;
|
118 |
}
|
119 |
}
|
120 |
|
121 |
return $columns;
|
122 |
}
|
123 |
|
124 |
-
|
125 |
-
*
|
126 |
*
|
127 |
* @since 0.2
|
128 |
*
|
@@ -130,65 +153,74 @@ class Lingotek_Strings_Table extends WP_List_Table {
|
|
130 |
*/
|
131 |
function get_sortable_columns() {
|
132 |
return array(
|
133 |
-
'context' => array('context', false),
|
134 |
-
'count' => array('count', false),
|
135 |
);
|
136 |
}
|
137 |
|
138 |
-
|
139 |
-
*
|
140 |
*
|
141 |
* @since 0.2
|
142 |
*
|
143 |
-
* @param array $data
|
144 |
*/
|
145 |
-
function prepare_items($data = array()) {
|
146 |
-
$per_page = $this->get_items_per_page('lingotek_strings_per_page');
|
147 |
-
$this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
};
|
153 |
|
154 |
-
if (!empty(
|
155 |
-
usort($data, 'usort_reorder');
|
|
|
156 |
|
157 |
-
$total_items = count($data);
|
158 |
-
$this->items = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
159 |
|
160 |
$this->set_pagination_args(array(
|
161 |
'total_items' => $total_items,
|
162 |
'per_page' => $per_page,
|
163 |
-
'total_pages' => ceil($total_items
|
164 |
));
|
165 |
}
|
166 |
|
167 |
-
|
168 |
-
*
|
169 |
*
|
170 |
* @since 0.2
|
171 |
*
|
172 |
* @return array
|
173 |
*/
|
174 |
function get_bulk_actions() {
|
175 |
-
foreach (Lingotek_String_actions::$actions as $action => $strings)
|
176 |
-
$arr['bulk-lingotek-' . $action] = $strings['action'];
|
|
|
177 |
return $arr;
|
178 |
}
|
179 |
|
180 |
-
|
181 |
-
*
|
182 |
*
|
183 |
* @since 1.2
|
184 |
*
|
185 |
* @return string first language column name
|
186 |
*/
|
187 |
protected function get_first_language_column() {
|
188 |
-
foreach ($this->pllm->get_languages_list() as $language) {
|
189 |
-
$columns[] = 'language_'
|
190 |
}
|
191 |
|
192 |
-
return empty($columns) ? '' : reset($columns);
|
193 |
}
|
194 |
}
|
1 |
<?php
|
2 |
|
3 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1.
|
5 |
}
|
6 |
|
7 |
+
/**
|
8 |
+
* Lingotek Strings Table class.
|
9 |
+
*/
|
10 |
class Lingotek_Strings_Table extends WP_List_Table {
|
11 |
+
/**
|
12 |
+
* Polylang model.
|
13 |
+
*
|
14 |
+
* @var object
|
15 |
+
*/
|
16 |
+
public $pllm;
|
17 |
+
/**
|
18 |
+
* Lingotek model.
|
19 |
+
*
|
20 |
+
* @var object.
|
21 |
+
*/
|
22 |
+
public $lgtm;
|
23 |
+
/**
|
24 |
+
* String actions.
|
25 |
+
*
|
26 |
+
* @var object
|
27 |
+
*/
|
28 |
+
public $string_actions;
|
29 |
|
30 |
+
/**
|
31 |
+
* Constructor
|
32 |
*
|
33 |
* @since 0.2
|
34 |
+
* @param string $string_actions string actions.
|
35 |
*/
|
36 |
+
function __construct( $string_actions ) {
|
37 |
parent::__construct(array(
|
38 |
+
'plural' => 'lingotek-strings-translations', // do not translate (used for css class).
|
39 |
+
'ajax' => false,
|
40 |
));
|
41 |
$this->pllm = $GLOBALS['polylang']->model;
|
42 |
$this->lgtm = $GLOBALS['wp_lingotek']->model;
|
43 |
$this->string_actions = $string_actions;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* Displays the item information in a column (default case)
|
48 |
*
|
49 |
* @since 0.2
|
50 |
*
|
51 |
+
* @param array $item item.
|
52 |
+
* @param string $column_name column name.
|
|
|
53 |
*/
|
54 |
+
function column_default( $item, $column_name ) {
|
55 |
+
// generic case (count).
|
56 |
+
if ( false === strpos( $column_name, 'language_' ) ) {
|
57 |
+
return $item[ $column_name ];
|
58 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
// language column.
|
61 |
+
$language = $this->pllm->get_language( substr( $column_name, 9 ) );
|
62 |
+
$document = $this->lgtm->get_group( 'string', $item['context'] ); // FIXME.
|
63 |
+
|
64 |
+
$allowed_html = [
|
65 |
+
'a' => [
|
66 |
+
'class' => array(),
|
67 |
+
'title' => array(),
|
68 |
+
'href' => array(),
|
69 |
+
],
|
70 |
+
];
|
71 |
+
// post ready for upload.
|
72 |
+
if ( $this->lgtm->can_upload( 'string', $item['context'] ) && $language->slug === $this->pllm->options['default_lang'] ) {
|
73 |
+
echo wp_kses( $this->string_actions->upload_icon( $item['context'] ), $allowed_html );
|
74 |
+
} // translation disabled.
|
75 |
+
elseif ( isset( $document->source ) && $document->is_disabled_target( $language ) ) {
|
76 |
echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
77 |
+
} // source post is uploaded.
|
78 |
+
elseif ( isset( $document->source ) && $document->source === $language->mo_id ) {
|
79 |
+
echo wp_kses( 'importing' === $document->status ? Lingotek_Actions::importing_icon( $document ) : Lingotek_String_actions::uploaded_icon( $item['context'] ), $allowed_html );
|
80 |
+
} // translations.
|
81 |
+
elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
|
82 |
+
echo wp_kses( Lingotek_Actions::translation_icon( $document, $language ), $allowed_html );
|
83 |
+
} // no translation.
|
84 |
+
else { echo '<div class="lingotek-color dashicons dashicons-no"></div>';
|
85 |
+
}
|
86 |
|
87 |
$language_only = 'language_' . $language->slug;
|
88 |
+
$errors = get_option( 'lingotek_log_errors' );
|
89 |
+
if ( $language_only === $this->get_first_language_column() ) {
|
90 |
+
if ( isset( $errors[ $item['context'] ] ) ) {
|
91 |
+
$api_error = Lingotek_Actions::retrieve_api_error( $errors[ $item['context'] ] );
|
92 |
+
echo esc_html( Lingotek_Actions::display_error_icon( 'error', $api_error ) );
|
93 |
}
|
94 |
}
|
95 |
}
|
96 |
|
97 |
+
/**
|
98 |
+
* Displays the checkbox in first column
|
99 |
*
|
100 |
* @since 0.2
|
101 |
*
|
102 |
+
* @param array $item item.
|
103 |
* @return string
|
104 |
*/
|
105 |
+
function column_cb( $item ) {
|
106 |
+
return sprintf( '<input type="checkbox" name="strings[]" value="%d" />', esc_attr( $item['row'] ) );
|
107 |
}
|
108 |
|
109 |
+
/**
|
110 |
+
* Displays the item information in the column 'group'
|
111 |
* displays the row actions links
|
112 |
*
|
113 |
* @since 0.2
|
114 |
*
|
115 |
+
* @param object $item item.
|
116 |
* @return string
|
117 |
*/
|
118 |
+
function column_context( $item ) {
|
119 |
+
return $item['context'] . $this->row_actions( $this->string_actions->row_actions( $item['context'] ) );
|
120 |
}
|
121 |
|
122 |
+
/**
|
123 |
+
* Gets the list of columns
|
124 |
*
|
125 |
* @since 0.2
|
126 |
*
|
128 |
*/
|
129 |
function get_columns() {
|
130 |
$columns = array(
|
131 |
+
'cb' => '<input type="checkbox" />', // checkbox.
|
132 |
+
'context' => __( 'Group', 'lingotek-translation' ),
|
133 |
+
'count' => __( 'Count', 'lingotek-translation' ),
|
134 |
);
|
135 |
|
136 |
+
foreach ( $GLOBALS['polylang']->model->get_languages_list() as $lang ) {
|
137 |
+
if ( ! $lang->flag ) {
|
138 |
+
$columns[ 'language_' . $lang->slug ] = $lang->slug;
|
139 |
+
} else {
|
140 |
+
$columns[ 'language_' . $lang->slug ] = $lang->flag;
|
|
|
141 |
}
|
142 |
}
|
143 |
|
144 |
return $columns;
|
145 |
}
|
146 |
|
147 |
+
/**
|
148 |
+
* Gets the list of sortable columns
|
149 |
*
|
150 |
* @since 0.2
|
151 |
*
|
153 |
*/
|
154 |
function get_sortable_columns() {
|
155 |
return array(
|
156 |
+
'context' => array( 'context', false ),
|
157 |
+
'count' => array( 'count', false ),
|
158 |
);
|
159 |
}
|
160 |
|
161 |
+
/**
|
162 |
+
* Prepares the list of items ofr displaying
|
163 |
*
|
164 |
* @since 0.2
|
165 |
*
|
166 |
+
* @param array $data data.
|
167 |
*/
|
168 |
+
function prepare_items( $data = array() ) {
|
169 |
+
$per_page = $this->get_items_per_page( 'lingotek_strings_per_page' );
|
170 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Custom sorting comparator.
|
174 |
+
*
|
175 |
+
* @param array $a array of strings.
|
176 |
+
* @param array $b array of strings.
|
177 |
+
* @return int sort direction.
|
178 |
+
*/
|
179 |
+
function usort_reorder( $a, $b ) {
|
180 |
+
$result = strcmp( $a[ filter_input( INPUT_GET, 'orderby' ) ], $b[ filter_input( INPUT_GET, 'orderby' ) ] ); // determine sort order.
|
181 |
+
return (empty( filter_input( INPUT_GET, 'order' ) ) || 'asc' === filter_input( INPUT_GET, 'order' ) ) ? $result : -$result; // send final sort direction to usort.
|
182 |
};
|
183 |
|
184 |
+
if ( ! empty( filter_input( INPUT_GET, 'orderby' ) ) ) { // no sort by default.
|
185 |
+
usort( $data, 'usort_reorder' );
|
186 |
+
}
|
187 |
|
188 |
+
$total_items = count( $data );
|
189 |
+
$this->items = array_slice( $data, ($this->get_pagenum() - 1) * $per_page, $per_page );
|
190 |
|
191 |
$this->set_pagination_args(array(
|
192 |
'total_items' => $total_items,
|
193 |
'per_page' => $per_page,
|
194 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
195 |
));
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* Get the list of possible bulk actions
|
200 |
*
|
201 |
* @since 0.2
|
202 |
*
|
203 |
* @return array
|
204 |
*/
|
205 |
function get_bulk_actions() {
|
206 |
+
foreach ( Lingotek_String_actions::$actions as $action => $strings ) {
|
207 |
+
$arr[ 'bulk-lingotek-' . $action ] = $strings['action'];
|
208 |
+
}
|
209 |
return $arr;
|
210 |
}
|
211 |
|
212 |
+
/**
|
213 |
+
* Returns the first language column
|
214 |
*
|
215 |
* @since 1.2
|
216 |
*
|
217 |
* @return string first language column name
|
218 |
*/
|
219 |
protected function get_first_language_column() {
|
220 |
+
foreach ( $this->pllm->get_languages_list() as $language ) {
|
221 |
+
$columns[] = 'language_' . $language->slug;
|
222 |
}
|
223 |
|
224 |
+
return empty( $columns ) ? '' : reset( $columns );
|
225 |
}
|
226 |
}
|
admin/table-string.php
CHANGED
@@ -1,74 +1,79 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* @since 0.3
|
7 |
-
*/
|
8 |
-
class Lingotek_Table_String extends PLL_Table_String {
|
9 |
-
|
10 |
-
*
|
11 |
-
*
|
12 |
-
* @since 0.3
|
13 |
-
*
|
14 |
-
* @param array $item
|
15 |
-
* @return string
|
16 |
-
*/
|
17 |
-
function column_translations($item) {
|
18 |
-
$out = '';
|
19 |
-
foreach($item['translations'] as $key => $translation) {
|
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('<div class="translation"><label for="%1$s-%2$s">%3$s</label>'
|
24 |
-
esc_attr($key),
|
25 |
-
esc_attr($item['row']),
|
26 |
-
esc_html($this->languages['languages'][$key]),
|
27 |
-
|
28 |
-
}
|
29 |
-
return $out;
|
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 |
-
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Extends the Polylang class to disable the input fields
|
5 |
+
*
|
6 |
+
* @since 0.3
|
7 |
+
*/
|
8 |
+
class Lingotek_Table_String extends PLL_Table_String {
|
9 |
+
/**
|
10 |
+
* Displays the translations to edit (disabled).
|
11 |
+
*
|
12 |
+
* @since 0.3
|
13 |
+
*
|
14 |
+
* @param array $item item.
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
function column_translations( $item ) {
|
18 |
+
$out = '';
|
19 |
+
foreach ( $item['translations'] as $key => $translation ) {
|
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('<div class="translation"><label for="%1$s-%2$s">%3$s</label>' . $input_type . '</div>' . "\n",
|
24 |
+
esc_attr( $key ),
|
25 |
+
esc_attr( $item['row'] ),
|
26 |
+
esc_html( $this->languages['languages'][ $key ] ),
|
27 |
+
format_to_edit( $translation )); // don't interpret special chars.
|
28 |
+
}
|
29 |
+
return $out;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Prepares items for display.
|
34 |
+
*
|
35 |
+
* @param array $data data.
|
36 |
+
*/
|
37 |
+
function prepare_items( $data = null ) {
|
38 |
+
$listlanguages = $GLOBALS['polylang']->model->get_languages_list();
|
39 |
+
|
40 |
+
// Filter for search string.
|
41 |
+
$s = empty( filter_input( INPUT_GET, 's' ) ) ? '' : wp_unslash( filter_input( INPUT_GET, 's' ) );
|
42 |
+
foreach ( $data as $key => $row ) {
|
43 |
+
if ( ( -1 !== $this->selected_group && $row['context'] !== $this->selected_group ) || ( ! empty( $s ) && stripos( $row['name'], $s ) === false && stripos( $row['string'], $s ) === false ) ) {
|
44 |
+
unset( $data[ $key ] );
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
// Load translations.
|
49 |
+
foreach ( $listlanguages as $language ) {
|
50 |
+
// filters by language if requested.
|
51 |
+
if ( ($lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true )) && $language->slug !== $lg ) {
|
52 |
+
continue;
|
53 |
+
}
|
54 |
+
|
55 |
+
$mo = new PLL_MO();
|
56 |
+
$mo->import_from_db( $language );
|
57 |
+
foreach ( $data as $key => $row ) {
|
58 |
+
$data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
|
59 |
+
$data[ $key ]['row'] = $key; // store the row number for convenience.
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
$per_page = $this->get_items_per_page( 'pll_strings_per_page' );
|
64 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
65 |
+
|
66 |
+
if ( ! empty( filter_input( INPUT_GET, 'orderby' ) ) ) { // No sort by default.
|
67 |
+
usort( $data, array( $this, 'usort_reorder' ) );
|
68 |
+
}
|
69 |
+
|
70 |
+
$total_items = count( $data );
|
71 |
+
$this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
|
72 |
+
|
73 |
+
$this->set_pagination_args( array(
|
74 |
+
'total_items' => $total_items,
|
75 |
+
'per_page' => $per_page,
|
76 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
77 |
+
) );
|
78 |
+
}
|
79 |
+
}
|
admin/workflows/professional-translation-workflow.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Adds the thickbox Wordpress component. Loades the professional-workflow js file that attaches listeners to uploads.
|
10 |
+
* Sends the workflow id to the js file.
|
11 |
+
*
|
12 |
+
* @param string $id the workflow id.
|
13 |
+
*/
|
14 |
+
public function override_events( $id ) {
|
15 |
+
add_thickbox();
|
16 |
+
wp_enqueue_script( 'lingotek_professional_workflow', LINGOTEK_URL . '/js/workflow/professional-workflow.js' );
|
17 |
+
$vars = [
|
18 |
+
'id' => $id,
|
19 |
+
];
|
20 |
+
wp_localize_script( 'lingotek_professional_workflow', 'workflow_vars', $vars );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Writes a modal to the output buffer that contains information about this workflow.
|
25 |
+
*
|
26 |
+
* @param string $id the workflow id.
|
27 |
+
*/
|
28 |
+
public function echo_info_modal( $id ) {
|
29 |
+
if ( ! $this->info_modal_launched ) {
|
30 |
+
$this->info_modal_launched = true;
|
31 |
+
$args = [
|
32 |
+
'header' => __( 'Professional Translation Workflow', 'lingotek-translation' ),
|
33 |
+
'body' => __( "The Professional Translation Workflow allows you to have any of your content
|
34 |
+
translated professionally. Translations are priced by word count and can be requested from within
|
35 |
+
the Wordpress Posts or Pages tab.
|
36 |
+
<br><br>In order to use this workflow you must set up a payment method and purchase Word Credits.
|
37 |
+
<br><br>Would you like to set up a payment method?", 'lingotek-translation' ),
|
38 |
+
'id' => $id,
|
39 |
+
];
|
40 |
+
$this->_echo_modal( $args );
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
46 |
+
*
|
47 |
+
* @param string $id the workflow id.
|
48 |
+
*/
|
49 |
+
public function echo_posts_modal( $id ) {
|
50 |
+
if ( ! $this->post_modal_launched ) {
|
51 |
+
$this->post_modal_launched = true;
|
52 |
+
$args = [
|
53 |
+
'header' => __( 'Confirm Document Upload', 'lingotek-translation' ),
|
54 |
+
'body' => __( "You have the Professional Translation workflow selected. This means that all
|
55 |
+
translations of this document will cost Word Credits.
|
56 |
+
<br><br>Any translations of the uploaded document will be <b>final</b>. A new transaction(s) will be made if this document is
|
57 |
+
edited and re-translations are requested.
|
58 |
+
<br><br>Would you like to continue?", 'lingotek-translation' ),
|
59 |
+
'id' => $id,
|
60 |
+
];
|
61 |
+
$this->_echo_modal( $args );
|
62 |
+
$this->echo_request_modal( $id );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Writes a modal to the output buffer that tells the user how much it is going to cost.
|
69 |
+
*
|
70 |
+
* @param string $id the workflow id.
|
71 |
+
*/
|
72 |
+
public function echo_terms_modal( $id ) {
|
73 |
+
if ( ! $this->terms_modal_launched ) {
|
74 |
+
$this->terms_modal_launched = true;
|
75 |
+
$args = [
|
76 |
+
'header' => __( 'Lingotek Terms', 'lingotek-translation' ),
|
77 |
+
'body' => __( 'This is an example of a terms modal.', 'lingotek-translation' ),
|
78 |
+
'id' => $id,
|
79 |
+
];
|
80 |
+
$this->_echo_modal( $args );
|
81 |
+
$this->echo_request_modal( $id );
|
82 |
+
}
|
83 |
+
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Writes a modal to the output buffer that is launched when the user clicks on the 'request translation'
|
88 |
+
* option.
|
89 |
+
*
|
90 |
+
* @param string $id the workflow id.
|
91 |
+
*/
|
92 |
+
public function echo_request_modal( $id ) {
|
93 |
+
$args = [
|
94 |
+
'header' => __( 'Confirm Request Translation', 'lingotek-translation' ),
|
95 |
+
'body' => __( "You have the Professional Translation workflow selected. This document will be translated by a professional
|
96 |
+
in the selected language.
|
97 |
+
|
98 |
+
<br><br>The approximated cost to translate this document is 13 Word Credits.
|
99 |
+
<br><br>The translation request is <b>final</b> meaning that if the source document is changed then it will cost Word Credits to request re-translation.
|
100 |
+
<br><br> Would you like to request this translation?", 'lingotek-translation' ),
|
101 |
+
'id' => $id . '-request',
|
102 |
+
];
|
103 |
+
$this->_echo_modal( $args );
|
104 |
+
}
|
105 |
+
}
|
admin/workflows/workflow-factory.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WorkflowFactory
|
5 |
+
*
|
6 |
+
* Returns an instance of a Workflow object.
|
7 |
+
*/
|
8 |
+
class Lingotek_Workflow_Factory {
|
9 |
+
|
10 |
+
const BASE_WORKFLOW = 'Lingotek_Workflow';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Constructor. Loads the base workflow class and the base workflow js file.
|
14 |
+
*/
|
15 |
+
public function __construct() {
|
16 |
+
self::class_load( self::BASE_WORKFLOW );
|
17 |
+
wp_enqueue_script( 'lingotek_workflow_namespace', LINGOTEK_URL . '/js/workflow/workflow.js' );
|
18 |
+
}
|
19 |
+
/**
|
20 |
+
* An associative array that maps a workflowId to a Workflow object.
|
21 |
+
*
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
+
private static $map = [
|
25 |
+
'professional-translation' => 'Lingotek_Professional_Translation_Workflow',
|
26 |
+
];
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Checks the map to see if a specialized workflow exists. A BasicWorkflow is returned
|
30 |
+
* if a specialized workflow type does not exist.
|
31 |
+
*
|
32 |
+
* @param string $workflow_id the Id of the given workflow.
|
33 |
+
*/
|
34 |
+
public static function get_workflow_instance( $workflow_id ) {
|
35 |
+
if ( ! isset( self::$map[ $workflow_id ] ) )
|
36 |
+
{
|
37 |
+
return new Lingotek_Workflow();
|
38 |
+
}
|
39 |
+
else
|
40 |
+
{
|
41 |
+
self::class_load( self::$map[ $workflow_id ] );
|
42 |
+
return new self::$map[ $workflow_id ]();
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Echos the information modals describing various details about the workflow.
|
48 |
+
*/
|
49 |
+
public static function echo_info_modals() {
|
50 |
+
add_thickbox();
|
51 |
+
foreach ( self::$map as $id => $class ) {
|
52 |
+
$workflow = new $class();
|
53 |
+
$workflow->echo_info_modal( $id );
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Lazyloads classes as they are needed.
|
59 |
+
*
|
60 |
+
* @param string $class class name to be loaded.
|
61 |
+
*/
|
62 |
+
private static function class_load( $class ) {
|
63 |
+
if ( ! isset( $class ) ) { return; }
|
64 |
+
if ( ! class_exists( $class ) ) { require_once( LINGOTEK_WORKFLOWS . '/' . Lingotek::convert_class_to_file( $class ) . '.php' ); }
|
65 |
+
}
|
66 |
+
}
|
admin/workflows/workflow.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The base class that all specialized workflows can override.
|
5 |
+
*/
|
6 |
+
class Lingotek_Workflow {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* If a modal has already been written to the output buffer then we don't
|
10 |
+
* want to write it again.
|
11 |
+
*
|
12 |
+
* @var boolean
|
13 |
+
*/
|
14 |
+
protected $info_modal_launched = false;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* If a modal has already been written to the output buffer then we don't
|
18 |
+
* want to write it again.
|
19 |
+
*
|
20 |
+
* @var boolean
|
21 |
+
*/
|
22 |
+
protected $post_modal_launched = false;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* If a modal has already been written to the output buffer then we don't
|
26 |
+
* want to write it again.
|
27 |
+
*
|
28 |
+
* @var boolean
|
29 |
+
*/
|
30 |
+
protected $terms_modal_launched = false;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* This method is called when the Posts or Pages pages are loaded. The overriding class may choose to
|
34 |
+
* load a custom js file to handle events or do any sort of custom 'prep work'.
|
35 |
+
*
|
36 |
+
* @param string $id the workflow id.
|
37 |
+
*/
|
38 |
+
public function override_events( $id ) {}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Writes a modal to the output buffer. This is called when the Translation > Settings > Defaults pages is loaded.
|
42 |
+
* The modal should contain information about the workflow.
|
43 |
+
* NOTE: The workflow-defaults.js file is already loaded and set up to launch this modal. The workflow_id embedded in the
|
44 |
+
* html is used to identify the modal and show it to the user.
|
45 |
+
*
|
46 |
+
* @param string $id the workflow id.
|
47 |
+
*/
|
48 |
+
public function echo_info_modal( $id ) {}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* This method is called when the Posts or Pages columns are being rendered.
|
52 |
+
*
|
53 |
+
* @param string $id the workflow id.
|
54 |
+
*/
|
55 |
+
public function echo_posts_modal( $id ) {}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* This method is called when the Terms table is being rendered.
|
59 |
+
*
|
60 |
+
* @param string $id the workflow id.
|
61 |
+
*/
|
62 |
+
public function echo_terms_modal( $id ) {}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* This method writes the modal that should be displayed when
|
66 |
+
* the request icon is clicked.
|
67 |
+
*
|
68 |
+
* @param string $id the workflow id.
|
69 |
+
*/
|
70 |
+
public function echo_request_modal( $id ) {}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* This method acts as a template for building the modals. The arguments passed
|
74 |
+
* are inserted into the html string and then echo'd. If any extra html elements
|
75 |
+
* need to be added at a later date, they must be added to the $allowed_html array so
|
76 |
+
* that they are not stripped away during the wp_kses() call.
|
77 |
+
*
|
78 |
+
* @param array $args the arguments to populate the modal.
|
79 |
+
*/
|
80 |
+
protected function _echo_modal( $args ) {
|
81 |
+
/**
|
82 |
+
* This allows us to use the 'display' CSS attribute. WP
|
83 |
+
* blacklists it by default.
|
84 |
+
*/
|
85 |
+
add_filter( 'safe_style_css', function( $styles ) {
|
86 |
+
$styles[] = 'display';
|
87 |
+
$styles[] = 'position';
|
88 |
+
$styles[] = 'bottom';
|
89 |
+
return $styles;
|
90 |
+
} );
|
91 |
+
|
92 |
+
$allowed_html = [
|
93 |
+
'div' => [
|
94 |
+
'id' => [],
|
95 |
+
'style' => [],
|
96 |
+
],
|
97 |
+
'h2' => [
|
98 |
+
'style' => [],
|
99 |
+
],
|
100 |
+
'br' => [],
|
101 |
+
'b' => [],
|
102 |
+
'p' => [
|
103 |
+
'style' => [],
|
104 |
+
],
|
105 |
+
'a' => [
|
106 |
+
'id' => [],
|
107 |
+
'href' => [],
|
108 |
+
'style' => [],
|
109 |
+
'class' => []
|
110 |
+
],
|
111 |
+
];
|
112 |
+
$id = isset( $args['id'] ) ? '-' . $args['id'] : '';
|
113 |
+
echo wp_kses( "<div id='modal-window-id" . esc_attr( $id ) . "' style='display:none; height:100%;' >
|
114 |
+
<h2 style='text-align:center; font-size:large;'>" . esc_html( $args['header'] ) . "</h2>
|
115 |
+
<p style='text-align:center; font-size:110%;'>" . wp_kses( $args['body'], $allowed_html ) . "</p>
|
116 |
+
<br>
|
117 |
+
<a id='yes" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:left; bottom:30px;'>Continue</a>
|
118 |
+
<div style='float:right; padding-right:55px;'>
|
119 |
+
<a id='no" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:right; bottom:30px;'>Cancel</a>
|
120 |
+
</div>
|
121 |
+
</div>", $allowed_html);
|
122 |
+
}
|
123 |
+
}
|
include/group-post.php
CHANGED
@@ -263,7 +263,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
263 |
public static function is_valid_auto_upload_post_status($post_status) {
|
264 |
$prefs = Lingotek_Model::get_prefs();
|
265 |
$valid_statuses = $prefs['auto_upload_post_statuses'];
|
266 |
-
$valid =
|
267 |
return $valid;
|
268 |
}
|
269 |
|
@@ -294,14 +294,15 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
294 |
|
295 |
$client = new Lingotek_API();
|
296 |
|
297 |
-
|
298 |
-
|
299 |
-
|
|
|
|
|
300 |
|
301 |
self::$creating_translation = true;
|
302 |
$prefs = Lingotek_Model::get_prefs(); // need an array by default
|
303 |
|
304 |
-
$translation = json_decode($translation, true); // wp_insert_post expects array
|
305 |
$tr_post = $translation['post'];
|
306 |
|
307 |
$post = get_post($this->source); // source post
|
@@ -381,6 +382,17 @@ class Lingotek_Group_Post extends Lingotek_Group {
|
|
381 |
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
382 |
}
|
383 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
/*
|
385 |
* copies source meta strings to translations or deletes meta if set to ignore
|
386 |
*
|
263 |
public static function is_valid_auto_upload_post_status($post_status) {
|
264 |
$prefs = Lingotek_Model::get_prefs();
|
265 |
$valid_statuses = $prefs['auto_upload_post_statuses'];
|
266 |
+
$valid = isset( $valid_statuses[$post_status] ) && $valid_statuses[$post_status];
|
267 |
return $valid;
|
268 |
}
|
269 |
|
294 |
|
295 |
$client = new Lingotek_API();
|
296 |
|
297 |
+
$translation = $client->get_translation($this->document_id, $locale, $this->source);
|
298 |
+
|
299 |
+
if (!$translation || $this->translationNotReady( json_decode($translation, true) )) return; // If the request failed.
|
300 |
+
|
301 |
+
$translation = json_decode($translation, true); // wp_insert_post expects array
|
302 |
|
303 |
self::$creating_translation = true;
|
304 |
$prefs = Lingotek_Model::get_prefs(); // need an array by default
|
305 |
|
|
|
306 |
$tr_post = $translation['post'];
|
307 |
|
308 |
$post = get_post($this->source); // source post
|
382 |
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
|
383 |
}
|
384 |
|
385 |
+
/**
|
386 |
+
* TMS will return an associative array with empty fields if the translation is not ready.
|
387 |
+
*
|
388 |
+
* @param array $translation the array returned from TMS.
|
389 |
+
*/
|
390 |
+
private function translationNotReady($translation) {
|
391 |
+
return empty( trim( $translation['post']['post_title'] ) ) &&
|
392 |
+
empty( trim( $translation['post']['post_content'] ) ) &&
|
393 |
+
empty( trim( $translation['post']['post_excerpt'] ) );
|
394 |
+
}
|
395 |
+
|
396 |
/*
|
397 |
* copies source meta strings to translations or deletes meta if set to ignore
|
398 |
*
|
include/model.php
CHANGED
@@ -130,8 +130,8 @@ class Lingotek_Model {
|
|
130 |
}
|
131 |
}
|
132 |
|
133 |
-
// default profile is manual except for post
|
134 |
-
$default = 'post' == $type ? 'automatic' : 'manual';
|
135 |
|
136 |
$profile = isset($content_types[$type]['sources'][$language->slug]) ?
|
137 |
$content_types[$type]['sources'][$language->slug] :
|
@@ -644,7 +644,7 @@ class Lingotek_Model {
|
|
644 |
|
645 |
// if a post is not a target, then it is source
|
646 |
$sources[$language->slug] = $n - $targets[$language->slug];
|
647 |
-
$sources[$language->slug] -= $disabled[$language->slug];
|
648 |
}
|
649 |
|
650 |
// untranslated posts have no associated translation group in DB
|
@@ -665,7 +665,7 @@ class Lingotek_Model {
|
|
665 |
// total of posts translations groups = untranslated + number of translation groups stored in DB
|
666 |
$count_posts = (array) wp_count_posts($post_type);
|
667 |
unset($count_posts['trash'], $count_posts['auto-draft']); // don't count trash and auto-draft
|
668 |
-
$total = array_sum($count_posts) - $n_translated + count($groups)
|
669 |
|
670 |
return $r[$post_type] = compact('sources', 'targets', 'total');
|
671 |
}
|
@@ -738,7 +738,7 @@ class Lingotek_Model {
|
|
738 |
|
739 |
// if a term is not a target, then it is a source
|
740 |
$sources[$language->slug] = $n - $targets[$language->slug];
|
741 |
-
$sources[$language->slug] -= $disabled[$language->slug];
|
742 |
}
|
743 |
|
744 |
$total = count($groups);
|
@@ -773,7 +773,7 @@ class Lingotek_Model {
|
|
773 |
}
|
774 |
}
|
775 |
|
776 |
-
$total -= array_sum($disabled);
|
777 |
return $r[$taxonomy] = compact('sources', 'targets', 'total');
|
778 |
}
|
779 |
}
|
130 |
}
|
131 |
}
|
132 |
|
133 |
+
// default profile is manual except for post. Custom types are set to disabled by default.
|
134 |
+
$default = 'post' == $type ? 'automatic' : ('page' === $type ? 'manual' : 'disabled');
|
135 |
|
136 |
$profile = isset($content_types[$type]['sources'][$language->slug]) ?
|
137 |
$content_types[$type]['sources'][$language->slug] :
|
644 |
|
645 |
// if a post is not a target, then it is source
|
646 |
$sources[$language->slug] = $n - $targets[$language->slug];
|
647 |
+
// $sources[$language->slug] -= $disabled[$language->slug];
|
648 |
}
|
649 |
|
650 |
// untranslated posts have no associated translation group in DB
|
665 |
// total of posts translations groups = untranslated + number of translation groups stored in DB
|
666 |
$count_posts = (array) wp_count_posts($post_type);
|
667 |
unset($count_posts['trash'], $count_posts['auto-draft']); // don't count trash and auto-draft
|
668 |
+
$total = array_sum($count_posts) - $n_translated + count($groups);
|
669 |
|
670 |
return $r[$post_type] = compact('sources', 'targets', 'total');
|
671 |
}
|
738 |
|
739 |
// if a term is not a target, then it is a source
|
740 |
$sources[$language->slug] = $n - $targets[$language->slug];
|
741 |
+
// $sources[$language->slug] -= $disabled[$language->slug];
|
742 |
}
|
743 |
|
744 |
$total = count($groups);
|
773 |
}
|
774 |
}
|
775 |
|
776 |
+
// $total -= array_sum($disabled);
|
777 |
return $r[$taxonomy] = compact('sources', 'targets', 'total');
|
778 |
}
|
779 |
}
|
js/workflow/professional-workflow.js
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function() {
|
2 |
+
var yes = '#yes-' + workflow_vars.id;
|
3 |
+
var no = '#no-' + workflow_vars.id;
|
4 |
+
var yes_request = yes + '-request';
|
5 |
+
var no_request = no + '-request';
|
6 |
+
|
7 |
+
jQuery(".dashicons-upload").on('click', function(event){
|
8 |
+
event.preventDefault();
|
9 |
+
jQuery(this).addClass('thickbox');
|
10 |
+
var url = Workflow.modals.replace_href(this);
|
11 |
+
jQuery(yes).attr('href', url);
|
12 |
+
jQuery(this).attr('href', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow_vars.id);
|
13 |
+
});
|
14 |
+
|
15 |
+
jQuery(".dashicons-plus").on('click', function(event){
|
16 |
+
event.preventDefault();
|
17 |
+
jQuery(this).addClass('thickbox');
|
18 |
+
var url = Workflow.modals.replace_href(this);
|
19 |
+
jQuery(yes_request).attr('href', url);
|
20 |
+
jQuery(this).attr('href', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow_vars.id + '-request');
|
21 |
+
});
|
22 |
+
|
23 |
+
jQuery(yes + ',' + yes_request).on('click', function() {
|
24 |
+
Workflow.modals.close_modal('TB_closeWindowButton');
|
25 |
+
});
|
26 |
+
jQuery(no + ',' + no_request).on('click', function() {
|
27 |
+
Workflow.modals.close_modal('TB_closeWindowButton');
|
28 |
+
});
|
29 |
+
})
|
js/workflow/workflow-defaults.js
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function() {
|
2 |
+
var lastSel = jQuery('#workflow_id option:selected');
|
3 |
+
// try new rollback here.
|
4 |
+
jQuery('select').change(function(e) {
|
5 |
+
|
6 |
+
if (Workflow.workflows.hasOwnProperty(this.value))
|
7 |
+
{
|
8 |
+
var workflow = this.value;
|
9 |
+
jQuery('#yes-' + workflow).attr('href', Workflow.workflows[this.value]);
|
10 |
+
|
11 |
+
jQuery('#no-' + workflow).on('click', function() {
|
12 |
+
lastSel.attr('selected', true);
|
13 |
+
Workflow.modals.close_modal('TB_closeWindowButton');
|
14 |
+
});
|
15 |
+
|
16 |
+
tb_show('Default Settings', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow);
|
17 |
+
}
|
18 |
+
});
|
19 |
+
});
|
js/workflow/workflow.js
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Workflow = {};
|
2 |
+
|
3 |
+
Workflow.modals = {};
|
4 |
+
|
5 |
+
Workflow.modals.close_modal = function(id) {
|
6 |
+
jQuery('#' + id).trigger('click');
|
7 |
+
}
|
8 |
+
|
9 |
+
Workflow.modals.replace_href = function(element) {
|
10 |
+
if (!jQuery(element).attr('url'))
|
11 |
+
{
|
12 |
+
jQuery(element).attr('url', jQuery(element).attr('href'));
|
13 |
+
}
|
14 |
+
return jQuery(element).attr('url');
|
15 |
+
}
|
16 |
+
|
17 |
+
Workflow.workflows = {
|
18 |
+
'professional-translation' : 'https://www.lingotek.com/'
|
19 |
+
}
|
lingotek.php
CHANGED
@@ -1,66 +1,172 @@
|
|
1 |
<?php
|
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.2.
|
6 |
-
Author: Lingotek and Frédéric Demarle
|
7 |
-
Author uri: http://lingotek.com
|
8 |
-
Description: Lingotek offers convenient cloud-based localization and translation.
|
9 |
-
Text Domain: lingotek-translation
|
10 |
-
Domain Path: /languages
|
11 |
-
GitHub Plugin URI: https://github.com/lingotek/lingotek-translation
|
12 |
-
*/
|
13 |
-
|
14 |
-
// don't access directly
|
15 |
-
if (!function_exists('add_action'))
|
16 |
exit();
|
|
|
17 |
|
18 |
-
define('LINGOTEK_VERSION', '1.2.
|
19 |
-
define('LINGOTEK_MIN_PLL_VERSION', '1.8');
|
20 |
-
define('LINGOTEK_BASENAME', plugin_basename(__FILE__)); // plugin name as known by WP
|
21 |
-
define('LINGOTEK_PLUGIN_SLUG', 'lingotek-translation');// plugin slug (should match above meta: Text Domain)
|
22 |
-
define('LINGOTEK_DIR', dirname(__FILE__)); // our directory
|
23 |
-
define('LINGOTEK_INC', LINGOTEK_DIR . '/include');
|
24 |
-
define('LINGOTEK_ADMIN_INC', LINGOTEK_DIR . '/admin');
|
25 |
-
define('
|
|
|
26 |
|
27 |
class Lingotek {
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
public $callback;
|
30 |
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
33 |
public static $lingotek_locales = array(
|
34 |
-
'af' => 'af-ZA',
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
'
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
'
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
);
|
53 |
|
54 |
/**
|
55 |
*
|
56 |
* Unique identifier for your plugin.
|
57 |
*
|
58 |
-
*
|
59 |
* The variable name is used as the text domain when internationalizing strings
|
60 |
* of text. Its value should match the Text Domain file header in the main
|
61 |
* plugin file.
|
62 |
*
|
63 |
-
* @since 1.0.0
|
64 |
*
|
65 |
* @var string
|
66 |
*/
|
@@ -75,48 +181,54 @@ class Lingotek {
|
|
75 |
*/
|
76 |
protected static $instance = null;
|
77 |
|
78 |
-
protected static $logging =
|
79 |
|
80 |
-
|
81 |
-
*
|
82 |
*
|
83 |
* @since 0.1
|
84 |
*/
|
85 |
public function __construct() {
|
86 |
-
// manages plugin activation and deactivation
|
87 |
-
register_activation_hook( __FILE__, array(&$this, 'activate'));
|
88 |
-
register_deactivation_hook( __FILE__, array(&$this, 'deactivate'));
|
89 |
|
90 |
-
// stopping here if we are going to deactivate the plugin (avoids breaking rewrite rules)
|
91 |
-
if (
|
92 |
return;
|
|
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
98 |
}
|
99 |
|
100 |
-
spl_autoload_register(array(&$this, 'autoload')); // autoload classes
|
101 |
|
102 |
-
// init
|
103 |
-
add_filter('pll_model', array(&$this, 'pll_model'));
|
104 |
-
add_action('init', array(&$this, 'init'));
|
105 |
-
add_action('admin_init', array(&$this, 'admin_init'));
|
106 |
|
107 |
-
// add Lingotek locale to languages
|
108 |
-
add_filter('pll_languages_list', array(&$this, 'pre_set_languages_list'));
|
109 |
|
110 |
-
// flag title
|
111 |
-
add_filter('pll_flag_title', array(&$this, 'pll_flag_title'), 10, 3);
|
112 |
|
113 |
-
// adds a pointer upon plugin activation to draw attention to Lingotek
|
114 |
-
if (!get_option('lingotek_token')) {
|
115 |
-
add_action('init', array(&$this, 'lingotek_activation_pointer'));
|
116 |
}
|
117 |
|
118 |
-
// adds extra plugin compatibility - borrowed from Polylang
|
119 |
-
if (!defined('LINGOTEK_PLUGINS_COMPAT') || LINGOTEK_PLUGINS_COMPAT) {
|
120 |
Lingotek_Plugins_Compat::instance();
|
121 |
}
|
122 |
}
|
@@ -142,89 +254,88 @@ class Lingotek {
|
|
142 |
public static function get_instance() {
|
143 |
|
144 |
// If the single instance hasn't been set, set it now.
|
145 |
-
if ( null
|
146 |
self::$instance = new self;
|
147 |
}
|
148 |
|
149 |
return self::$instance;
|
150 |
}
|
151 |
|
152 |
-
|
153 |
-
*
|
154 |
* method taken from Polylang
|
155 |
*
|
156 |
* @since 0.1
|
157 |
*
|
158 |
-
* @param string $what either 'activate' or 'deactivate'
|
159 |
*/
|
160 |
-
protected function do_for_all_blogs($what) {
|
161 |
-
// network
|
162 |
-
if (is_multisite() &&
|
163 |
global $wpdb;
|
164 |
|
165 |
-
foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $blog_id) {
|
166 |
-
switch_to_blog($blog_id);
|
167 |
-
|
168 |
}
|
169 |
restore_current_blog();
|
|
|
|
|
|
|
170 |
}
|
171 |
-
|
172 |
-
// single blog
|
173 |
-
else
|
174 |
-
$what == 'activate' ? $this->_activate() : $this->_deactivate();
|
175 |
}
|
176 |
|
177 |
-
|
178 |
-
*
|
179 |
*
|
180 |
* @since 0.1
|
181 |
*/
|
182 |
public function activate() {
|
183 |
-
$this->do_for_all_blogs('activate');
|
184 |
}
|
185 |
|
186 |
-
|
187 |
-
*
|
188 |
*
|
189 |
* @since 0.1
|
190 |
*/
|
191 |
protected function _activate() {
|
192 |
global $polylang;
|
193 |
|
194 |
-
if (isset($polylang)) {
|
195 |
-
$polylang->model->clean_languages_cache(); // to add lingotek_locale property
|
196 |
}
|
197 |
|
198 |
-
// default profiles
|
199 |
-
if (false === get_option('lingotek_profiles')) {
|
200 |
$profiles = array(
|
201 |
'automatic' => array(
|
202 |
'profile' => 'automatic',
|
203 |
-
'name' => __('Automatic', 'lingotek-translation'),
|
204 |
'upload' => 'automatic',
|
205 |
-
'download' => 'automatic'
|
206 |
),
|
207 |
'manual' => array(
|
208 |
'profile' => 'manual',
|
209 |
-
'name' => __('Manual', 'lingotek-translation'),
|
210 |
'upload' => 'manual',
|
211 |
-
'download' => 'manual'
|
212 |
),
|
213 |
'disabled' => array(
|
214 |
'profile' => 'disabled',
|
215 |
-
'name' => __('Disabled', 'lingotek-translation'),
|
216 |
),
|
217 |
);
|
218 |
-
update_option('lingotek_profiles', $profiles);
|
219 |
}
|
220 |
|
221 |
-
// for the end point for the Lingoteck callback in rewrite rules
|
222 |
-
// don't use flush_rewrite_rules at network activation. See #32471
|
223 |
-
delete_option('rewrite_rules');
|
224 |
}
|
225 |
|
226 |
-
|
227 |
-
*
|
228 |
*
|
229 |
* @since 1.0
|
230 |
*
|
@@ -234,176 +345,182 @@ class Lingotek {
|
|
234 |
$default_profiles = array(
|
235 |
'automatic' => array(
|
236 |
'profile' => 'automatic',
|
237 |
-
'name' => __('Automatic', 'lingotek-translation'),
|
238 |
'upload' => 'automatic',
|
239 |
-
'download' => 'automatic'
|
240 |
),
|
241 |
'manual' => array(
|
242 |
'profile' => 'manual',
|
243 |
-
'name' => __('Manual', 'lingotek-translation'),
|
244 |
'upload' => 'manual',
|
245 |
-
'download' => 'manual'
|
246 |
),
|
247 |
'disabled' => array(
|
248 |
'profile' => 'disabled',
|
249 |
-
'name' => __('Disabled', 'lingotek-translation'),
|
250 |
),
|
251 |
);
|
252 |
|
253 |
-
$profiles = get_option('lingotek_profiles');
|
254 |
-
if (is_array($profiles)) {
|
255 |
-
$profiles = array_merge($default_profiles, $profiles);
|
256 |
-
}
|
257 |
-
else {
|
258 |
$profiles = $default_profiles;
|
259 |
}
|
260 |
|
261 |
-
//localize canned profile names
|
262 |
-
foreach($profiles as $k
|
263 |
-
if(in_array($k,array('automatic','manual','disabled'))){
|
264 |
-
$profile_name = $profiles[$k]['name'];
|
265 |
-
$profiles[$k]['name'] = __($profile_name,'lingotek-translation');// localize canned profile names
|
266 |
}
|
267 |
}
|
268 |
|
269 |
-
update_option('lingotek_profiles', $profiles);
|
270 |
return $profiles;
|
271 |
}
|
272 |
|
273 |
-
|
274 |
-
*
|
275 |
*
|
276 |
* @since 0.1
|
277 |
*/
|
278 |
public function deactivate() {
|
279 |
-
$this->do_for_all_blogs('deactivate');
|
280 |
}
|
281 |
|
282 |
-
|
283 |
-
*
|
284 |
*
|
285 |
* @since 0.5
|
286 |
*/
|
287 |
protected function _deactivate() {
|
288 |
-
delete_option('rewrite_rules');
|
289 |
}
|
290 |
|
291 |
-
|
292 |
-
*
|
293 |
*
|
294 |
* @since 0.1
|
295 |
*
|
296 |
-
* @param int $blog_id
|
297 |
*/
|
298 |
-
public function wpmu_new_blog($blog_id) {
|
299 |
-
switch_to_blog($blog_id);
|
300 |
$this->_activate();
|
301 |
restore_current_blog();
|
302 |
}
|
303 |
|
304 |
-
|
305 |
-
*
|
306 |
*
|
307 |
* @since 0.1
|
308 |
*
|
309 |
-
* @param string $class
|
310 |
*/
|
311 |
-
public function autoload($class) {
|
312 |
-
// not a Lingotek class
|
313 |
-
if (0 !== strncmp('Lingotek_', $class, 9))
|
314 |
return;
|
|
|
315 |
|
316 |
-
$class =
|
317 |
-
foreach (array(LINGOTEK_INC, LINGOTEK_ADMIN_INC) as $path) {
|
318 |
-
if (file_exists($file = "$path/$class.php")) {
|
319 |
-
require_once($file);
|
320 |
break;
|
321 |
}
|
322 |
}
|
323 |
}
|
324 |
|
325 |
-
|
326 |
-
*
|
327 |
*
|
328 |
* @since 0.2
|
329 |
*
|
330 |
-
* @param string $class
|
331 |
-
* @return string modified class 'PLL_Model' | 'PLL_Admin_Model'
|
332 |
*/
|
333 |
-
public function pll_model($class) {
|
334 |
-
if (PLL_ADMIN &&
|
335 |
return 'PLL_Admin_Model';
|
|
|
336 |
return $class;
|
337 |
}
|
338 |
|
339 |
-
|
340 |
-
*
|
341 |
* sets filters to call Lingotek child classes instead of Polylang classes
|
342 |
*
|
343 |
* @since 0.1
|
344 |
-
*
|
345 |
*/
|
346 |
public function init() {
|
347 |
-
if (!defined('POLYLANG_VERSION'))
|
348 |
return;
|
|
|
349 |
|
350 |
add_rewrite_rule( 'lingotek/?$', 'index.php?lingotek=1&$matches[1]', 'top' );
|
351 |
|
352 |
-
if (is_admin())
|
353 |
new Lingotek_Admin();
|
|
|
354 |
|
355 |
-
// admin side
|
356 |
-
if (PLL_ADMIN && !PLL_SETTINGS) {
|
357 |
$this->model = new Lingotek_Model();
|
358 |
|
359 |
-
// overrides Polylang classes
|
360 |
-
$classes = array('Filters_Post', 'Filters_Term', 'Filters_Media', 'Filters_Columns');
|
361 |
-
foreach ($classes as $class)
|
362 |
-
|
|
|
|
|
|
|
|
|
363 |
|
364 |
-
// add actions to posts, media and terms list
|
365 |
-
// no need to load this if there is no language yet
|
366 |
-
if ($GLOBALS['polylang']->model->get_languages_list()) {
|
367 |
$this->post_actions = new Lingotek_Post_Actions();
|
368 |
$this->term_actions = new Lingotek_Term_Actions();
|
369 |
$this->string_actions = new Lingotek_String_actions();
|
|
|
370 |
}
|
371 |
|
372 |
$this->utilities = new Lingotek_Utilities();
|
373 |
-
}
|
374 |
-
|
375 |
-
|
376 |
-
elseif (!PLL_ADMIN && !PLL_AJAX_ON_FRONT) {
|
377 |
-
$GLOBALS['wp']->add_query_var('lingotek');
|
378 |
|
379 |
$this->model = new Lingotek_Model();
|
380 |
-
$this->callback = new Lingotek_Callback($this->model);
|
381 |
}
|
382 |
}
|
383 |
|
384 |
-
|
385 |
-
*
|
386 |
*
|
387 |
* @since 0.1
|
388 |
*/
|
389 |
public function admin_init() {
|
390 |
-
// plugin i18n, only needed for backend
|
391 |
-
load_plugin_textdomain('lingotek-translation', false, basename(LINGOTEK_DIR).'/languages');
|
392 |
|
393 |
-
if (!defined('POLYLANG_VERSION'))
|
394 |
-
add_action('all_admin_notices', array(&$this, 'pll_inactive_notice'));
|
395 |
|
396 |
-
elseif (version_compare(POLYLANG_VERSION, LINGOTEK_MIN_PLL_VERSION, '<'))
|
397 |
-
add_action('all_admin_notices', array(&$this, 'pll_old_notice'));
|
398 |
|
399 |
-
elseif (isset($GLOBALS['polylang']) && !count($GLOBALS['polylang']->model->get_languages_list()))
|
400 |
self::create_first_language();
|
|
|
401 |
|
402 |
-
wp_enqueue_style('lingotek_admin', LINGOTEK_URL .'/css/admin.css', array(), LINGOTEK_VERSION);
|
403 |
}
|
404 |
|
405 |
-
|
406 |
-
*
|
407 |
*
|
408 |
* @since 0.1
|
409 |
*/
|
@@ -414,158 +531,179 @@ class Lingotek {
|
|
414 |
add_query_arg(
|
415 |
array(
|
416 |
'action' => $action,
|
417 |
-
'plugin' => $slug
|
418 |
),
|
419 |
admin_url( 'update.php' )
|
420 |
),
|
421 |
-
$action.'_'
|
422 |
);
|
423 |
printf(
|
424 |
'<div class="error" style="height:55px"><p style="font-size:1.5em">%s<a href="%s">%s</a></p></div>',
|
425 |
-
__('Lingotek Translation requires Polylang to work. ', 'lingotek-translation'), $url, __('Install Polylang', 'lingotek-translation')
|
426 |
);
|
427 |
}
|
428 |
|
429 |
-
|
430 |
-
*
|
431 |
*
|
432 |
* @since 0.1
|
433 |
*/
|
434 |
public function pll_old_notice() {
|
|
|
|
|
|
|
435 |
printf(
|
436 |
'<div class="error"><p>%s</p></div>',
|
437 |
sprintf(
|
438 |
-
__('Lingotek Translation requires Polylang %s to work. Please upgrade Polylang.', 'lingotek-translation'),
|
439 |
-
'<strong>' . LINGOTEK_MIN_PLL_VERSION . '</strong>'
|
440 |
)
|
441 |
);
|
442 |
}
|
443 |
|
444 |
-
|
445 |
-
*
|
446 |
*
|
447 |
* @since 0.2
|
448 |
*/
|
449 |
static protected function create_first_language() {
|
450 |
global $polylang;
|
451 |
|
452 |
-
include(PLL_ADMIN_INC.'/languages.php');
|
453 |
$locale = get_locale();
|
454 |
|
455 |
-
// attempts to set the default language from the current locale
|
456 |
-
foreach ($languages as $lang) {
|
457 |
-
if (get_locale()
|
458 |
$language = $lang;
|
|
|
459 |
}
|
460 |
|
461 |
-
// defaults to en_US
|
462 |
-
if (empty($language))
|
463 |
-
$language = array('en', 'en_US', 'English');
|
|
|
464 |
|
465 |
-
$pll_model = new PLL_Admin_Model($polylang->options); // need admin model
|
466 |
$pll_model->add_language(array(
|
467 |
'slug' => $language[0],
|
468 |
'locale' => $language[1],
|
469 |
'name' => $language[2],
|
470 |
-
'rtl' => isset($language[3]) ? 1 : 0,
|
471 |
-
'term_group' => 0
|
472 |
));
|
473 |
}
|
474 |
|
475 |
-
|
476 |
-
*
|
477 |
* uses the map otherwise uses a stupid fallback
|
478 |
*
|
479 |
* @since 0.1
|
480 |
*
|
481 |
-
* @param array $languages list of language objects
|
482 |
* @return array
|
483 |
*/
|
484 |
-
public function pre_set_languages_list($languages) {
|
485 |
-
foreach ($languages as $key => $language) {
|
486 |
-
if (is_object($language))
|
487 |
-
$languages[$key]->lingotek_locale = self::map_to_lingotek_locale($language->locale); // backward compatibility with Polylang < 1.7.3
|
488 |
-
else
|
489 |
-
|
490 |
}
|
491 |
|
492 |
return $languages;
|
493 |
}
|
494 |
|
495 |
-
|
496 |
-
*
|
497 |
*
|
498 |
* @since 0.3
|
499 |
*
|
500 |
-
* @param string $lingotek_locale Lingotek locale
|
501 |
-
* @return string WordPress locale
|
502 |
*/
|
503 |
-
public static function map_to_wp_locale($lingotek_locale) {
|
504 |
-
// look for the locale in the map (take care that Lingotek sends locales with either '_' or '-'
|
505 |
-
// if not found just replace '-' by '_'
|
506 |
-
$wp_locale = array_search(str_replace('_', '-', $lingotek_locale), self::$lingotek_locales);
|
507 |
-
return $wp_locale ? $wp_locale : str_replace('-', '_', $lingotek_locale);
|
508 |
}
|
509 |
|
510 |
-
|
511 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
*
|
513 |
* @since 0.3
|
514 |
*
|
515 |
-
* @param string $wp_locale WordPress locale
|
516 |
* @return string Lingotek locale
|
517 |
*/
|
518 |
-
public static function map_to_lingotek_locale($wp_locale) {
|
519 |
-
// look for the locale in the map
|
520 |
-
// if not found just replace '_ 'by '-'
|
521 |
-
return isset(self::$lingotek_locales[$wp_locale]) ? self::$lingotek_locales[$wp_locale] : str_replace('_', '-', $wp_locale);
|
522 |
}
|
523 |
|
524 |
-
|
525 |
-
*
|
526 |
*
|
527 |
* @since 0.3
|
528 |
*
|
529 |
-
* @param string $name language name
|
530 |
-
* @param string $slug language code
|
531 |
-
* @param string $locale language locale
|
532 |
* @return string
|
533 |
*/
|
534 |
-
public function pll_flag_title($name, $slug, $locale) {
|
535 |
return "$name ($locale)";
|
536 |
}
|
537 |
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
542 |
$log_string .= $label . "\n";
|
543 |
-
if (is_string($data)) {
|
544 |
-
$log_string .= $data;
|
545 |
}
|
546 |
-
|
547 |
-
$log_string .=
|
|
|
|
|
548 |
}
|
549 |
-
error_log($log_string);
|
550 |
}
|
551 |
}
|
552 |
|
553 |
-
|
554 |
* Creates a pointer to draw attention to the new Lingotek menu item upon plugin activation
|
555 |
* code borrowed from Polylang
|
|
|
556 |
* @since 1.0.1
|
557 |
*/
|
558 |
public function lingotek_activation_pointer() {
|
559 |
-
$content = __('You’ve just installed Lingotek Translation! Click below to activate your account and automatically translate your website for free!', 'lingotek-translation');
|
560 |
|
561 |
$buttons = array(
|
562 |
array(
|
563 |
-
'label' => __('Close')
|
564 |
),
|
565 |
array(
|
566 |
-
'label' => __('Activate Account', 'lingotek-translation'),
|
567 |
-
'link' => admin_url('admin.php?page=' . $this->plugin_slug . '_settings&connect=new'),
|
568 |
-
)
|
569 |
);
|
570 |
|
571 |
$args = array(
|
@@ -576,12 +714,12 @@ class Lingotek {
|
|
576 |
'align' => 'left',
|
577 |
),
|
578 |
'width' => 380,
|
579 |
-
'title' => __('Congratulations!', 'lingotek-translation'),
|
580 |
'content' => $content,
|
581 |
-
'buttons' => $buttons
|
582 |
);
|
583 |
|
584 |
-
new Lingotek_Pointer($args);
|
585 |
}
|
586 |
}
|
587 |
|
1 |
<?php
|
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.2.7
|
6 |
+
Author: Lingotek and Frédéric Demarle
|
7 |
+
Author uri: http://lingotek.com
|
8 |
+
Description: Lingotek offers convenient cloud-based localization and translation.
|
9 |
+
Text Domain: lingotek-translation
|
10 |
+
Domain Path: /languages
|
11 |
+
GitHub Plugin URI: https://github.com/lingotek/lingotek-translation
|
12 |
+
*/
|
13 |
+
|
14 |
+
// don't access directly.
|
15 |
+
if ( ! function_exists( 'add_action' ) ) {
|
16 |
exit();
|
17 |
+
}
|
18 |
|
19 |
+
define( 'LINGOTEK_VERSION', '1.2.7' ); // plugin version (should match above meta).
|
20 |
+
define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
|
21 |
+
define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) ); // plugin name as known by WP.
|
22 |
+
define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );// plugin slug (should match above meta: Text Domain).
|
23 |
+
define( 'LINGOTEK_DIR', dirname( __FILE__ ) ); // our directory.
|
24 |
+
define( 'LINGOTEK_INC', LINGOTEK_DIR . '/include' );
|
25 |
+
define( 'LINGOTEK_ADMIN_INC', LINGOTEK_DIR . '/admin' );
|
26 |
+
define( 'LINGOTEK_WORKFLOWS', LINGOTEK_ADMIN_INC . '/workflows' );
|
27 |
+
define( 'LINGOTEK_URL', plugins_url( '', __FILE__ ) );
|
28 |
|
29 |
class Lingotek {
|
30 |
+
/**
|
31 |
+
* Lingotek model.
|
32 |
+
*
|
33 |
+
* @var object
|
34 |
+
*/
|
35 |
+
public $model;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Callback method
|
39 |
+
*
|
40 |
+
* @var method
|
41 |
+
*/
|
42 |
public $callback;
|
43 |
|
44 |
+
/**
|
45 |
+
* Array to map Lingotek locales to WP locales.
|
46 |
+
* map as 'WP locale' => 'Lingotek locale'.
|
47 |
+
*
|
48 |
+
* @var array
|
49 |
+
*/
|
50 |
public static $lingotek_locales = array(
|
51 |
+
'af' => 'af-ZA',
|
52 |
+
'ak' => 'ak-GH',
|
53 |
+
'am' => 'am-ET',
|
54 |
+
'ar' => 'ar',
|
55 |
+
'as' => 'as-IN',
|
56 |
+
'az' => 'az-AZ',
|
57 |
+
'ba' => 'ba-RU',
|
58 |
+
'bel' => 'be-BY',
|
59 |
+
'bg_BG' => 'bg-BG',
|
60 |
+
'bn_BD' => 'bn-BD',
|
61 |
+
'bo' => 'bo-CN',
|
62 |
+
'bs_BA' => 'bs-BA',
|
63 |
+
'ca' => 'ca-ES',
|
64 |
+
'co' => 'co-FR',
|
65 |
+
'cs_CZ' => 'cs-CZ',
|
66 |
+
'cy' => 'cy-GB',
|
67 |
+
'da_DK' => 'da-DK',
|
68 |
+
'de_CH' => 'de-CH',
|
69 |
+
'de_DE' => 'de-DE',
|
70 |
+
'dv' => 'dv-MV',
|
71 |
+
'el' => 'el-GR',
|
72 |
+
'en_AU' => 'en-AU',
|
73 |
+
'en_CA' => 'en-CA',
|
74 |
+
'en_GB' => 'en-GB',
|
75 |
+
'en_US' => 'en-US',
|
76 |
+
'eo' => 'eo-FR',
|
77 |
+
'es_AR' => 'es-AR',
|
78 |
+
'es_CL' => 'es-CL',
|
79 |
+
'es_CO' => 'es-CO',
|
80 |
+
'es_ES' => 'es-ES',
|
81 |
+
'es_MX' => 'es-MX',
|
82 |
+
'es_PE' => 'es-PE',
|
83 |
+
'es_PR' => 'es-PR',
|
84 |
+
'es_VE' => 'es-VE',
|
85 |
+
'et' => 'et-EE',
|
86 |
+
'eu' => 'eu-ES',
|
87 |
+
'fa_IR' => 'fa-IR',
|
88 |
+
'fi' => 'fi-FI',
|
89 |
+
'fr_FR' => 'fr-FR',
|
90 |
+
'ga' => 'ga-IE',
|
91 |
+
'gd' => 'gd-GB',
|
92 |
+
'gl_ES' => 'gl-ES',
|
93 |
+
'gn' => 'gn-BO',
|
94 |
+
'haw_US' => 'haw-US',
|
95 |
+
'he_IL' => 'he-IL',
|
96 |
+
'hi_IN' => 'hi-IN',
|
97 |
+
'hr' => 'hr-HR',
|
98 |
+
'hu_HU' => 'hu-HU',
|
99 |
+
'hy' => 'hy-AM',
|
100 |
+
'id_ID' => 'id-ID',
|
101 |
+
'is_IS' => 'is-IS',
|
102 |
+
'it_IT' => 'it-IT',
|
103 |
+
'ja' => 'ja-JP',
|
104 |
+
'jv_ID' => 'jv-ID',
|
105 |
+
'ka_GE' => 'ka-GE',
|
106 |
+
'kin' => 'kin-RW',
|
107 |
+
'kk' => 'kk-KZ',
|
108 |
+
'kn' => 'kn-IN',
|
109 |
+
'ko_KR' => 'ko-KR',
|
110 |
+
'ky_KY' => 'ky-KG',
|
111 |
+
'lb_LU' => 'lb-LU',
|
112 |
+
'lo' => 'lo-LA',
|
113 |
+
'lt_LT' => 'lt-LT',
|
114 |
+
'lv' => 'lv-LV',
|
115 |
+
'mg_MG' => 'mg-MG',
|
116 |
+
'mk_MK' => 'mk-MK',
|
117 |
+
'ml_IN' => 'ml-IN',
|
118 |
+
'mn' => 'mn-MN',
|
119 |
+
'mr' => 'mr-IN',
|
120 |
+
'ms_MY' => 'ms-MY',
|
121 |
+
'my_MM' => 'my-MM',
|
122 |
+
'ne_NP' => 'ne-NP',
|
123 |
+
'nl_BE' => 'nl-BE',
|
124 |
+
'nl_NL' => 'nl-NL',
|
125 |
+
'nn_NO' => 'nn-NO',
|
126 |
+
'pa_IN' => 'pa-IN',
|
127 |
+
'pl_PL' => 'pl-PL',
|
128 |
+
'ps' => 'ps-AF',
|
129 |
+
'pt_BR' => 'pt-BR',
|
130 |
+
'pt_PT' => 'pt-PT',
|
131 |
+
'ro_RO' => 'ro-RO',
|
132 |
+
'ru_RU' => 'ru-RU',
|
133 |
+
'sa_IN' => 'sa-IN',
|
134 |
+
'sd_PK' => 'sd-PK',
|
135 |
+
'si_LK' => 'si-LK',
|
136 |
+
'sk_SK' => 'sk-SK',
|
137 |
+
'sl_SI' => 'sl-SI',
|
138 |
+
'so_SO' => 'so-SO',
|
139 |
+
'sq' => 'sq-SQ',
|
140 |
+
'sr_RS' => 'sr-CS',
|
141 |
+
'su_ID' => 'su-ID',
|
142 |
+
'sv_SE' => 'sv-SE',
|
143 |
+
'sw' => 'sw-TZ',
|
144 |
+
'ta_IN' => 'ta-IN',
|
145 |
+
'te' => 'te-IN',
|
146 |
+
'tg' => 'tg-TJ',
|
147 |
+
'th' => 'th-TH',
|
148 |
+
'tir' => 'ti-ER',
|
149 |
+
'tl' => 'tl-PH',
|
150 |
+
'tr_TR' => 'tr-TR',
|
151 |
+
'ug_CN' => 'ug-CN',
|
152 |
+
'uk' => 'uk-UA',
|
153 |
+
'ur' => 'ur-PK',
|
154 |
+
'uz_UZ' => 'uz-UZ',
|
155 |
+
'vi' => 'vi-VN',
|
156 |
+
'zh_CN' => 'zh-CN',
|
157 |
+
'zh_HK' => 'zh-HK',
|
158 |
+
'zh_TW' => 'zh-TW',
|
159 |
);
|
160 |
|
161 |
/**
|
162 |
*
|
163 |
* Unique identifier for your plugin.
|
164 |
*
|
|
|
165 |
* The variable name is used as the text domain when internationalizing strings
|
166 |
* of text. Its value should match the Text Domain file header in the main
|
167 |
* plugin file.
|
168 |
*
|
169 |
+
* @since 1.0.0==
|
170 |
*
|
171 |
* @var string
|
172 |
*/
|
181 |
*/
|
182 |
protected static $instance = null;
|
183 |
|
184 |
+
protected static $logging = false;
|
185 |
|
186 |
+
/**
|
187 |
+
* Constructor
|
188 |
*
|
189 |
* @since 0.1
|
190 |
*/
|
191 |
public function __construct() {
|
192 |
+
// manages plugin activation and deactivation.
|
193 |
+
register_activation_hook( __FILE__, array( &$this, 'activate' ) );
|
194 |
+
register_deactivation_hook( __FILE__, array( &$this, 'deactivate' ) );
|
195 |
|
196 |
+
// stopping here if we are going to deactivate the plugin (avoids breaking rewrite rules).
|
197 |
+
if ( ! empty( filter_input( INPUT_GET, 'action' ) ) && ! empty( filter_input( INPUT_GET, 'plugin' ) ) && 'deactivate' === filter_input( INPUT_GET, 'action' ) && plugin_basename( __FILE__ ) === filter_input( INPUT_GET, 'plugin' ) ) {
|
198 |
return;
|
199 |
+
}
|
200 |
|
201 |
+
$action = filter_input( INPUT_GET, 'action' );
|
202 |
+
$action = isset( $action ) ? $action : filter_input( INPUT_POST, 'action' );
|
203 |
+
// loads the admin side of Polylang for the dashboard.
|
204 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $action ) && 'lingotek_language' === $action ) {
|
205 |
+
define( 'PLL_AJAX_ON_FRONT', false );
|
206 |
+
$method = function( $c ) {
|
207 |
+
return 'PLL_Admin_Model';
|
208 |
+
};
|
209 |
+
add_filter( 'pll_model', $method );
|
210 |
}
|
211 |
|
212 |
+
spl_autoload_register( array( &$this, 'autoload' ) ); // autoload classes.
|
213 |
|
214 |
+
// init.
|
215 |
+
add_filter( 'pll_model', array( &$this, 'pll_model' ) );
|
216 |
+
add_action( 'init', array( &$this, 'init' ) );
|
217 |
+
add_action( 'admin_init', array( &$this, 'admin_init' ) );
|
218 |
|
219 |
+
// add Lingotek locale to languages.
|
220 |
+
add_filter( 'pll_languages_list', array( &$this, 'pre_set_languages_list' ) );
|
221 |
|
222 |
+
// flag title.
|
223 |
+
add_filter( 'pll_flag_title', array( &$this, 'pll_flag_title' ), 10, 3 );
|
224 |
|
225 |
+
// adds a pointer upon plugin activation to draw attention to Lingotek.
|
226 |
+
if ( ! get_option( 'lingotek_token' ) ) {
|
227 |
+
add_action( 'init', array( &$this, 'lingotek_activation_pointer' ) );
|
228 |
}
|
229 |
|
230 |
+
// adds extra plugin compatibility - borrowed from Polylang.
|
231 |
+
if ( ! defined( 'LINGOTEK_PLUGINS_COMPAT' ) || LINGOTEK_PLUGINS_COMPAT ) {
|
232 |
Lingotek_Plugins_Compat::instance();
|
233 |
}
|
234 |
}
|
254 |
public static function get_instance() {
|
255 |
|
256 |
// If the single instance hasn't been set, set it now.
|
257 |
+
if ( null === self::$instance ) {
|
258 |
self::$instance = new self;
|
259 |
}
|
260 |
|
261 |
return self::$instance;
|
262 |
}
|
263 |
|
264 |
+
/**
|
265 |
+
* Activation or deactivation for all blogs
|
266 |
* method taken from Polylang
|
267 |
*
|
268 |
* @since 0.1
|
269 |
*
|
270 |
+
* @param string $what either 'activate' or 'deactivate'.
|
271 |
*/
|
272 |
+
protected function do_for_all_blogs( $what ) {
|
273 |
+
// network.
|
274 |
+
if ( is_multisite() && ! empty( filter_input( INPUT_GET, 'networkwide' ) ) && ( 1 === filter_input( INPUT_GET, 'networkwide' ) ) ) {
|
275 |
global $wpdb;
|
276 |
|
277 |
+
foreach ( $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ) as $blog_id ) {
|
278 |
+
switch_to_blog( $blog_id );
|
279 |
+
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
280 |
}
|
281 |
restore_current_blog();
|
282 |
+
} // single blog.
|
283 |
+
else {
|
284 |
+
'activate' === $what ? $this->_activate() : $this->_deactivate();
|
285 |
}
|
|
|
|
|
|
|
|
|
286 |
}
|
287 |
|
288 |
+
/**
|
289 |
+
* Plugin activation for multisite
|
290 |
*
|
291 |
* @since 0.1
|
292 |
*/
|
293 |
public function activate() {
|
294 |
+
$this->do_for_all_blogs( 'activate' );
|
295 |
}
|
296 |
|
297 |
+
/**
|
298 |
+
* Plugin activation
|
299 |
*
|
300 |
* @since 0.1
|
301 |
*/
|
302 |
protected function _activate() {
|
303 |
global $polylang;
|
304 |
|
305 |
+
if ( isset( $polylang ) ) {
|
306 |
+
$polylang->model->clean_languages_cache(); // to add lingotek_locale property.
|
307 |
}
|
308 |
|
309 |
+
// default profiles.
|
310 |
+
if ( false === get_option( 'lingotek_profiles' ) ) {
|
311 |
$profiles = array(
|
312 |
'automatic' => array(
|
313 |
'profile' => 'automatic',
|
314 |
+
'name' => __( 'Automatic', 'lingotek-translation' ),
|
315 |
'upload' => 'automatic',
|
316 |
+
'download' => 'automatic',
|
317 |
),
|
318 |
'manual' => array(
|
319 |
'profile' => 'manual',
|
320 |
+
'name' => __( 'Manual', 'lingotek-translation' ),
|
321 |
'upload' => 'manual',
|
322 |
+
'download' => 'manual',
|
323 |
),
|
324 |
'disabled' => array(
|
325 |
'profile' => 'disabled',
|
326 |
+
'name' => __( 'Disabled', 'lingotek-translation' ),
|
327 |
),
|
328 |
);
|
329 |
+
update_option( 'lingotek_profiles', $profiles );
|
330 |
}
|
331 |
|
332 |
+
// for the end point for the Lingoteck callback in rewrite rules.
|
333 |
+
// don't use flush_rewrite_rules at network activation. See #32471.
|
334 |
+
delete_option( 'rewrite_rules' );
|
335 |
}
|
336 |
|
337 |
+
/**
|
338 |
+
* Provides localized version of the canned translation profiles
|
339 |
*
|
340 |
* @since 1.0
|
341 |
*
|
345 |
$default_profiles = array(
|
346 |
'automatic' => array(
|
347 |
'profile' => 'automatic',
|
348 |
+
'name' => __( 'Automatic', 'lingotek-translation' ),
|
349 |
'upload' => 'automatic',
|
350 |
+
'download' => 'automatic',
|
351 |
),
|
352 |
'manual' => array(
|
353 |
'profile' => 'manual',
|
354 |
+
'name' => __( 'Manual', 'lingotek-translation' ),
|
355 |
'upload' => 'manual',
|
356 |
+
'download' => 'manual',
|
357 |
),
|
358 |
'disabled' => array(
|
359 |
'profile' => 'disabled',
|
360 |
+
'name' => __( 'Disabled', 'lingotek-translation' ),
|
361 |
),
|
362 |
);
|
363 |
|
364 |
+
$profiles = get_option( 'lingotek_profiles' );
|
365 |
+
if ( is_array( $profiles ) ) {
|
366 |
+
$profiles = array_merge( $default_profiles, $profiles );
|
367 |
+
} else {
|
|
|
368 |
$profiles = $default_profiles;
|
369 |
}
|
370 |
|
371 |
+
// localize canned profile names.
|
372 |
+
foreach ( $profiles as $k => $v ) {
|
373 |
+
if ( in_array( $k,array( 'automatic', 'manual', 'disabled' ), true ) ) {
|
374 |
+
$profile_name = $profiles[ $k ]['name'];
|
375 |
+
$profiles[ $k ]['name'] = __( $profile_name,'lingotek-translation' );// localize canned profile names.
|
376 |
}
|
377 |
}
|
378 |
|
379 |
+
update_option( 'lingotek_profiles', $profiles );
|
380 |
return $profiles;
|
381 |
}
|
382 |
|
383 |
+
/**
|
384 |
+
* Plugin deactivation for multisite
|
385 |
*
|
386 |
* @since 0.1
|
387 |
*/
|
388 |
public function deactivate() {
|
389 |
+
$this->do_for_all_blogs( 'deactivate' );
|
390 |
}
|
391 |
|
392 |
+
/**
|
393 |
+
* Plugin deactivation
|
394 |
*
|
395 |
* @since 0.5
|
396 |
*/
|
397 |
protected function _deactivate() {
|
398 |
+
delete_option( 'rewrite_rules' );
|
399 |
}
|
400 |
|
401 |
+
/**
|
402 |
+
* Blog creation on multisite (to set default options)
|
403 |
*
|
404 |
* @since 0.1
|
405 |
*
|
406 |
+
* @param int $blog_id blog id.
|
407 |
*/
|
408 |
+
public function wpmu_new_blog( $blog_id ) {
|
409 |
+
switch_to_blog( $blog_id );
|
410 |
$this->_activate();
|
411 |
restore_current_blog();
|
412 |
}
|
413 |
|
414 |
+
/**
|
415 |
+
* Autoload classes
|
416 |
*
|
417 |
* @since 0.1
|
418 |
*
|
419 |
+
* @param string $class class name.
|
420 |
*/
|
421 |
+
public function autoload( $class ) {
|
422 |
+
// not a Lingotek class.
|
423 |
+
if ( 0 !== strncmp( 'Lingotek_', $class, 9 ) ) {
|
424 |
return;
|
425 |
+
}
|
426 |
|
427 |
+
$class = self::convert_class_to_file( $class );
|
428 |
+
foreach ( array( LINGOTEK_WORKFLOWS, LINGOTEK_INC, LINGOTEK_ADMIN_INC ) as $path ) {
|
429 |
+
if ( file_exists( $file = "$path/$class.php" ) ) {
|
430 |
+
require_once( $file );
|
431 |
break;
|
432 |
}
|
433 |
}
|
434 |
}
|
435 |
|
436 |
+
/**
|
437 |
+
* Set the Polylang model class to PLL_Admin_Model on Lingotek admin pages
|
438 |
*
|
439 |
* @since 0.2
|
440 |
*
|
441 |
+
* @param string $class class name.
|
442 |
+
* @return string modified class 'PLL_Model' | 'PLL_Admin_Model'.
|
443 |
*/
|
444 |
+
public function pll_model( $class ) {
|
445 |
+
if ( PLL_ADMIN && ! empty( filter_input( INPUT_GET, 'page' ) ) && in_array( filter_input( INPUT_GET, 'page' ), array( 'lingotek-translation', 'lingotek-translation_manage', 'lingotek-translation_settings', 'lingotek-translation_network' ), true ) ) {
|
446 |
return 'PLL_Admin_Model';
|
447 |
+
}
|
448 |
return $class;
|
449 |
}
|
450 |
|
451 |
+
/**
|
452 |
+
* Setups Lingotek model and callback
|
453 |
* sets filters to call Lingotek child classes instead of Polylang classes
|
454 |
*
|
455 |
* @since 0.1
|
|
|
456 |
*/
|
457 |
public function init() {
|
458 |
+
if ( ! defined( 'POLYLANG_VERSION' ) ) {
|
459 |
return;
|
460 |
+
}
|
461 |
|
462 |
add_rewrite_rule( 'lingotek/?$', 'index.php?lingotek=1&$matches[1]', 'top' );
|
463 |
|
464 |
+
if ( is_admin() ) {
|
465 |
new Lingotek_Admin();
|
466 |
+
}
|
467 |
|
468 |
+
// admin side.
|
469 |
+
if ( PLL_ADMIN && ! PLL_SETTINGS ) {
|
470 |
$this->model = new Lingotek_Model();
|
471 |
|
472 |
+
// overrides Polylang classes.
|
473 |
+
$classes = array( 'Filters_Post', 'Filters_Term', 'Filters_Media', 'Filters_Columns' );
|
474 |
+
foreach ( $classes as $class ) {
|
475 |
+
$method = function( $v ) use ( $class ) {
|
476 |
+
return "Lingotek_$class";
|
477 |
+
};
|
478 |
+
add_filter( 'pll_' . strtolower( $class ) , $method );
|
479 |
+
}
|
480 |
|
481 |
+
// add actions to posts, media and terms list.
|
482 |
+
// no need to load this if there is no language yet.
|
483 |
+
if ( $GLOBALS['polylang']->model->get_languages_list() ) {
|
484 |
$this->post_actions = new Lingotek_Post_Actions();
|
485 |
$this->term_actions = new Lingotek_Term_Actions();
|
486 |
$this->string_actions = new Lingotek_String_actions();
|
487 |
+
new Lingotek_Workflow_Factory(); // autoloads class.
|
488 |
}
|
489 |
|
490 |
$this->utilities = new Lingotek_Utilities();
|
491 |
+
} // callback.
|
492 |
+
elseif ( ! PLL_ADMIN && ! PLL_AJAX_ON_FRONT ) {
|
493 |
+
$GLOBALS['wp']->add_query_var( 'lingotek' );
|
|
|
|
|
494 |
|
495 |
$this->model = new Lingotek_Model();
|
496 |
+
$this->callback = new Lingotek_Callback( $this->model );
|
497 |
}
|
498 |
}
|
499 |
|
500 |
+
/**
|
501 |
+
* Some init
|
502 |
*
|
503 |
* @since 0.1
|
504 |
*/
|
505 |
public function admin_init() {
|
506 |
+
// plugin i18n, only needed for backend.
|
507 |
+
load_plugin_textdomain( 'lingotek-translation', false, basename( LINGOTEK_DIR ) . '/languages' );
|
508 |
|
509 |
+
if ( ! defined( 'POLYLANG_VERSION' ) ) {
|
510 |
+
add_action( 'all_admin_notices', array( &$this, 'pll_inactive_notice' ) );
|
511 |
|
512 |
+
} elseif ( version_compare( POLYLANG_VERSION, LINGOTEK_MIN_PLL_VERSION, '<' ) ) {
|
513 |
+
add_action( 'all_admin_notices', array( &$this, 'pll_old_notice' ) );
|
514 |
|
515 |
+
} elseif ( isset( $GLOBALS['polylang'] ) && ! count( $GLOBALS['polylang']->model->get_languages_list() ) ) {
|
516 |
self::create_first_language();
|
517 |
+
}
|
518 |
|
519 |
+
wp_enqueue_style( 'lingotek_admin', LINGOTEK_URL . '/css/admin.css', array(), LINGOTEK_VERSION );
|
520 |
}
|
521 |
|
522 |
+
/**
|
523 |
+
* Displays a notice if Polylang is inactive
|
524 |
*
|
525 |
* @since 0.1
|
526 |
*/
|
531 |
add_query_arg(
|
532 |
array(
|
533 |
'action' => $action,
|
534 |
+
'plugin' => $slug,
|
535 |
),
|
536 |
admin_url( 'update.php' )
|
537 |
),
|
538 |
+
$action . '_' . $slug
|
539 |
);
|
540 |
printf(
|
541 |
'<div class="error" style="height:55px"><p style="font-size:1.5em">%s<a href="%s">%s</a></p></div>',
|
542 |
+
esc_html( __( 'Lingotek Translation requires Polylang to work. ', 'lingotek-translation' ) ), esc_url( $url ), esc_html( __( 'Install Polylang', 'lingotek-translation' ) )
|
543 |
);
|
544 |
}
|
545 |
|
546 |
+
/**
|
547 |
+
* Displays a notice if Polylang is obsolete
|
548 |
*
|
549 |
* @since 0.1
|
550 |
*/
|
551 |
public function pll_old_notice() {
|
552 |
+
$allowed_html = [
|
553 |
+
'strong' => [],
|
554 |
+
];
|
555 |
printf(
|
556 |
'<div class="error"><p>%s</p></div>',
|
557 |
sprintf(
|
558 |
+
esc_html( __( 'Lingotek Translation requires Polylang %s to work. Please upgrade Polylang.', 'lingotek-translation' ) ),
|
559 |
+
wp_kses( '<strong>' . LINGOTEK_MIN_PLL_VERSION . '</strong>' , $allowed_html )
|
560 |
)
|
561 |
);
|
562 |
}
|
563 |
|
564 |
+
/**
|
565 |
+
* Creates at least on language to avoid breaking the Lingotek Dashboard
|
566 |
*
|
567 |
* @since 0.2
|
568 |
*/
|
569 |
static protected function create_first_language() {
|
570 |
global $polylang;
|
571 |
|
572 |
+
include( PLL_ADMIN_INC . '/languages.php' );
|
573 |
$locale = get_locale();
|
574 |
|
575 |
+
// attempts to set the default language from the current locale.
|
576 |
+
foreach ( $languages as $lang ) {
|
577 |
+
if ( get_locale() === $lang[1] ) {
|
578 |
$language = $lang;
|
579 |
+
}
|
580 |
}
|
581 |
|
582 |
+
// defaults to en_US.
|
583 |
+
if ( empty( $language ) ) {
|
584 |
+
$language = array( 'en', 'en_US', 'English' );
|
585 |
+
}
|
586 |
|
587 |
+
$pll_model = new PLL_Admin_Model( $polylang->options ); // need admin model.
|
588 |
$pll_model->add_language(array(
|
589 |
'slug' => $language[0],
|
590 |
'locale' => $language[1],
|
591 |
'name' => $language[2],
|
592 |
+
'rtl' => isset( $language[3] ) ? 1 : 0,
|
593 |
+
'term_group' => 0,
|
594 |
));
|
595 |
}
|
596 |
|
597 |
+
/**
|
598 |
+
* Adds Lingotek locale to the PLL_Language objects
|
599 |
* uses the map otherwise uses a stupid fallback
|
600 |
*
|
601 |
* @since 0.1
|
602 |
*
|
603 |
+
* @param array $languages list of language objects.
|
604 |
* @return array
|
605 |
*/
|
606 |
+
public function pre_set_languages_list( $languages ) {
|
607 |
+
foreach ( $languages as $key => $language ) {
|
608 |
+
if ( is_object( $language ) ) {
|
609 |
+
$languages[ $key ]->lingotek_locale = self::map_to_lingotek_locale( $language->locale ); // backward compatibility with Polylang < 1.7.3.
|
610 |
+
} else { $languages[ $key ]['lingotek_locale'] = self::map_to_lingotek_locale( $language['locale'] );
|
611 |
+
}
|
612 |
}
|
613 |
|
614 |
return $languages;
|
615 |
}
|
616 |
|
617 |
+
/**
|
618 |
+
* Maps a Lingotek locale to a WordPress locale
|
619 |
*
|
620 |
* @since 0.3
|
621 |
*
|
622 |
+
* @param string $lingotek_locale Lingotek locale.
|
623 |
+
* @return string WordPress locale.
|
624 |
*/
|
625 |
+
public static function map_to_wp_locale( $lingotek_locale ) {
|
626 |
+
// look for the locale in the map (take care that Lingotek sends locales with either '_' or '-'.
|
627 |
+
// if not found just replace '-' by '_'.
|
628 |
+
$wp_locale = array_search( str_replace( '_', '-', $lingotek_locale ), self::$lingotek_locales, true );
|
629 |
+
return $wp_locale ? $wp_locale : str_replace( '-', '_', $lingotek_locale );
|
630 |
}
|
631 |
|
632 |
+
/**
|
633 |
+
* Converts the class name to the appropriate file name for class loading.
|
634 |
+
*
|
635 |
+
* @param string $class the class name.
|
636 |
+
*/
|
637 |
+
public static function convert_class_to_file( $class ) {
|
638 |
+
return str_replace( '_', '-', strtolower( substr( $class, 9 ) ) );
|
639 |
+
}
|
640 |
+
|
641 |
+
/**
|
642 |
+
* Maps a WordPres locale to a Lingotek locale
|
643 |
*
|
644 |
* @since 0.3
|
645 |
*
|
646 |
+
* @param string $wp_locale WordPress locale.
|
647 |
* @return string Lingotek locale
|
648 |
*/
|
649 |
+
public static function map_to_lingotek_locale( $wp_locale ) {
|
650 |
+
// look for the locale in the map.
|
651 |
+
// if not found just replace '_ 'by '-'.
|
652 |
+
return isset( self::$lingotek_locales[ $wp_locale ] ) ? self::$lingotek_locales[ $wp_locale ] : str_replace( '_', '-', $wp_locale );
|
653 |
}
|
654 |
|
655 |
+
/**
|
656 |
+
* Modifies the flag title to add the locale
|
657 |
*
|
658 |
* @since 0.3
|
659 |
*
|
660 |
+
* @param string $name language name.
|
661 |
+
* @param string $slug language code.
|
662 |
+
* @param string $locale language locale.
|
663 |
* @return string
|
664 |
*/
|
665 |
+
public function pll_flag_title( $name, $slug, $locale ) {
|
666 |
return "$name ($locale)";
|
667 |
}
|
668 |
|
669 |
+
/**
|
670 |
+
* Writes data to a log.
|
671 |
+
*
|
672 |
+
* @param multiple $data the data to be written.
|
673 |
+
* @param string $label the label to identify the data.
|
674 |
+
*/
|
675 |
+
public static function log( $data, $label = null ) {
|
676 |
+
if ( self::$logging ) {
|
677 |
+
$log_string = '';
|
678 |
+
if ( is_string( $label ) ) {
|
679 |
$log_string .= $label . "\n";
|
|
|
|
|
680 |
}
|
681 |
+
if ( is_string( $data ) ) {
|
682 |
+
$log_string .= $data;
|
683 |
+
} else {
|
684 |
+
$log_string .= print_r( $data, true );
|
685 |
}
|
686 |
+
error_log( $log_string );
|
687 |
}
|
688 |
}
|
689 |
|
690 |
+
/**
|
691 |
* Creates a pointer to draw attention to the new Lingotek menu item upon plugin activation
|
692 |
* code borrowed from Polylang
|
693 |
+
*
|
694 |
* @since 1.0.1
|
695 |
*/
|
696 |
public function lingotek_activation_pointer() {
|
697 |
+
$content = __( 'You’ve just installed Lingotek Translation! Click below to activate your account and automatically translate your website for free!', 'lingotek-translation' );
|
698 |
|
699 |
$buttons = array(
|
700 |
array(
|
701 |
+
'label' => __( 'Close' ),
|
702 |
),
|
703 |
array(
|
704 |
+
'label' => __( 'Activate Account', 'lingotek-translation' ),
|
705 |
+
'link' => admin_url( 'admin.php?page=' . $this->plugin_slug . '_settings&connect=new' ),
|
706 |
+
),
|
707 |
);
|
708 |
|
709 |
$args = array(
|
714 |
'align' => 'left',
|
715 |
),
|
716 |
'width' => 380,
|
717 |
+
'title' => __( 'Congratulations!', 'lingotek-translation' ),
|
718 |
'content' => $content,
|
719 |
+
'buttons' => $buttons,
|
720 |
);
|
721 |
|
722 |
+
new Lingotek_Pointer( $args );
|
723 |
}
|
724 |
}
|
725 |
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://lingotek.com/
|
|
4 |
Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.7
|
7 |
-
Stable tag: 1.2.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -122,6 +122,14 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
|
|
122 |
|
123 |
== Changelog ==
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
= 1.2.6 (2017-3-3) =
|
126 |
|
127 |
* Increased API timeout
|
4 |
Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.7
|
7 |
+
Stable tag: 1.2.7
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
122 |
|
123 |
== Changelog ==
|
124 |
|
125 |
+
= 1.2.7 (2017-4-14) =
|
126 |
+
|
127 |
+
* Added Lingotek bulk actions to custom content types
|
128 |
+
* Fixed incorrect number display on the Translation Dashboard when content was disabled for translation
|
129 |
+
* Fixed a bug that created empty content if trying to download translations before they were finished
|
130 |
+
* Fixed the String Groups page
|
131 |
+
* Code refactoring to meet WordPress coding standards
|
132 |
+
|
133 |
= 1.2.6 (2017-3-3) =
|
134 |
|
135 |
* Increased API timeout
|