template_service = $template_service; $this->manager_records = $manager_records; $this->translator_records = $translator_records; $logger_settings = new WPML_Jobs_Fetch_Log_Settings(); $wpml_wp_api = new WPML_WP_API(); $this->logger_ui = new WPML_Jobs_Fetch_Log_UI( $logger_settings, $wpml_wp_api ); parent::__construct(); } protected function render_main() { ?>

should_show_wizard_for_administrator() ) { $tm_wizard = new WPML_TM_Wizard_For_Admin(); echo $tm_wizard->render(); } else { if ( $this->should_show_wizard_for_manager() ) { $tm_strings_factory = new WPML_TM_Scripts_Factory(); $tm_wizard = new WPML_TM_Wizard_For_Manager( $tm_strings_factory ); echo $tm_wizard->render(); } else { do_action( 'icl_tm_messages' ); $this->build_tab_items(); $this->render_items(); } } ?>
tab_items = array(); $this->build_dashboard_item(); $this->build_basket_item(); foreach( $this->get_admin_section_factories() as $factory ) { /** @var IWPML_TM_Admin_Section_Factory $factory */ if ( in_array( 'IWPML_TM_Admin_Section_Factory', class_implements( $factory ), true ) ) { $sections_factory = new $factory; $section = $sections_factory->create(); /** @var IWPML_TM_Admin_Section $section */ if ( in_array( 'IWPML_TM_Admin_Section', class_implements( $section ), true ) && $section->is_visible() ) { $this->tab_items[ $section->get_slug() ] = array( 'caption' => $section->get_caption(), 'current_user_can' => $section->get_capabilities(), 'callback' => $section->get_callback(), ); } } } $this->build_translation_jobs_item(); $this->build_tp_com_log_item(); $this->build_tp_pickup_log_item(); } private function should_show_wizard_for_manager() { if ( get_option( WPML_TM_Wizard_For_Manager_Options::WIZARD_COMPLETE, false ) || get_user_option( self::SKIP_TM_WIZARD_META_KEY, get_current_user_id() ) ) { return false; } return current_user_can( WPML_Manage_Translations_Role::CAPABILITY ) && ( ( 0 === $this->translator_records->get_number_of_users_with_capability() && ! $this->is_any_translation_service_active() ) || $this->is_wizard_for_manager_running() ); } private function is_wizard_for_manager_running() { return get_option( WPML_TM_Wizard_For_Manager_Options::CURRENT_STEP, false ); } private function is_any_translation_service_active() { $is_active = TranslationProxy::get_current_service(); return $feedback = ( $is_active !== false ? true : false ); } private function build_dashboard_item() { $this->tab_items['dashboard'] = array( 'caption' => esc_html__( 'Translation Dashboard', 'wpml-translation-management' ), 'current_user_can' => array( WPML_Manage_Translations_Role::CAPABILITY, 'manage_options' ), 'callback' => array( $this, 'build_content_dashboard' ), ); } public function build_content_dashboard() { /** @var SitePress $sitepress */ global $sitepress; $this->active_languages = $sitepress->get_active_languages(); $this->translatable_types = apply_filters( 'wpml_tm_dashboard_translatable_types', $sitepress->get_translatable_documents() ); $this->build_dashboard_data(); if ( $this->found_documents > $this->documents || $this->there_are_hidden_posts() ) { $this->display_hidden_posts_message(); } $this->build_content_dashboard_remote_translations_controls(); $this->build_content_dashboard_filter(); $this->build_content_dashboard_results(); } /** * Used only by unit tests at the moment * @return mixed */ private function build_dashboard_data() { $this->build_dashboard_filter_arguments(); $this->build_dashboard_documents(); } private function build_dashboard_filter_arguments() { global $sitepress, $iclTranslationManagement; $this->current_language = $sitepress->get_current_language(); $this->source_language = TranslationProxy_Basket::get_source_language(); $action = isset( $_GET['action'] ) ? filter_var( $_GET['action'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : ''; if ( $action && 'reset' === $action ) { unset( $_SESSION[ 'translation_dashboard_filter' ] ); } if ( isset( $_SESSION[ 'translation_dashboard_filter' ] ) ) { $this->translation_filter = $_SESSION[ 'translation_dashboard_filter' ]; } if ( $this->source_language || ! isset( $this->translation_filter[ 'from_lang' ] ) ) { if ( $this->source_language ) { $this->translation_filter[ 'from_lang' ] = $this->source_language; } else { $this->translation_filter[ 'from_lang' ] = $this->current_language; if ( array_key_exists( 'lang', $_GET ) && $lang = filter_var( $_GET['lang'] , FILTER_SANITIZE_STRING, FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) { $this->translation_filter[ 'from_lang' ] = $lang; } } } if (!isset($this->translation_filter['to_lang'])) { $this->translation_filter['to_lang'] = ''; if ( array_key_exists( 'to_lang', $_GET ) && $lang = filter_var( $_GET['to_lang'] , FILTER_SANITIZE_STRING, FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) { $this->translation_filter[ 'to_lang' ] = $lang; } } if ($this->translation_filter['to_lang'] == $this->translation_filter['from_lang']) { $this->translation_filter['to_lang'] = false; } if (!isset($this->translation_filter['tstatus'])) { $this->translation_filter['tstatus'] = isset($_GET['tstatus']) ? $_GET['tstatus'] : -1; // -1 == All documents } if (!isset($this->translation_filter['sort_by']) || !$this->translation_filter['sort_by']) { $this->translation_filter['sort_by'] = 'date'; } if (!isset($this->translation_filter['sort_order']) || !$this->translation_filter['sort_order']) { $this->translation_filter['sort_order'] = 'DESC'; } if ( ! isset( $this->translation_filter['type'] ) ) { $this->translation_filter['type'] = 'page'; } $sort_order_next = $this->translation_filter['sort_order'] == 'ASC' ? 'DESC' : 'ASC'; $this->dashboard_title_sort_link = 'admin.php?page=' . WPML_TM_FOLDER . $this->get_page_slug() . '&sm=dashboard&icl_tm_action=sort&sort_by=title&sort_order=' . $sort_order_next; $this->dashboard_date_sort_link = 'admin.php?page=' . WPML_TM_FOLDER . $this->get_page_slug() . '&sm=dashboard&icl_tm_action=sort&sort_by=date&sort_order=' . $sort_order_next; $this->post_statuses = array( 'publish' => __('Published', 'wpml-translation-management'), 'draft' => __('Draft', 'wpml-translation-management'), 'pending' => __('Pending Review', 'wpml-translation-management'), 'future' => __('Scheduled', 'wpml-translation-management'), 'private' => __('Private', 'wpml-translation-management') ); $this->post_statuses = apply_filters('wpml_tm_dashboard_post_statuses', $this->post_statuses); $this->translation_priorities = new WPML_TM_Translation_Priorities(); // Get the document types that we can translate /** * attachments are excluded * @since 2.6.0 */ add_filter( 'wpml_tm_dashboard_translatable_types', array( $this, 'exclude_attachments' ) ); $this->post_types = $sitepress->get_translatable_documents(); $this->post_types = apply_filters('wpml_tm_dashboard_translatable_types', $this->post_types); $this->build_external_types(); $this->selected_languages = array(); if (!empty($iclTranslationManagement->dashboard_select)) { $this->selected_posts = $iclTranslationManagement->dashboard_select['post']; $this->selected_languages = $iclTranslationManagement->dashboard_select['translate_to']; } if (isset($this->translation_filter['icl_selected_posts'])) { parse_str($this->translation_filter['icl_selected_posts'], $this->selected_posts); } $this->filter_post_status = isset($this->translation_filter['status']) ? $this->translation_filter['status'] : false; if ( isset( $_GET[ 'type' ] ) ) { $this->translation_filter[ 'type' ] = $_GET[ 'type' ]; } $paged = (int) filter_input( INPUT_GET, 'paged', FILTER_SANITIZE_NUMBER_INT ); $this->translation_filter['page'] = $paged ? $paged - 1 : 0; $this->filter_translation_type = isset( $this->translation_filter[ 'type' ] ) ? $this->translation_filter[ 'type' ] : false; } private function build_dashboard_documents() { global $wpdb, $sitepress; $wpml_tm_dashboard_pagination = new WPML_TM_Dashboard_Pagination(); $wpml_tm_dashboard_pagination->add_hooks(); $tm_dashboard = new WPML_TM_Dashboard( $wpdb, $sitepress ); $this->translation_filter['limit_no'] = $this->dashboard_pagination ? $this->dashboard_pagination->get_items_per_page() : 20; $dashboard_data = $tm_dashboard->get_documents( $this->translation_filter ); $this->documents = $dashboard_data['documents']; $this->found_documents = $dashboard_data['found_documents']; } /** * @return bool */ private function there_are_hidden_posts() { return -1 === $this->found_documents; } private function display_hidden_posts_message() { ?>

' . esc_html__( 'Help', 'wpml-translation-management' ) . '' ) ?>

build_content_dashboard_fetch_translations_box(); $active_service = icl_do_not_promote() ? false : TranslationProxy::get_current_service(); $service_dashboard_info = TranslationProxy::get_service_dashboard_info(); if ( $active_service && $service_dashboard_info ) { ?>

name . ' ' . __( 'account status', 'wpml-translation-management' ) ?>

build_content_dashboard_documents(); $this->heading( __( '2. Select translation options', 'wpml-translation-management' ) ); $this->build_content_dashboard_documents_options(); do_action('wpml_tm_dashboard_promo'); ?>
build_content_dashboard_documents_head_footer_cells(); ?> build_content_dashboard_documents_head_footer_cells(); ?> build_content_dashboard_documents_body(); ?>
0' ) ?> ' ); ?>
dashboard_pagination && ! empty( $this->translation_filter['type'] ) ) { do_action( 'wpml_tm_dashboard_pagination', $this->dashboard_pagination->get_items_per_page(), $this->found_documents ); } ?>
is_translation_locked() ) { $translate_checked = 'disabled="disabled"'; $do_nothing_checked = 'checked="checked"'; } $flag_factory = new WPML_Flags_Factory( $wpdb ); $flags = $flag_factory->create(); $translate_radio_text = esc_html__( 'Translate', 'wpml-translation-management' ); if ( ! current_user_can( WPML_Manage_Translations_Role::CAPABILITY ) ) { $translators_tab_url = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=translators' ); $translation_manager_link = '' . __( 'Translation Managers', 'wpml-translation-management' ) . ''; $translate_message = esc_html( sprintf( _x( "Only %s can add translations to the site. You can assign a different WordPress user to be the site's Translation Manager or make yourself a Translation Manager.", '%s is a the words "Translation Managers" as a link', 'wpml-translation-management' ), $translation_manager_link ) ); $translate_radio_text .= '' . $translate_message . ''; } ?>
active_languages as $lang ): ?> translation_filter[ 'from_lang' ] ) { continue; } $radio_prefix_html = '
selected_languages ) && empty( $this->selected_posts ), true, false); $tm_jobs_submit_caption = __( 'Add selected content to translation basket', 'wpml-translation-management' ); ?>
/> build_content_dashboard_documents_sorting_link( $this->dashboard_title_sort_link, $dashboard_title_sort_caption, 'p.post_title' ); ?> get_active_languages(); $lang_count = count( $active_languages ); $lang_col_width = ( $lang_count - 1 ) * 26 . "px"; if ($lang_count > 10) { $lang_col_width = '30%'; } ?> translation_filter['to_lang'] && array_key_exists( $this->translation_filter['to_lang'], $active_languages ) ) { $lang = $active_languages[ $this->translation_filter['to_lang'] ]; ?> <?php echo esc_attr($this->translation_filter[ 'to_lang' ]) ?> translation_filter['from_lang'] ) { continue; } ?> <?php echo esc_attr($lang[ 'code' ]) ?> build_content_dashboard_documents_sorting_link( $this->dashboard_date_sort_link, $dashboard_date_sort_label, 'p.post_date' ); ?> documents ) {?> create(), $single_process_factory->create(), class_exists( 'WPML_ST_Package_Factory' ) ? new WPML_ST_Package_Factory() : null ); wp_nonce_field( 'save_translator_note_nonce', '_icl_nonce_stn_' ); $active_languages = $this->translation_filter[ 'to_lang' ] ? array( $this->translation_filter[ 'to_lang' ] => $this->active_languages[ $this->translation_filter[ 'to_lang' ] ] ) : $this->active_languages; foreach ( $this->documents as $doc ) { $selected = is_array( $this->selected_posts ) && in_array( $doc->ID, $this->selected_posts ); $doc_row = new WPML_TM_Dashboard_Document_Row( $doc, $this->translation_filter, $this->post_types, $this->post_statuses, $active_languages, $selected, $sitepress, $translatable_element_provider ); $doc_row->display(); } } } private function is_translation_locked() { global $WPML_Translation_Management; $locked = $WPML_Translation_Management->service_activation_incomplete(); $locked |= ! current_user_can( WPML_Manage_Translations_Role::CAPABILITY ); return $locked; } private function build_content_dashboard_documents_sorting_link( $url, $label, $filter_argument ) { $caption = $label; if ( $this->translation_filter[ 'sort_by' ] === $filter_argument ) { $caption .= ' '; $caption .= $this->translation_filter[ 'sort_order' ] === 'ASC' ? '↑' : '↓'; } ?> 0 ) { $this->tab_items['basket'] = array( 'caption' => $this->build_basket_item_caption( $basket_items_count ), 'current_user_can' => WPML_Manage_Translations_Role::CAPABILITY, 'callback' => array( $this, 'build_content_basket' ), ); } } /** * @param int $basket_items_count * * @return string */ private function build_basket_item_caption( $basket_items_count = 0 ) { if ( isset( $_GET[ 'clear_basket' ] ) && $_GET[ 'clear_basket' ] ) { $basket_items_count = 0; } else { if (! is_numeric( $basket_items_count )) { $basket_items_count = TranslationProxy_Basket::get_basket_items_count( true ); } if ( isset( $_GET[ 'action' ], $_GET[ 'id' ] ) && $_GET[ 'action' ] === 'delete' && $_GET[ 'id' ] ) { -- $basket_items_count; } } $basket_items_count_caption = esc_html__('Translation Basket', 'wpml-translation-management'); if ($basket_items_count > 0) { $basket_item_count_badge = '' . $basket_items_count . ''; $basket_items_count_caption .= $basket_item_count_badge; } return $basket_items_count_caption; } public function build_content_basket() { $basket_table = new SitePress_Table_Basket(); do_action( 'wpml_tm_before_basket_items_display' ); $basket_table->prepare_items(); $action_url = esc_attr( 'admin.php?page=' . WPML_TM_FOLDER . $this->get_page_slug() . '&sm=' . $_GET[ 'sm' ] ); $this->heading( __( '1. Review documents for translation', 'wpml-translation-management' ) ); ?>
display(); ?>
build_translation_options(); } private function build_translation_options() { global $sitepress, $wpdb; $basket_items_number = TranslationProxy_Basket::get_basket_items_count( true ); if ( $basket_items_number > 0 ) { $deadline_estimate_factory = new WPML_TM_Jobs_Deadline_Estimate_Factory(); $deadline_estimate_date = $deadline_estimate_factory->create()->get( TranslationProxy_Basket::get_basket(), array( 'translator_id' => TranslationProxy_Service::get_wpml_translator_id(), 'service' => TranslationProxy::get_current_service_id(), ) ); $basket_name_max_length = TranslationProxy::get_current_service_batch_name_max_length(); $source_language = TranslationProxy_Basket::get_source_language(); $basket = new WPML_Translation_Basket( $wpdb ); $basket_name_placeholder = sprintf( __( "%s|WPML|%s", 'wpml-translation-management' ), htmlspecialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $source_language ); $basket_name_placeholder = $basket->get_unique_basket_name( $basket_name_placeholder, $basket_name_max_length ); $basket_languages = TranslationProxy_Basket::get_target_languages(); $target_languages = array(); $translators_dropdowns = array(); if ( $basket_languages ) { $target_languages = $sitepress->get_active_languages(); foreach ( $target_languages as $key => $lang ) { if ( ! in_array( $lang['code'], $basket_languages, true ) || TranslationProxy_Basket::get_source_language() === $lang['code'] ) { unset( $target_languages[ $key ] ); } else { $translators_dropdowns[ $lang['code'] ] = $this->get_translators_dropdown( $lang['code'] ); $target_languages[ $lang['code'] ]['flag'] = $sitepress->get_flag_img( $lang['code'] ); } } } $tooltip_content = esc_html__( 'This deadline is what WPML suggests according to the amount of work that you already sent to this translator. You can modify this date to set the deadline manually.', 'wpml-translation-management' ); try { $translation_service_enabled = false !== TranslationProxy::get_current_service(); } catch ( WPMLTranslationProxyApiException $ex ) { $translation_service_enabled = false; } $model = array( 'strings' => array( 'heading_basket_name' => __( '2. Set a batch name and deadline', 'wpml-translation-management' ), 'heading_translators' => __( '3. Choose local translator or Translation Service', 'wpml-translation-management' ), 'batch_name_label' => __( 'Batch name:', 'wpml-translation-management' ), 'batch_name_desc' => __( 'Give a name to the batch. If omitted, the default name will be applied.', 'wpml-translation-management' ), 'column_language' => __( 'Language pair', 'wpml-translation-management' ), 'column_translator' => __( 'Translator', 'wpml-translation-management' ), 'pro_translation_tip' => __( 'Did you know that you can also set Translation Services and professional translators will handle your translation?', 'wpml-translation-management' ), 'batch_deadline_label' => __( 'Suggested deadline:', 'wpml-translation-management' ), 'batch_deadline_tooltip' => $tooltip_content, 'button_send_all' => __( 'Send all items for translation', 'wpml-translation-management' ), ), 'source_language' => $sitepress->get_language_details( $source_language ), 'source_language_flag' => $sitepress->get_flag_img( $source_language ), 'basket_name_max_length' => $basket_name_max_length, 'basket_name_placeholder' => $basket_name_placeholder, 'target_languages' => $target_languages, 'dropdowns_translators' => $translators_dropdowns, 'pro_translation_link' => '
' . __( 'Check available Translation Services', 'wpml-translation-management' ) . '', 'deadline_estimation_date' => $deadline_estimate_date, 'extra_basket_fields' => TranslationProxy_Basket::get_basket_extra_fields_section(), 'nonces' => array( '_icl_nonce_send_basket_items' => wp_create_nonce( 'send_basket_items_nonce' ), '_icl_nonce_send_basket_item' => wp_create_nonce( 'send_basket_item_nonce' ), '_icl_nonce_send_basket_commit' => wp_create_nonce( 'send_basket_commit_nonce' ), '_icl_nonce_check_basket_name' => wp_create_nonce( 'check_basket_name_nonce' ), '_icl_nonce_refresh_deadline' => wp_create_nonce( 'wpml-tm-jobs-deadline-estimate-ajax-action' ), ), 'translation_service_enabled' => $translation_service_enabled ); echo $this->template_service->show( $model, 'basket/options.twig' ); } do_action( 'wpml_translation_basket_page_after' ); } private function get_translators_dropdown( $lang_code ) { $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() ), 'echo' => false, ); $blog_translators = wpml_tm_load_blog_translators(); $translators_dropdown = new WPML_TM_Translators_Dropdown( $blog_translators ); return $translators_dropdown->render( $args ); } private function build_translation_jobs_item() { $this->tab_items['jobs'] = array( 'caption' => esc_html__( 'Translation Jobs', 'wpml-translation-management' ), 'current_user_can' => WPML_Manage_Translations_Role::CAPABILITY, 'callback' => array( $this, 'build_content_translation_jobs' ), ); } public function build_content_translation_jobs() { ?>
tab_items['com-log']['caption'] = esc_html__( 'Communication Log', 'wpml-translation-management' ); $this->tab_items['com-log']['callback'] = array( $this, 'build_tp_com_log' ); $this->tab_items['com-log']['current_user_can'] = 'manage_options'; } } public function build_tp_com_log( ) { if ( isset( $_POST[ 'tp-com-clear-log' ] ) ) { WPML_TranslationProxy_Com_Log::clear_log( ); } if ( isset( $_POST[ 'tp-com-disable-log' ] ) ) { WPML_TranslationProxy_Com_Log::set_logging_state( false ); } if ( isset( $_POST[ 'tp-com-enable-log' ] ) ) { WPML_TranslationProxy_Com_Log::set_logging_state( true ); } $action_url = esc_attr( 'admin.php?page=' . WPML_TM_FOLDER . $this->get_page_slug() . '&sm=' . $_GET[ 'sm' ] ); $com_log = WPML_TranslationProxy_Com_Log::get_log( ); ?>








get_ui_key() === $_GET['sm'] ) { $this->tab_items[ $logger_settings->get_ui_key() ]['caption'] = esc_html__( 'Content updates log', 'wpml-translation-management' ); $this->tab_items[ $logger_settings->get_ui_key() ]['callback'] = array( $this, 'build_tp_pickup_log' ); $this->tab_items[ $logger_settings->get_ui_key() ]['current_user_can'] = 'manage_options'; } } public function build_tp_pickup_log() { $this->logger_ui->render(); } /** * @return array */ private function get_admin_section_factories() { $admin_sections_factories = array( 'WPML_TM_Translation_Roles_Section_Factory', 'WPML_TM_Translation_Services_Admin_Section_Factory', ); return apply_filters( 'wpml_tm_admin_sections_factories', $admin_sections_factories ); } public function get_dashboard_documents(){ return $this->documents; } public function build_content_dashboard_filter() { global $wpdb; $dashboard_filter = new WPML_TM_Dashboard_Display_Filter( $this->active_languages, $this->source_language, $this->translation_filter, $this->post_types, $this->post_statuses, $this->translation_priorities->get_values(), $wpdb ); $dashboard_filter->display(); } private function build_external_types() { $this->post_types = apply_filters( 'wpml_get_translatable_types', $this->post_types ); foreach ( $this->post_types as $id => $type_info ) { if ( isset( $type_info->prefix ) ) { // this is an external type returned by wpml_get_translatable_types $new_type = new stdClass(); $new_type->labels = new stdClass(); $new_type->labels->singular_name = isset( $type_info->labels->singular_name ) ? $type_info->labels->singular_name : $type_info->label; $new_type->labels->name = isset( $type_info->labels->name ) ? $type_info->labels->name : $type_info->label; $new_type->prefix = $type_info->prefix; $new_type->external_type = 1; $this->post_types[ $id ] = $new_type; } } } /** * @param array $post_types * * @since 2.6.0 * * @return array */ public function exclude_attachments( $post_types ) { unset( $post_types['attachment'] ); return $post_types; } private function should_show_wizard_for_administrator() { $current_user_id = get_current_user_id(); if ( isset( $_GET['skip_wizard'] ) && '1' === $_GET['skip_wizard'] ) { update_user_option( $current_user_id, self::SKIP_TM_WIZARD_META_KEY , true ); return false; } if ( get_user_option( self::SKIP_TM_WIZARD_META_KEY, $current_user_id ) ) { return false; } return $this->manager_records->get_number_of_users_with_capability() === 0; } protected function get_page_slug() { return WPML_Translation_Management::PAGE_SLUG_MANAGEMENT; } protected function get_default_tab() { return 'dashboard'; } }