tm_loader = &$tm_loader; $this->tm_instance = &$tm_instance; } function load() { global $pagenow; $this->tm_loader->tm_after_load(); $wpml_wp_api = $this->sitepress->get_wp_api(); $this->ensure_includes(); if ( $wpml_wp_api->is_admin() ) { $this->tm_loader->load_xliff_frontend(); } $this->plugin_localization(); add_action('wp_ajax_basket_extra_fields_refresh', array($this, 'basket_extra_fields_refresh') ); // Check if WPML is active. If not display warning message and not load Sticky links if ( ! defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE ) { if ( ! function_exists( 'is_multisite' ) || ! is_multisite() ) { add_action( 'admin_notices', array( $this, '_no_wpml_warning' ) ); } return false; } elseif ( ! $this->sitepress->get_setting( 'setup_complete' ) ) { add_action( 'admin_notices', array( $this, '_wpml_not_installed_warning' ) ); return false; } if ( isset( $_GET['icl_action'] ) ) { if ( $_GET['icl_action'] === 'reminder_popup' && isset( $_GET['_icl_nonce'] ) && wp_verify_nonce( $_GET['_icl_nonce'], 'reminder_popup_nonce' ) === 1 ) { add_action( 'init', array( 'TranslationProxy_Popup', 'display' ) ); } elseif ( $_GET['icl_action'] === 'dismiss_help' ) { $this->sitepress->set_setting( 'dont_show_help_admin_notice', true, true ); } } $this->tm_loader->load_pro_translation( $wpml_wp_api ); add_action( 'wp_ajax_wpml_check_batch_status', array($this, 'check_batch_status_ajax') ); if ( $wpml_wp_api->is_admin() ) { add_action( 'init', array( $this, 'automatic_service_selection_action' ) ); add_action( 'translation_service_authentication', array( $this, 'translation_service_authentication' ) ); add_filter( 'translation_service_js_data', array( $this, 'translation_service_js_data' ) ); add_filter( 'wpml_string_status_text', array( 'WPML_Remote_String_Translation', 'string_status_text_filter' ), 10, 3 ); add_action( 'wp_ajax_translation_service_toggle', array( $this, 'translation_service_toggle_ajax' ) ); add_action( 'trashed_post', array( $this, 'trashed_post_actions' ), 10, 2 ); add_action( 'wp_ajax_icl_get_jobs_table', 'icl_get_jobs_table' ); add_action( 'wp_ajax_icl_cancel_translation_jobs', 'icl_cancel_translation_jobs' ); add_action( 'wp_ajax_icl_populate_translations_pickup_box', 'icl_populate_translations_pickup_box' ); add_action( 'wp_ajax_icl_pickup_translations', 'icl_pickup_translations' ); add_action( 'wp_ajax_icl_get_blog_users_not_translators', 'icl_get_blog_users_not_translators' ); add_action( 'wp_ajax_get_translator_status', array('TranslationProxy_Translator', 'get_translator_status_ajax') ); add_action( 'wpml_updated_translation_status', array( 'TranslationProxy_Batch', 'maybe_assign_generic_batch' ), 10, 2 ); add_action('init', array($this, 'handle_notices_action')); do_action('wpml_tm_init'); if ( $pagenow != 'customize.php' ) { // stop TM scripts from messing up theme customizer add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); add_action( 'admin_print_styles', array( $this, 'admin_print_styles' ) ); } add_action( 'icl_wpml_top_menu_added', array( $this, '_icl_hook_top_menu' ) ); add_action( 'admin_menu', array( $this, 'menu' ) ); add_action( 'admin_menu', array( $this, 'menu_fix_order' ), 999 ); // force 'Translations' at the end add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 ); add_action( 'icl_dashboard_widget_content_top', array( $this, 'icl_dashboard_widget_content' ) ); // Add a nice warning message if the user tries to edit a post manually and it's actually in the process of being translated $request_get_trid = filter_input( INPUT_GET, 'trid', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE ); $request_get_post = filter_input( INPUT_GET, 'post', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE ); $request_get_lang = filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE ); if ( ( $pagenow == 'post-new.php' || $pagenow == 'post.php' ) && ( $request_get_trid || $request_get_post ) && $request_get_lang ) { add_action( 'admin_notices', array( $this, '_warn_editing_icl_translation' ) ); } add_action( 'wp_ajax_dismiss_icl_side_by_site', array( $this, 'dismiss_icl_side_by_site' ) ); add_action( 'wp_ajax_icl_tm_parent_filter', array( $this, '_icl_tm_parent_filter' ) ); add_action( 'wp_ajax_icl_tm_toggle_promo', array( $this, '_icl_tm_toggle_promo' ) ); add_action ( 'wpml_support_page_after', array( $this, 'add_com_log_link' ) ); add_action ( 'wpml_translation_basket_page_after', array( $this, 'add_com_log_link' ) ); } do_action( 'wpml_tm_loaded' ); return true; } function trashed_post_actions( $post_id ) { //Removes trashed post from the basket TranslationProxy_Basket::delete_item_from_basket( $post_id ); } function is_jobs_tab() { return $this->is_tm_page('jobs'); } function is_translators_tab() { return $this->is_tm_page('translators'); } function admin_enqueue_scripts() { if ( ! defined( 'DOING_AJAX' ) ) { wp_register_script( 'wpml-tm-progressbar', WPML_TM_URL . '/res/js/wpml-progressbar.js', array( 'jquery', 'jquery-ui-progressbar', 'backbone' ), WPML_TM_VERSION ); wp_register_script( 'tp-polling', WPML_TM_URL . '/res/js/tp-polling/poll-for-translations.js', array( 'jquery' ), WPML_TM_VERSION ); wp_register_script( 'wpml-tm-scripts', WPML_TM_URL . '/res/js/scripts.js', array( 'jquery', 'wpml-tm-progressbar', 'tp-polling' ), WPML_TM_VERSION ); wp_enqueue_script( 'tp-polling' ); wp_enqueue_script( 'wpml-tm-scripts' ); wp_enqueue_style('wpml-tm-styles', WPML_TM_URL . '/res/css/style.css', array(), WPML_TM_VERSION); wp_enqueue_style('wpml-tm-queue', WPML_TM_URL . '/res/css/translations-queue.css', array(), WPML_TM_VERSION); if ( filter_input(INPUT_GET, 'page') === WPML_TM_FOLDER . '/menu/main.php' ) { if ( isset( $_GET[ 'sm' ] ) && ( $_GET[ 'sm' ] == 'services' || $_GET[ 'sm' ] === 'translators' ) ) { wp_register_script( 'wpml-tm-translation-services', WPML_TM_URL . '/res/js/translation-services.js', array( 'wpml-tm-scripts', 'jquery-ui-dialog' ), WPML_TM_VERSION ); wp_register_script( 'wpml-tm-translation-translators', WPML_TM_URL . '/res/js/translation-translators.js', array( 'wpml-tm-scripts', 'jquery-ui-autocomplete', 'underscore' ), WPML_TM_VERSION ); $active_service = TranslationProxy::get_current_service(); $service_name = isset($active_service->name) ? $active_service->name : __('Translation Service', 'wpml-translation-management'); if (isset($active_service->url)) { $service_site_url = "{$service_name}"; } else { $service_site_url = $service_name; } $tm_ts_data = array( 'strings' => array( 'done' => __( 'Done', 'sitepress' ), 'header' => sprintf(__('%s requires additional data', 'wpml-translation-management'), $service_name), 'tip' => sprintf(__("You can find this at %s site", 'wpml-translation-management'), $service_site_url) ), ); $tm_tt_data = array( 'no_matches' => __( 'No matches', 'wpml-translation-management' ), 'found' => __( 'User found', 'wpml-translation-management' ) ); $tm_ts_data = apply_filters( 'translation_service_js_data', $tm_ts_data ); wp_localize_script( 'wpml-tm-translation-services', 'tm_ts_data', $tm_ts_data ); wp_localize_script( 'wpml-tm-translation-translators', 'tm_tt_data', $tm_tt_data ); wp_enqueue_script( 'wpml-tm-translation-services' ); wp_enqueue_script( 'wpml-tm-translation-translators' ); } wp_enqueue_script( 'wpml-tm-translation-proxy', WPML_TM_URL . '/res/js/translation-proxy.js', array( 'wpml-tm-scripts', 'jquery-ui-dialog' ), WPML_TM_VERSION ); } wp_enqueue_style ( 'wp-jquery-ui-dialog' ); wp_enqueue_script( 'thickbox' ); wp_enqueue_script( 'sitepress-icl_reminders', WPML_TM_URL . '/res/js/icl_reminders.js', array(), WPML_TM_VERSION ); do_action('wpml_tm_scripts_enqueued'); } } function admin_print_styles() { if ( ! defined( 'DOING_AJAX' ) ) { wp_enqueue_style( 'wpml-tm-styles', WPML_TM_URL . '/res/css/style.css', array( 'jquery-ui-theme' ), WPML_TM_VERSION ); wp_enqueue_style( 'wpml-tm-queue', WPML_TM_URL . '/res/css/translations-queue.css', array(), WPML_TM_VERSION ); } } function translation_service_authentication() { $active_service = TranslationProxy::get_current_service(); $custom_fields = TranslationProxy::get_custom_fields( $active_service->id ); $auth_content[] = '
'; $auth_content[] = ''; $auth_content[] = '
'; $auth_content_full = implode("\n", $auth_content); ICL_AdminNotifier::display_instant_message($auth_content_full); } 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(); } function check_batch_status_ajax() { $batch_id = filter_input( INPUT_POST, 'batch_id', FILTER_SANITIZE_NUMBER_INT ); $valid_nonce = wp_verify_nonce( $_POST[ 'nonce' ], $_POST[ 'action' ] ); if ( $valid_nonce && $batch_id > 0 ) { $project = TranslationProxy::get_current_project(); $project->check_status( $batch_id ); wp_send_json_success( array( 'error' => 0 ) ); } else { wp_send_json_error( __( 'Invalid request', 'sitepress' ) ); } } function translation_service_js_data($data) { $data['nonce']['translation_service_authentication'] = wp_create_nonce( 'translation_service_authentication' ); $data['nonce']['translation_service_toggle'] = wp_create_nonce( 'translation_service_toggle' ); return $data; } function _no_wpml_warning(){ ?>

WPML in order to work.', 'wpml-translation-management'), 'https://wpml.org/'); ?>

WPML versions prior 2.0.5.', 'wpml-translation-management'), 'https://wpml.org/'); ?>

display_main(); } /** * Sets up the menu items for non-admin translators pointing at the TM * and ST translators interfaces */ function menu() { if ( $this->sitepress->setup() ) { $wp_api = $this->sitepress->get_wp_api(); if ( $wp_api->current_user_can( 'wpml_manage_translation_management' ) ) { $wp_api->add_submenu_page( apply_filters( 'icl_menu_main_page', ICL_PLUGIN_FOLDER . '/menu/languages.php' ), __( 'Translations', 'wpml-translation-management' ), __( 'Translations', 'wpml-translation-management' ), 'wpml_manage_translation_management', WPML_TM_FOLDER . '/menu/translations-queue.php' ); } elseif ( (bool) $this->tm_instance->get_current_translator()->language_pairs === true ) { $wp_api->add_menu_page( __( 'Translation interface', 'wpml-translation-management' ), __( 'Translation interface', 'wpml-translation-management' ), 'translate', WPML_TM_FOLDER . '/menu/translations-queue.php', null, ICL_PLUGIN_URL . '/res/img/icon16.png' ); } } } function menu_fix_order(){ global $submenu; if(!isset($submenu[WPML_TM_FOLDER . '/menu/main.php'])) return; // Make sure 'Translations' stays at the end $found = false; foreach($submenu[WPML_TM_FOLDER . '/menu/main.php'] as $id => $sm){ if($sm[2] == WPML_TM_FOLDER . '/menu/translations-queue.php'){ $found = $sm; unset($submenu[WPML_TM_FOLDER . '/menu/main.php'][$id]); break; } } if($found){ $submenu[WPML_TM_FOLDER . '/menu/main.php'][] = $found; } } function _warn_editing_icl_translation(){ global $wpdb, $sitepress, $iclTranslationManagement; $request_get_trid = filter_input(INPUT_GET, 'trid', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $request_get_post = filter_input(INPUT_GET, 'post', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $request_get_lang = filter_input(INPUT_GET, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $post_type = false; if($request_get_trid){ $translation_id = $wpdb->get_var($wpdb->prepare(" SELECT t.translation_id FROM {$wpdb->prefix}icl_translations t JOIN {$wpdb->prefix}icl_translation_status s ON t.translation_id = s.translation_id WHERE t.trid=%d AND t.language_code=%s" , $request_get_trid, $request_get_lang)); }else{ $post_type = $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $request_get_post)); $translation_id = $wpdb->get_var($wpdb->prepare(" SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s AND language_code=%s" , $request_get_post, 'post_' . $post_type, $request_get_lang)); } if($translation_id){ $translation_status = $wpdb->get_var($wpdb->prepare(" SELECT status FROM {$wpdb->prefix}icl_translation_status WHERE translation_id=%d" , $translation_id)); if(!is_null($translation_status) && $translation_status > 0 && $translation_status != ICL_TM_DUPLICATE && $translation_status < ICL_TM_COMPLETE){ echo '

'. sprintf(__('Warning: You are trying to edit a translation that is currently in the process of being added using WPML.' , 'wpml-translation-management')) . '

'. sprintf(__('Please refer to the Translation management dashboard for the exact status of this translation.' , 'wpml-translation-management'), admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/main.php&')) . '

