template_service = $template_service; $this->manager_records = $manager_records; $this->translator_records = $translator_records; $wpml_wp_api = new WPML_WP_API(); $this->admin_sections = WPML\Container\make( 'WPML_TM_Admin_Sections' ); $this->admin_sections->init_hooks(); parent::__construct(); } protected function render_main() { if ( ! AteApiLock::isLocked() ) { ?>

should_show_wizard() ) { ?>

' . esc_html__( "WPML's Translation Management", 'wpml-translation-management' ) . ''; echo sprintf( esc_html__( 'Before you can use %s, you need to complete this quick setup.', 'wpml-translation-management' ), $link ); ?>

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(); /** @var \WPML_TM_Admin_Sections $admin_sections */ foreach ( $this->admin_sections->get_tab_items() as $slug => $tab_item ) { $this->tab_items[ $slug ] = $tab_item; } $this->build_translation_jobs_item(); $this->build_tp_com_log_item(); $this->reorder_items(); } /** * It reorders all items based on their `order` key as well as the order (index) they were added. */ private function reorder_items() { $order_of_sections = array(); $tab_items = $this->tab_items; foreach ( $tab_items as $key => $value ) { $order_of_sections[ $key ] = (int) $value['order']; } if ( array_multisort( $order_of_sections, SORT_ASC, $tab_items ) ) { $this->tab_items = $tab_items; } } public function should_show_wizard() { $current_user_id = get_current_user_id(); if ( get_option( WPML_TM_Wizard_Options::WIZARD_COMPLETE_FOR_MANAGER, false ) || // Allow for pre 4.2.5 setting get_user_option( WPML_TM_Wizard_Options::WIZARD_COMPLETE_FOR_MANAGER, $current_user_id ) || get_user_option( self::SKIP_TM_WIZARD_META_KEY, $current_user_id ) ) { return false; } if ( ! current_user_can( WPML_Manage_Translations_Role::CAPABILITY ) ) { return false; } if ( ! $this->is_wizard_running() && ( $this->translator_records->get_number_of_users_with_capability() || $this->is_any_translation_service_active() ) ) { update_user_option( $current_user_id, WPML_TM_Wizard_Options::WIZARD_COMPLETE_FOR_MANAGER, true ); return false; } return true; } private function is_wizard_running() { return get_option( WPML_TM_Wizard_Options::CURRENT_STEP, false ); } private function is_any_translation_service_active() { $is_active = TranslationProxy::get_current_service(); $has_preferred = TranslationProxy::has_preferred_translation_service(); return ( $is_active !== false || $has_preferred ) ? true : false; } private function build_dashboard_item() { $this->tab_items['dashboard'] = array( 'caption' => __( 'Translation Dashboard', 'wpml-translation-management' ), 'current_user_can' => array( WPML_Manage_Translations_Role::CAPABILITY, 'manage_options' ), 'callback' => array( $this, 'build_content_dashboard' ), 'order' => 100, ); } 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 */ 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(); if ( isset( $_COOKIE['wp-translation_dashboard_filter'] ) ) { parse_str( $_COOKIE['wp-translation_dashboard_filter'], $this->translation_filter ); $this->translation_filter = filter_var_array( $this->translation_filter, array( 'type' => FILTER_SANITIZE_STRING, 'parent_type' => FILTER_SANITIZE_STRING, 'parent_id' => FILTER_SANITIZE_NUMBER_INT, 'from_lang' => FILTER_SANITIZE_STRING, 'to_lang' => FILTER_SANITIZE_STRING, 'tstatus' => FILTER_SANITIZE_NUMBER_INT, 'status' => FILTER_SANITIZE_STRING, 'translation_priority' => FILTER_SANITIZE_NUMBER_INT, 'title' => FILTER_SANITIZE_STRING, 'sort_by' => FILTER_SANITIZE_STRING, 'sort_order' => FILTER_SANITIZE_STRING, ) ); } 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 ); } ?>
get_translate_tooltip_text(); if ( $translate_radio_message ) { return ' class="js-otgs-popover-tooltip" data-tippy-zIndex="999999" title="' . esc_attr( $translate_radio_message ) . '"'; } return null; } private function get_translate_tooltip_text() { if ( ! wpml_tm_load_blog_translators()->has_translators() ) { if ( ! wpml_translation_management()->has_active_service() ) { /* translators: This text will be used to build a link to the translation roles page */ $translators_link = $this->get_translation_roles_link( __( 'at least one translator', 'wpml-translation-management' ) ); /* translators: This text will be used to build a link to the translation services page */ $translation_services_link = $this->get_translation_services_link( __( 'active and authenticated translation service', 'wpml-translation-management' ) ); /* translators: %1$s contains a link to the translation roles page with "at least one translator" as a text whilst %2$s is a link to the translation services page with "active and authenticated translation service" as a text */ $tooltip_text = __( 'To send content to translation first make sure you either have %1$s or an %2$s.', 'wpml-translation-management' ); return sprintf( $tooltip_text, $translators_link, $translation_services_link ); } if ( wpml_translation_management()->service_activation_incomplete() ) { /* translators: %s is replaced with the name of the active translation service */ $tooltip_text = __( 'To send content to translation first make sure "%s" is authenticated or you have at least one translator.', 'wpml-translation-management' ); $translation_services_link = $this->get_translation_services_link( TranslationProxy::get_current_service_name() ); return sprintf( $tooltip_text, $translation_services_link ); } } return null; } private function build_content_dashboard_documents_options() { global $wpdb; $translate_checked = 'checked="checked"'; $duplicate_checked = ''; $do_nothing_checked = ''; $flag_factory = new WPML_Flags_Factory( $wpdb ); $flags = $flag_factory->create(); $translate_radio_text = __( 'Translate', 'wpml-translation-management' ); $translate_tooltip_attributes = $this->get_translate_tooltip_attributes(); if ( $translate_tooltip_attributes ) { $translate_checked = 'disabled="disabled"'; $do_nothing_checked = 'checked="checked"'; } ?>
active_languages as $lang ) : ?> translation_filter['from_lang'] ) { continue; } $radio_prefix_html = '
<?php echo esc_url( sprintf( __( 'Flag for %s', 'wpml-translation-management' ), $lang['code'] ) ); ?>
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(); } } } /** * @return bool */ private function current_user_can_manage_translations() { return current_user_can( WPML_Manage_Translations_Role::CAPABILITY ); } 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' ), 'order' => 101, ); } } /** * @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( __( '%1$s|WPML|%2$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 ); $utility = make( Utility::class ); $target_languages = $utility->getTargetLanguages(); $isTheOnlyAvailableTranslator = $utility->isTheOnlyAvailableTranslatorForTargetLanguages( $target_languages ); $translators_dropdowns = \wpml_collect( $target_languages )->pluck( 'code', 'code' ) ->map( [ $this, 'get_translators_dropdown' ] ); $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' ); $translation_service_enabled = $this->is_translation_service_enabled(); $model = array( 'strings' => array( 'heading_basket_name' => __( '2. Set a batch name and deadline', 'wpml-translation-management' ), 'heading_translators' => __( '3. Choose 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' ), '_icl_nonce_rollback_basket' => wp_create_nonce( 'rollback_basket_nonce' ), ), 'translation_service_enabled' => $translation_service_enabled, 'current_user_only_translator' => $isTheOnlyAvailableTranslator, ); echo $this->template_service->show( $model, 'basket/options.twig' ); } do_action( 'wpml_translation_basket_page_after' ); } public 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, ); return wpml_tm_get_translators_dropdown()->render( $args ); } private function build_translation_jobs_item() { $jobs_repository = wpml_tm_get_jobs_repository(); $jobs_count = $jobs_repository->get_count( new WPML_TM_Jobs_Search_Params() ); if ( $jobs_count ) { $this->tab_items['jobs'] = array( 'caption' => __( 'Translation Jobs', 'wpml-translation-management' ), 'current_user_can' => WPML_Manage_Translations_Role::CAPABILITY, 'callback' => array( $this, 'build_content_translation_jobs' ), 'order' => 100000, ); } } public function build_content_translation_jobs() { echo "
"; } private function build_tp_com_log_item() { if ( isset( $_GET['sm'] ) && 'com-log' === $_GET['sm'] ) { $this->tab_items['com-log'] = array( 'caption' => __( 'Communication Log', 'wpml-translation-management' ), 'current_user_can' => 'manage_options', 'callback' => array( $this, 'build_tp_com_log' ), 'order' => 1000000, ); } } 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(); ?>








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; } protected function get_page_slug() { return WPML_Translation_Management::PAGE_SLUG_MANAGEMENT; } protected function get_default_tab() { return 'dashboard'; } /** * @return bool|\TranslationProxy_Service|\WP_Error */ private function is_translation_service_enabled() { $translation_service_enabled = TranslationProxy::get_current_service(); if ( is_wp_error( $translation_service_enabled ) ) { $translation_service_enabled = false; } return $translation_service_enabled; } /** * @return string */ private function get_translation_roles_link( $text ) { return $this->get_tm_menu_link( WPML_TM_Translation_Roles_Section::SLUG, $text ); } /** * @return string */ private function get_translation_services_link( $text ) { return $this->get_tm_menu_link( Section::SLUG, $text ); } private function get_tm_menu_link( $section, $text ) { $admin_url = admin_url( 'admin.php' ); $args = array( 'page' => urlencode( WPML_TM_FOLDER . WPML_Translation_Management::PAGE_SLUG_MANAGEMENT ), 'sm' => urlencode( $section ), ); $menu_link_url = add_query_arg( $args, $admin_url ); return '' . esc_html( $text ) . ''; } }