ACIL FM
Dark
Refresh
Current DIR:
/home/mhhtmff/www/site/wp-content/plugins/sitepress-multilingual-cms
/
home
mhhtmff
www
site
wp-content
plugins
sitepress-multilingual-cms
Upload
Zip Selected
Delete Selected
Pilih semua
Nama
Ukuran
Permission
Aksi
addons
-
chmod
Open
Rename
Delete
API
-
chmod
Open
Rename
Delete
classes
-
chmod
Open
Rename
Delete
compatibility
-
chmod
Open
Rename
Delete
dist
-
chmod
Open
Rename
Delete
docs
-
chmod
Open
Rename
Delete
inc
-
chmod
Open
Rename
Delete
lib
-
chmod
Open
Rename
Delete
locale
-
chmod
Open
Rename
Delete
menu
-
chmod
Open
Rename
Delete
modules
-
chmod
Open
Rename
Delete
res
-
chmod
Open
Rename
Delete
templates
-
chmod
Open
Rename
Delete
vendor
-
chmod
Open
Rename
Delete
ajax.php
18.27 MB
chmod
View
DL
Edit
Rename
Delete
license.txt
34.32 MB
chmod
View
DL
Edit
Rename
Delete
readme.txt
52 B
chmod
View
DL
Edit
Rename
Delete
sitepress.class.php
157.78 MB
chmod
View
DL
Edit
Rename
Delete
sitepress.php
16.43 MB
chmod
View
DL
Edit
Rename
Delete
tm.php
9.03 MB
chmod
View
DL
Edit
Rename
Delete
wpml-config.xml
16.51 MB
chmod
View
DL
Edit
Rename
Delete
wpml-dependencies.json
255 B
chmod
View
DL
Edit
Rename
Delete
Edit file: /home/mhhtmff/www/site/wp-content/plugins/sitepress-multilingual-cms/sitepress.class.php
<?php use WPML\FP\Fns; use WPML\FP\Logic; use WPML\FP\Obj; use WPML\FP\Str; use WPML\LIB\WP\Url; use function WPML\FP\pipe; /** * Main SitePress Class * * @package wpml-core */ class SitePress extends WPML_WPDB_User implements IWPML_Current_Language, IWPML_Taxonomy_State, \WPML\Core\ISitePress { const AFTER_ST_PLUGIN_LOADED_HOOK = - PHP_INT_MAX + 1; /** @var WPML_Taxonomy_Translation */ private $taxonomy_translation; private $template_real_path; /** @var WPML_Post_Translation $post_translation */ private $post_translation; /** @var WPML_Term_Translation $term_translation */ private $term_translation; /** @var WPML_Post_Duplication $post_duplication */ private $post_duplication; /** @var WPML_Term_Actions $term_actions */ private $term_actions; /** @var WPML_Admin_Scripts_Setup $scripts_handler */ private $scripts_handler; /** @var WPML_Set_Language $language_setter */ private $language_setter; /** @var WPML_Term_Query_Filter $term_query_filter */ private $term_query_filter; /** @var array $settings */ private $settings; private $active_languages = array(); private $_admin_notices = array(); private $this_lang; /** @var \WP_Query */ private $wp_query; private $admin_language; private $user_preferences = array(); /** @var WPML_WP_API $wp_api */ private $wp_api; /** @var int $loaded_blog_id */ private $loaded_blog_id; /** * @var string $original_language caches the initial language when calling * \SitePress::switch_lang() for the first time. */ private $original_language; /** * @var string $original_language_cookie caches the initial language value * in the user's cookie when calling \SitePress::switch_lang() for the * first time. */ private $original_language_cookie; /** @var WPML_Locale $locale_utils */ public $locale_utils; public $footer_preview = false; /** * @var icl_cache */ public $icl_translations_cache; /** * @var WPML_Flags */ private $flags; /** * @var icl_cache */ public $icl_language_name_cache; /** * @var icl_cache */ public $icl_term_taxonomy_cache; /** @var WPML_Term_Adjust_Id */ private $wpml_term_adjust_id = null; /** * @var array $current_request_data - Use to store temporary information during the current request */ private $current_request_data = array(); function __construct() { do_action( 'wpml_before_startup' ); /** @var array $sitepress_settings */ global $pagenow, $sitepress_settings, $wpdb, $wpml_post_translations, $locale, $wpml_term_translations; parent::__construct( $wpdb ); $this->locale_utils = new WPML_Locale( $wpdb, $this, $locale ); $sitepress_settings = WPML\LIB\WP\Option::getOrAttemptRecovery( 'icl_sitepress_settings', [] ); $this->settings = &$sitepress_settings; $this->post_translation = &$wpml_post_translations; $this->term_translation = &$wpml_term_translations; // @since 3.1 if ( is_admin() && ! $this->get_setting( 'icl_capabilities_verified' ) ) { wpml_enable_capabilities(); } if ( null === $pagenow && is_multisite() ) { include WPML_PLUGIN_PATH . '/inc/hacks/vars-php-multisite.php'; } if ( $this->settings ) { $this->verify_settings(); } if ( isset( $_GET['page'], $_GET['debug_action'] ) && WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' === $_GET['page'] ) { ob_start(); } if ( isset( $_REQUEST['icl_ajx_action'] ) ) { /** * It is very common to register a CPT on admin_init, thus * the init hook is too early in this case. This causes * malformed post guid as well as empty post content * when saving the post a second time. E.g.: Avada. */ if ( 'make_duplicates' === $_REQUEST['icl_ajx_action'] ) { add_action( 'admin_init', [ $this, 'ajax_setup' ], PHP_INT_MAX ); } else { add_action( 'init', array( $this, 'ajax_setup' ), 15 ); } } $this->initialize_cache(); $flags_factory = new WPML_Flags_Factory( $wpdb ); $this->flags = $flags_factory->create(); add_action( 'plugins_loaded', array( $this, 'plugin_localization' ), self::AFTER_ST_PLUGIN_LOADED_HOOK ); add_action( 'plugins_loaded', array( $this, 'init' ), 1 ); add_action( 'wp_loaded', array( $this, 'maybe_set_this_lang' ) ); add_action( 'switch_blog', array( $this, 'init_settings' ), 10, 1 ); // Administration menus add_action( 'admin_menu', array( $this, 'administration_menu' ) ); if ( $this->get_setting( 'existing_content_language_verified' ) && ( $this->get_setting( 'setup_complete' ) || ( ! empty( $_GET['page'] ) && $this->get_setting( 'setup_wizard_step' ) > 1 && $_GET['page'] == WPML_PLUGIN_FOLDER . '/menu/languages.php' ) ) ) { // Post/page language box add_filter( 'comment_feed_join', array( $this, 'comment_feed_join' ) ); add_filter( 'comments_clauses', array( $this, 'comments_clauses' ), 10, 2 ); // Allow us to filter the Query vars before the posts query is being built and executed add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); if ( $pagenow === 'edit.php' ) { add_action( 'quick_edit_custom_box', array( 'WPML_Terms_Translations', 'quick_edit_terms_removal' ), 10, 2 ); } add_filter( 'get_pages', array( $this, 'exclude_other_language_pages2' ), 10, 2 ); add_filter( 'wp_dropdown_pages', array( $this, 'wp_dropdown_pages' ) ); add_filter( 'get_comment_link', array( $this, 'get_comment_link_filter' ) ); $this->set_term_filters_and_hooks(); add_action( 'parse_query', array( $this, 'parse_query' ) ); // AJAX Actions for the post edit screen add_action( 'wp_ajax_wpml_save_term', array( 'WPML_Post_Edit_Ajax', 'wpml_save_term_action' ) ); add_action( 'wp_ajax_wpml_switch_post_language', array( 'WPML_Post_Edit_Ajax', 'wpml_switch_post_language' ) ); add_action( 'wp_ajax_wpml_get_default_lang', array( 'WPML_Post_Edit_Ajax', 'wpml_get_default_lang' ) ); // AJAX Actions for the taxonomy translation screen add_action( 'wp_ajax_wpml_get_terms_and_labels_for_taxonomy_table', array( 'WPML_Taxonomy_Translation_Table_Display', 'wpml_get_terms_and_labels_for_taxonomy_table' ) ); // Ajax Action for the updating of term names on the troubleshooting page add_action( 'wp_ajax_wpml_update_term_names_troubleshoot', array( 'WPML_Troubleshooting_Terms_Menu', 'wpml_update_term_names_troubleshoot' ) ); add_action( 'wp_ajax_wpml_generate_term_slug', array( $this->get_term_actions_helper(), 'generate_unique_term_slug_ajax_handler' ) ); // short circuit get default category add_filter( 'pre_option_default_category', array( $this, 'pre_option_default_category' ) ); add_filter( 'update_option_default_category', array( $this, 'update_option_default_category' ), 1, 2 ); // back end js add_action( 'admin_enqueue_scripts', array( $this, 'backend_js' ) ); add_action( 'wp_head', array( $this, 'rtl_fix' ) ); add_action( 'admin_print_styles', array( $this, 'rtl_fix' ) ); add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) ); // feeds links add_filter( 'feed_link', array( $this, 'feed_link' ) ); // commenting links add_filter( 'post_comments_feed_link', array( $this, 'post_comments_feed_link' ) ); add_filter( 'trackback_url', array( $this, 'trackback_url' ) ); add_filter( 'user_trailingslashit', array( $this, 'user_trailingslashit' ), 1, 2 ); add_filter( 'pre_option_home', array( $this, 'pre_option_home' ) ); // Filter custom type archive link (since WP 3.1) add_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10, 2 ); add_filter( 'author_link', array( $this, 'author_link' ) ); // language negotiation add_action( 'query_vars', array( $this, 'query_vars' ) ); add_filter( 'language_attributes', array( $this, 'language_attributes' ) ); add_filter( 'locale', array( $this, 'locale_filter' ), 10, 1 ); add_filter( 'pre_option_page_on_front', array( $this, 'pre_option_page_on_front' ) ); add_filter( 'pre_option_page_for_posts', array( $this, 'pre_option_page_for_posts' ) ); $sticky_posts_loader = new WPML_Sticky_Posts_Loader( $this ); $sticky_posts_loader->add_hooks(); add_filter( 'trashed_post', array( $this, 'fix_trashed_front_or_posts_page_settings' ) ); add_filter( 'delete_post', array( $this, 'fix_trashed_front_or_posts_page_settings' ) ); add_action( 'wp', array( $this, 'set_wp_query' ) ); add_action( 'personal_options_update', array( $this, 'save_user_options' ) ); add_action( 'edit_user_profile_update', array( $this, 'save_user_options' ) ); if ( ! is_admin() ) { add_action( 'wp_head', array( $this, 'meta_generator_tag' ) ); } if ( $this->is_setup_complete() ) { $icl_nav_menu = new WPML_Nav_Menu( $this, $wpdb, $wpml_post_translations, $wpml_term_translations ); $icl_nav_menu->init_hooks(); } add_action( 'wp_login', array( $this, 'reset_admin_language_cookie' ) ); $this->handle_head_hreflang(); /** * add extra debug information */ add_filter( 'icl_get_extra_debug_info', array( $this, 'add_extra_debug_info' ) ); } else { add_action( 'admin_enqueue_scripts', function () { $this->backend_js( false ); } ); } //end if the initial language is set - existing_content_language_verified add_filter( 'core_version_check_locale', array( $this, 'wp_upgrade_locale' ) ); if ( $pagenow === 'post.php' && isset( $_REQUEST['action'], $_GET['post'] ) && $_REQUEST['action'] === 'edit' ) { add_action( 'init', '_icl_trash_restore_prompt' ); } add_action( 'init', array( $this, 'register_assets' ), 2 ); add_action( 'admin_enqueue_scripts', array( $this, 'js_load' ), 2 ); // enqueue scripts - higher priority add_action( 'wp_enqueue_scripts', array( $this, 'js_load' ), 2 ); // enqueue scripts - higher priority add_filter( 'url_to_postid', array( $this, 'url_to_postid' ) ); // cron job to update WPML config index file from CDN $xml_config_log_factory = new WPML_XML_Config_Log_Factory(); $log = $xml_config_log_factory->create_log(); if ( $this->is_setup_complete() ) { $xml_config_log_notice = $xml_config_log_factory->create_notice(); $xml_config_log_notice->add_hooks(); } $wpml_config_update_integrator = new WPML_Config_Update_Integrator( $log ); $wpml_config_update_integrator->add_hooks(); add_action( 'core_upgrade_preamble', array( $this, 'update_index_screen' ) ); add_filter( 'get_search_form', array( $this, 'get_search_form_filter' ) ); $this->api_hooks(); add_action( 'wpml_loaded', array( $this, 'load_dependencies' ), 10000 ); do_action( 'wpml_after_startup' ); // Load adjust count for terms display as translated. new WPML_Term_Display_As_Translated_Adjust_Count( $this, $this->wpdb ); } /** * @since 3.2 */ public function api_hooks() { /** * @deprecated in favour of lowercased namespaces */ add_filter( 'WPML_get_setting', array( $this, 'filter_get_setting' ), 10, 2 ); /** * @deprecated in favour of lowercased namespaces */ add_filter( 'WPML_get_current_language', array( $this, 'get_current_language' ), 10, 0 ); /** * @deprecated in favour of lowercased namespaces */ add_filter( 'WPML_get_user_admin_language', array( $this, 'get_user_admin_language_filter' ), 10, 2 ); /** * @deprecated in favour of lowercased namespaces */ add_filter( 'WPML_is_admin_action_from_referer', array( $this, 'check_if_admin_action_from_referer' ), 10, 0 ); /** * @deprecated in favour of lowercased namespaces */ add_filter( 'WPML_current_user', array( $this, 'get_current_user' ), 10, 0 ); add_filter( 'wpml_get_setting', array( $this, 'filter_get_setting' ), 10, 2 ); add_action( 'wpml_set_setting', array( $this, 'action_set_setting' ), 10, 3 ); add_filter( 'wpml_get_language_cookie', array( $this, 'get_language_cookie' ), 10, 0 ); add_filter( 'wpml_current_language', array( $this, 'get_current_language' ), 10, 0 ); add_filter( 'wpml_get_user_admin_language', array( $this, 'get_user_admin_language_filter' ), 10, 2 ); add_filter( 'wpml_is_admin_action_from_referer', array( $this, 'check_if_admin_action_from_referer' ), 10, 0 ); add_filter( 'wpml_current_user', array( $this, 'get_current_user' ), 10, 0 ); add_filter( 'wpml_new_post_source_id', array( $this, 'get_new_post_source_id' ), 10, 1 ); /** * @uses \SitePress::get_translatable_documents_filter */ add_filter( 'wpml_translatable_documents', array( $this, 'get_translatable_documents_filter' ), 10, 1 ); add_filter( 'wpml_is_translated_post_type', array( $this, 'is_translated_post_type_filter' ), 10, 2 ); add_filter( 'wpml_is_display_as_translated_post_type', array( $this, 'is_display_as_translated_post_type_filter' ), 10, 2 ); add_filter( 'wpml_is_translated_taxonomy', array( $this, 'is_translated_taxonomy_filter' ), 10, 2 ); /** * @deprecated it has a wrong hook tag * @since 3.2 */ add_filter( 'wpml_get_element_translations_filter', array( $this, 'get_element_translations_filter' ), 10, 6 ); /** * @deprecated it has a wrong hook tag * @since 3.2 */ add_filter( 'wpml_get_element_translations', array( $this, 'get_element_translations_filter' ), 10, 6 ); add_filter( 'wpml_is_original_content', array( $this, 'is_original_content_filter' ), 10, 3 ); add_filter( 'wpml_original_element_id', array( $this, 'get_original_element_id_filter' ), 10, 3 ); add_filter( 'wpml_element_trid', array( $this, 'get_element_trid_filter' ), 10, 3 ); add_filter( 'wpml_is_rtl', array( $this, 'is_rtl' ) ); add_filter( 'wpml_home_url', 'wpml_get_home_url_filter', 10 ); add_filter( 'wpml_active_languages', 'wpml_get_active_languages_filter', 10, 2 ); add_filter( 'wpml_display_language_names', 'wpml_display_language_names_filter', 10, 5 ); add_filter( 'wpml_display_single_language_name', array( $this, 'get_display_single_language_name_filter' ), 10, 2 ); add_filter( 'wpml_element_link', 'wpml_link_to_element_filter', 10, 7 ); add_filter( 'wpml_object_id', 'wpml_object_id_filter', 10, 4 ); add_filter( 'wpml_translated_language_name', 'wpml_translated_language_name_filter', 10, 3 ); add_filter( 'wpml_default_language', 'wpml_get_default_language_filter', 10, 1 ); add_filter( 'wpml_post_language_details', 'wpml_get_language_information', 10, 2 ); add_action( 'wpml_add_language_form_field', 'wpml_add_language_form_field_action' ); add_shortcode( 'wpml_language_form_field', 'wpml_language_form_field_shortcode' ); add_filter( 'wpml_element_translation_type', 'wpml_get_element_translation_type_filter', 10, 3 ); add_filter( 'wpml_element_has_translations', 'wpml_element_has_translations_filter', 10, 3 ); add_filter( 'wpml_content_translations', 'wpml_get_content_translations_filter', 10, 3 ); add_filter( 'wpml_master_post_from_duplicate', 'wpml_get_master_post_from_duplicate_filter' ); add_filter( 'wpml_post_duplicates', 'wpml_get_post_duplicates_filter' ); add_filter( 'wpml_element_type', 'wpml_element_type_filter' ); add_filter( 'wpml_setting', 'wpml_get_setting_filter', 10, 3 ); add_filter( 'wpml_sub_setting', 'wpml_get_sub_setting_filter', 10, 4 ); add_filter( 'wpml_language_is_active', 'wpml_language_is_active_filter', 10, 2 ); add_action( 'wpml_admin_make_post_duplicates', 'wpml_admin_make_post_duplicates_action', 10, 1 ); add_action( 'wpml_make_post_duplicates', 'wpml_make_post_duplicates_action', 10, 1 ); add_filter( 'wpml_element_language_details', 'wpml_element_language_details_filter', 10, 2 ); add_action( 'wpml_set_element_language_details', array( $this, 'set_element_language_details_action' ), 10, 1 ); add_filter( 'wpml_element_language_code', 'wpml_element_language_code_filter', 10, 2 ); add_filter( 'wpml_elements_without_translations', 'wpml_elements_without_translations_filter', 10, 2 ); add_action( 'wpml_switch_language', 'wpml_switch_language_action', 10, 1 ); } function init() { do_action( 'wpml_before_init' ); $this->locale_utils->init(); $this->maybe_set_this_lang(); if ( function_exists( 'w3tc_add_action' ) ) { w3tc_add_action( 'w3tc_object_cache_key', 'w3tc_translate_cache_key_filter' ); } $this->get_user_preferences(); $this->set_admin_language(); // Run only if existing content language has been verified, and is front-end or settings are not corrupted if ( $this->get_setting( 'existing_content_language_verified' ) ) { add_action( 'wpml_verify_post_translations', array( $this, 'verify_post_translations_action', ), 10, 1 ); if ( 2 === (int) $this->get_setting( 'language_negotiation_type' ) ) { add_filter( 'allowed_redirect_hosts', array( $this, 'allowed_redirect_hosts' ) ); } $this->move_current_language_to_the_top(); add_filter( 'mod_rewrite_rules', array( $this, 'rewrite_rules_filter' ), 10, 1 ); if ( is_admin() && $this->get_setting( 'setup_complete' ) && ! $this->get_wp_api() ->is_translation_queue_page() && ! $this->get_wp_api() ->is_string_translation_page() ) { // Admin language switcher goes to the WP admin bar if ( apply_filters( 'wpml_show_admin_language_switcher', true ) ) { add_action( 'wp_before_admin_bar_render', array( $this, 'admin_language_switcher' ) ); } else { $this->set_this_lang( 'all' ); } } } if ( $this->is_rtl() ) { $GLOBALS['text_direction'] = 'rtl'; } if ( ! wpml_is_ajax() && is_admin() && ! $this->get_setting( 'dont_show_help_admin_notice' ) ) { if ( $this->get_setting( 'setup_complete' ) ) { WPML_Troubleshooting_Terms_Menu::display_terms_with_suffix_admin_notice(); } else { $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_URL ); if ( current_user_can( 'manage_options' ) && ! Str::includes( 'menu/setup.php', $page ) ) { add_action( 'admin_notices', array( $this, 'help_admin_notice' ) ); } } } $short_v = implode( '.', array_slice( explode( '.', ICL_SITEPRESS_VERSION ), 0, 3 ) ); if ( is_admin() && ( ! isset( $this->settings['hide_upgrade_notice'] ) || $this->get_setting( 'hide_upgrade_notice' ) !== $short_v ) ) { add_action( 'admin_notices', array( $this, 'upgrade_notice' ) ); } if ( ! defined( 'ICL_LANGUAGE_CODE' ) ) { define( 'ICL_LANGUAGE_CODE', $this->this_lang ); } $language_details = $this->get_language_details( ICL_LANGUAGE_CODE ); if ( ! defined( 'ICL_LANGUAGE_NAME' ) ) { $display_name = isset( $language_details['display_name'] ) ? $language_details['display_name'] : null; define( 'ICL_LANGUAGE_NAME', $display_name ); } if ( ! defined( 'ICL_LANGUAGE_NAME_EN' ) ) { $english_name = isset( $language_details['english_name'] ) ? $language_details['english_name'] : null; define( 'ICL_LANGUAGE_NAME_EN', $english_name ); } if ( defined( 'WPML_LOAD_API_SUPPORT' ) ) { require_once WPML_PLUGIN_PATH . '/inc/wpml-api.php'; } add_action( 'wp_footer', array( $this, 'display_wpml_footer' ), 20 ); if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { add_action( 'xmlrpc_call', array( $this, 'xmlrpc_call_actions' ) ); add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) ); } global $pagenow; // set language to default and remove language switcher when in Taxonomy Translation page // If the page uses AJAX and the language must be forced to default, please use the // if ( $pagenow == 'admin-ajax.php' )above if ( is_admin() && ( $this->is_taxonomy_related_page() || $this->is_saving_taxonomy_labels() ) ) { $this->switch_to_admin_language(); add_action( 'init', array( $this, 'remove_admin_language_switcher' ) ); } /* Posts and new inline created terms, can only be saved in an active language. * Also the content of the post-new.php should always be filtered for one specific * active language, so to display the correct taxonomy terms for selection. */ if ( $pagenow === 'post-new.php' ) { if ( ! $this->is_active_language( $this->get_current_language() ) ) { $this->switch_to_admin_language(); } } // Code to run when reactivating the plugin $recently_activated = $this->get_setting( 'just_reactivated' ); if ( $recently_activated ) { add_action( 'init', array( $this, 'rebuild_language_information' ), 1000 ); } if ( is_admin() ) { $mo_file_search = new WPML_MO_File_Search( $this ); add_action( 'after_switch_theme', array( $mo_file_search, 'reload_theme_dirs' ) ); } do_action( 'wpml_after_init' ); do_action( 'wpml_loaded', $this ); if ( isset( $_GET['page'] ) && WPML_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' === $_GET['page'] && is_admin() ) { $this->taxonomy_translation = new WPML_Taxonomy_Translation( '', array(), new WPML_UI_Screen_Options_Factory( $this ) ); } if ( WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->get_setting( 'language_negotiation_type' ) && $this->get_setting( 'language_per_domain_sso_enabled', false ) ) { $sso = new WPML_Language_Per_Domain_SSO( $this, new WPML_PHP_Functions(), new WPML_Cookie() ); $sso->init_hooks(); } } /** * Sets the current language in \SitePress::$this_lang, redirects if * frontend requests point to incomplete or incorrect urls, un-sets the * $_GET['lang'] and $_GET['admin_bar'] values so that upload.php is able to * enqueue 'media-grid' correctly without url parameters breaking its * functionality. */ public function maybe_set_this_lang() { /** @var WPML_Request $wpml_request_handler */ global $wpml_request_handler, $pagenow, $wpml_language_resolution, $mode; $isLoadingATEAutomaticTranslationWidget = strpos( $_SERVER['REQUEST_URI'], 'ate-widget' ); if ( ! defined( 'WP_ADMIN' ) && isset( $_SERVER['HTTP_HOST'] ) && ! empty( $_SERVER['HTTP_HOST'] ) && $_SERVER['HTTP_HOST'] && ! defined( 'WP_CLI' ) && did_action( 'init' ) && ! $isLoadingATEAutomaticTranslationWidget ) { require_once WPML_PLUGIN_PATH . '/classes/request-handling/redirection/wpml-frontend-redirection.php'; /** @var \WPML\Language\Detection\Frontend $wpml_request_handler */ $redirect_helper = _wpml_get_redirect_helper(); $redirection = new WPML_Frontend_Redirection( $this, $wpml_request_handler, $redirect_helper, $wpml_language_resolution ); $this->set_this_lang( $redirection->maybe_redirect() ); } else { $this->set_this_lang( $wpml_request_handler->get_requested_lang() ); } /** * Save language code in cookies when wpml_should_skip_saving_language_in_cookies filter hook returns FALSE * @see https://onthegosystems.myjetbrains.com/youtrack/issue/wpmldev-1544 */ if ( ! apply_filters( 'wpml_should_skip_saving_language_in_cookies', false ) ) { $wpml_request_handler->set_language_cookie( $this->this_lang ); } if ( $pagenow === 'upload.php' && isset( $mode ) && 'grid' === $mode ) { $_GET['lang'] = null; $_GET['admin_bar'] = null; } } function load_dependencies() { do_action( 'wpml_load_dependencies' ); } /** * Sets up all term/taxonomy actions for use outside Translations Management or the Post Edit screen */ function set_term_filters_and_hooks() { // The delete filter only ensures the synchronizing of delete actions between translations of a term. add_action( 'delete_term', array( $this, 'delete_term' ), 1, 3 ); add_action( 'set_object_terms', array( 'WPML_Terms_Translations', 'set_object_terms_action' ), 10, 6 ); // filters terms by language for the term/tag-box autoselect if ( ( isset( $_GET['action'] ) && 'ajax-tag-search' === $_GET['action'] ) || ( isset( $_POST['action'] ) && 'get-tagcloud' === $_POST['action'] ) ) { add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 ); } add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 3 ); add_action( 'create_term', array( $this, 'create_term' ), 1, 3 ); add_action( 'edit_term', array( $this, 'create_term' ), 1, 3 ); add_filter( 'get_terms_args', array( $this, 'get_terms_args_filter' ), 10, 2 ); add_filter( 'get_edit_term_link', array( $this, 'get_edit_term_link' ), 1, 4 ); add_action( 'deleted_term_relationships', array( $this, 'deleted_term_relationships' ), 10, 3 ); add_action( 'wp_ajax_icl_repair_broken_type_and_language_assignments', 'icl_repair_broken_type_and_language_assignments' ); // adjust queried categories and tags ids according to the language if ( (bool) $this->get_setting( 'auto_adjust_ids' ) ) { add_action( 'wp_list_pages_excludes', array( $this, 'adjust_wp_list_pages_excludes' ) ); if ( (! $this->get_wp_api() ->is_admin() || $this->get_wp_api() ->constant( 'DOING_AJAX' )) && ! wpml_is_rest_request() ) { add_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1, 1 ); add_action( 'edited_term', array( $this, 'edited_term_action' ) ); add_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1, 2 ); } } add_action( 'clean_term_cache', array( $this, 'clear_elements_cache' ), 10, 2 ); } function remove_admin_language_switcher() { remove_action( 'wp_before_admin_bar_render', array( $this, 'admin_language_switcher' ) ); } function rebuild_language_information() { $this->set_setting( 'just_reactivated', 0 ); $this->save_settings(); /** @var TranslationManagement $iclTranslationManagement */ global $iclTranslationManagement; if ( $iclTranslationManagement ) { $iclTranslationManagement->add_missing_language_information(); } } function setup() { $setup_complete = $this->get_setting( 'setup_complete' ); if ( ! $setup_complete ) { $this->set_setting( 'setup_complete', false ); } return $setup_complete; } public function user_lang_by_authcookie() { global $current_user; if ( ! isset( $current_user ) ) { $username = ''; if ( function_exists( 'wp_parse_auth_cookie' ) ) { $cookie_data = wp_parse_auth_cookie(); $username = isset( $cookie_data['username'] ) ? $cookie_data['username'] : null; } $user_obj = new WP_User( 0, $username ); } else { $user_obj = $current_user; } $user_id = isset( $user_obj->ID ) ? $user_obj->ID : 0; $user_lang = $this->get_user_admin_language( $user_id ); $user_lang = $user_lang ? $user_lang : $this->get_current_language(); return $user_lang; } function get_current_user() { global $current_user; return $current_user !== null ? $current_user : new WP_User(); } function ajax_setup() { require_once WPML_PLUGIN_PATH . '/ajax.php'; } function check_if_admin_action_from_referer() { $referer = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ''; return strpos( $referer, strtolower( admin_url() ) ) === 0; } /** * Check translation mangement column screen option. * * @param string $post_type Current post type. * * @return bool */ public function show_management_column_content( $post_type ) { $custom_columns = new WPML_Custom_Columns( $this ); return $custom_columns->show_management_column_content( $post_type ); } function initialize_cache() { require_once WPML_PLUGIN_PATH . '/inc/cache.php'; } /** * @return icl_cache */ function get_translations_cache() { if ( ! isset( $this->icl_translations_cache ) ) { $this->icl_translations_cache = new icl_cache(); } return $this->icl_translations_cache; } /** * @return icl_cache */ function get_language_name_cache() { if ( ! $this->icl_language_name_cache ) { $this->icl_language_name_cache = new icl_cache( 'language_name', true ); } return $this->icl_language_name_cache; } public function set_admin_language( $admin_language = false ) { $default_language = $this->get_default_language(); $this->admin_language = $admin_language ? $admin_language : $this->user_lang_by_authcookie(); $lang_codes = array_keys( $this->get_languages() ); if ( (bool) $this->admin_language === true && ! in_array( $this->admin_language, $lang_codes, true ) ) { delete_user_meta( $this->get_current_user()->ID, 'icl_admin_language' ); } if ( empty( $this->settings['admin_default_language'] ) || ! in_array( $this->settings['admin_default_language'], array_merge( $lang_codes, array( '_default_' ) ), true ) ) { $this->settings['admin_default_language'] = '_default_'; $this->save_settings(); } if ( ! $this->admin_language ) { $this->admin_language = $this->settings['admin_default_language']; } if ( $this->admin_language === '_default_' && $default_language ) { $this->admin_language = $default_language; } } function get_admin_language() { $current_user = $this->get_current_user(); if ( ( ! empty( $current_user->ID ) && $this->get_wp_api() ->get_user_meta( $current_user->ID, 'icl_admin_language_for_edit', true ) && $this->is_post_edit_screen() ) || $this->is_wpml_switch_language_triggered() ) { $admin_language = $this->get_current_language(); } else { $admin_language = $this->user_lang_by_authcookie(); } return $admin_language; } public function is_wpml_switch_language_triggered() { return isset( $GLOBALS['icl_language_switched'] ) ? true : false; } /** * @return bool */ function is_post_edit_screen() { global $pagenow; $action = isset( $_GET['action'] ) ? $_GET['action'] : ''; return $pagenow === 'post-new.php' || ( $pagenow === 'post.php' && ( 0 === strcmp( $action, 'edit' ) ) ); } function get_user_admin_language_filter( $value, $user_id ) { return $this->get_user_admin_language( $user_id ); } function get_user_admin_language( $user_id, $reload = false ) { $user_admin_language = new WPML_User_Admin_Language( $this ); return $user_admin_language->get( $user_id, $reload ); } /** * @todo rename this method, has it has nothing to do with the menus */ function administration_menu() { if ( ! $this->is_setup_complete() ) { $this->check_and_display_missing_records_notice(); } } private function check_and_display_missing_records_notice() { if ( ! $this->is_troubleshooting_page() && ! SitePress_Setup::languages_table_is_complete() ) { $troubleshooting_url = admin_url( 'admin.php?page=' . WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' ); $troubleshooting_link = '<a href="' . $troubleshooting_url . '" title="' . esc_attr( __( 'Troubleshooting', 'sitepress' ) ) . '">' . __( 'Troubleshooting', 'sitepress' ) . '</a>'; $message = ''; $message .= __( 'WPML is missing some records in the languages tables and it cannot fully work until this issue is fixed.', 'sitepress' ); $message .= '<br />'; $message .= sprintf( __( 'Please go to the %1$s page and click on "%2$s" to fix this problem.', 'sitepress' ), $troubleshooting_link, __( 'Clear language information and repopulate languages', 'sitepress' ) ); $message .= '<br />'; $message .= '<br />'; $message .= __( 'This warning will disappear once this issue is fixed.', 'sitepress' ); ICL_AdminNotifier::removeMessage( 'setup-incomplete' ); ICL_AdminNotifier::addMessage( 'setup-incomplete', $message, 'error', false, false, false, 'setup', true ); ICL_AdminNotifier::displayMessages( 'setup' ); } } function taxonomy_translation_page() { $this->taxonomy_translation->render(); } /** * @param int|string $blog_id */ function init_settings( $blog_id ) { $blog_id = (int) $blog_id; if ( ! isset( $this->loaded_blog_id ) || $this->loaded_blog_id != $blog_id ) { $this->loaded_blog_id = $blog_id; $this->settings = get_option( 'icl_sitepress_settings' ); $default_lang_code = isset( $this->settings['default_language'] ) ? $this->settings['default_language'] : false; load_wpml_url_converter( $this->settings, false, $default_lang_code ); } } /** * @param array|null $settings */ function save_settings( $settings = null ) { if ( null !== $settings ) { foreach ( $settings as $k => $v ) { if ( is_array( $v ) ) { foreach ( $v as $k2 => $v2 ) { $this->settings[ $k ][ $k2 ] = $v2; } } else { $this->settings[ $k ] = $v; } } } if ( ! empty( $this->settings ) ) { update_option( 'icl_sitepress_settings', $this->settings ); } do_action( 'icl_save_settings', $settings ); } /** * @since 3.1 */ function get_settings() { return $this->settings; } function filter_get_setting( $value, $key ) { return $this->get_setting( $key, $value ); } /** * @param string $key * @param mixed|bool $default * * @since 3.1 * * @return bool|mixed */ function get_setting( $key, $default = false ) { return wpml_get_setting_filter( $default, $key ); } function action_set_setting( $key, $value, $save_now ) { $this->set_setting( $key, $value, $save_now ); } /** * @param string $key * @param mixed $value * @param bool $save_now Immediately update the settings record in the DB * * @since 3.1 * * @return bool Always True. If `$save_now === true`, it returns the result of `update_option` */ function set_setting( $key, $value, $save_now = false ) { return icl_set_setting( $key, $value, $save_now ); } function get_user_preferences() { if ( ! isset( $this->user_preferences ) || ! $this->user_preferences ) { $this->user_preferences = get_user_meta( $this->get_current_user()->ID, '_icl_preferences', true ); } if ( ( is_array( $this->user_preferences ) && $this->user_preferences == array( 0 => false ) ) || ! $this->user_preferences ) { $this->user_preferences = array(); } if ( ! is_array( $this->user_preferences ) ) { $this->user_preferences = (array) $this->user_preferences; } return $this->user_preferences; } function set_user_preferences( $value ) { $this->user_preferences = $value; } function save_user_preferences() { update_user_meta( $this->get_current_user()->ID, '_icl_preferences', $this->user_preferences ); } /** * @param string $option_name * * @return mixed|null * @deprecated Use \SitePress::get_setting instead * */ public function get_option( $option_name ) { return $this->get_setting( $option_name, null ); } function verify_settings() { $verify_settings = new WPML_Verify_SitePress_Settings( $this->get_wp_api() ); list( $this->settings, $update_settings ) = $verify_settings->verify( $this->settings ); if ( $update_settings ) { $this->save_settings(); } } /** * @param bool $refresh * @param bool $major_first * @param string $order_by * * @return array<string,string> */ function get_active_languages( $refresh = false, $major_first = false, $order_by = 'english_name' ) { /** @var WPML_Request $wpml_request_handler */ global $wpml_request_handler; $in_language = defined( 'WP_ADMIN' ) && $this->admin_language ? $this->admin_language : null; $in_language = $in_language === null ? $this->get_current_language() : $in_language; $in_language = $in_language ? $in_language : $this->get_default_language(); $active_languages = $this->get_languages( $in_language, true, $refresh, $major_first, $order_by ); $active_languages = isset( $active_languages[ $in_language ] ) ? $active_languages : $this->get_languages( $in_language, true, true, $major_first, $order_by ); $active_languages = $active_languages ? $active_languages : array(); $this->active_languages = $wpml_request_handler->show_hidden() ? $active_languages : array_diff_key( $active_languages, array_fill_keys( $this->get_setting( 'hidden_languages', array() ), 1 ) ); return $this->active_languages; } /** * Returns an input array of languages, that are in the form of associative arrays, * ordered by the user-chosen language order * * @param array[] $languages * * @return array[] */ function order_languages( $languages ) { $ordered_languages = array(); if ( isset( $this->settings['languages_order'] ) && is_array( $this->settings['languages_order'] ) ) { foreach ( $this->settings['languages_order'] as $code ) { if ( isset( $languages[ $code ] ) ) { $ordered_languages[ $code ] = $languages[ $code ]; unset( $languages[ $code ] ); } } } else { // initial save $iclsettings['languages_order'] = array_keys( $languages ); $this->save_settings( $iclsettings ); } if ( ! empty( $languages ) ) { foreach ( $languages as $code => $lang ) { $ordered_languages[ $code ] = $lang; } } return $ordered_languages; } /** * @param string $lang_code * Checks if a given language code belongs to a currently active language. * * @return bool */ function is_active_language( $lang_code ) { $result = false; $active_languages = $this->get_active_languages(); foreach ( $active_languages as $lang ) { if ( $lang_code == $lang['code'] ) { $result = true; break; } } return $result; } public function get_languages( $lang = false, $active_only = false, $refresh = false, $major_first = false, $order_by = 'english_name' ) { $res = false; if ( ! $lang ) { $lang = $this->get_default_language(); } if ( $active_only && ! $refresh ) { $res = $this->get_language_name_cache() ->get( 'in_language_' . $lang . '_' . $major_first . '_' . $order_by ); } if ( ! $res && ! $active_only && ! $refresh ) { $res = $this->get_language_name_cache() ->get( 'all_language_' . $lang . '_' . $major_first . '_' . $order_by ); } if ( ! $res ) { $setup_instance = wpml_get_setup_instance(); $res = $setup_instance->refresh_active_lang_cache( $lang, $active_only, $major_first, $order_by ); } return $res; } function get_language_details( $code ) { if ( ! $code ) { return false; } $displayLanguageCode = $this->get_wp_api()->is_front_end() ? $code : $this->admin_language; $details = $this->get_language_name_cache()->get( 'language_details_' . $code . $displayLanguageCode ); return $details ?: Obj::propOr( false, $code, $this->get_languages( $displayLanguageCode ) ); } function get_language_code( $english_name ) { $query = $this->wpdb->prepare( " SELECT code FROM {$this->wpdb->prefix}icl_languages WHERE english_name = %s LIMIT 1", $english_name ); $code = $this->wpdb->get_var( $query ); return $code; } function get_language_code_from_locale( $locale ) { $query = $this->wpdb->prepare( " SELECT code FROM {$this->wpdb->prefix}icl_languages WHERE default_locale = %s LIMIT 1", $locale ); $code = $this->wpdb->get_var( $query ); return $code; } function get_locale_from_language_code( $code ) { $query = $this->wpdb->prepare( " SELECT default_locale FROM {$this->wpdb->prefix}icl_languages WHERE code = %s LIMIT 1", $code ); $locale = $this->wpdb->get_var( $query ); return $locale; } function get_default_language() { return isset( $this->settings['default_language'] ) ? $this->settings['default_language'] : false; } private function is_valid_language( $language ) { $active_languages = $this->active_languages; if ( ! $active_languages ) { $active_languages = $this->get_languages(); } $is_wp_cli_request = defined( 'WP_CLI' ) && WP_CLI; $is_admin = $this->get_wp_api()->is_admin(); return isset( $active_languages[ $language ] ) || ( 'all' === $language && ( $is_admin || $is_wp_cli_request ) ); } private function set_this_lang( $new_value ) { if ( $this->is_valid_language( $new_value ) ) { $this->this_lang = $new_value; } } public function get_this_lang() { return $this->this_lang; } function get_current_language() { /** * @var WPML_Request $wpml_request_handler * @var WPML_Language_Resolution $wpml_language_resolution */ global $wpml_request_handler, $wpml_language_resolution; if ( ! $this->this_lang ) { $this->set_this_lang( $wpml_request_handler->get_requested_lang() ); } if ( ! $this->this_lang ) { $this->set_this_lang( $this->get_default_language() ); } return $wpml_language_resolution->current_lang_filter( $this->this_lang, $wpml_request_handler ); } /** * Switches whole site to the given language or back to the current language * that was set when first calling this function. * * @param null|string $code language code to switch into, will revert to * initial language if null is given * @param bool|string $cookie_lang optionally also switch the cookie language * to the value given */ public function switch_lang( $code = null, $cookie_lang = false ) { /** * @var WPML_Request $wpml_request_handler * @var WPML_Language_Resolution $wpml_language_resolution */ global $wpml_language_resolution, $wpml_request_handler; WPML_Non_Persistent_Cache::flush_group( [ 'WPML_String_Translation', 'icl_get_string_translations_by_id' ] ); $this->original_language = $this->original_language === null ? $this->get_current_language() : $this->original_language; if ( is_null( $code ) ) { $this->set_this_lang( $this->original_language ); if ( ! empty( $this->original_language_cookie ) ) { $wpml_request_handler->set_language_cookie( $this->original_language_cookie ); $this->original_language_cookie = false; } } else { if ( $code === 'all' || in_array( $code, $wpml_language_resolution->get_active_language_codes(), true ) ) { $this->set_this_lang( $code ); } if ( $cookie_lang ) { $this->original_language_cookie = $wpml_request_handler->get_cookie_lang(); $wpml_request_handler->set_language_cookie( $code ); } } if ( $code ) { $GLOBALS['icl_language_switched'] = true; } else { unset( $GLOBALS['icl_language_switched'] ); } do_action( 'wpml_language_has_switched', $code, $cookie_lang, $this->original_language ); } function set_default_language( $code ) { $previous_default = $this->get_setting( 'default_language' ); $this->set_setting( 'default_language', $code ); $this->set_setting( 'admin_default_language', $code ); $this->save_settings(); do_action( 'icl_after_set_default_language', $code, $previous_default ); // change WP locale $locale = $this->get_locale( $code ); if ( $locale ) { update_option( 'WPLANG', $locale ); } $user_language = new WPML_User_Language( $this ); $user_language->sync_default_admin_user_languages(); return $code !== 'en' && ! file_exists( WP_LANG_DIR . '/' . $locale . '.mo' ) ? 1 : true; } /** * Hooked to `init` */ function register_assets() { global $wpdb, $wpml_post_translations, $wpml_term_translations; $page = filter_input( INPUT_GET, 'page' ); $page = $page !== null ? basename( $_GET['page'] ) : null; $page_basename = $page === null ? '' : preg_replace( '/[^\w-]/', '', str_replace( '.php', '', $page ) ); $this->scripts_handler = new WPML_Admin_Scripts_Setup( $wpdb, $this, $wpml_post_translations, $wpml_term_translations, (string) $page_basename ); $this->scripts_handler->register_styles(); } /** * Hooked to `admin_enqueue_scripts` AND `wp_enqueue_scripts` */ function js_load() { global $pagenow, $wpdb, $wpml_post_translations, $wpml_term_translations; $page = filter_input( INPUT_GET, 'page' ); $page = $page !== null ? basename( $_GET['page'] ) : null; $page_basename = $page === null ? '' : preg_replace( '/[^\w-]/', '', str_replace( '.php', '', $page ) ); $this->scripts_handler = new WPML_Admin_Scripts_Setup( $wpdb, $this, $wpml_post_translations, $wpml_term_translations, (string) $page_basename ); if ( is_admin() && ! defined( 'DOING_AJAX' ) && ! wpml_is_rest_request() && empty( $_GET['legacy-widget-preview'] ) ) { $this->scripts_handler->add_admin_hooks(); if ( $this->is_post_edit_script_allowed() ) { wp_register_script( 'sitepress-post-edit-tags', ICL_PLUGIN_URL . '/res/js/post-edit-terms.js', array( 'jquery' ) ); $post_edit_messages = array( 'switch_language_title' => __( 'You are about to change the language of {post_name}.', 'sitepress' ), 'switch_language_alert' => __( 'All categories and tags will be translated if possible.', 'sitepress' ), 'connection_loss_alert' => __( 'The following terms do not have a translation in the chosen language and will be disconnected from this post:', 'sitepress' ), 'loading' => __( 'Loading Language Data for {post_name}', 'sitepress' ), 'switch_language_message' => __( 'Please make sure that you\'ve saved all the changes. We will have to reload the page.', 'sitepress' ), 'switch_language_confirm' => __( 'Do you want to continue?', 'sitepress' ), '_nonce' => wp_create_nonce( 'wpml_switch_post_lang_nonce' ), 'empty_post_title' => __( '(No title for this post yet)', 'sitepress' ), 'ok_button_label' => __( 'OK', 'sitepress' ), 'cancel_button_label' => __( 'Cancel', 'sitepress' ), '_get_default_lang_nonce' => wp_create_nonce( 'wpml_get_default_lang' ), ); wp_localize_script( 'sitepress-post-edit-tags', 'icl_post_edit_messages', $post_edit_messages ); wp_enqueue_script( 'sitepress-post-edit-tags' ); } if ( isset( $_SERVER['SCRIPT_NAME'] ) && strpos( $_SERVER['SCRIPT_NAME'], 'edit.php' ) ) { wp_register_script( 'sitepress-post-list-quickedit', ICL_PLUGIN_URL . '/res/js/post-list-quickedit.js', array( 'jquery' ) ); wp_enqueue_script( 'sitepress-post-list-quickedit' ); } wp_register_script( 'wpml-purify', ICL_PLUGIN_URL . '/dist/js/domPurify/app.js', [], ICL_SITEPRESS_VERSION ); wp_register_script( 'sitepress-scripts', ICL_PLUGIN_URL . '/res/js/scripts.js', [ 'jquery', 'jquery-ui-dialog', 'wpml-purify' ], ICL_SITEPRESS_VERSION ); wp_localize_script( 'sitepress-scripts', 'wpml_core_strings', [ 'dialogCloseText' => __( 'Close', 'sitepress' ), ] ); wp_enqueue_script( 'sitepress-scripts' ); if ( isset( $page_basename ) && file_exists( WPML_PLUGIN_PATH . '/res/js/' . $page_basename . '.js' ) ) { $dependencies = array(); $localization = false; $color_picker_handler = 'wp-color-picker'; switch ( $page_basename ) { case 'languages': $dependencies[] = $color_picker_handler; $dependencies[] = 'sitepress-scripts'; $dependencies[] = 'wpml-domain-validation'; $dependencies[] = 'jquery-ui-dialog'; break; case 'troubleshooting': $dependencies [] = 'jquery-ui-dialog'; $localization = array( 'object_name' => 'troubleshooting_strings', 'strings' => array( 'success_1' => __( 'Post type and source language assignment have been fixed for ', 'sitepress' ), 'success_2' => __( ' elements', 'sitepress' ), 'no_problems' => __( 'No errors were found in the assignment of post types.', 'sitepress' ), 'suffixesRemoved' => __( 'Language suffixes were removed from the selected terms.', 'sitepress' ), 'done' => __( 'Done', 'sitepress' ), 'termNamesNonce' => wp_create_nonce( 'update_term_names_nonce' ), 'cacheClearNonce' => wp_create_nonce( 'cache_clear' ), 'brokenTypeNonce' => wp_create_nonce( 'broken_type_nonce' ), 'syncPostsTaxNonce' => wp_create_nonce( WPML_Troubleshoot_Action::SYNC_POSTS_TAXONOMIES_SLUG ), 'removeNotificationsNonce' => wp_create_nonce( 'icl_remove_notifications' ), 'restoreNotificationsNonce' => wp_create_nonce( 'icl_restore_notifications' ), ), ); wp_enqueue_style( 'wp-jquery-ui-dialog' ); break; case 'menus-sync': $localization = array( 'object_name' => 'menus_sync', 'strings' => array( 'text1' => esc_html__( "Your menu includes custom items, which you need to translate using WPML's String Translation.", 'sitepress' ), 'text2' => esc_html__( '1. Translate these strings: ', 'sitepress' ), 'text3' => esc_html__( "2. When you're done translating, return here and run the menu synchronization again. This will use the strings that you translated to update the menus.", 'sitepress' ), 'menusSyncNonce' => wp_create_nonce( 'wpml_get_links_for_menu_strings_translation' ), ), ); break; } $handle = 'sitepress-' . $page_basename; wp_register_script( $handle, ICL_PLUGIN_URL . '/res/js/' . $page_basename . '.js', $dependencies, ICL_SITEPRESS_VERSION ); if ( $localization ) { wp_localize_script( $handle, $localization['object_name'], $localization['strings'] ); } if ( in_array( $color_picker_handler, $dependencies ) ) { wp_enqueue_style( $color_picker_handler ); } wp_enqueue_script( $handle ); } if ( $pagenow == 'edit.php' ) { add_action( 'admin_enqueue_scripts', array( $this, 'language_filter' ) ); } wp_enqueue_style( 'wpml-select-2', ICL_PLUGIN_URL . '/lib/select2/select2.css' ); } } private function is_post_edit_script_allowed() { return ( isset( $_SERVER['SCRIPT_NAME'] ) && ( strpos( $_SERVER['SCRIPT_NAME'], 'post-new.php' ) || strpos( $_SERVER['SCRIPT_NAME'], 'post.php' ) ) || apply_filters( 'wpml_enable_language_meta_box', false ) ); } function backend_js( $setup_complete = true ) { wp_register_script( 'sitepress', ICL_PLUGIN_URL . '/res/js/sitepress.js' ); wp_enqueue_script( 'sitepress' ); $vars = [ 'restUrl' => untrailingslashit( rest_url() ), 'restNonce' => wp_create_nonce( 'wp_rest' ), 'loadLanguageJs' => ! ( defined( 'ICL_DONT_LOAD_LANGUAGES_JS' ) && ICL_DONT_LOAD_LANGUAGES_JS ), ]; if ( $setup_complete ) { $vars = array_merge( $vars, [ 'current_language' => $this->this_lang, 'icl_home' => $this->language_url(), 'ajax_url' => $this->convert_url( admin_url( 'admin-ajax.php' ), $this->this_lang ), 'url_type' => $this->settings['language_negotiation_type'], ] ); } else { $vars = array_merge( $vars, [ 'current_language' => 'en', 'icl_home' => '', ] ); } wp_localize_script( 'sitepress', 'icl_vars', $vars ); } function rtl_fix() { global $wp_styles; if ( ! empty( $wp_styles ) && $this->is_rtl() ) { $wp_styles->text_direction = 'rtl'; } } function post_edit_language_options() { /** @var TranslationManagement $iclTranslationManagement */ global $post, $iclTranslationManagement, $post_new_file, $post_type_object, $pagenow; if ( null === $post || ! $this->get_setting( 'setup_complete', false ) ) { return; } $is_preview = ( isset( $_POST['wp-preview'] ) && $_POST['wp-preview'] === 'dopreview' ) || is_preview(); $is_attachment = in_array( $pagenow, array( 'upload.php', 'media-upload.php' ), true ) || ( $post && 'attachment' === $post->post_type ) || is_attachment(); if ( $is_attachment || $is_preview ) { return; } if ( current_user_can( 'manage_options' ) && \WPML\WP\OptionManager::getOr( false, 'core', 'show_cf_meta_box' ) ) { add_meta_box( 'icl_div_config', __( 'Multilingual Content Setup', 'sitepress' ), array( $this, 'meta_box_config' ), $post->post_type, 'normal', 'low' ); } if ( filter_input( INPUT_POST, 'icl_action' ) === 'icl_mcs_inline' ) { $custom_post_type = filter_input( INPUT_POST, 'custom_post' ); $translate = (int) filter_input( INPUT_POST, 'translate' ); $iclsettings['custom_posts_sync_option'][ $custom_post_type ] = $translate; if ( $translate ) { $this->verify_post_translations( $custom_post_type ); } $custom_taxs_off = (array) filter_input( INPUT_POST, 'custom_taxs_off', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY ); $custom_taxs_on = (array) filter_input( INPUT_POST, 'custom_taxs_on', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY ); $tax_sync_options = array_merge( array_fill_keys( $custom_taxs_on, 1 ), array_fill_keys( $custom_taxs_off, 0 ) ); foreach ( $tax_sync_options as $key => $setting ) { $iclsettings['taxonomies_sync_option'][ $key ] = $setting; if ( $setting ) { $this->verify_taxonomy_translations( $key ); } } $cf_names = (array) filter_input( INPUT_POST, 'cfnames', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY ); $cf_vals = (array) filter_input( INPUT_POST, 'cfvals', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY ); $translations = []; $original_post_id = null; if ( in_array( 1, $cf_vals, false ) ) { global $wpml_post_translations; $original_post_id = $wpml_post_translations->get_original_element( $post->ID, true ); $translations = array_diff( $wpml_post_translations->get_element_translations( $original_post_id ), array( $original_post_id ) ); } foreach ( $cf_names as $k => $v ) { $custom_field_name = base64_decode( $v ); $cf_translation_state = isset( $cf_vals[ $k ] ) ? (int) $cf_vals[ $k ] : 0; $iclTranslationManagement->settings['custom_fields_translation'][ $custom_field_name ] = $cf_translation_state; $iclTranslationManagement->save_settings(); /** * Fires after update of custom fields synchronisation preferences on the post edit screen */ do_action( 'wpml_single_custom_field_sync_option_updated', array( $custom_field_name => $cf_translation_state ) ); // sync the custom fields for the current post if ( $original_post_id && $translations && 1 === $cf_translation_state ) { foreach ( $translations as $translated_id ) { $this->sync_custom_field( $original_post_id, $translated_id, $custom_field_name ); } } } $this->save_settings( $iclsettings ); } $post_types = array_keys( $this->get_translatable_documents() ); if ( in_array( $post->post_type, $post_types, true ) ) { add_meta_box( WPML_Meta_Boxes_Post_Edit_HTML::WRAPPER_ID, __( 'Language', 'sitepress' ), array( $this, 'meta_box', ), (string) $post->post_type, /** This filter is documented in sitepress-multilingual-cms/inc/post-translation/wpml-root-page-actions.class.php */ apply_filters( 'wpml_post_edit_meta_box_context', 'side', WPML_Meta_Boxes_Post_Edit_HTML::WRAPPER_ID ), apply_filters( 'wpml_post_edit_meta_box_priority', 'high' ) ); } // Fix the "Add new" button adding the language argument, so to create new content in the same language if ( isset( $post_new_file, $post_type_object ) && $this->is_translated_post_type( $post_type_object->name ) ) { $post_language = $this->get_language_for_element( $post->ID, 'post_' . $post_type_object->name ); $post_new_file = add_query_arg( array( 'lang' => $post_language ), $post_new_file ); } } function set_element_language_details_action( $args ) { $element_id = $args['element_id']; $element_type = isset( $args['element_type'] ) ? $args['element_type'] : 'post_post'; $trid = $args['trid']; $language_code = $args['language_code']; $source_language_code = isset( $args['source_language_code'] ) ? $args['source_language_code'] : null; $check_duplicates = isset( $args['check_duplicates'] ) ? $args['check_duplicates'] : true; $result = $this->set_element_language_details( $element_id, $element_type, $trid, $language_code, $source_language_code, $check_duplicates ); $args['result'] = $result; } /** * @param int $el_id the element's ID (for terms we use the `term_taxonomy_id`) * @param string $el_type * @param int $trid * @param string $language_code * @param null|string $src_language_code * @param bool $check_duplicates * * @return bool|int|null|string */ public function set_element_language_details( $el_id, $el_type, $trid, $language_code, $src_language_code = null, $check_duplicates = true ) { if ( ! $this->language_setter ) { $this->language_setter = new WPML_Set_Language( $this, $this->wpdb, $this->post_translation, $this->term_translation ); } return $this->language_setter->set( $el_id, $el_type, $trid, $language_code, $src_language_code, $check_duplicates ); } public function delete_orphan_element( $element_id, $element_type, $target_language ) { $this->delete_element_translation( $this->get_element_trid( $element_id, $element_type ), $element_type, $target_language, true ); } function delete_element_translation( $trid, $element_type, $language_code = false, $orphan_translation_only = false ) { $result = false; if ( $trid !== false && is_numeric( $trid ) && $element_type !== false && is_string( $trid ) ) { $delete_where = array( 'trid' => $trid, 'element_type' => $element_type, ); $delete_formats = array( '%d', '%s' ); if ( $language_code ) { $delete_where['language_code'] = $language_code; $delete_formats[] = '%s'; } if ( $orphan_translation_only ) { $delete_where['element_id'] = null; } $context = explode( '_', $element_type ); $update_args = array( 'trid' => $trid, 'element_type' => $element_type, 'context' => $context[0], ); do_action( 'wpml_translation_update', array_merge( $update_args, array( 'type' => 'before_delete' ) ) ); $result = $this->wpdb->delete( $this->wpdb->prefix . 'icl_translations', $delete_where, $delete_formats ); do_action( 'wpml_translation_update', array_merge( $update_args, array( 'type' => 'after_delete' ) ) ); $this->get_translations_cache() ->clear(); } return $result; } /** * @param int $el_id * @param string $el_type * * @return \stdClass */ function get_element_language_details( $el_id, $el_type = 'post_post' ) { $details = false; if ( $el_id ) { if ( strpos( $el_type, 'post_' ) === 0 ) { $details = $this->post_translation->get_element_language_details( $el_id, OBJECT ); } if ( strpos( $el_type, 'tax_' ) === 0 ) { $details = $this->term_translation->get_element_language_details( $el_id, OBJECT ); } if ( ! $details ) { $cache_key = $el_id . ':' . $el_type; $cache_group = 'element_language_details'; $cached_details = wp_cache_get( $cache_key, $cache_group ); if ( $cached_details ) { return $cached_details; } if ( $this->get_translations_cache() ->has_key( $el_id . $el_type ) ) { return $this->get_translations_cache() ->get( $el_id . $el_type ); } $details_query = " SELECT trid, language_code, source_language_code FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s "; $details_prepare = $this->wpdb->prepare( $details_query, array( $el_id, $el_type ) ); $details = $this->wpdb->get_row( $details_prepare ); $this->get_translations_cache() ->set( $el_id . $el_type, $details ); wp_cache_add( $cache_key, $details, $cache_group ); } } return $details; } public function sync_custom_field( $post_id_from, $post_id_to, $meta_key ) { $sync_custom_fields = new WPML_Sync_Custom_Fields( new WPML_Translation_Element_Factory( $this ), array( $meta_key ) ); $sync_custom_fields->sync_custom_field( $post_id_from, $post_id_to, $meta_key ); } function copy_custom_fields( $post_id_from, $post_id_to ) { $custom_fields_to_copy = $this->get_custom_fields_translation_settings( WPML_COPY_CUSTOM_FIELD ); $custom_fields_from = get_post_meta( $post_id_from ); $custom_fields_to = get_post_meta( $post_id_to ); foreach ( $custom_fields_to_copy as $meta_key ) { $meta_from = isset( $custom_fields_from[ $meta_key ] ) ? $custom_fields_from[ $meta_key ] : []; $meta_to = isset( $custom_fields_to[ $meta_key ] ) ? $custom_fields_to[ $meta_key ] : []; if ( $meta_from || $meta_to ) { $this->sync_custom_field( $post_id_from, $post_id_to, $meta_key ); } } $sync_deleted_fields = false; /** * This filter hook determines whether we should sync deleted custom * fields to translations. * * @since 4.4.9 * * @param bool $sync_deleted_fields True if we should sync deleted custom fields (the default is false). * * @return bool */ if ( apply_filters( 'wpml_sync_deleted_custom_fields', $sync_deleted_fields ) && $custom_fields_from && $custom_fields_to ) { $if_deleted_in_source_and_still_in_target = Logic::allPass( [ Obj::prop( Fns::__, $custom_fields_to ), pipe( Obj::prop( Fns::__, $custom_fields_from ), Logic::not() ), ] ); wpml_collect( $this->get_custom_fields_translation_settings( WPML_TRANSLATE_CUSTOM_FIELD ) ) ->filter( $if_deleted_in_source_and_still_in_target ) ->map( function ( $meta_key ) use ( $post_id_from, $post_id_to ) { $this->sync_custom_field( $post_id_from, $post_id_to, $meta_key ); } ); } } /** * @param int|string $mode * * @return array */ public function get_custom_fields_translation_settings( $mode ) { $custom_fields_for_mode = []; $tm_settings = wpml_load_core_tm()->get_settings(); if ( isset( $tm_settings['custom_fields_translation'] ) ) { foreach ( $tm_settings['custom_fields_translation'] as $meta_key => $option ) { if ( $option == $mode ) { $custom_fields_for_mode[] = $meta_key; } } } return $custom_fields_for_mode; } /** * This method does nothing and is only there as a placeholder for backward compatibility with old Types versions! * * @param int $meta_id * @param int $object_id * @param string $meta_key * @param mixed $_meta_value * * @deprecated Since WPML 3.1.9 * */ function update_post_meta( $meta_id, $object_id, $meta_key, $_meta_value ) { return; } /** * This method does nothing and is only there as a placeholder for backward compatibility with old Types versions! * * @deprecated Since WPML 3.1.9 * * @param int $meta_id */ function delete_post_meta( $meta_id ) { return; } /* Custom fields synchronization - END */ function get_element_translations_filter( $value, $trid, $el_type = 'post_post', $skip_empty = false, $all_statuses = false, $skip_cache = false ) { return $this->get_element_translations( $trid, $el_type, $skip_empty, $all_statuses, $skip_cache ); } public function get_original_element_id_filter( $empty, $element_id, $element_type = 'post_post' ) { $original_element_id = $this->get_original_element_id( $element_id, $element_type ); return $original_element_id; } public function get_element_trid_filter( $empty, $element_id, $element_type = 'post_post' ) { $trid = $this->get_element_trid( $element_id, $element_type ); return $trid; } function is_original_content_filter( $default, $element_id, $element_type = 'post_post' ) { $is_original_content = $default; $trid = $this->get_element_trid( $element_id, $element_type ); $translations = $this->get_element_translations( $trid, $element_type ); if ( $translations ) { foreach ( $translations as $language_code => $translation ) { if ( $translation->element_id == $element_id ) { $is_original_content = $translation->original; break; } } } return $is_original_content; } /** * @param int $trid * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment') * @param bool $skip_empty * @param bool $all_statuses * @param bool $skip_cache * @param bool $skip_recursions * @param bool $skipPrivilegeChecking * * @return array<string,\stdClass> */ function get_element_translations( $trid, $el_type = 'post_post', $skip_empty = false, $all_statuses = false, $skip_cache = false, $skip_recursions = false, $skipPrivilegeChecking = false ) { $wpml_translations = new WPML_Translations( $this ); $wpml_translations->skip_empty = $skip_empty; $wpml_translations->all_statuses = $all_statuses; $wpml_translations->skip_cache = $skip_cache; $wpml_translations->skip_recursions = $skip_recursions; return $wpml_translations->get_translations( $trid, $el_type, $skipPrivilegeChecking ); } function clear_elements_cache( $ids, $taxonomy ) { $cache = new WPML_WP_Cache( WPML_ELEMENT_TRANSLATIONS_CACHE_GROUP ); $cache->flush_group_cache(); } static function get_original_element_id( $element_id, $element_type = 'post_post', $skip_empty = false, $all_statuses = false, $skip_cache = false ) { global $sitepress; $original_element_id = false; $trid = $sitepress->get_element_trid( $element_id, $element_type ); if ( $trid ) { $original_element = $sitepress->get_original_element_translation( $trid, $element_type, $skip_empty, $all_statuses, $skip_cache ); if ( $original_element ) { $original_element_id = $original_element->element_id; } } return $original_element_id; } public function get_original_element_translation( $trid, $element_type, $skip_empty = false, $all_statuses = false, $skip_cache = false ) { $cache_key_args = array_filter( array( $trid, $element_type, $skip_empty, $all_statuses ) ); $cache_key = md5( (string) wp_json_encode( $cache_key_args ) ); $cache_group = 'original_element'; $original_element = null; if ( ! $skip_cache ) { $original_element = wp_cache_get( $cache_key, $cache_group ); } if ( $original_element ) { return $original_element; } $element_translations = $this->get_element_translations( $trid, $element_type, $skip_empty, $all_statuses, $skip_cache ); $original_element = null; foreach ( $element_translations as $element_translation ) { if ( $element_translation->original ) { $original_element = $element_translation; break; } } if ( $original_element ) { wp_cache_set( $cache_key, $original_element, $cache_group ); } return $original_element; } /** * @param int $element_id Use term_taxonomy_id for taxonomies, post_id for posts * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment') * * @return bool|mixed|null|string */ function get_element_trid( $element_id, $el_type = 'post_post' ) { if ( strpos( $el_type, 'tax_' ) === 0 ) { /** @var WPML_Term_Translation $wpml_term_translations */ global $wpml_term_translations; return $wpml_term_translations->get_element_trid( $element_id ); } elseif ( strpos( $el_type, 'post_' ) === 0 ) { global $wpml_post_translations; return $wpml_post_translations->get_element_trid( $element_id ); } else { $cache_key = $element_id . ':' . $el_type; $cache_group = 'element_trid'; $temp_trid = wp_cache_get( $cache_key, $cache_group ); if ( (bool) $temp_trid === true ) { return $temp_trid; } $trid_prepared = $this->wpdb->prepare( "SELECT trid FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", array( $element_id, $el_type ) ); $trid = $this->wpdb->get_var( $trid_prepared ); if ( $trid ) { wp_cache_add( $cache_key, $trid, $cache_group ); } } return $trid; } /** * @param int $trid * * @return int|bool */ static function get_original_element_id_by_trid( $trid ) { global $wpdb; if ( (bool) $trid === true ) { $original_element_id_prepared = $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND source_language_code IS NULL LIMIT 1", $trid ); $element_id = $wpdb->get_var( $original_element_id_prepared ); } else { $element_id = false; } return $element_id; } /** * @param int|null|0 $trid * * @return string|null language code */ static function get_source_language_by_trid( $trid ) { if ( ! $trid ) { return null; } $getLanguageCodeByTridFromDB = function ( $trid ) { return Obj::prop( 'language_code', \WPML\Records\Translations::getSourceByTrid( $trid ) ); }; $cachedFn = \WPML\LIB\WP\Cache::memorize( 'get_source_language_by_trid', 0, $getLanguageCodeByTridFromDB ); return $cachedFn( (int) $trid ); } public function get_element_translations_object( $element_type ) { global $wpml_post_translations, $wpml_term_translations, $wpml_cache_factory; $element_translations = null; if ( strpos( $element_type, 'tax_' ) === 0 ) { $element_translations = $wpml_term_translations; } elseif ( strpos( $element_type, 'post_' ) === 0 ) { $element_translations = $wpml_post_translations; } else { $element_translations = new WPML_Element_Type_Translation( $this->wpdb, $wpml_cache_factory, $element_type ); } return $element_translations; } /** * @param int $element_id Use term_taxonomy_id for taxonomies, post_id for posts * @param string $element_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, * post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment') * * @return null|string */ function get_language_for_element( $element_id, $element_type = 'post_post' ) { $translation_object = $this->get_element_translations_object( $element_type ); return $translation_object->get_element_lang_code( $element_id ); } /** * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment') * @param string $target_lang Target language code * @param string $source_lang Source language code * * @return array */ function get_elements_without_translations( $el_type, $target_lang, $source_lang ) { $sql = $this->wpdb->prepare( "SELECT trid FROM {$this->wpdb->prefix}icl_translations WHERE language_code = %s AND element_type = %s", $target_lang, $el_type ); $trids_for_target = $this->wpdb->get_col( $sql ); if ( sizeof( $trids_for_target ) > 0 ) { $trids_for_target = wpml_prepare_in( $trids_for_target, '%d' ); $not_trids = 'AND trid NOT IN (' . $trids_for_target . ')'; } else { $not_trids = ''; } $join = $where = ''; // exclude trashed posts if ( 0 === strpos( $el_type, 'post_' ) ) { $join .= " JOIN {$this->wpdb->posts} ON {$this->wpdb->posts}.ID = {$this->wpdb->prefix}icl_translations.element_id"; $where .= " AND {$this->wpdb->posts}.post_status <> 'trash' AND {$this->wpdb->posts}.post_status <> 'auto-draft'"; } // Now get all the elements that are in the source language that // are not already translated into the target language. $sql = $this->wpdb->prepare( "SELECT element_id FROM {$this->wpdb->prefix}icl_translations {$join} WHERE language_code = %s {$not_trids} AND element_type= %s {$where} ", $source_lang, $el_type ); return $this->wpdb->get_col( $sql ); } /** * @param string $selected_language * @param string $default_language * @param string $post_type * * @used_by SitePress:meta_box * * @return array */ function get_posts_without_translations( $selected_language, $default_language, $post_type = 'post_post' ) { $untranslated_ids = $this->get_elements_without_translations( $post_type, $selected_language, $default_language ); $untranslated = array(); foreach ( $untranslated_ids as $id ) { $untranslated[ $id ] = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT post_title FROM {$this->wpdb->prefix}posts WHERE ID = %d", $id ) ); } return $untranslated; } public function get_orphan_translations( $trid, $post_type, $source_language ) { $results = array(); $translations = $this->get_element_translations( $trid, 'post_' . $post_type ); if ( count( (array) $translations ) === 1 ) { $sql = ' SELECT trid, '; $language_codes = array_keys( $this->get_active_languages() ); $sql_languages = array(); $sql_languages_having = array(); foreach ( $language_codes as $language_code ) { $sql_languages[] = "SUM(CASE language_code WHEN '" . esc_sql( $language_code ) . "' THEN 1 ELSE 0 END) AS `" . esc_sql( $language_code ) . '`'; if ( $language_code == $source_language ) { $sql_languages_having[] = '`' . esc_sql( $language_code ) . '`= 0'; } } $sql .= implode( ',', $sql_languages ); $sql .= " FROM {$this->wpdb->prefix}icl_translations WHERE element_type = %s "; $sql .= 'GROUP BY trid '; $sql .= 'HAVING ' . implode( ' AND ', $sql_languages_having ); $sql .= ' ORDER BY trid;'; $sql_prepared = $this->wpdb->prepare( $sql, array( 'post_' . $post_type ) ); $trid_results = $this->wpdb->get_results( $sql_prepared, 'ARRAY_A' ); //phpcs:disable PHPCompatibility.FunctionUse.NewFunctions.array_columnFound -- A fallback function is defined at `inc/hacks/missing-php-functions.php` $trid_list = is_array( $trid_results ) ? array_column( $trid_results, 'trid' ) : false; //phpcs:enable PHPCompatibility.FunctionUse.NewFunctions.array_columnFound if ( $trid_list ) { $sql = "SELECT trid AS value, CONCAT('[', t.language_code, '] ', (CASE p.post_title WHEN '' THEN CONCAT(LEFT(p.post_content, 30), '...') ELSE p.post_title END)) AS label FROM {$this->wpdb->posts} p INNER JOIN {$this->wpdb->prefix}icl_translations t ON p.ID = t.element_id WHERE t.element_type = %s AND t.language_code <> %s AND t.trid IN (" . wpml_prepare_in( $trid_list, '%d' ) . ') '; $sql_prepared = $this->wpdb->prepare( $sql, array( 'post_' . $post_type, $source_language ) ); $results = $this->wpdb->get_results( $sql_prepared ); } } return $results; } /** * @param WP_Post $post */ function meta_box( $post ) { $post_edit_metabox = new WPML_Meta_Boxes_Post_Edit_HTML( $this, $this->post_translation ); $post_edit_metabox->render_languages( $post ); do_action( 'wpml_post_edit_languages', $post ); } function meta_box_config( $post ) { /** @var TranslationManagement $iclTranslationManagement */ global $iclTranslationManagement, $wp_taxonomies, $wp_post_types, $sitepress_settings; if ( ! $this->settings['setup_complete'] ) { return; } $translation_modes = new WPML_Translation_Modes(); echo '<div class="icl_form_success" style="display:none">' . __( 'Settings saved', 'sitepress' ) . '</div>'; $cp_editable = true; $radio_disabled = ''; $translation_mode = WPML_CONTENT_TYPE_DONT_TRANSLATE; if ( isset( $sitepress_settings['custom_posts_sync_option'][ $post->post_type ] ) ) { $translation_mode = (int) $sitepress_settings['custom_posts_sync_option'][ $post->post_type ]; } $read_only_translation_mode = null; if ( array_key_exists( $post->post_type, $iclTranslationManagement->settings['custom-types_readonly_config'] ) ) { $read_only_translation_mode = (int) $iclTranslationManagement->settings['custom-types_readonly_config'][ $post->post_type ]; } $unlocked = false; if ( isset( $sitepress_settings['custom_posts_unlocked_option'][ $post->post_type ] ) ) { $unlocked = (bool) $sitepress_settings['custom_posts_unlocked_option'][ $post->post_type ]; } if ( null !== $read_only_translation_mode && ! $unlocked ) { if ( array_key_exists( $post->post_type, $this->get_translatable_documents() ) ) { $translation_mode = $read_only_translation_mode; $radio_disabled = 'disabled="disabled"'; } $cp_editable = false; } echo '<ul>'; foreach ( $translation_modes->get_options_for_post_type( $wp_post_types[ $post->post_type ]->labels->name ) as $value => $label ) { $checked = checked( $value, $translation_mode, false ); $disabled_state_for_mode = WPML_Custom_Types_Translation_UI::get_disabled_state_for_mode( $unlocked, (bool) $radio_disabled, $value, $post->post_type ); if ( $disabled_state_for_mode['reason_message'] ) { $label .= ' - ' . $disabled_state_for_mode['reason_message']; } $input_value = esc_attr( $post->post_type ) . ',' . esc_attr( $value ); echo '<li>'; echo '<label>'; echo '<input id="icl_make_translatable' . $input_value . '" name="icl_make_translatable" type="radio" value="' . $input_value . '" ' . $checked . $disabled_state_for_mode['html_attribute'] . '/>'; echo ' ' . wp_kses_post( $label ); echo '</label>'; echo '</li>'; } echo '</ul>'; echo '<br clear="all" /><span id="icl_mcs_details">'; if ( $translation_modes->is_translatable_mode( $translation_mode ) ) { $custom_taxonomies = array_diff( get_object_taxonomies( $post->post_type ), array( 'post_tag', 'category', 'nav_menu', 'link_category', 'post_format' ) ); if ( ! empty( $custom_taxonomies ) ) { ?> <table class="widefat"> <thead> <tr> <th colspan="2"><?php _e( 'Custom taxonomies', 'sitepress' ); ?></th> </tr> </thead> <tbody> <?php foreach ( $custom_taxonomies as $ctax ) : ?> <?php $checked_tax_translate = ! empty( $sitepress_settings['taxonomies_sync_option'][ $ctax ] ) ? ' checked="checked"' : ''; $checked_do_nothing = empty( $sitepress_settings['taxonomies_sync_option'][ $ctax ] ) ? ' checked="checked"' : ''; $radio_disabled = isset( $iclTranslationManagement->settings['taxonomies_readonly_config'][ $ctax ] ) ? ' disabled="disabled"' : ''; ?> <tr> <td><?php echo $wp_taxonomies[ $ctax ]->labels->name; ?></td> <td align="right"> <label><input name="icl_mcs_custom_taxs_<?php echo $ctax; ?>" class="icl_mcs_custom_taxs" type="radio" value="<?php echo $ctax; ?>" <?php echo $checked_tax_translate; ?><?php echo $radio_disabled; ?> /> <?php _e( 'Translate', 'sitepress' ); ?></label> <label><input name="icl_mcs_custom_taxs_<?php echo $ctax; ?>" type="radio" value="0" <?php echo $checked_do_nothing; ?><?php echo $radio_disabled; ?> /> <?php _e( 'Do nothing', 'sitepress' ); ?></label> </td> </tr> <?php endforeach; ?> </tbody> </table> <br/> <?php } if ( $this->get_wp_api() ->constant( 'WPML_TM_VERSION' ) ) { $settings_factory = $iclTranslationManagement->settings_factory(); $settings_factory->show_system_fields = array_key_exists( 'show_system_fields', $_GET ) ? (bool) $_GET['show_system_fields'] : false; ?> <p> <?php $toggle_system_fields = array( 'url' => add_query_arg( array( 'show_system_fields' => ! $settings_factory->show_system_fields ) ), 'text' => $settings_factory->show_system_fields ? __( 'Hide system fields', 'sitepress' ) : __( 'Show system fields', 'sitepress' ), ); ?> <a href="<?php echo esc_url( $toggle_system_fields['url'] ); ?>"><?php echo $toggle_system_fields['text']; ?></a> </p> <?php $settings_menu = new WPML_TM_Post_Edit_Custom_Field_Settings_Menu( $settings_factory, $post ); echo $settings_menu->render(); $custom_keys = $settings_menu->is_rendered(); } if ( ! empty( $custom_taxonomies ) || ! empty( $custom_keys ) ) { echo '<small>' . __( 'Note: Custom taxonomies and custom fields are shared across different post types.', 'sitepress' ) . '</small>'; } } echo '</span>'; if ( $cp_editable || ! empty( $custom_taxonomies ) || ! empty( $custom_keys ) ) { echo '<p class="submit" style="margin:0;padding:0"><input class="button-secondary" id="icl_make_translatable_submit" type="button" value="' . __( 'Apply', 'sitepress' ) . '" /></p><br clear="all" />'; wp_nonce_field( 'icl_mcs_inline_nonce', '_icl_nonce_imi' ); } else { _e( 'Nothing to configure.', 'sitepress' ); } } /** * Filters the WP_Query in case of retrieving an ajax post list, * e.g. links in the WYSIWYG post editor * * @param WP_Query $wpq * * @return WP_Query */ function pre_get_posts( $wpq ) { $post_action = isset( $_POST['action'] ) ? $_POST['action'] : null; if ( 'wp-link-ajax' === $post_action ) { /** @var WPML_Language_Resolution $wpml_language_resolution */ global $wpml_language_resolution; $lang = $wpml_language_resolution->get_referrer_language_code(); $this->set_this_lang( $lang ); $wpq->query_vars['suppress_filters'] = false; } return $wpq; } function comment_feed_join( $join ) { global $wp_query; $type = isset( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] ? esc_sql( $wp_query->query_vars['post_type'] ) : 'post'; $wp_query->query_vars['is_comment_feed'] = true; $join .= $this->wpdb->prepare( " JOIN {$this->wpdb->prefix}icl_translations wpml_translations ON {$this->wpdb->comments}.comment_post_ID = wpml_translations.element_id AND wpml_translations.element_type = %s AND wpml_translations.language_code = %s ", 'post_' . $type, $this->this_lang ); return $join; } /** * @param string[] $clauses * @param WP_Comment_Query $obj * * @return string[] */ function comments_clauses( $clauses, $obj ) { /** @var WPML_Query_Filter $wpml_query_filter */ global $wpml_query_filter; return $wpml_query_filter->comments_clauses_filter( $clauses, $obj ); } function language_filter() { require_once WPML_PLUGIN_PATH . '/menu/post-menus/wpml-post-language-filter.class.php'; $post_lang_filter = new WPML_Post_Language_Filter( $this->wpdb, $this ); $post_lang_filter->register_scripts(); return $post_lang_filter->post_language_filter(); } /** * @param array $arr Array of posts to filter * @param array $get_page_arguments Arguments passed to the `get_pages` function * * @return array */ function exclude_other_language_pages2( $arr, $get_page_arguments ) { global $wpdb; $post_hooks = new WPML_Remove_Pages_Not_In_Current_Language( $wpdb, $this ); return $post_hooks->filter_pages( $arr, $get_page_arguments ); } function wp_dropdown_pages( $output ) { if ( isset( $_POST['lang_switch'] ) ) { $post_id = esc_sql( $_POST['lang_switch'] ); $lang = esc_sql( strip_tags( $_GET['lang'] ) ); $parent = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT post_parent FROM {$this->wpdb->posts} WHERE ID=%d", $post_id ) ); if ( $parent ) { global $wpml_post_translations; $trid = $wpml_post_translations->get_element_trid( $parent ); $translated_parent_id = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT element_id FROM {$this->wpdb->prefix}icl_translations WHERE trid=%d AND element_type='post_page' AND language_code=%s", $trid, $lang ) ); if ( $translated_parent_id ) { $output = str_replace( 'selected="selected"', '', $output ); $output = str_replace( 'value="' . $translated_parent_id . '"', 'value="' . $translated_parent_id . '" selected="selected"', $output ); } } } elseif ( isset( $_GET['lang'] ) && isset( $_GET['trid'] ) ) { $lang = esc_sql( strip_tags( $_GET['lang'] ) ); $trid = esc_sql( $_GET['trid'] ); $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'page'; $elements_id = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT element_id FROM {$this->wpdb->prefix}icl_translations WHERE trid=%d AND element_type=%s AND element_id IS NOT NULL", $trid, 'post_' . $post_type ) ); $translated_parent_id = 0; foreach ( $elements_id as $element_id ) { $parent = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT post_parent FROM {$this->wpdb->posts} WHERE ID=%d", $element_id ) ); $trid = $this->wpdb->get_var( $this->wpdb->prepare( " SELECT trid FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $parent, 'post_' . $post_type ) ); $translated_parent_id = $this->wpdb->get_var( $this->wpdb->prepare( " SELECT element_id FROM {$this->wpdb->prefix}icl_translations WHERE trid=%d AND element_type=%s AND language_code=%s", $trid, 'post_' . $post_type, $lang ) ); if ( $translated_parent_id ) { break; } } if ( $translated_parent_id ) { $output = str_replace( 'selected="selected"', '', $output ); $output = str_replace( 'value="' . $translated_parent_id . '"', 'value="' . $translated_parent_id . '" selected="selected"', $output ); } } if ( ! $output ) { $output = '<select id="parent_id"><option value="">' . __( 'Main Page (no parent)', 'sitepress' ) . '</option></select>'; } return $output; } /** * @param int $trid * @param array<string> $active_languages * @param string $selected_language * @param array<string,\stdClass> $translations * @param string $type */ function add_translate_options( $trid, $active_languages, $selected_language, $translations, $type ) { if ( $trid && $this->wp_api->is_term_edit_page() ) : if ( ! $this->settings['setup_complete'] ) { return; } ?> <div id="icl_translate_options"> <?php // count number of translated and un-translated pages. $translations_found = 0; $untranslated_found = 0; foreach ( $active_languages as $lang ) { if ( $selected_language == $lang['code'] ) { continue; } if ( isset( $translations[ $lang['code'] ]->element_id ) ) { $translations_found += 1; } else { $untranslated_found += 1; } } ?> <?php if ( $untranslated_found > 0 ) : ?> <table cellspacing="1" class="icl_translations_table" style="min-width:200px;margin-top:10px;"> <thead> <tr> <th colspan="2" style="padding:4px;background-color:#DFDFDF"><b><?php esc_html_e( 'Translate', 'sitepress' ); ?></b></th> </tr> </thead> <tbody> <?php foreach ( $active_languages as $lang ) : if ( $selected_language == $lang['code'] ) { continue; } ?> <tr> <?php if ( ! isset( $translations[ $lang['code'] ]->element_id ) ) : ?> <td style="padding:4px;line-height:normal;"><?php echo esc_html( $lang['display_name'] ); ?></td> <?php $taxonomy = $_GET['taxonomy']; $post_type_q = isset( $_GET['post_type'] ) ? '&post_type=' . esc_html( $_GET['post_type'] ) : ''; $add_link = admin_url( 'edit-tags.php?taxonomy=' . esc_html( $taxonomy ) . '&trid=' . $trid . '&lang=' . esc_attr( $lang['code'] ) . '&source_lang=' . esc_attr( $selected_language ) . $post_type_q ); ?> <td style="padding:4px;line-height:normal;"><a href="<?php echo $add_link; ?>"><?php echo esc_html__( 'add', 'sitepress' ); ?></a></td> <?php endif; ?> </tr> <?php endforeach; ?> </tbody> </table> <?php endif; ?> <?php if ( $translations_found > 0 ) : ?> <p style="clear:both;margin:5px 0 5px 0"> <b><?php esc_html_e( 'Translations', 'sitepress' ); ?></b> (<a class="icl_toggle_show_translations" href="#" <?php if ( empty( $this->settings['show_translations_flag'] ) ) : ?> style="display:none;"<?php endif; ?>><?php esc_html_e( 'hide', 'sitepress' ); ?></a><a class="icl_toggle_show_translations" href="#" <?php if ( ! empty( $this->settings['show_translations_flag'] ) ) : ?> style="display:none;"<?php endif; ?>><?php esc_html_e( 'show', 'sitepress' ); ?></a>) <?php wp_nonce_field( 'toggle_show_translations_nonce', '_icl_nonce_tst' ); ?> <table cellspacing="1" width="100%" id="icl_translations_table" style=" <?php if ( empty( $this->settings['show_translations_flag'] ) ) : ?> display:none;<?php endif; ?>margin-left:0;"> <?php foreach ( $active_languages as $lang ) : if ( $selected_language === $lang['code'] ) { continue; } ?> <tr> <?php if ( isset( $translations[ $lang['code'] ]->element_id ) ) : ?> <td style="line-height:normal;"><?php echo esc_html( $lang['display_name'] ); ?></td> <?php $taxonomy = $_GET['taxonomy']; $edit_link = get_edit_term_link( $translations[ $lang['code'] ]->term_id, $taxonomy, isset( $_GET['post_type'] ) ? $_GET['post_type'] : null ); ?> <td align="right" width="30%" style="line-height:normal;"><?php echo isset( $translations[ $lang['code'] ]->name ) ? '<a href="' . esc_url( $edit_link ) . '" title="' . esc_attr__( 'Edit', 'sitepress' ) . '">' . esc_html( $translations[ $lang['code'] ]->name ) . '</a>' : esc_html__( 'n/a', 'sitepress' ); ?></td> <?php endif; ?> </tr> <?php endforeach; ?> </table> <?php endif; ?> <br clear="all" style="line-height:1px;"/> <?php /** * Extends the translation options for terms * * Called after rendering the translation options for terms, right before closing the main container tag * * @since 3.8.2 * * @param array $args { * Information about the current term and its translations * * @type int $trid The translation cluster ID. * @type array $active_languages All active languages data. * @type string $selected_language The language of the current term being edited. * @type array $translations All the available translations (including the current one). * @type string $type The translation element type (e.g. `tax_category`, `tax_{taxonomy}`. * } */ do_action( 'wpml_translate_options_terms', array( 'trid' => $trid, 'active_languages' => $active_languages, 'selected_language' => $selected_language, 'translations' => $translations, 'type' => $type, ) ); ?> </div> <?php endif; } /** * @param array|string $name * * @deprecated deprecated since version 3.1.8 * @return array|mixed */ function the_category_name_filter( $name ) { if ( is_array( $name ) ) { foreach ( $name as $k => $v ) { $name[ $k ] = $this->the_category_name_filter( $v ); } return $name; } if ( false === strpos( $name, '@' ) ) { return $name; } if ( false !== strpos( $name, '<a' ) ) { $int = preg_match_all( '|<a([^>]+)>([^<]+)</a>|i', $name, $matches ); if ( $int && count( $matches[0] ) > 1 ) { $originals = $filtered = array(); foreach ( $matches[0] as $m ) { $originals[] = $m; $filtered[] = $this->the_category_name_filter( $m ); } $name = str_replace( $originals, $filtered, $name ); } else { $name_sh = strip_tags( $name ); $exp = explode( '@', $name_sh ); $name = str_replace( $name_sh, trim( $exp[0] ), $name ); } } else { $name = preg_replace( '#(.*) @(.*)#i', '$1', $name ); } return $name; } /** * @param array<string,\stdClass>|WP_Error $terms * * @return mixed * @deprecated deprecated since version 3.1.8 */ function get_terms_filter( $terms ) { if ( is_wp_error( $terms ) ) { return $terms; } foreach ( $terms as $k => $v ) { if ( isset( $terms[ $k ]->name ) ) { $terms[ $k ]->name = $this->the_category_name_filter( $terms[ $k ]->name ); } } return $terms; } /** * Wrapper for \WPML_Term_Actions::save_term_actions * * @param int $cat_id * @param int $tt_id term taxonomy id of the new term * @param string $taxonomy * * @uses \WPML_Term_Actions::save_term_actions to handle required actions * when creating a term * * @hook delete_term */ function create_term( $cat_id, $tt_id, $taxonomy ) { $term_actions = $this->get_term_actions_helper(); $term_actions->save_term_actions( $tt_id, $taxonomy ); } /** * Wrapper for \WPML_Term_Actions::deleted_term_relationships * * @param int $post_id * @param array $delete_terms * * @uses \WPML_Term_Actions::deleted_term_relationships to handle required actions * when removing a term from a post * * @hook deleted_term_relationships */ function deleted_term_relationships( $post_id, $delete_terms, $taxonomy ) { if ( $this->get_setting( 'sync_post_taxonomies' ) ) { $term_actions = $this->get_term_actions_helper(); $term_actions->deleted_term_relationships( $post_id, $delete_terms, $taxonomy ); } } /** * Wrapper for \WPML_Term_Actions::delete_term_actions * * @param mixed $cat * @param int $tt_id term taxonomy id of the deleted term * @param string $taxonomy * * @uses \WPML_Term_Actions::delete_term_actions to handle required actions * when deleting a term * * @hook delete_term */ function delete_term( $cat, $tt_id, $taxonomy ) { $term_actions = $this->get_term_actions_helper(); $term_actions->delete_term_actions( $tt_id, $taxonomy ); } /** * @return WPML_Term_Actions */ public function get_term_actions_helper() { if ( ! isset( $this->term_actions ) ) { global $wpml_term_translations, $wpml_post_translations; $this->term_actions = new WPML_Term_Actions( $this, $this->wpdb, $wpml_post_translations, $wpml_term_translations ); } return $this->term_actions; } function get_terms_args_filter( $args, $taxonomies ) { if ( ! $this->term_query_filter ) { /** @var WPML_Term_Translation $wpml_term_translations */ global $wpml_term_translations; $this->term_query_filter = new WPML_Term_Query_Filter( $wpml_term_translations, new WPML_Debug_BackTrace( null, 5 ), $this->get_wpdb(), $this ); } $this->term_query_filter->set_lang( $this->get_current_language(), $this->get_default_language() ); return $this->term_query_filter->get_terms_args_filter( $args, $taxonomies ); } public function clear_term_query_filter() { $this->term_query_filter = null; } function terms_clauses( $clauses, $taxonomies, $args ) { $term_clauses = new WPML_Term_Clauses( $this, $this->wpdb, new WPML_Display_As_Translated_Taxonomy_Query( $this->wpdb, 'tt' ), new WPML_Debug_BackTrace( null, 10 ) ); return $term_clauses->filter( $clauses, $taxonomies, $args ); } /** * Saves the current $wp_query to \SitePress::$wp_query * * @global WP_Query $wp_query */ public function set_wp_query() { global $wp_query; if ( 'wp' === $this->get_wp_api() ->current_action() || ! $this->get_wp_api() ->did_action( 'wp' ) ) { $this->wp_query = is_object( $wp_query ) ? clone $wp_query : null; } } /** * @return WP_Query */ public function get_wp_query() { return $this->wp_query; } /** * Converts WP generated url to language specific based on plugin settings * * @param string $url * @param null|string $code (if null, fallback to default language for root page, or current language in all other cases) * * @return bool|string */ function convert_url( $url, $code = null ) { /** @var WPML_URL_Converter $wpml_url_converter */ global $wpml_url_converter; return $wpml_url_converter->convert_url( $url, $code ); } /** * @param string $url * @param string $code * * @return string */ function convert_url_string( $url, $code ) { /* @var WPML_URL_Converter $wpml_url_converter */ global $wpml_url_converter; return $wpml_url_converter->get_strategy() ->convert_url_string( $url, $code ); } function language_url( $code = null ) { global $wpml_url_converter; if ( is_null( $code ) ) { $code = $this->this_lang; } $abs_home = $wpml_url_converter->get_abs_home(); $url = $this->convert_url( $abs_home, $code ); return $url; } function post_type_archive_link_filter( $link, $post_type ) { /* @var WPML_URL_Converter $wpml_url_converter */ global $wpml_url_converter; if ( isset( $this->settings['custom_posts_sync_option'][ $post_type ] ) && $this->settings['custom_posts_sync_option'][ $post_type ] ) { $link = $wpml_url_converter->convert_url( $link ); $link = $this->adjust_cpt_in_url( $link, $post_type ); } return $link; } public function adjust_cpt_in_url( $link, $post_type, $language_code = null ) { if ( $this->cpt_slug_translation_turned_on( $post_type ) ) { $url_cpt_converter = new WPML_URL_Converter_CPT(); $link = $url_cpt_converter->adjust_cpt_slug_in_url( $link, $post_type, $language_code ); } return $link; } /** * Check if "Translate base slugs (via WPML String Translation)." * and slug translation for given $post_type are both checked * * @param string $post_type * * @return boolean */ private function cpt_slug_translation_turned_on( $post_type ) { return isset( $this->settings['posts_slug_translation']['types'][ $post_type ] ) && $this->settings['posts_slug_translation']['types'][ $post_type ] && get_option( 'wpml_base_slug_translation' ); } function home_url( $url ) { return $url; } function get_comment_link_filter( $link ) { // decode html characters since they are already encoded in the template for some reason $link = html_entity_decode( $link ); return $link; } /** * @return WPML_Query_Utils */ public function get_query_utils() { return new WPML_Query_Utils( $this->wpdb, $this->wp_api, array_keys( $this->get_display_as_translated_documents() ) ); } /** * @return WPML_Root_Page_Actions */ public function get_root_page_utils() { return wpml_get_root_page_actions_obj(); } /** * @return WPML_WP_API */ public function get_wp_api() { $this->wp_api = $this->wp_api ? $this->wp_api : new WPML_WP_API(); return $this->wp_api; } /** * @return wpdb */ public function &wpdb() { return $this->wpdb; } /** * @return TranslationManagement */ public function &core_tm() { global $iclTranslationManagement; return $iclTranslationManagement; } /** * @return WPML_Term_Translation */ function &term_translations() { return $this->term_translation; } /** * @return WPML_Post_Translation */ function &post_translations() { return $this->post_translation; } /** * @param WPML_WP_API $wp_api */ public function set_wp_api( $wp_api ) { $this->wp_api = $wp_api; } public function get_ls_languages( $template_args = array() ) { /** @var WP_Query|null $wp_query */ global $wp_query, $wpml_post_translations, $wpml_term_translations, $wpml_url_converter; $this->set_wp_query(); $current_language = $this->get_current_language(); $default_language = $this->get_default_language(); $cache = new WPML_LS_Languages_Cache( $template_args, $current_language, $default_language, $this->wp_query ); $ls_languages = $cache->get(); if ( $ls_languages ) { return $ls_languages; } // use original wp_query for this // backup current $wp_query if ( ! isset( $wp_query ) ) { return apply_filters( 'wpml_active_languages_access', $this->get_active_languages(), array( 'action' => 'read' ) ); } $ls_languages_status = WPML_Get_LS_Languages_Status::get_instance(); $ls_languages_status->start(); $_wp_query_back = clone $wp_query; // This part will reset the local value of $wp_query to it's global state. // `unset` function called on globals only removes local variable and then declaring it global again restores global state. unset( $wp_query ); global $wp_query; // make it global again after unset if ( is_object( $this->wp_query ) ) { $wp_query = clone $this->wp_query; } else { // If `$this->wp_query` is not set at least uss native $wp_query $this->wp_query = clone $wp_query; } $w_active_languages = apply_filters( 'wpml_active_languages_access', $this->get_active_languages(), array( 'action' => 'read' ) ); if ( isset( $template_args['skip_missing'] ) ) { // override default setting $icl_lso_link_empty = ! $template_args['skip_missing']; } else { $icl_lso_link_empty = $this->settings['icl_lso_link_empty']; } $link_empty_to = ! empty( $template_args['link_empty_to'] ) ? $template_args['link_empty_to'] : null; $languages_helper = new WPML_Languages( $wpml_term_translations, $this, $wpml_post_translations ); /** @var array<string,\stdClass> $translations */ /** @var \WP_Query $wp_query */ list( $translations, $wp_query ) = $languages_helper->get_ls_translations( $wp_query, $_wp_query_back, $this->wp_query ); $display_as_translated_ls_link = new WPML_LS_Display_As_Translated_Link( $this, $wpml_url_converter->get_strategy(), $this->wp_query, new WPML_Translation_Element_Factory( $this ) ); // 2. determine url foreach ( $w_active_languages as $k => $lang ) { $skip_lang = false; if ( is_singular() || ( isset( $_wp_query_back->query['name'] ) && isset( $_wp_query_back->query['post_type'] ) ) || $this->is_page_query() ) { $this_lang_tmp = $this->this_lang; $this->switch_lang( $lang['code'] ); $lang_page_on_front = get_option( 'page_on_front' ); $lang_page_for_posts = get_option( 'page_for_posts' ); if ( $lang_page_on_front ) { $lang_page_on_front = icl_object_id( $lang_page_on_front, 'page', false, $lang['code'] ); } if ( $lang_page_for_posts ) { $lang_page_for_posts = icl_object_id( $lang_page_for_posts, 'page', false, $lang['code'] ); } if ( 'page' === get_option( 'show_on_front' ) && ! empty( $translations[ $lang['code'] ] ) && $translations[ $lang['code'] ]->element_id == $lang_page_on_front ) { $lang['translated_url'] = $this->language_url( $lang['code'] ); } elseif ( 'page' == get_option( 'show_on_front' ) && ! empty( $translations[ $lang['code'] ] ) && $translations[ $lang['code'] ]->element_id && $translations[ $lang['code'] ]->element_id == $lang_page_for_posts ) { if ( $lang_page_for_posts ) { $lang['translated_url'] = get_permalink( $lang_page_for_posts ); } else { $lang['translated_url'] = $this->language_url( $lang['code'] ); } } else { if ( ! empty( $translations[ $lang['code'] ] ) && isset( $translations[ $lang['code'] ]->post_title ) ) { $this->switch_lang( $lang['code'] ); $lang['translated_url'] = get_permalink( $translations[ $lang['code'] ]->element_id ); $lang['missing'] = 0; $this->switch_lang( $current_language ); } else { $translated_url = $display_as_translated_ls_link->get_url( $translations, $lang['code'] ); if ( $translated_url ) { $lang['translated_url'] = $translated_url; } else { if ( $icl_lso_link_empty ) { if ( ! empty( $link_empty_to ) ) { $lang['translated_url'] = str_replace( '{%lang}', $lang['code'], $link_empty_to ); } else { $lang['translated_url'] = $this->language_url( $lang['code'] ); } } else { $skip_lang = true; } } $lang['missing'] = 1; } } $this->switch_lang( $this_lang_tmp ); } elseif ( is_category() || is_tax() || is_tag() ) { global $icl_adjust_id_url_filter_off; $icl_adjust_id_url_filter_off = true; list( $lang, $skip_lang ) = $languages_helper->add_tax_url_to_ls_lang( $lang, $translations, $icl_lso_link_empty, $skip_lang, $link_empty_to, $display_as_translated_ls_link ); $icl_adjust_id_url_filter_off = false; } elseif ( is_author() ) { global $authordata; if ( empty( $authordata ) ) { $authordata = get_userdata( get_query_var( 'author' ) ); } remove_filter( 'home_url', array( $this, 'home_url' ), 1 ); remove_filter( 'author_link', array( $this, 'author_link' ) ); list( $lang, $skip_lang ) = $languages_helper->add_author_url_to_ls_lang( $lang, $default_language, $authordata, $icl_lso_link_empty, $skip_lang, $link_empty_to ); add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 ); add_filter( 'author_link', array( $this, 'author_link' ) ); } elseif ( is_archive() && ! is_tag() ) { global $icl_archive_url_filter_off; $icl_archive_url_filter_off = true; remove_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10 ); list( $lang, $skip_lang ) = $languages_helper->add_date_or_cpt_url_to_ls_lang( $lang, $default_language, $this->wp_query, $icl_lso_link_empty, $skip_lang, $link_empty_to ); add_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10, 2 ); $icl_archive_url_filter_off = false; } elseif ( is_search() ) { $url_glue = strpos( $this->language_url( $lang['code'] ), '?' ) === false ? '?' : '&'; $lang['translated_url'] = $this->language_url( $lang['code'] ) . $url_glue . 's=' . urlencode( $wp_query->query['s'] ); } else { if ( $icl_lso_link_empty || is_home() || is_404() || ( 'page' === get_option( 'show_on_front' ) && ( $this->wp_query->queried_object_id == get_option( 'page_on_front' ) || $this->wp_query->queried_object_id == get_option( 'page_for_posts' ) ) ) || WPML_Root_Page::is_current_request_root() ) { $lang['translated_url'] = $this->language_url( $lang['code'] ); $skip_lang = false; } else { $skip_lang = true; unset( $w_active_languages[ $k ] ); } } if ( ! $skip_lang ) { $w_active_languages[ $k ] = $lang; } else { unset( $w_active_languages[ $k ] ); } } // 3. foreach ( $w_active_languages as $k => $v ) { $w_active_languages[ $k ] = $languages_helper->get_ls_language( $k, $current_language, $w_active_languages[ $k ] ); } // 4. pass GET parameters $parameters_copied = apply_filters( 'icl_lang_sel_copy_parameters', array_map( 'trim', explode( ',', wpml_get_setting_filter( '', 'icl_lang_sel_copy_parameters' ) ) ) ); if ( $parameters_copied ) { foreach ( $_GET as $k => $v ) { if ( in_array( $k, $parameters_copied, true ) ) { $gets_passed[ $k ] = $v; } } } if ( ! empty( $gets_passed ) ) { foreach ( $w_active_languages as $code => $al ) { if ( empty( $al['missing'] ) ) { $w_active_languages[ $code ]['url'] = add_query_arg( $gets_passed, $w_active_languages[ $code ]['url'] ); } } } // restore current $wp_query unset( $wp_query ); global $wp_query; // make it global again after unset $wp_query = clone $_wp_query_back; unset( $_wp_query_back ); $w_active_languages = apply_filters( 'icl_ls_languages', $w_active_languages ); $w_active_languages = $languages_helper->sort_ls_languages( $w_active_languages, $template_args ); // Change the url, in case languages in subdomains are set. if ( $this->get_setting( 'language_negotiation_type' ) == WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN ) { foreach ( $w_active_languages as $lang => $element ) { $w_active_languages[ $lang ]['url'] = $this->convert_url( $element['url'], $lang ); } } $w_active_languages = $this->maybeHideLanguages( $w_active_languages ); wp_reset_query(); $cache->set( $w_active_languages ); $ls_languages_status->end(); return $w_active_languages; } function get_display_single_language_name_filter( $empty, $args ) { $language_code = $args['language_code']; $display_code = isset( $args['display_code'] ) ? $args['display_code'] : null; return $this->get_display_language_name( $language_code, $display_code ); } function get_display_language_name( $lang_code, $display_code = null ) { $display_code = $display_code ? $display_code : $this->get_current_language(); $translated_name = $this->get_language_name_cache() ->get( $lang_code . $display_code ); if ( ! $translated_name ) { $display_code = $display_code === 'all' ? $this->get_admin_language() : $display_code; $translated_name = $this->wpdb->get_var( $this->wpdb->prepare( " SELECT name FROM {$this->wpdb->prefix}icl_languages_translations WHERE language_code=%s AND display_language_code=%s", $lang_code, $display_code ) ); $this->get_language_name_cache() ->set( $lang_code . $display_code, $translated_name ); } return $translated_name; } function get_flag( $lang_code ) { return $this->flags->get_flag( $lang_code ); } function get_flag_url( $code ) { return $this->flags->get_flag_url( $code ); } /** * @param string $code * * @return string * @deprecated Use \SitePress::get_flag_image instead */ function get_flag_img( $code ) { return $this->get_flag_image( $code ); } /** * @param string $code * @param int[] $size An array describing [ $width, $height ]. It defaults to [18, 12]. * @param string $fallback_text * @param string[] $css_classes Array of CSS class strings. * * @return string */ function get_flag_image( $code, $size = [], $fallback_text = '', $css_classes = [] ) { return $this->flags->get_flag_image( $code, $size, $fallback_text, $css_classes ); } function clear_flags_cache() { $this->flags->clear(); } /** * @deprecated * * @return string */ function get_desktop_language_selector() { return $this->get_language_selector(); } /** * @deprecated * * @return string */ function get_mobile_language_selector() { return $this->get_language_selector(); } /** * @deprecated * * @return string */ function get_language_selector() { ob_start(); do_action( 'wpml_add_language_selector' ); $output = ob_get_contents(); ob_end_clean(); return $output; } /** * @deprecated */ function language_selector() { do_action( 'wpml_add_language_selector' ); } public function add_extra_debug_info( $extra_debug ) { $extra_debug['WPML'] = $this->get_settings(); return $extra_debug; } function set_default_categories( $def_cat ) { $this->settings['default_categories'] = $def_cat; $this->save_settings(); } function pre_option_default_category( $setting ) { $lang = filter_input( INPUT_POST, 'icl_post_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $lang = $lang ? $lang : filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $lang = $lang ? $lang : $this->get_current_language(); $lang = $lang === 'all' ? $this->get_default_language() : $lang; $ttid = isset( $this->settings['default_categories'][ $lang ] ) ? (int) $this->settings['default_categories'][ $lang ] : 0; return $ttid === 0 ? null : $this->wpdb->get_var( $this->wpdb->prepare( "SELECT term_id FROM {$this->wpdb->term_taxonomy} WHERE term_taxonomy_id= %d AND taxonomy='category'", $ttid ) ); } function update_option_default_category( $oldvalue, $new_value ) { $new_value = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE taxonomy='category' AND term_id=%d", $new_value ) ); $translations = $new_value ? $this->get_element_translations( $this->get_element_trid( (int) $new_value, 'tax_category' ) ) : []; if ( ! empty( $translations ) ) { $icl_settings = []; foreach ( $translations as $t ) { $icl_settings['default_categories'][ $t->language_code ] = $t->element_id; } if ( $icl_settings ) { $this->save_settings( $icl_settings ); } } } /** * @param WP_Term $term * * @return WP_Term */ public function get_term_adjust_id( $term ) { global $icl_adjust_id_url_filter_off, $wpml_term_translations, $wpml_post_translations; if ( ! $this->wpml_term_adjust_id ) { $this->wpml_term_adjust_id = new WPML_Term_Adjust_Id( new WPML_Debug_BackTrace( null, 15 ), $wpml_term_translations, $wpml_post_translations, $this ); } /** * Allow to disable the automatic translation of terms. * * @since 4.5 * * @param bool $icl_adjust_id_url_filter_off * @param WP_Term $term */ return $this->wpml_term_adjust_id->filter( $term, apply_filters( 'wpml_disable_term_adjust_id', $icl_adjust_id_url_filter_off, $term ) ); } public function edited_term_action() { WPML_Non_Persistent_Cache::flush_group( [ 'WPML_Term_Adjust_Id' ] ); } function get_pages_adjust_ids( $pages, $args ) { if ( $pages && $this->get_current_language() !== $this->get_default_language() ) { $args_hash = md5( (string) wp_json_encode( $args ) ); $cache_key_args = md5( (string) wp_json_encode( wp_list_pluck( $pages, 'ID' ) ) ); $cache_key_args .= ':'; $cache_key_args .= $args_hash; $cache_key = $cache_key_args; $cache_group = 'get_pages_adjust_ids'; $found = false; $cached_result = wp_cache_get( $cache_key, $cache_group, false, $found ); if ( ! $found ) { if ( $args['include'] ) { $args = $this->translate_csv_page_ids( $args, 'include' ); } if ( $args['exclude'] ) { $args = $this->translate_csv_page_ids( $args, 'exclude' ); } if ( $args['child_of'] ) { $args['child_of'] = icl_object_id( $args['child_of'], 'page', true ); } if ( md5( (string) wp_json_encode( $args ) ) !== $args_hash ) { remove_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1 ); $pages = get_pages( $args ); add_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1, 2 ); } wp_cache_set( $cache_key, $pages, $cache_group ); } else { $pages = $cached_result; } } return $pages; } private function translate_csv_page_ids( $args, $index ) { $translated_ids = array(); if ( array_key_exists( $index, $args ) ) { $original_ids = $args[ $index ]; if ( ! is_array( $args[ $index ] ) ) { $original_ids = array_map( 'trim', explode( ',', $args[ $index ] ) ); } foreach ( $original_ids as $i ) { $t = icl_object_id( $i, 'page', true ); if ( $t ) { $translated_ids[] = $t; } } } $args[ $index ] = implode( ',', $translated_ids ); return $args; } // feeds links function feed_link( $out ) { return $this->convert_url( $out ); } // commenting links function post_comments_feed_link( $out ) { if ( $this->settings['language_negotiation_type'] == 3 ) { $out = preg_replace( '@(\?|&)lang=([^/]+)/feed/@i', 'feed/$1lang=$2', $out ); } return $out; } function trackback_url( $out ) { return $this->convert_url( $out ); } function user_trailingslashit( $string, $type_of_url ) { // fixes comment link for when the comments list pagination is enabled if ( $type_of_url == 'comment' ) { $string = preg_replace( '@(.*)/\?lang=([a-z-]+)/(.*)@is', '$1/$3?lang=$2', $string ); } return $string; } /** * Fixes double dashes * * @param string $url * * @return string */ function author_link( $url ) { $url = $this->convert_url( $url ); return is_string( $url ) ? preg_replace( '#^http://(.+)//(.+)$#', 'http://$1/$2', $url ) : ''; } function pre_option_home( $setting = false ) { if ( ! defined( 'TEMPLATEPATH' ) ) { return $setting; } if ( null === $this->template_real_path ) { $this->template_real_path = realpath( TEMPLATEPATH ); } // The TEMPLATEPATH could not be resolved (the theme folder is possibly missing). if ( false === $this->template_real_path ) { return $setting; } $debug_backtrace = $this->get_backtrace( 7 ); // Ignore objects and limit to first 7 stack frames, since 6 is the highest index we use $function = isset( $debug_backtrace[4] ) && isset( $debug_backtrace[4]['function'] ) ? $debug_backtrace[4]['function'] : null; $previous_function = isset( $debug_backtrace[5] ) && isset( $debug_backtrace[5]['function'] ) ? $debug_backtrace[5]['function'] : null; $inc_methods = array( 'include', 'include_once', 'require', 'require_once' ); if ( $function === 'get_bloginfo' && $previous_function === 'bloginfo' ) { // case of bloginfo $is_template_file = false !== strpos( $debug_backtrace[5]['file'], (string) $this->template_real_path ); $is_direct_call = in_array( $debug_backtrace[6]['function'], $inc_methods ) || ( false !== strpos( $debug_backtrace[6]['file'], (string) $this->template_real_path ) ); } elseif ( in_array( $function, array( 'get_bloginfo', 'get_settings' ), true ) ) { // case of get_bloginfo or get_settings $is_template_file = false !== strpos( $debug_backtrace[4]['file'], (string) $this->template_real_path ); $is_direct_call = in_array( $previous_function, $inc_methods ) || ( false !== strpos( $debug_backtrace[5]['file'], (string) $this->template_real_path ) ); } else { // case of get_option $is_template_file = isset( $debug_backtrace[3]['file'] ) && ( false !== strpos( $debug_backtrace[3]['file'], (string) $this->template_real_path ) ); $is_direct_call = in_array( $function, $inc_methods ) || ( isset( $debug_backtrace[4]['file'] ) && false !== strpos( $debug_backtrace[4]['file'], (string) $this->template_real_path ) ); } $home_url = $is_template_file && $is_direct_call ? $this->language_url( $this->this_lang ) : $setting; return $home_url; } /** * * * @param array $public_query_vars * * @return array with added 'lang' index */ function query_vars( $public_query_vars ) { global $wp_query; $public_query_vars[] = 'lang'; $wp_query->query_vars['lang'] = $this->this_lang; return $public_query_vars; } function parse_query( $q ) { global $wpml_query_filter; $query_parser = new WPML_Query_Parser( $this, $wpml_query_filter ); return $query_parser->parse_query( $q ); } function adjust_wp_list_pages_excludes( $pages ) { foreach ( $pages as $k => $v ) { $pages[ $k ] = icl_object_id( $v, 'page', true ); } return $pages; } function language_attributes( $output ) { // This has been implemented to be a safe hotfix for a security issue. // This is not a proper fix, since there is another filter in WPML_Locale, and it sometimes contains different // value for the current locale. // We have a ticket (wpmldev-1640) to fix it. return preg_replace( '#lang="(.*?)"#', 'lang="' . str_replace( '_', '-', $this->this_lang ) . '"', $output ); } // Localization function plugin_localization() { load_plugin_textdomain( 'sitepress', false, WPML_PLUGIN_FOLDER . '/locale' ); } /** * @return WPML_Locale */ public function get_wpml_locale() { return $this->locale_utils; } function locale_filter( $default ) { if ( ! $this->get_settings() ) { return $default; } return $this->locale_utils->locale(); } function get_language_tag( $code ) { if ( is_null( $code ) ) { return false; } $found = false; $tags = wp_cache_get( 'icl_language_tags', '', false, $found ); if ( $found === true ) { if ( isset( $tags[ $code ] ) ) { return $tags[ $code ]; } } $all_tags = array(); $all_tags_data = $this->wpdb->get_results( "SELECT code, tag FROM {$this->wpdb->prefix}icl_languages" ); foreach ( $all_tags_data as $tag_data ) { $all_tags[ $tag_data->code ] = $tag_data->tag; } $tag = isset( $all_tags[ $code ] ) ? $all_tags[ $code ] : false; wp_cache_set( 'icl_language_tags', $all_tags ); return $tag ? $tag : $this->get_locale( $code ); } function get_locale( $code ) { return $this->locale_utils->get_locale( $code ); } function switch_locale( $lang_code = false ) { $this->locale_utils->switch_locale( $lang_code ); } function get_locale_file_names() { return $this->locale_utils->get_locale_file_names(); } function pre_option_page_on_front() { global $switched; $pre_option_page = new WPML_Pre_Option_Page( $this->wpdb, $this, $switched, $this->this_lang ); return $pre_option_page->get( 'page_on_front' ); } function pre_option_page_for_posts() { global $switched; $pre_option_page = new WPML_Pre_Option_Page( $this->wpdb, $this, $switched, $this->this_lang ); return $pre_option_page->get( 'page_for_posts' ); } function fix_trashed_front_or_posts_page_settings( $post_id ) { global $switched; $pre_option_page_current = new WPML_Pre_Option_Page( $this->wpdb, $this, $switched, $this->this_lang ); $pre_option_page_current->fix_trashed_front_or_posts_page_settings( $post_id ); } // adds the language parameter to the admin post filtering/search function restrict_manage_posts() { echo '<input type="hidden" name="lang" value="' . esc_attr( $this->this_lang ) . '" />'; } function get_edit_term_link( $link, $term_id, $taxonomy, $object_type ) { /** @var WPML_Term_Translation $wpml_term_translations */ global $wpml_term_translations; $default_language = $this->get_default_language(); $current_language = $this->get_current_language(); $lang = $wpml_term_translations->lang_code_by_termid( $term_id ); $lang = $lang ? $lang : $default_language; if ( $lang !== $default_language || $current_language !== $default_language ) { $link .= '&lang=' . $lang; } return $link; } function noscript_notice() { ?> <noscript> <div class="error"><?php echo __( 'WPML admin screens require JavaScript in order to display. JavaScript is currently off in your browser.', 'sitepress' ); ?></div> </noscript> <?php } function save_user_options() { $user_id = $_POST['user_id']; if ( $user_id ) { if ( $this->get_wp_api() ->is_admin() ) { update_user_meta( $user_id, 'icl_admin_language', $_POST['icl_user_admin_language'] ); } update_user_meta( $user_id, 'icl_show_hidden_languages', isset( $_POST['icl_show_hidden_languages'] ) ? (int) $_POST['icl_show_hidden_languages'] : 0 ); update_user_meta( $user_id, 'icl_admin_language_for_edit', isset( $_POST['icl_admin_language_for_edit'] ) ? (int) $_POST['icl_admin_language_for_edit'] : 0 ); $this->reset_admin_language_cookie(); } } function help_admin_notice() { $args = array( 'name' => 'wpml-intro', 'iso' => defined( 'WPLANG' ) ? WPLANG : '', ); $q = http_build_query( $args ); ?> <div id="message" class="notice wpml-notice otgs-is-dismissible"> <p> <?php _e( 'You need to configure WPML before you can start translating.', 'sitepress' ); ?> </p> <p> <input type="hidden" id="icl_dismiss_help_nonce" value="<?php echo $icl_dhn = wp_create_nonce( 'dismiss_help_nonce' ); ?>"/> <a href="admin.php?page=<?php echo WPML_PLUGIN_FOLDER . '/menu/setup.php'; ?>" class="button-primary configure-wpml"><?php _e( 'Configure WPML', 'sitepress' ); ?></a> <a href="https://wpml.org/documentation/getting-started-guide/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore" target="_blank"> <?php _e( 'Getting started guide', 'sitepress' ); ?> </a> </p> <span title="<?php _e( 'Stop showing this message', 'sitepress' ); ?>" id="icl_dismiss_help" class="notice-dismiss"><span class="screen-reader-text"><?php _e( 'Dismiss', 'sitepress' ); ?></span></span> </div> <?php } function upgrade_notice() { include WPML_PLUGIN_PATH . '/menu/upgrade_notice.php'; } function display_wpml_footer() { if ( $this->settings['promote_wpml'] ) { $wpml_site_languages = array( 'es', 'de', 'fr', 'pt-br', 'ja', 'ru', 'zh-hans', 'it', 'he', 'ar' ); $url_language_code = in_array( ICL_LANGUAGE_CODE, $wpml_site_languages ) ? ICL_LANGUAGE_CODE . '/' : ''; $part_one = _x( 'Multilingual WordPress', 'Multilingual WordPress with WPML: first part', 'sitepress' ); $part_two = _x( 'with WPML', 'Multilingual WordPress with WPML: second part', 'sitepress' ); echo '<p id="wpml_credit_footer"><a href="https://wpml.org/' . $url_language_code . '" rel="nofollow" >' . $part_one . '</a> ' . $part_two . '</p>'; } } function xmlrpc_methods( $methods ) { // Translation proxy XMLRPC calls /** * @deprecated Use `wpml.get_languages` XMLRPC call * @since 3.5.0 */ $methods['translationproxy.get_languages_list'] = array( $this, 'xmlrpc_get_languages_list' ); return $methods; } function xmlrpc_call_actions( $action ) { $params = icl_xml2array( print_r( file_get_contents( 'php://input' ), true ) ); add_filter( 'is_protected_meta', array( $this, 'xml_unprotect_wpml_meta' ), 10, 3 ); switch ( $action ) { case 'wp.getPage': case 'blogger.getPost': // yet this doesn't return custom fields if ( isset( $params['methodCall']['params']['param'][1]['value']['int']['value'] ) ) { $page_id = (int) filter_var( $params['methodCall']['params']['param'][1]['value']['int']['value'], FILTER_SANITIZE_NUMBER_INT ); $lang_details = $this->get_element_language_details( $page_id, 'post_' . get_post_type( $page_id ) ); $this->set_this_lang( $lang_details->language_code ); // set the current language to the posts language update_post_meta( $page_id, '_wpml_language', $lang_details->language_code ); update_post_meta( $page_id, '_wpml_trid', $lang_details->trid ); $active_languages = $this->get_active_languages(); $res = $this->get_element_translations( $lang_details->trid ); $translations = array(); foreach ( $active_languages as $k => $v ) { if ( $page_id != $res[ $k ]->element_id ) { $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0; } } update_post_meta( $page_id, '_wpml_translations', wp_json_encode( $translations ) ); } break; case 'metaWeblog.getPost': if ( isset( $params['methodCall']['params']['param'][0]['value']['int']['value'] ) ) { $page_id = (int) filter_var( $params['methodCall']['params']['param'][0]['value']['int']['value'], FILTER_SANITIZE_NUMBER_INT ); $lang_details = $this->get_element_language_details( $page_id, 'post_' . get_post_type( $page_id ) ); $this->set_this_lang( $lang_details->language_code ); // set the current language to the posts language update_post_meta( $page_id, '_wpml_language', $lang_details->language_code ); update_post_meta( $page_id, '_wpml_trid', $lang_details->trid ); $active_languages = $this->get_active_languages(); $res = $this->get_element_translations( $lang_details->trid ); $translations = array(); foreach ( $active_languages as $k => $v ) { if ( isset( $res[ $k ] ) && $page_id != $res[ $k ]->element_id ) { $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0; } } update_post_meta( $page_id, '_wpml_translations', wp_json_encode( $translations ) ); } break; case 'metaWeblog.getRecentPosts': if ( isset( $params['methodCall']['params']['param'][3]['value']['int']['value'] ) ) { $num_posts = (int) filter_var( $params['methodCall']['params']['param'][3]['value']['int']['value'], FILTER_SANITIZE_NUMBER_INT ); if ( $num_posts ) { $posts = get_posts( [ 'suppress_filters' => false, 'numberposts' => $num_posts ] ); foreach ( $posts as $p ) { $lang_details = $this->get_element_language_details( $p->ID, 'post_post' ); update_post_meta( $p->ID, '_wpml_language', $lang_details->language_code ); update_post_meta( $p->ID, '_wpml_trid', $lang_details->trid ); $active_languages = $this->get_active_languages(); $res = $this->get_element_translations( $lang_details->trid ); $translations = array(); foreach ( $active_languages as $k => $v ) { if ( $p->ID != $res[ $k ]->element_id ) { $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0; } } update_post_meta( $p->ID, '_wpml_translations', wp_json_encode( $translations ) ); } } } break; } } /** * @param string $lang * * @return array|bool|mixed|null * @deprecated Use `wpml.get_languages` XMLRPC call * @since 3.5.0 * */ function xmlrpc_get_languages_list( $lang ) { if ( ! is_null( $lang ) ) { if ( ! $this->wpdb->get_var( $this->wpdb->prepare( "SELECT code FROM {$this->wpdb->prefix}icl_languages WHERE code=%s", $lang ) ) ) { $IXR_Error = new IXR_Error( 401, __( 'Invalid language code', 'sitepress' ) ); echo $IXR_Error->getXml(); exit( 1 ); } $this->admin_language = $lang; } define( 'WP_ADMIN', true ); // hack - allow to force display language $active_languages = $this->get_active_languages( true ); return $active_languages; } function xml_unprotect_wpml_meta( $protected, $meta_key, $meta_type ) { $metas_list = array( '_wpml_trid', '_wpml_translations', '_wpml_language' ); if ( in_array( $meta_key, $metas_list, true ) ) { $protected = false; } return $protected; } function meta_generator_tag() { $lids = array(); $active_languages = $this->get_active_languages(); if ( $active_languages ) { foreach ( $active_languages as $l ) { $lids[] = $l['id']; } $stt = join( ',', $lids ); $stt .= ';'; printf( '<meta name="generator" content="WPML ver:%s stt:%s" />' . PHP_EOL, ICL_SITEPRESS_VERSION, $stt ); } } function get_language_cookie() { global $wpml_request_handler; return $wpml_request_handler->get_cookie_lang(); } function set_admin_language_cookie( $lang = false ) { if ( is_admin() ) { global $wpml_request_handler; $wpml_request_handler->set_language_cookie( $lang ? $lang : $this->get_default_language() ); } } function get_admin_language_cookie() { global $wpml_request_handler; return ( is_admin() || wpml_is_rest_request() ) ? $wpml_request_handler->get_cookie_lang() : null; } function reset_admin_language_cookie() { $this->set_admin_language_cookie( $this->get_default_language() ); } function rewrite_rules_filter( $value ) { global $wpml_language_resolution; $active_language_codes = $wpml_language_resolution->get_active_language_codes(); $filter = new WPML_Rewrite_Rules_Filter( $active_language_codes ); return $filter->rid_of_language_param( $value ); } function is_rtl( $lang = false ) { if ( is_admin() ) { if ( empty( $lang ) ) { $lang = $this->get_admin_language(); } } else { if ( empty( $lang ) ) { $lang = $this->get_current_language(); } } $rtl_languages_codes = apply_filters( 'wpml_rtl_languages_codes', array( 'ar', 'he', 'fa', 'ku', 'ur' ) ); return in_array( $lang, $rtl_languages_codes ); } /** * Returns an array of post types that are set to be translatable * * @param array $default Set the default value, in case no posts are set to be translatable (default: array()) * * @return array */ function get_translatable_documents_filter( $default = array() ) { $post_types = $this->get_translatable_documents( false ); if ( ! $post_types ) { $post_types = $default; } return $post_types; } function get_translatable_documents( $include_not_synced = false ) { $translatable_post_types = array(); $exceptions = array( 'revision', 'nav_menu_item' ); $translation_modes = new WPML_Translation_Modes(); foreach ( $this->get_wp_api() ->get_wp_post_types_global() as $k => $v ) { if ( ! in_array( $k, $exceptions ) ) { if ( ! $include_not_synced && ( empty( $this->settings['custom_posts_sync_option'][ $k ] ) || ! $translation_modes->is_translatable_mode( $this->settings['custom_posts_sync_option'][ $k ] ) ) ) { continue; } $translatable_post_types[ $k ] = $v; } } $translatable_post_types = apply_filters( 'get_translatable_documents', $translatable_post_types ); $tm_settings = $this->get_setting( 'translation-management', array() ); if ( array_key_exists( 'custom-types_readonly_config', $tm_settings ) ) { $cpt_unlocked_options = $this->get_setting( 'custom_posts_unlocked_option', array() ); $settings_filters = new WPML_Settings_Filters(); $translatable_post_types = $settings_filters->get_translatable_documents( $translatable_post_types, $tm_settings['custom-types_readonly_config'], $cpt_unlocked_options ); } return apply_filters( 'get_translatable_documents_all', $translatable_post_types ); } public function get_display_as_translated_documents() { $display_as_translated_post_types = array(); foreach ( $this->get_wp_api() ->get_wp_post_types_global() as $k => $v ) { if ( isset( $this->settings['custom_posts_sync_option'][ $k ] ) && WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED == $this->settings['custom_posts_sync_option'][ $k ] ) { $display_as_translated_post_types[ $k ] = $v; } } return apply_filters( 'get_display_as_translated_documents', $display_as_translated_post_types ); } /** * @param bool $include_not_synced * @param string $deprecated * * @return array * @internal string $deprecated * @since 3.8.0 $deprecated (formerly $object_type) is not used anymore */ function get_translatable_taxonomies( $include_not_synced = false, $deprecated = 'post' ) { global $wp_taxonomies; $t_taxonomies = array(); if ( $include_not_synced ) { $t_taxonomies[] = 'post_tag'; $t_taxonomies[] = 'category'; } foreach ( (array) $wp_taxonomies as $taxonomy_name => $taxonomy ) { if ( 'post_format' === $taxonomy_name ) { continue; } if ( ! empty( $this->settings['taxonomies_sync_option'][ $taxonomy_name ] ) ) { $t_taxonomies[] = $taxonomy_name; } } if ( has_filter( 'get_translatable_taxonomies' ) ) { $filtered = apply_filters( 'get_translatable_taxonomies', array( 'taxs' => $t_taxonomies, 'object_type' => $deprecated, ) ); $t_taxonomies = $filtered['taxs']; if ( empty( $t_taxonomies ) ) { $t_taxonomies = array(); } } return $t_taxonomies; } /** * @param string $tax * * @return bool */ function is_translated_taxonomy( $tax ) { $option_key = 'taxonomies_sync_option'; $readonly_config_key = 'taxonomies_readonly_config'; $translated = apply_filters( 'pre_wpml_is_translated_taxonomy', null, $tax ); return $translated !== null ? $translated : $this->is_translated_element( $tax, $option_key, $readonly_config_key, WPML_Settings_Helper::KEY_TAXONOMY_UNLOCK_OPTION ); } public function is_display_as_translated_taxonomy( $tax ) { return isset( $this->settings['taxonomies_sync_option'][ $tax ] ) && WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED == $this->settings['taxonomies_sync_option'][ $tax ]; } public function get_display_as_translated_taxonomies() { global $wp_taxonomies; $taxonomies = array(); foreach ( (array) $wp_taxonomies as $taxonomy_name => $taxonomy ) { if ( $this->is_display_as_translated_taxonomy( $taxonomy_name ) ) { $taxonomies[] = $taxonomy_name; } } return apply_filters( 'get_display_as_translated_taxonomies', $taxonomies ); } public function is_translated_post_type_filter( $value, $post_type ) { return $this->is_translated_post_type( $post_type ); } /** * @param string $type * * @return bool */ public function is_translated_post_type( $type ) { $translated = apply_filters( 'pre_wpml_is_translated_post_type', null, $type ); return $translated !== null ? $translated : $this->is_translated_element( $type, 'custom_posts_sync_option', 'custom-types_readonly_config', WPML_Settings_Helper::KEY_CPT_UNLOCK_OPTION ); } public function is_display_as_translated_post_type_filter( $value, $post_type ) { return $this->is_display_as_translated_post_type( $post_type ); } public function is_display_as_translated_post_type( $type ) { return isset( $this->settings['custom_posts_sync_option'][ $type ] ) && WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED == $this->settings['custom_posts_sync_option'][ $type ]; } /** * @param null $value * @param string $taxonomy * * @return int */ public function is_translated_taxonomy_filter( $value, $taxonomy ) { return $this->is_translated_taxonomy( $taxonomy ); } function verify_post_translations_action( $post_types ) { if ( ! is_array( $post_types ) ) { $post_types = (array) $post_types; } foreach ( $post_types as $post_type => $translate ) { if ( $translate && ! is_numeric( $post_type ) ) { $this->verify_post_translations( $post_type ); } } } /** * Sets the default language for all posts in a given post type that do not have any language set * * @param string $post_type */ public function verify_post_translations( $post_type ) { $set_default_language = new WPML_Initialize_Language_For_Post_Type( $this->wpdb ); $set_default_language->run( $post_type, $this->get_default_language() ); } /** * This function is to be used on setting a taxonomy from untranslated to being translated. * It creates potentially missing translations and reassigns posts to the then created terms in the correct language. * This function affects all terms in a taxonomy and therefore, depending on the database size results in * heavy resource demand. It should not be used to fix term and post assignment problems other than those * resulting from the action of turning a translated taxonomy into an untranslated one. * * An exception is being made for the installation process assigning all existing terms the default language, * given no prior language information is saved about them in the database. * * @param string $taxonomy */ function verify_taxonomy_translations( $taxonomy ) { $term_utils = new WPML_Terms_Translations(); $tax_sync = new WPML_Term_Language_Synchronization( $this, $term_utils, $taxonomy ); if ( $this->get_setting( 'setup_complete' ) ) { $tax_sync->set_translated(); } else { $tax_sync->set_initial_term_language(); } delete_option( $taxonomy . '_children' ); } function wp_upgrade_locale( $locale ) { $default_language = $this->get_default_language(); $default_locale = $this->get_locale_from_language_code( $default_language ); return defined( 'WPLANG' ) && WPLANG ? WPLANG : $default_locale; } function admin_language_switcher() { require_once WPML_PLUGIN_PATH . '/menu/wpml-admin-lang-switcher.class.php'; $admin_lang_switcher = new WPML_Admin_Language_Switcher(); $admin_lang_switcher->render(); } function admin_notices( $message, $class = 'updated' ) { static $hook_added = 0; $this->_admin_notices[] = array( 'class' => $class, 'message' => $message, ); if ( ! $hook_added ) { add_action( 'admin_notices', array( $this, '_admin_notices_hook' ) ); } $hook_added = 1; } function _admin_notices_hook() { if ( ! empty( $this->_admin_notices ) ) { foreach ( $this->_admin_notices as $n ) { echo '<div class="' . $n['class'] . '">'; echo '<p>' . $n['message'] . '</p>'; echo '</div>'; } } } function allowed_redirect_hosts( $hosts ) { if ( $this->settings['language_negotiation_type'] == 2 ) { $allowed_redirect_hosts = new WPML_Allowed_Redirect_Hosts( $this ); $hosts = $allowed_redirect_hosts->get_hosts( $hosts ); } return $hosts; } public static function get_installed_plugins() { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $wp_plugins = get_plugins(); $wpml_plugins_list = array( 'WPML Multilingual CMS' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'sitepress-multilingual-cms', ), 'WPML CMS Nav' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-cms-nav', ), 'WPML String Translation' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-string-translation', ), 'WPML Sticky Links' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-sticky-links', ), 'WPML Translation Management' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-translation-management', ), 'WPML Media' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-media', ), 'WooCommerce Multilingual' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'woocommerce-multilingual', ), 'Gravity Forms Multilingual' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'gravityforms-multilingual', ), 'WPML SEO' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wp-seo-multilingual', ), ); foreach ( $wpml_plugins_list as $wpml_plugin_name => $v ) { foreach ( $wp_plugins as $file => $plugin ) { $plugin_name = $plugin['Name']; if ( $plugin_name == $wpml_plugin_name ) { $wpml_plugins_list[ $plugin_name ]['installed'] = true; $wpml_plugins_list[ $plugin_name ]['plugin'] = $plugin; $wpml_plugins_list[ $plugin_name ]['file'] = $file; } } } return $wpml_plugins_list; } /** * @param int $limit * @param bool $provide_object * @param bool $ignore_args * * @return array */ public function get_backtrace( $limit = 0, $provide_object = false, $ignore_args = true ) { $options = false; // phpcs:disable PHPCompatibility.FunctionUse.NewFunctionParameters.debug_backtrace_limitFound -- It has a version check // phpcs:disable PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- It has a version check if ( version_compare( $this->wp_api->phpversion(), '5.3.6' ) < 0 ) { // Before 5.3.6, the only values recognized are TRUE or FALSE, // which are the same as setting or not setting the DEBUG_BACKTRACE_PROVIDE_OBJECT option respectively. $options = $provide_object; } else { // As of 5.3.6, 'options' parameter is a bitmask for the following options: if ( $provide_object ) { $options |= DEBUG_BACKTRACE_PROVIDE_OBJECT; } if ( $ignore_args ) { // phpcs:disable PHPCompatibility.Constants.NewConstants.debug_backtrace_ignore_argsFound -- It has a version check $options |= DEBUG_BACKTRACE_IGNORE_ARGS; // phpcs:enable PHPCompatibility.Constants.NewConstants.debug_backtrace_ignore_argsFound } } if ( version_compare( $this->wp_api->phpversion(), '5.4.0' ) >= 0 ) { $actual_limit = $limit == 0 ? 0 : $limit + 1; $debug_backtrace = debug_backtrace( $options, $actual_limit ); // add one item to include the current frame } elseif ( version_compare( $this->wp_api->phpversion(), '5.2.4' ) >= 0 ) { // @link https://core.trac.wordpress.org/ticket/20953 $debug_backtrace = debug_backtrace(); } else { $debug_backtrace = debug_backtrace( $options ); } // phpcs:enable PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection // phpcs:enable PHPCompatibility.FunctionUse.NewFunctionParameters.debug_backtrace_limitFound // Remove the current frame if ( $debug_backtrace ) { array_shift( $debug_backtrace ); } return $debug_backtrace; } /** * Used as filter for WordPress core function url_to_postid() * * @global AbsoluteLinks $absolute_links_object * * @param string $url URL to filter * * @return string URL changed into format ...?p={ID} or original */ function url_to_postid( $url ) { if ( Url::isLogin( $url ) || Url::isAdmin( $url ) || Url::isContentDirectory( $url ) ) { return $url; } $is_language_in_domain = false; // if language negotiation type as lang. in domain $is_translated_domain = false; // if this url is in secondary language domain // for 'different domain per language' we need to switch_lang according to domain of parsed $url if ( 2 == $this->settings['language_negotiation_type'] && isset( $this->settings['language_domains'] ) ) { $is_language_in_domain = true; // if url domain fits to one of secondary language domains // switch sitepress language to this // but save current language context in $current_language, we will have to switch to this back $domains = array_filter( $this->get_setting( 'language_domains' ) ); foreach ( $domains as $code => $domain ) { if ( strpos( $url, (string) $domain ) === 0 ) { $is_translated_domain = true; $current_language = $this->get_current_language(); $this->switch_lang( $code ); $url = str_replace( $domain, site_url(), $url ); break; } } // if it is url in original domain // switch sitepress language to default language // but save current language context in $current_language, we will have to switch to this back if ( ! $is_translated_domain ) { $current_language = $this->get_current_language(); $default_language = $this->get_default_language(); $this->switch_lang( $default_language ); } } // we will use AbsoluteLinks::_process_generic_text, so make sure that // we have this object here global $absolute_links_object; if ( ! isset( $absolute_links_object ) || ! is_a( $absolute_links_object, 'AbsoluteLinks' ) || $is_language_in_domain ) { $absolute_links_object = new AbsoluteLinks(); } // in next steps we will have to compare processed url with original, // so we need to save original $original_url = $url; // we also need site_url for comparisions $site_url = site_url(); // _process_generic_text will change slug urls into ?p=1 or ?cpt-slug=cpt-title // but this function operates not on clean url but on html <a> element // we need to change temporary url into html, pass to this function and // extract url from returned html $html = '<a href="' . $url . '">removeit</a>'; $alp_broken_links = array(); remove_filter( 'url_to_postid', array( $this, 'url_to_postid' ) ); $html = $absolute_links_object->_process_generic_text( $html, $alp_broken_links ); add_filter( 'url_to_postid', array( $this, 'url_to_postid' ) ); $url = str_replace( array( '<a href="', '">removeit</a>' ), array( '', '' ), $html ); // for 'different domain per language', switch language back. now we can do this if ( $is_language_in_domain && isset( $current_language ) ) { $this->switch_lang( $current_language ); } // if this is not url to external site if ( 0 === strpos( $original_url, (string) $site_url ) ) { // if this is url like ...?cpt-rewrite-slug=cpt-title // change it into ...?p=11 $url2 = $this->cpt_url_to_id_url( $url, $original_url ); if ( $url2 == $url && $original_url != $url ) { // if it was not a case with ?cpt-slug=cpt-title // if this is translated post and it has the same slug as original, // _process_generic_text returns the same ID for both // lets check if it is this case and replace ID in returned url $url = $this->maybe_adjust_url( $url, $original_url ); } else { // yes! it was not a case with ?cpt-slug=cpt-title $url = $url2; } } return $url; } /** * Check if $url is in format ...?cpt-slug=cpt-title and change into ...?p={ID} * * @param string $url URL, probably in format ?cpt-slug=cpt-title * @param string $original_url URL in original format (probably with permalink) * * @return string URL, if $url was in expected format ?cpt-slug format, url is now changed into ?p={ID}, otherwise, returns $url as it was passed in parameter */ function cpt_url_to_id_url( $url, $original_url ) { $parsed_url = wpml_parse_url( $url ); if ( ! isset( $parsed_url['query'] ) ) { return $url; } $query = $parsed_url['query']; parse_str( $query, $vars ); $args = array( 'public' => true, '_builtin' => false, ); $post_types = get_post_types( $args, 'objects' ); foreach ( $post_types as $name => $attrs ) { $slug = trim( Obj::pathOr( '', [ 'rewrite', 'slug' ], $attrs ), '/' ); if ( $slug && isset( $vars[ $slug ] ) ) { $post_type = $name; $post_slug = $vars[ $slug ]; break; } } if ( ! isset( $post_type, $post_slug ) ) { return $url; } $args = array( 'name' => $post_slug, 'post_type' => $post_type, ); $post = new WP_Query( $args ); if ( ! isset( $post->post ) ) { return $url; } $id = $post->post->ID; $post_language = $this->get_language_for_element( $id, 'post_' . $post_type ); $url_language = $this->get_language_from_url( $original_url ); $new_vars = array(); if ( $post_language != $url_language ) { $trid = $this->get_element_trid( $id, 'post_' . $post_type ); $translations = $this->get_element_translations( $trid, 'post_' . $post_type ); if ( isset( $translations[ $url_language ] ) ) { $translation = $translations[ $url_language ]; if ( isset( $translation->element_id ) ) { $new_vars['p'] = $translation->element_id; } } } else { $new_vars['p'] = $id; } $new_query = http_build_query( $new_vars ); $url = str_replace( $query, $new_query, $url ); return $url; } /** * Fix sticky link url to have ID of translated post (used in case both translations have same slug) * * @param string $url - url in sticky link form * @param string $original_url - url in permalink form * * @return string - url in sticky link form to correct translation */ private function maybe_adjust_url( $url, $original_url ) { $parsed_url = wpml_parse_url( $url ); $query = isset( $parsed_url['query'] ) ? $parsed_url['query'] : ''; parse_str( $query, $vars ); $post_id = null; $inurl = null; if ( isset( $vars['page_id'] ) ) { $inurl = 'page_id'; } elseif ( isset( $vars['p'] ) ) { $inurl = 'p'; } if ( $inurl ) { $post_id = $vars[ $inurl ]; } if ( $post_id ) { $post_id = (int) $post_id; $post_type = get_post_type( $post_id ); $post_language = $this->get_language_for_element( $post_id, 'post_' . $post_type ); $url_language = $this->get_language_from_url( $original_url ); if ( $post_language !== $url_language ) { $trid = $this->get_element_trid( $post_id, 'post_' . $post_type ); $translations = $this->get_element_translations( $trid, 'post_' . $post_type ); if ( isset( $translations[ $url_language ] ) ) { $translation = $translations[ $url_language ]; if ( isset( $translation->element_id ) ) { $vars[ $inurl ] = $translation->element_id; $new_query = http_build_query( $vars ); $url = str_replace( $query, $new_query, $url ); } } } } return $url; } /** * Find language of document based on given permalink * * @param string $url Local url in permalink form * * @return string language code */ function get_language_from_url( $url ) { /* @var WPML_URL_Converter $wpml_url_converter */ global $wpml_url_converter; return $wpml_url_converter->get_language_from_url( $url ); } function update_index_screen() { return include WPML_PLUGIN_PATH . '/menu/theme-plugins-compatibility.php'; } /** * Filter to add language field to WordPress search form * * @param string $form HTML code of search for before filtering * * @return string HTML code of search form */ function get_search_form_filter( $form ) { $language_form_field = wpml_get_language_form_field(); if ( strpos( $form, (string) $language_form_field ) === false && WPML_LANGUAGE_NEGOTIATION_TYPE_PARAMETER === (int) $this->get_setting( 'language_negotiation_type' ) ) { $form = str_replace( '</form>', $language_form_field . '</form>', $form ); } return $form; } /** * @param string $key * * @return bool|mixed */ public function get_string_translation_settings( $key = '' ) { $setting = $this->get_setting( 'st' ); if ( $this->setting_array_is_set_or_has_key( $setting, $key ) ) { $setting = $setting[ $key ]; } return $setting; } /** * @param array<string,mixed> $setting * @param string $key * * @return bool */ private function setting_array_is_set_or_has_key( $setting, $key ) { return $key != '' && $setting && isset( $setting[ $key ] ); } /** * @param string $element_type * @param string $option_key * @param string $readonly_config_key * @param string $unlocked_key * * @return bool */ private function is_translated_element( $element_type, $option_key, $readonly_config_key, $unlocked_key ) { $ret = false; if ( is_scalar( $element_type ) ) { $translation_management_options = $this->get_setting( 'translation-management' ); if ( 'any' === $element_type ) { $ret = $translation_management_options[ $readonly_config_key ] || count( (array) $this->get_setting( $option_key ) ) > 0; } else { $ret = icl_get_sub_setting( $option_key, $element_type ); if ( ! $ret ) { $is_read_only_translatable = isset( $translation_management_options[ $readonly_config_key ][ $element_type ] ) && $translation_management_options[ $readonly_config_key ][ $element_type ] == 1; $unlocked = $this->get_setting( $unlocked_key, array() ); $is_setting_unlocked = isset( $unlocked[ $element_type ] ) && $unlocked[ $element_type ]; if ( $is_read_only_translatable && ! $is_setting_unlocked ) { $ret = true; } else { $ret = false; } } } } return (bool) $ret; } /** * @return array */ public function get_always_translatable_post_types() { return array(); } /** * @param Integer $master_post_id The original post id for which duplicate posts are to be retrieved * * @return Integer[] An associative array with language codes as indexes and post_ids as values */ function get_duplicates( $master_post_id ) { $this->post_duplication = $this->post_duplication === null ? new WPML_Post_Duplication( $this->wpdb, $this ) : $this->post_duplication; return $this->post_duplication->get_duplicates( $master_post_id ); } /** * @param Integer $master_post_id ID of the to be duplicated post * @param String $lang Language code to which the post is to be duplicated * * @return bool|int|WP_Error */ function make_duplicate( $master_post_id, $lang ) { $this->post_duplication = $this->post_duplication === null ? new WPML_Post_Duplication( $this->wpdb, $this ) : $this->post_duplication; return $this->post_duplication->make_duplicate( $master_post_id, $lang ); } function get_new_post_source_id( $post_id ) { global $pagenow; if ( $pagenow == 'post-new.php' && isset( $_GET['trid'] ) && isset( $_GET['source_lang'] ) ) { // Get the template from the source post. $translations = $this->get_element_translations( $_GET['trid'] ); if ( isset( $translations[ $_GET['source_lang'] ] ) ) { $post_id = $translations[ $_GET['source_lang'] ]->element_id; } } return $post_id; } /** * @param int $element_id * @param string $element_type * @param bool|false $return_original_if_missing * @param null $language_code * * @return int|null */ function get_object_id( $element_id, $element_type = 'post', $return_original_if_missing = false, $language_code = null ) { global $wp_post_types, $wp_taxonomies; /** @var WPML_Post_Translation $wpml_post_translations */ global $wpml_post_translations; /** @var WPML_Term_Translation $wpml_term_translations */ global $wpml_term_translations; $ret_element_id = null; if ( $element_id ) { $language_code = $language_code ?: $this->get_current_language(); $element_type = $element_type === 'any' ? get_post_type( $element_id ) : $element_type; if ( $element_type ) { $postTypeIsTranslatable = is_post_type_translated( $element_type ); $taxonomyTypeIsTranslatable = is_taxonomy_translated( $element_type ); if ( $postTypeIsTranslatable || $taxonomyTypeIsTranslatable ) { $post_id = isset( $wp_post_types[ $element_type ] ) && $postTypeIsTranslatable ? $wpml_post_translations->element_id_in( $element_id, $language_code ) : null; $term_id = ! $post_id && isset( $wp_taxonomies[ $element_type ] ) && $taxonomyTypeIsTranslatable ? $wpml_term_translations->term_id_in( $element_id, $language_code ) : null; $ret_element_id = $post_id ?: $term_id ?: ( $return_original_if_missing ? $element_id : null ); } else { $ret_element_id = $element_id; } } } return $ret_element_id ? (int) $ret_element_id : null; } private function is_troubleshooting_page() { return isset( $_REQUEST['page'] ) && $_REQUEST['page'] == WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php'; } public function handle_head_hreflang() { ( new WPML_SEO_HeadLangs( $this ) )->init_hooks(); } /** * Get previously set data for the current request. * * @param string $key * @param null|mixed $default * * @return mixed|null */ public function get_current_request_data( $key, $default = null ) { return isset( $this->current_request_data[ $key ] ) ? $this->current_request_data[ $key ] : $default; } /** * Set temporary data for the current request that can be recalled later * * @param string $key * @param mixed $data */ public function set_current_request_data( $key, $data ) { $this->current_request_data[ $key ] = $data; } /** * Clear the data for the current request * * @param string $key */ public function clear_current_request_data( $key ) { unset( $this->current_request_data[ $key ] ); } /** * Load \TranslationManagement class. */ public function load_core_tm() { $iclTranslationManagement = wpml_load_core_tm(); } public function is_setup_complete() { return $this->get_setting( 'setup_complete' ); } /** * @return bool */ private function is_taxonomy_related_page() { return isset( $_GET['page'] ) && ( $_GET['page'] == WPML_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' || $_GET['page'] == WPML_PLUGIN_FOLDER . '/menu/menu-sync/menus-sync.php' || $_GET['page'] == WPML_PLUGIN_FOLDER . '/menu/term-taxonomy-menus/taxonomy-translation-display.class.php' ); } /** * @return bool */ private function is_saving_taxonomy_labels() { global $pagenow; return ( $pagenow === 'admin-ajax.php' && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_tt_save_labels_translation' ); } private function switch_to_admin_language() { $this->switch_lang( $this->get_admin_language(), true ); } private function move_current_language_to_the_top() { $active_languages = $this->get_active_languages(); foreach ( $active_languages as $k => $active_lang ) { if ( $k === $this->this_lang ) { unset( $this->active_languages[ $k ] ); /** @noinspection SlowArrayOperationsInLoopInspection */ $this->active_languages = array_merge( array( $k => $active_lang ), $this->active_languages ); break; } } } /** * @param array<string,mixed> $active_languages * * @return array<string,mixed> */ private function maybeHideLanguages( array $active_languages ) { $mustHideLanguages = isset( $this->wp_query->query_vars['post_type'] ) && ! is_array( $this->wp_query->query_vars['post_type'] ) && ! empty( $this->wp_query->query_vars['post_type'] ) && ! $this->is_translated_post_type( $this->wp_query->query_vars['post_type'] ); if ( $mustHideLanguages ) { foreach ( $active_languages as $lang => $element ) { unset( $active_languages[ $lang ] ); } } return $active_languages; } /** * @return bool */ private function is_page_query() { return ( ! empty( $this->wp_query->queried_object_id ) && ( isset( $this->wp_query->query['paged'] ) || isset( $this->wp_query->query['page'] ) ) && $this->wp_query->queried_object_id == get_option( 'page_for_posts' ) ); } }
Simpan
Batal
Isi Zip:
Unzip
Create
Buat Folder
Buat File
Terminal / Execute
Run
Chmod Bulk
All File
All Folder
All File dan Folder
Apply