'; }else{ $is_original = false; if($post_type) { $element_language_details = $sitepress->get_element_language_details($request_get_post, 'post_' . $post_type); $is_original = !$element_language_details->source_language_code; } if(!$is_original && $iclTranslationManagement->settings['doc_translation_method'] == ICL_TM_TMETHOD_EDITOR){ ?>

Warning: You are trying to edit a translation using the standard WordPress editor but your site is configured to use the WPML Translation Editor.' , 'wpml-translation-management')?>

is_translated_post_type($post_type)) && $iclTranslationManagement->settings['doc_translation_method'] == ICL_TM_TMETHOD_EDITOR){ ?>

Warning: You are trying to add a translation using the standard WordPress editor but your site is configured to use the WPML Translation Editor.' , 'wpml-translation-management')?>

Translation management dashboard to send the original document to translation.' , 'wpml-translation-management'), admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/main.php')); ?>

settings['doc_translation_method'] = ICL_TM_TMETHOD_MANUAL; $iclTranslationManagement->save_settings(); exit; } function icl_dashboard_widget_content(){ global $wpdb; get_currentuserinfo(); $docs_sent = 0; $docs_completed = 0; $docs_waiting = 0; $docs_statuses = $wpdb->get_results($wpdb->prepare("SELECT status FROM {$wpdb->prefix}icl_translation_status WHERE status > %d", ICL_TM_NOT_TRANSLATED)); foreach ( $docs_statuses as $doc_status ) { if ( in_array( $doc_status->status, array( ICL_TM_COMPLETE, ICL_TM_WAITING_FOR_TRANSLATOR , ICL_TM_IN_PROGRESS) ) ) { $docs_sent += 1; if ( $doc_status->status == ICL_TM_COMPLETE ) { $docs_completed += 1; } elseif ( $doc_status->status == ICL_TM_WAITING_FOR_TRANSLATOR || $doc_status->status == ICL_TM_IN_PROGRESS ) { $docs_waiting += 1; } } } include WPML_TM_PATH . '/menu/_icl_dashboard_widget.php'; } function plugin_action_links($links, $file){ $this_plugin = basename(WPML_TM_PATH) . '/plugin.php'; if($file == $this_plugin) { $links[] = '' . __('Configure', 'wpml-translation-management') . ''; } return $links; } // Localization function plugin_localization(){ load_plugin_textdomain( 'wpml-translation-management', false, WPML_TM_FOLDER . '/locale'); } // function _icl_tm_parent_filter(){ global $sitepress; $current_language = $sitepress->get_current_language(); $request_post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $request_post_lang = filter_input(INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $request_post_parent_id = filter_input(INPUT_POST, 'parent_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $request_post_parent_all = filter_input(INPUT_POST, 'parent_all', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $sitepress->switch_lang($request_post_lang); if($request_post_type == 'page'){ $html = wp_dropdown_pages(array('echo'=>0, 'name'=>'filter[parent_id]', 'selected'=>$request_post_parent_id)); }elseif($request_post_type == 'category'){ $html = wp_dropdown_categories(array('echo'=>0, 'orderby'=>'name', 'name'=>'filter[parent_id]', 'selected'=>$request_post_parent_id)); }else{ $html = ''; } $sitepress->switch_lang($current_language); $html .= "
        "; if(is_null($request_post_parent_all) || $request_post_parent_all) { $checked = ' checked="checked"'; } else { $checked=""; } $html .= "'; $html .= "
        "; if(empty($request_post_parent_all)) { $checked = ' checked="checked"'; } else { $checked=""; } $html .= "'; echo wp_json_encode(array('html'=>$html)); exit; } function _icl_tm_toggle_promo() { global $sitepress; $value = filter_input( INPUT_POST, 'value', FILTER_VALIDATE_INT ); $iclsettings[ 'dashboard' ][ 'hide_icl_promo' ] = intval( $value ); $sitepress->save_settings( $iclsettings ); exit; } /** * @return array */ public function get_active_services() { $cache_key = 'active_services'; $cache_group = ''; $found = false; $result = wp_cache_get($cache_key, $cache_group, false, $found); if($found) return $result; $active_services = array( 'local' => array() ); $current_service = TranslationProxy::get_current_service(); if ( !is_wp_error( $current_service ) ) { if ( $current_service ) { $active_services[ $current_service->name ] = $current_service; } wp_cache_set( $cache_key, $active_services, $cache_group ); } return $active_services; } public function automatic_service_selection_action() { $this->automatic_service_selection(); } public function handle_notices_action() { $this->handle_notices(); } public function basket_extra_fields_refresh() { echo TranslationProxy_Basket::get_basket_extra_fields_inputs(); die(); } /** * If user display Translation Dashboard or Translators * * @return boolean */ function automatic_service_selection_pages() { return is_admin() && isset($_GET['page']) && $_GET['page'] == WPML_TM_FOLDER . '/menu/main.php' && ( !isset($_GET['sm']) || $_GET['sm'] == 'translators' || $_GET['sm'] == 'dashboard' ); } public function add_com_log_link( ) { require_once WPML_TM_PATH . '/inc/translation-proxy/translationproxy-com-log.class.php'; TranslationProxy_Com_Log::add_com_log_link( ); } public function service_activation_incomplete() { return $this->has_active_service() && ($this->service_requires_authentication() || $this->service_requires_translators()); } private function has_active_service() { return TranslationProxy::get_current_service() !== false; } private function service_requires_translators() { $result = false; $service_has_translators = TranslationProxy::translator_selection_available(); if ( $service_has_translators ) { $result = !$this->service_has_accepted_translators(); } return $result; } private function service_requires_authentication() { $result = false; $service_has_translators = TranslationProxy::translator_selection_available(); if ( !$service_has_translators ) { $has_custom_fields = TranslationProxy::has_custom_fields(); $custom_fields_data = TranslationProxy::get_custom_fields_data(); $result = $has_custom_fields && !$custom_fields_data; } return $result; } private function service_has_accepted_translators() { $result = false; $icl_data = TranslationProxy_Translator::get_icl_translator_status(); if ( isset( $icl_data[ 'icl_lang_status' ] ) && is_array( $icl_data[ 'icl_lang_status' ] ) ) { foreach ( $icl_data[ 'icl_lang_status' ] as $translator ) { if ( isset( $translator[ 'contract_id' ] ) && $translator[ 'contract_id' ] != 0 ) { $result = true; break; } } } return $result; } private function service_authentication_notice() { $message_id = 'current_service_authentication_required'; if ( $this->service_activation_incomplete() ) { $current_service_name = TranslationProxy::get_current_service_name(); if ( $this->is_translators_tab() ) { if ( $this->service_requires_translators() && $current_service_name == 'ICanLocalize' ) { $message = __( 'You selected %1$s as your translation service. Next, you need to add translators from %1$s to your site. Click on the "Add translators" button. Select the source and target language and choose %1$s as the source of the translator. You can add different translators between different languages.', 'wpml-translation-management' ); $button_text = __( 'Getting started with ICanLocalize', 'wpml-translation-management' ); $button_url = 'https://wpml.org/translation-service/icanlocalize/'; $notification_message = ''; $notification_message .= '

'; $notification_message .= sprintf( $message, $current_service_name ); $notification_message .= '

'; $notification_message .= '' . $button_text . ''; } } else { $service_tab_name = __( 'Translators', 'wpml-translation-management' ); $services_url = "admin.php?page=" . WPML_TM_FOLDER . "/menu/main.php&sm=translators"; $href_open = ''; $href_close = ''; $services_link = $href_open . $service_tab_name . ' Tab' . $href_close; $service_authentication_link = '' . __( 'Authenticate', 'wpml-translation-management' ) . ' button'; $service_deactivation_link = '' . __( 'Deactivate', 'wpml-translation-management' ) . ' button'; if ( TranslationProxy::get_tp_default_suid() ) { $notification_message = __( "You are using a translation service which requires authentication.", 'wpml-translation-management' ); $notification_message .= '