/** * Returns a WPML readable string that allows to tell translation service and translator id * (typically used for translators dropdowns) * * @param int|bool $translation_service_id * @param int|bool $translator_id * * @return string */ public static function get_wpml_translator_id($translation_service_id = false, $translator_id = false) { if ($translation_service_id === false) { $translation_service_id = TranslationProxy::get_current_service_id(); } $result = 'ts-' . $translation_service_id; if ($translator_id !== false) { $result .= '-' . $translator_id; } return $result; }
function ajax_calls($call, $data) { global $wpdb, $sitepress; switch ($call) { case 'assign_translator': $translator_data = TranslationProxy_Service::get_translator_data_from_wpml($data['translator_id']); $service_id = $translator_data['translation_service']; $translator_id = $translator_data['translator_id']; $assign_translation_job = $this->assign_translation_job($data['job_id'], $translator_id, $service_id, $data['job_type']); if ($assign_translation_job) { $translator_edit_link = ''; if ($translator_id) { if ($service_id == TranslationProxy::get_current_service_id()) { $job = $this->get_translation_job($data['job_id']); /** @var $ICL_Pro_Translation WPML_Pro_Translation */ global $ICL_Pro_Translation; $ICL_Pro_Translation->send_post($job->original_doc_id, array($job->language_code), $translator_id, $data['job_id']); $project = TranslationProxy::get_current_project(); $translator_edit_link = TranslationProxy_Popup::get_link($project->translator_contact_iframe_url($translator_id), array('title' => __('Contact the translator', 'sitepress'), 'unload_cb' => 'icl_thickbox_refresh')) . esc_html(TranslationProxy_Translator::get_translator_name($translator_id)) . "</a> ({$project->service}->name)"; } else { $translator_edit_link = '<a href="' . TranslationManagement::get_translator_edit_url($data['translator_id']) . '">' . esc_html($wpdb->get_var($wpdb->prepare("SELECT display_name FROM {$wpdb->users} WHERE ID=%d", $data['translator_id']))) . '</a>'; } } echo wp_json_encode(array('error' => 0, 'message' => $translator_edit_link, 'status' => TranslationManagement::status2text(ICL_TM_WAITING_FOR_TRANSLATOR), 'service' => $service_id)); } else { echo wp_json_encode(array('error' => 1)); } break; case 'icl_cf_translation': case 'icl_tcf_translation': if (!empty($data['cf'])) { foreach ($data['cf'] as $k => $v) { $cft[base64_decode($k)] = $v; } if (isset($cft)) { $this->settings[$call === 'icl_tcf_translation' ? WPML_TERM_META_SETTING_INDEX_PLURAL : WPML_POST_META_SETTING_INDEX_PLURAL] = $cft; $this->save_settings(); } } echo '1|'; break; case 'icl_doc_translation_method': $this->settings['doc_translation_method'] = intval($data['t_method']); $sitepress->set_setting('doc_translation_method', $this->settings['doc_translation_method']); $sitepress->save_settings(array('hide_how_to_translate' => empty($data['how_to_translate']))); if (isset($data['tm_block_retranslating_terms'])) { $sitepress->set_setting('tm_block_retranslating_terms', $data['tm_block_retranslating_terms']); } else { $sitepress->set_setting('tm_block_retranslating_terms', ''); } if (isset($data['tm_block_retranslating_terms'])) { $sitepress->set_setting('tm_block_retranslating_terms', $data['tm_block_retranslating_terms']); } else { $sitepress->set_setting('tm_block_retranslating_terms', ''); } $this->save_settings(); echo '1|'; break; case 'reset_duplication': $this->reset_duplicate_flag($_POST['post_id']); break; case 'set_duplication': $new_id = $this->set_duplicate($_POST['wpml_original_post_id'], $_POST['post_lang']); wp_send_json_success(array('id' => $new_id)); break; case 'make_duplicates': $mdata['iclpost'] = array($data['post_id']); $langs = explode(',', $data['langs']); foreach ($langs as $lang) { $mdata['duplicate_to'][$lang] = 1; } $this->make_duplicates($mdata); do_action('wpml_new_duplicated_terms', (array) $mdata['iclpost'], false); break; } }
private function build_translation_options() { global $sitepress, $wpdb; $basket_items_number = TranslationProxy_Basket::get_basket_items_count(true); $basket_name_max_length = TranslationProxy::get_current_service_batch_name_max_length(); if ($basket_items_number > 0) { $source_language = TranslationProxy_Basket::get_source_language(); $basket_name_placeholder = sprintf(__("%s|WPML|%s", 'wpml-translation-management'), get_option('blogname'), $source_language); $basket = new WPML_Translation_Basket($wpdb); $basket_name_placeholder = esc_attr($basket->get_unique_basket_name($basket_name_placeholder, $basket_name_max_length)); ?> <h3>2. <?php _e('Choose translation options', 'wpml-translation-management'); ?> </h3> <form method="post" id="translation-jobs-translators-form" name="translation-jobs-translators" action=""> <input type="hidden" name="icl_tm_action" value="send_all_jobs"/> <label for="basket_name"><strong><?php _e('Batch name', 'wpml-translation-management'); ?> :</strong></label> <input id="basket_name" name="basket_name" type="text" style="width: 40%;" value="<?php echo $basket_name_placeholder; ?> " maxlength="<?php echo $basket_name_max_length; ?> " placeholder="<?php echo $basket_name_placeholder; ?> "> <br/><span class="description"><?php _e('Give a name to the batch. If omitted, the default name will be applied.', 'wpml-translation-management'); ?> </span> <table class="widefat fixed" id="icl-translation-translators" cellspacing="0"> <thead> <tr> <th scope="col" width="15%"><?php _e('Language', 'wpml-translation-management'); ?> </th> <th scope="col"><?php _e('Translator', 'wpml-translation-management'); ?> </th> </tr> </thead> <tfoot> <tr> <th scope="col"><?php _e('Language', 'wpml-translation-management'); ?> </th> <th scope="col"><?php _e('Translator', 'wpml-translation-management'); ?> </th> </tr> </tfoot> <?php $basket_languages = TranslationProxy_Basket::get_target_languages(); if ($basket_languages) { ?> <tbody> <?php $target_languages = $sitepress->get_active_languages(); foreach ($target_languages as $key => $lang) { if (!in_array($lang['code'], $basket_languages)) { unset($target_languages[$key]); } } foreach ($target_languages as $lang) { if ($lang['code'] === TranslationProxy_Basket::get_source_language()) { continue; } ?> <tr> <td><strong><?php echo $lang['display_name']; ?> </strong></td> <td> <label for="<?php echo esc_attr('translator[' . $lang['code'] . ']'); ?> "> <?php _e('Translate by', 'wpml-translation-management'); ?> </label> <?php $selected_translator = isset($icl_selected_translators[$lang['code']]) ? $icl_selected_translators[$lang['code']] : false; if ($selected_translator === false) { $selected_translator = TranslationProxy_Service::get_wpml_translator_id(); } $args = array('from' => TranslationProxy_Basket::get_source_language(), 'to' => $lang['code'], 'name' => 'translator[' . $lang['code'] . ']', 'selected' => $selected_translator, 'services' => array('local', TranslationProxy::get_current_service_id())); TranslationManagement::translators_dropdown($args); ?> <a href="admin.php?page=<?php echo WPML_TM_FOLDER; ?> /menu/main.php&sm=translators"><?php _e('Manage translators', 'wpml-translation-management'); ?> </a> </td> </tr> <?php } ?> </tbody> <?php } ?> </table> <br> <?php echo TranslationProxy_Basket::get_basket_extra_fields_section(); ?> <?php wp_nonce_field('send_basket_items_nonce', '_icl_nonce_send_basket_items'); ?> <?php wp_nonce_field('send_basket_item_nonce', '_icl_nonce_send_basket_item'); ?> <?php wp_nonce_field('send_basket_commit_nonce', '_icl_nonce_send_basket_commit'); ?> <?php wp_nonce_field('check_basket_name_nonce', '_icl_nonce_check_basket_name'); ?> <input type="submit" class="button-primary" name="send-all-jobs-for-translation" value="<?php _e('Send all items for translation', 'wpml-translation-management'); ?> "> </form> <?php } do_action('wpml_translation_basket_page_after'); }
function translation_service_authentication_ajax() { $translation_service_authentication = false; if (isset($_POST['nonce'])) { $translation_service_authentication = wp_verify_nonce($_POST['nonce'], 'translation_service_authentication'); } $errors = 0; $message = ''; $invalidate = isset($_POST['invalidate']) ? $_POST['invalidate'] : false; if ($translation_service_authentication) { if ($invalidate) { $result = TranslationProxy::invalidate_service(TranslationProxy::get_current_service_id()); if (!$result) { $message = __('Unable to invalidate this service. Please contact WPML support.', 'wpml-translation-management'); $errors++; } else { $message = __('Service invalidated.', 'wpml-translation-management'); } } else { if (isset($_POST['custom_fields'])) { $custom_fields_data_serialized = $_POST['custom_fields']; $custom_fields_data = json_decode(stripslashes($custom_fields_data_serialized), true); $result = TranslationProxy::authenticate_service($_POST['service_id'], $custom_fields_data); if (!$result) { $message = __('Unable to activate this service. Please check entered data and try again.', 'wpml-translation-management'); $errors++; } else { $message = __('Service activated.', 'wpml-translation-management'); } } } } else { $message = __('You are not allowed to perform this action.', 'wpml-translation-management'); $errors++; } $response = array('errors' => $errors, 'message' => $message, 'reload' => !$errors ? 1 : 0); echo wp_json_encode($response); die; }
protected function get_translator_html($job) { $job = (object) $job; $current_service_name = TranslationProxy::get_current_service_name(); $translation_services = array('local', TranslationProxy::get_current_service_id()); $translator = ''; if ($job->translation_service && $job->translation_service !== 'local') { try { $project = TranslationProxy::get_current_project(); if ($project) { if ($project->service->has_translator_selection) { $translator_contact_iframe_url = $project->translator_contact_iframe_url($job->translator_id); $iframe_args = array('title' => __('Contact the translator', 'wpml-translation-management'), 'unload_cb' => 'icl_thickbox_refresh'); $translator .= TranslationProxy_Popup::get_link($translator_contact_iframe_url, $iframe_args); $translator .= esc_html($job->translator_name); $translator .= "</a> (" . $current_service_name . ")"; } else { $translator .= $current_service_name; } } else { $translator .= esc_html($job->translator_name); } } catch (Exception $e) { // Just doesn't create the output } } elseif ($job->status == ICL_TM_COMPLETE) { $translator_data = get_userdata($job->translator_id); $translator_name = $translator_data ? $translator_data->display_name : ""; $translator = '<span class="icl-finished-local-name">' . $translator_name . '</span>'; } else { $translator .= '<span class="icl_tj_select_translator">'; $selected_translator = isset($job->translator_id) ? $job->translator_id : false; $disabled = false; if ($job->translation_service && $job->translation_service !== 'local' && is_numeric($job->translation_service)) { $selected_translator = TranslationProxy_Service::get_wpml_translator_id($job->translation_service, $job->translator_id); $disabled = true; } $job_id = isset($job->job_id) ? $job->job_id : $job->id; $local_only = isset($job->local_only) ? $job->local_only : true; $args = array('id' => 'icl_tj_translator_for_' . $job_id, 'name' => 'icl_tj_translator_for_' . $job_id, 'from' => $job->source_language_code, 'to' => $job->language_code, 'selected' => $selected_translator, 'services' => $translation_services, 'disabled' => $disabled, 'echo' => false, 'local_only' => $local_only); $translator .= TranslationManagement::translators_dropdown($args); $translator .= '<input type="hidden" id="icl_tj_ov_' . $job_id . '" value="' . (int) $job->translator_id . '" />'; $translator .= '<input type="hidden" id="icl_tj_ty_' . $job_id . '" value="' . strtolower($this->get_type()) . '" />'; $translator .= '<span class="icl_tj_select_translator_controls" id="icl_tj_tc_' . $job_id . '">'; $translator .= '<input type="button" class="button-secondary icl_tj_ok" value="' . __('Send', 'wpml-translation-management') . '" /> '; $translator .= '<input type="button" class="button-secondary icl_tj_cancel" value="' . __('Cancel', 'wpml-translation-management') . '" />'; $translator .= '</span>'; } return $translator; }
static function sync_cancelled() { global $wpdb, $sitepress; $project = TranslationProxy::get_current_project(); $requests = $project->cancelled_jobs(); if ($requests === false) { echo wp_json_encode(array('errors' => 1, 'message' => 'Failed fetching jobs list from the server.')); exit; } $cms_ids = array(); if (!empty($requests)) { foreach ($requests as $request) { $cms_ids[] = $request->cms_id; } } // get jobs that are in progress $translations_sql = "\n SELECT t.element_id, t.element_type, t.language_code, t.source_language_code, t.trid,\n s.rid, s._prevstate, s.translation_id\n FROM {$wpdb->prefix}icl_translation_status s\n JOIN {$wpdb->prefix}icl_translations t\n ON t.translation_id = s.translation_id\n WHERE s.translation_service=%s\n AND s.status = %d\n "; $translations_prepared = $wpdb->prepare($translations_sql, array(TranslationProxy::get_current_service_id(), ICL_TM_IN_PROGRESS)); $translations = $wpdb->get_results($translations_prepared); $jobs2delete = array(); $translations2cancel = array(); foreach ($translations as $t) { $original_id_sql = "SELECT element_id FROM {$wpdb->prefix}icl_translations\n WHERE trid=%d AND source_language_code IS NULL"; $original_id_prepared = $wpdb->prepare($original_id_sql, $t->trid); $original_id = $wpdb->get_var($original_id_prepared); $cms_id = sprintf('%s_%d_%s_%s', preg_replace('#^post_#', '', $t->element_type), $original_id, $t->source_language_code, $t->language_code); if (in_array($cms_id, $cms_ids)) { $_lang_details = $sitepress->get_language_details($t->source_language_code); $lang_from = $_lang_details['english_name']; $_lang_details = $sitepress->get_language_details($t->language_code); $lang_to = $_lang_details['english_name']; $jobs2delete[] = '<a href="' . get_permalink($original_id) . '">' . get_the_title($original_id) . '</a>' . sprintf(' - from %s to %s', $lang_from, $lang_to); $translations2cancel[] = $t; } } $response_message = ''; if ($jobs2delete && $translations2cancel) { $response_message .= '<div class="error clear" style="padding-top:5px;font-size:11px;">'; $response_message .= __('About to cancel these jobs:', 'sitepress'); $response_message .= '<br />'; $response_message .= '<ul style="margin-left:10px;">'; $response_message .= '<li>'; $response_message .= join('</li><li>', $jobs2delete); $response_message .= '</li>'; $response_message .= '</ul>'; $response_message .= '<br />'; $response_message .= '<a id="icl_ts_cancel_ok" href="#" class="button-secondary">'; $response_message .= __('OK', 'sitepress'); $response_message .= '</a> '; $response_message .= '<a id="icl_ts_cancel_cancel" href="#" class="button-secondary">'; $response_message .= __('Cancel', 'sitepress'); $response_message .= '</a>'; $response_message .= '</div>'; $response_errors = 0; $response_data = array('t2c' => serialize($translations2cancel)); } elseif ($project->errors) { $response_message = join('<br/>', $project->errors); $response_errors = count($project->errors); $response_data = false; } else { $response_message = __('Nothing to cancel.', 'sitepress'); $response_errors = 0; $response_data = false; } $response = array('errors' => $response_errors, 'message' => $response_message, 'data' => $response_data); echo wp_json_encode($response); die; }
public static function translators_dropdown($args = array()) { $dropdown = ''; /** @var $from string|false */ /** @var $to string|false */ /** @var $classes string|false */ /** @var $id string|false */ /** @var $name string|false */ /** @var $selected bool */ /** @var $echo bool */ /** @var $add_label bool */ /** @var $services array */ /** @var $show_service bool */ /** @var $disabled bool */ /** @var $default_name bool|string */ /** @var $local_only bool */ //set default value for variables $from = false; $to = false; $id = 'translator_id'; $name = 'translator_id'; $selected = 0; $echo = true; $add_label = false; $services = array('local'); $show_service = true; $disabled = false; $default_name = false; $local_only = false; extract($args, EXTR_OVERWRITE); $translators = array(); try { $translation_service = TranslationProxy::get_current_service(); $translation_service_id = TranslationProxy::get_current_service_id(); $translation_service_name = TranslationProxy::get_current_service_name(); $is_service_authenticated = TranslationProxy::is_service_authenticated(); //if translation service does not support translators choice, always shows first available if (isset($translation_service->id) && !TranslationProxy::translator_selection_available() && $is_service_authenticated) { $translators[] = (object) array('ID' => TranslationProxy_Service::get_wpml_translator_id($translation_service->id), 'display_name' => __('First available', 'sitepress'), 'service' => $translation_service_name); } elseif (in_array($translation_service_id, $services) && $is_service_authenticated) { $lang_status = TranslationProxy_Translator::get_language_pairs(); if (empty($lang_status)) { $lang_status = array(); } foreach ((array) $lang_status as $language_pair) { if ($from && $from != $language_pair['from']) { continue; } if ($to && $to != $language_pair['to']) { continue; } if (!empty($language_pair['translators'])) { if (1 < count($language_pair['translators'])) { $translators[] = (object) array('ID' => TranslationProxy_Service::get_wpml_translator_id($translation_service->id), 'display_name' => __('First available', 'sitepress'), 'service' => $translation_service_name); } foreach ($language_pair['translators'] as $tr) { if (!isset($_icl_translators[$tr['id']])) { $translators[] = $_icl_translators[$tr['id']] = (object) array('ID' => TranslationProxy_Service::get_wpml_translator_id($translation_service->id, $tr['id']), 'display_name' => $tr['nickname'], 'service' => $translation_service_name); } } } } } if (in_array('local', $services)) { $translators[] = (object) array('ID' => 0, 'display_name' => __('First available', 'sitepress')); $translators = array_merge($translators, self::get_blog_translators(array('from' => $from, 'to' => $to))); } $translators = apply_filters('wpml_tm_translators_list', $translators); $dropdown .= '<select id="' . esc_attr($id) . '" name="' . esc_attr($name) . '" ' . ($disabled ? 'disabled="disabled"' : '') . '>'; if ($default_name) { $dropdown_selected = selected($selected, false, false); $dropdown .= '<option value="" ' . $dropdown_selected . '>'; $dropdown .= esc_html($default_name); $dropdown .= '</option>'; } foreach ($translators as $t) { if ($local_only && isset($t->service)) { continue; } $current_translator = $t->ID; $dropdown_selected = selected($selected, $current_translator, false); $dropdown .= '<option value="' . $current_translator . '" ' . $dropdown_selected . '>'; $dropdown .= esc_html($t->display_name); if ($show_service) { $dropdown .= ' ('; $dropdown .= isset($t->service) ? $t->service : __('Local', 'sitepress'); $dropdown .= ')'; } $dropdown .= '</option>'; } $dropdown .= '</select>'; } catch (TranslationProxy_Api_Error $ex) { $dropdown .= __('Translation Proxy error', 'sitepress') . ': ' . $ex->getMessage(); } catch (Exception $ex) { $dropdown .= __('Error', 'sitepress') . ': ' . $ex->getMessage(); } if ($add_label) { $dropdown = '<label for="' . esc_attr($id) . '">' . __('Translation jobs for:', 'wpml-translation-management') . '</label> ' . $dropdown; } if ($echo) { echo $dropdown; } return $dropdown; }
function get_strings_in_progress() { global $wpdb; $strings_in_progress_snipped = wpml_prepare_in(array(ICL_TM_IN_PROGRESS, ICL_TM_WAITING_FOR_TRANSLATOR), '%d'); $strings_in_progress_sql = "\tSELECT COUNT(*)\n\t\t\t\t\t\t\t\t\t\t\tFROM {$wpdb->prefix}icl_string_translations\n\t\t\t\t\t\t\t\t\t\t\tWHERE status IN ({$strings_in_progress_snipped})\n\t\t\t\t\t\t\t\t\t\t\t\tAND translation_service = %d"; $strings_in_progress_prepared = $wpdb->prepare($strings_in_progress_sql, TranslationProxy::get_current_service_id()); $strings_in_progress = $wpdb->get_var($strings_in_progress_prepared); return $strings_in_progress; }
function translation_service_toggle_ajax() { $translation_service_toggle = false; if (isset($_POST['nonce'])) { $translation_service_toggle = wp_verify_nonce($_POST['nonce'], 'translation_service_toggle'); } $errors = 0; $message = ''; if ($translation_service_toggle) { $service_id = false; if (isset($_POST['service_id'])) { $service_id = $_POST['service_id']; } $enable = false; if (isset($_POST['enable'])) { $enable = $_POST['enable']; } if (!$service_id) { return; } if ($enable && TranslationProxy::get_current_service_id() != $service_id) { $result = TranslationProxy::select_service($service_id); if (is_wp_error($result)) { $message = $result->get_error_message(); } } if (!$enable && TranslationProxy::get_current_service_id() == $service_id) { TranslationProxy::deselect_active_service(); } } else { $message = __('You are not allowed to perform this action.', 'wpml-translation-management'); $errors++; } $response = array('errors' => $errors, 'message' => $message, 'reload' => !$errors ? 1 : 0); echo wp_json_encode($response); die; }
/** * @return bool */ private function must_show_incomplete_jobs_notice() { return $this->is_jobs_tab() && TranslationProxy::get_current_service_id() && !$this->service_activation_incomplete() && !$this->service_activation_ajax->get_ignore_local_jobs(); }
<script type="text/html" id="table-listing-filter"> <?php global $iclTranslationManagement, $sitepress, $wpdb; $translation_services = array('local', TranslationProxy::get_current_service_id()); $args = array('name' => 'filter[translator_id]', 'default_name' => __('All', 'wpml-translation-management'), 'selected' => isset($icl_translation_filter['translator_id']) ? $icl_translation_filter['translator_id'] : '', 'services' => $translation_services, 'add_label' => true); $blog_translators = wpml_tm_load_blog_translators(); $translators_dropdown = new WPML_TM_Translators_Dropdown($blog_translators); $translators_dropdown->render($args); ?> <label for="filter-job-status"> <?php _e('Status', 'wpml-translation-management'); ?> </label> <select id="filter-job-status" name="filter[status]"> <option value=""><?php _e('All translation jobs', 'wpml-translation-management'); ?> </option> <option value="<?php echo ICL_TM_WAITING_FOR_TRANSLATOR; ?> "><?php echo TranslationManagement::status2text(ICL_TM_WAITING_FOR_TRANSLATOR); ?> </option> <option value="<?php echo ICL_TM_IN_PROGRESS; ?> "><?php echo TranslationManagement::status2text(ICL_TM_IN_PROGRESS); ?>
private function belongs_to_active_ts() { global $wpdb; $service_id = TranslationProxy::get_current_service_id(); $batch_id = $this->get_id(); $result = false; if ($service_id) { $result = $wpdb->get_var($wpdb->prepare("SELECT rid FROM {$wpdb->prefix}icl_translation_status WHERE batch_id = %d AND translation_service = %s LIMIT 1", array($batch_id, $service_id))); $result |= $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_string_translations WHERE batch_id = %d AND translation_service = %s LIMIT 1", array($batch_id, $service_id))); } return $result; }
/** * Get all string jobs sent to remote translation service * This function takes the same input array as does $iclTranslationManagement->get_translation_jobs * 'from' should contain the language code for the source of the translation job * 'to' specifies the target language code * 'status' follows the same conventions as for normal jobs so 1 and 2 are waiting for translator and 10 is * complete. Other values are not supported for strings at this point and will lead to empty results * * @param array $args * @param bool $only_ids * * @return array Array of jobs, every job is object * @global object $wpdb * @global object $sitepress * */ public function get_strings_jobs($args = array(), $only_ids = false) { global $wpdb, $sitepress; $translator_id = ""; $from = ""; $to = ""; $status = ""; $service = false; extract($args, EXTR_OVERWRITE); $where = !empty($from) ? $wpdb->prepare(" AND sc.language = %s ", $from) : ''; $where .= !empty($to) ? $wpdb->prepare(" AND st.language = %s ", $to) : ''; $where .= $status ? $where .= $wpdb->prepare(" AND st.status = %d ", $status == ICL_TM_IN_PROGRESS ? ICL_TM_WAITING_FOR_TRANSLATOR : $status) : ''; $service = is_numeric($translator_id) ? 'local' : $service; $service = $service !== 'local' && strpos($translator_id, "ts-") !== false ? substr($translator_id, 3) : $service; $where .= $service === 'local' ? $wpdb->prepare(" AND st.translator_id = %s ", $translator_id) : ''; $where .= $service !== false ? $wpdb->prepare(" AND st.translation_service = %s ", $service) : ''; $cols = "st.id, tb.id AS batch_id" . ($only_ids === false ? ",\n s.language AS source_language_code,\n st.language AS language_code,\n st.status,\n st.string_id,\n s.name,\n s.value,\n tb.id AS batch_id,\n st.translation_service,\n st.translator_id,\n u.display_name as translator_name,\n COUNT( st.id ) as strings_count" : ""); $query = "\tSELECT\n\t\t\t\t\t{$cols}\n\t\t\t\t\tFROM {$wpdb->prefix}icl_string_translations AS st\n\t\t\t\t\tINNER JOIN {$wpdb->prefix}icl_strings AS s\n\t\t\t\t\t\tON st.string_id = s.id\n\t\t\t\t\tINNER JOIN {$wpdb->prefix}icl_translation_batches AS tb\n\t\t\t\t\t\tON tb.id = st.batch_id\n\t\t\t\t\tLEFT JOIN {$wpdb->users} u\n\t\t\t\t ON st.translator_id = u.ID\n\t\t\t\t\tWHERE 1 {$where}\n\t\t\t\t\tGROUP BY st.id, s.id"; $result = $wpdb->get_results($query); if ($only_ids === false) { foreach ($result as $num => $value) { $lang_from = $sitepress->get_language_details($value->source_language_code); $lang_to = $sitepress->get_language_details($value->language_code); $lang_text = $lang_from['display_name'] . ' » ' . $lang_to['display_name']; $result[$num]->lang_text = $lang_text; if ($value->translation_service == TranslationProxy::get_current_service_id()) { $result[$num]->translator_name = TranslationProxy_Translator::get_translator_name($value->translator_id); } } } return $result; }