links_model->options ) || class_exists( 'TRP_Translate_Press' ) ) { // Detect Post/Term function add_filter( 'permalink_manager_detected_post_id', array( $this, 'fix_language_mismatch' ), 9, 4 ); add_filter( 'permalink_manager_detected_term_id', array( $this, 'fix_language_mismatch' ), 9, 4 ); // Fix posts page add_filter( 'permalink_manager_filter_query', array( $this, 'fix_posts_page' ), 5, 5 ); // URI Editor add_filter( 'permalink_manager_uri_editor_extra_info', array( $this, 'uri_editor_get_lang_col' ), 9, 3 ); add_filter( 'permalink_manager_uri_editor_extra_fields', array( $this, 'uri_editor_filter_lang' ), 9, 2 ); add_filter( 'permalink_manager_filter_uri_editor_query', array( $this, 'uri_editor_filter_sql_query' ), 9, 3 ); // Adjust front page ID add_filter( 'permalink_manager_is_front_page', array( $this, 'wpml_is_front_page' ), 9, 3 ); // Provide the language code for specific post/term add_filter( 'permalink_manager_get_language_code', array( $this, 'filter_get_language_code' ), 9, 2 ); // Regenerate/reset + Find & replace tools add_filter( 'permalink_manager_get_items_query', array( $this, 'filter_query_by_language' ), 10, 2 ); add_filter( 'permalink_manager_tools_fields', array( $this, 'add_language_field' ), 10, 2 ); // Get translation mode $mode = 0; // A. WPML if ( isset( $sitepress_settings['language_negotiation_type'] ) ) { $url_settings = $sitepress_settings['language_negotiation_type']; if ( in_array( $url_settings, array( 1, 2 ) ) ) { $mode = 'prepend'; } else if ( $url_settings == 3 ) { $mode = 'append'; } } // B. Polylang else if ( isset( $polylang->links_model->options['force_lang'] ) ) { $url_settings = $polylang->links_model->options['force_lang']; if ( in_array( $url_settings, array( 1, 2, 3 ) ) ) { $mode = 'prepend'; } } // C. TranslatePress else if ( class_exists( 'TRP_Translate_Press' ) ) { $mode = 'prepend'; } if ( $mode === 'prepend' ) { add_filter( 'permalink_manager_detect_uri', array( $this, 'detect_uri_language' ), 9, 3 ); add_filter( 'permalink_manager_filter_permalink_base', array( $this, 'prepend_lang_prefix' ), 9, 2 ); } else if ( $mode === 'append' ) { add_filter( 'permalink_manager_filter_final_post_permalink', array( $this, 'append_lang_prefix' ), 5, 2 ); add_filter( 'permalink_manager_filter_final_term_permalink', array( $this, 'append_lang_prefix' ), 5, 2 ); } // Translate permastructures add_filter( 'permalink_manager_filter_permastructure', array( $this, 'translate_permastructure' ), 9, 2 ); // Translate custom permalinks if ( $this->is_wpml_compatible() ) { add_filter( 'permalink_manager_filter_final_post_permalink', array( $this, 'translate_permalinks' ), 9, 2 ); } // Translate post type slug if ( class_exists( 'WPML_Slug_Translation' ) ) { add_filter( 'permalink_manager_filter_post_type_slug', array( $this, 'wpml_translate_post_type_slug' ), 9, 3 ); add_filter( 'permalink_manager_filter_taxonomy_slug', array( $this, 'wpml_translate_taxonomy_slug' ), 9, 3 ); } // Translate "page" endpoint if ( class_exists( 'PLL_Translate_Slugs_Model' ) ) { add_filter( 'permalink_manager_endpoints', array( $this, 'pl_translate_pagination_endpoint' ), 9 ); add_filter( 'permalink_manager_detect_uri', array( $this, 'pl_detect_pagination_endpoint' ), 10, 3 ); } // Translate WooCommerce endpoints if ( class_exists( 'WCML_Endpoints' ) ) { add_filter( 'request', array( $this, 'wpml_translate_wc_endpoints' ), 99999 ); } // Generate custom permalink after WPML's Advanced Translation editor is used if ( ! empty( $sitepress_settings['translation-management'] ) && ! empty( $sitepress_settings['translation-management']['doc_translation_method'] ) ) { add_filter( 'icl_job_elements', array( $this, 'wpml_editor_custom_permalink_field' ), 99, 3 ); add_filter( 'wpml_tm_adjust_translation_fields', array( $this, 'wpml_editor_custom_permalink_label' ), 99, 3 ); add_filter( 'wpml_pre_save_pro_translation', array( $this, 'wpml_prevent_uri_save_before_translation_completed' ), 99, 2 ); add_action( 'wpml_translation_editor_save_job_data', array( $this, 'wpml_save_uri_after_wpml_translation_completed' ), 99 ); add_action( 'wpml_pro_translation_completed', array( $this, 'wpml_save_uri_after_wpml_translation_completed' ), 99, 3 ); } add_action( 'icl_make_duplicate', array( $this, 'wpml_duplicate_uri' ), 999, 4 ); // Allow canonical redirect for default language if "Hide URL language information for default language" is turned on in Polylang settings if ( ! empty( $polylang ) && ! empty( $polylang->links_model ) && ! empty( $polylang->links_model->options['force_lang'] ) ) { add_filter( 'permalink_manager_filter_query', array( $this, 'pl_allow_canonical_redirect' ), 3, 5 ); } } } /** * Let users decide if they want Permalink Manager to force language code in the custom permalinks */ public static function is_wpml_compatible() { global $permalink_manager_options; // Use the current language if translation is not available but fallback mode is turned on return ( ! empty( $permalink_manager_options['general']['wpml_support'] ) ) ? $permalink_manager_options['general']['wpml_support'] : false; } /** * Return the language code string for specific post or term * * @param string|int|WP_Post|WP_Term $element * * @return false|string */ public static function get_language_code( $element ) { global $TRP_LANGUAGE, $icl_adjust_id_url_filter_off, $sitepress, $polylang, $wpml_post_translations, $wpml_term_translations; // Disable WPML adjust ID filter // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound $icl_adjust_id_url_filter_off_prior = $icl_adjust_id_url_filter_off; $icl_adjust_id_url_filter_off = true; // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound // Fallback if ( is_string( $element ) && strpos( $element, 'tax-' ) !== false ) { $element_id = intval( preg_replace( "/[^0-9]/", "", $element ) ); $element = get_term( $element_id ); } else if ( is_numeric( $element ) ) { $element = get_post( $element ); } // A. TranslatePress if ( ! empty( $TRP_LANGUAGE ) ) { $lang_code = self::get_translatepress_language_code( $TRP_LANGUAGE ); } // B. Polylang else if ( ! empty( $polylang ) && function_exists( 'pll_get_post_language' ) && function_exists( 'pll_get_term_language' ) ) { if ( isset( $element->post_type ) ) { $lang_code = pll_get_post_language( $element->ID, 'slug' ); } else if ( isset( $element->taxonomy ) ) { $lang_code = pll_get_term_language( $element->term_id, 'slug' ); } } // C. WPML else if ( ! empty( $sitepress ) ) { $is_wpml_compatible = ( method_exists( $sitepress, 'is_display_as_translated_post_type' ) ) ? self::is_wpml_compatible() : false; if ( isset( $element->post_type ) ) { $element_id = $element->ID; $element_type = $element->post_type; $fallback_lang_on = ( $is_wpml_compatible ) ? $sitepress->is_display_as_translated_post_type( $element_type ) : false; } else if ( isset( $element->taxonomy ) ) { $element_id = $element->term_taxonomy_id; $element_type = $element->taxonomy; $fallback_lang_on = ( $is_wpml_compatible ) ? $sitepress->is_display_as_translated_taxonomy( $element_type ) : false; } else { return false; } if ( ! empty( $fallback_lang_on ) && ! is_admin() && ! wp_doing_ajax() && ! defined( 'REST_REQUEST' ) ) { $current_language = $sitepress->get_current_language(); if ( ! empty( $element->post_type ) ) { $force_current_lang = $wpml_post_translations->element_id_in( $element_id, $current_language ) ? false : $current_language; } else if ( ! empty( $element->taxonomy ) ) { $force_current_lang = $wpml_term_translations->element_id_in( $element_id, $current_language ) ? false : $current_language; } } $lang_code = ( ! empty( $force_current_lang ) ) ? $force_current_lang : apply_filters( 'wpml_element_language_code', null, array( 'element_id' => $element_id, 'element_type' => $element_type ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound } // Enable WPML adjust ID filter $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter_off_prior; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound // Use default language if nothing detected return ( ! empty( $lang_code ) ) ? $lang_code : self::get_default_language(); } /** * Filter the language code of a provided post or term * * @param string $lang_code * @param string|integer $element * * @return false|string */ public function filter_get_language_code( $lang_code = '', $element = '' ) { return self::get_language_code( $element ); } /** * Extends an SQL query to filter results by specific WPML/Polylang language codes. * * @param string $query Original SQL query string. * @param string $where WHERE clause of the query. * * @return string Modified SQL query with WPML filtering applied. */ public function filter_query_by_language( $query, $where ) { global $wpdb, $polylang, $sitepress_settings; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce is already verified in parent/enclosing method $language_codes = ( ! empty( $_POST['language_filter'] ) && is_array( $_POST['language_filter'] ) ) ? array_map( 'sanitize_key', $_POST['language_filter'] ) : array(); if ( empty( $language_codes ) ) { return $query; } $is_terms_query = strpos( $query, "{$wpdb->terms}" ) !== false; if ( ! empty( $polylang->links_model->options ) ) { // 1. Prepare the slugs based on the condition if ( $is_terms_query ) { $all_slugs = array_merge( $language_codes, array_map( function ( $code ) { return 'pll_' . $code; }, $language_codes ) ); $taxonomy = 'term_language'; $join_on = 't.term_id'; } else { $all_slugs = $language_codes; $taxonomy = 'language'; $join_on = 'p.ID'; } $language_term_ids = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, 'slug' => $all_slugs, 'fields' => 'ids' ) ); $join = " JOIN {$wpdb->term_relationships} tr_lang ON tr_lang.object_id = {$join_on}"; if ( ! empty( $language_term_ids ) ) { $language_ids_in_sql = Permalink_Manager_Helper_Functions::prepare_array_for_sql_in( $language_term_ids ); $where_sql = " AND tr_lang.term_taxonomy_id IN ({$language_ids_in_sql})"; } else { $where_sql = " AND 1=0"; // Force no results if no terms found } } else if ( ! empty( $sitepress_settings ) ) { $language_codes_in_sql = Permalink_Manager_Helper_Functions::prepare_array_for_sql_in( $language_codes ); if ( $is_terms_query ) { $element_type = '"tax_%"'; $element_id = 'tt.term_taxonomy_id'; } else { $element_type = "CONCAT('post_', p.post_type)"; $element_id = "p.ID"; } $join = " JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = {$element_id} AND icl.element_type LIKE {$element_type}"; if ( ! empty( $language_codes_in_sql ) ) { $where_sql = " AND icl.language_code IN ({$language_codes_in_sql})"; } else { $where_sql = " AND 1=0"; // Force no results if no terms found } } else { return $where; } if ( stripos( $query, ' WHERE' ) !== false ) { $query = str_ireplace( ' WHERE', $join . ' WHERE', $query ); } else { $query .= ' ' . $join; } return str_replace( $where, $where . $where_sql, $query ); } /** * Adds a WPML language filter field to the Permalink Manager Tools UI. * * @param array $fields Existing fields array. * * @return array Modified fields array. */ public function add_language_field( $fields, $tool_name ) { $languages = $this->get_all_languages(); if ( empty( $languages ) || ! is_array( $fields ) || ! in_array( $tool_name, array( 'regenerate', 'find_and_replace' ) ) ) { return $fields; } $fields['language_filter'] = array( 'label' => __( 'Select by language', 'permalink-manager' ), 'type' => 'checkbox', 'container' => 'row', 'description' => __( 'Select languages to filter by, or leave blank for all.', 'permalink-manager' ), 'choices' => $languages ); return $fields; } /** * Return the language URL prefix code for TranslatePress * * @param string $lang * * @return false|string */ public static function get_translatepress_language_code( $lang ) { $translatepress_settings = self::get_translatepress_settings(); if ( ! empty( $translatepress_settings['url-slugs'] ) ) { $lang_code = ( ! empty( $translatepress_settings['url-slugs'][ $lang ] ) ) ? $translatepress_settings['url-slugs'][ $lang ] : ''; } return ( ! empty( $lang_code ) ) ? $lang_code : false; } /** * Get TranslatePress settings * * @return array */ private static function get_translatepress_settings() { static $settings = null; if ( $settings === null ) { $settings = ( class_exists( 'TRP_Translate_Press' ) ) ? get_option( 'trp_settings', array() ) : array(); } return $settings; } /** * Return the language code for the default language * * @return false|string */ public static function get_default_language() { global $sitepress; if ( function_exists( 'pll_default_language' ) ) { $def_lang = pll_default_language( 'slug' ); } else if ( is_object( $sitepress ) ) { $def_lang = $sitepress->get_default_language(); } else if ( class_exists( 'TRP_Translate_Press' ) ) { $translatepress_settings = self::get_translatepress_settings(); $def_lang = ( ! empty( $translatepress_settings['default-language'] ) ) ? self::get_translatepress_language_code( $translatepress_settings['default-language'] ) : ''; } else { $def_lang = ''; } return $def_lang; } /** * Return the array with all defined languages * * @param bool $exclude_default_language * * @return array */ public static function get_all_languages( $exclude_default_language = false ) { global $sitepress, $sitepress_settings; $languages_array = $active_languages = array(); $default_language = self::get_default_language(); if ( ! empty( $sitepress_settings['active_languages'] ) ) { $languages_array = $sitepress_settings['active_languages']; } elseif ( function_exists( 'pll_languages_list' ) ) { $languages_array = pll_languages_list( array( 'fields' => null ) ); } // Get native language names as value if ( $languages_array ) { foreach ( $languages_array as $val ) { if ( ! empty( $sitepress ) ) { $lang = $val; $lang_details = $sitepress->get_language_details( $lang ); $language_name = $lang_details['native_name']; } else if ( ! empty( $val->name ) ) { $lang = $val->slug; $language_name = $val->name; } if ( ! empty( $lang ) ) { $active_languages[ $lang ] = ( ! empty( $language_name ) ) ? sprintf( '%s (%s)', $language_name, $lang ) : '-'; } } // Exclude default language if needed if ( $exclude_default_language && $default_language && ! empty( $active_languages[ $default_language ] ) ) { unset( $active_languages[ $default_language ] ); } } return $active_languages; } /** * If the requested language code does not match the language of the requested content, modify which post/term is to be loaded * * @param string|int $item_id * @param array $uri_parts * @param bool $is_term * @param array|bool $old_query * * @return false|int */ function fix_language_mismatch( $item_id, $uri_parts, $is_term = false, $old_query = array() ) { global $permalink_manager_options, $pm_query, $polylang, $icl_adjust_id_url_filter_off; $mode = ( ! empty( $permalink_manager_options['general']['fix_language_mismatch'] ) ) ? $permalink_manager_options['general']['fix_language_mismatch'] : 0; // Stop WPML from changing the output of the get_term() and get_post() functions // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound $icl_adjust_id_url_filter_off_prior = $icl_adjust_id_url_filter_off; $icl_adjust_id_url_filter_off = true; // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound if ( $is_term ) { $element = get_term( $item_id ); if ( ! empty( $element ) && ! is_wp_error( $element ) ) { $element_id = $element->term_id; $element_type = $element->taxonomy; } else { return false; } } else { $element = get_post( $item_id ); if ( ! empty( $element->post_type ) ) { $element_id = $item_id; $element_type = $element->post_type; } } // Stop if no term or post is detected if ( empty( $element_id ) || empty( $element_type ) ) { return false; } // When url_to_postid() is called, always use the language code declared in $uri_parts if ( ! empty( $element->post_type ) && $old_query === false ) { $mode = 1; $no_query_set = true; } // Get the language code of the found post/term $element_language_code = self::get_language_code( $element ); // Try to get the detected language code if the query is already set if ( defined( 'ICL_LANGUAGE_CODE' ) && empty( $no_query_set ) ) { $detected_language_code = ICL_LANGUAGE_CODE; } else if ( ! empty( $uri_parts['lang'] ) ) { $detected_language_code = $uri_parts['lang']; } else { return $item_id; } if ( $detected_language_code !== $element_language_code ) { // A. Display the content in requested language // B. Allow the canonical redirect if ( $mode == 1 || $mode == 2 ) { if ( ! empty( $polylang ) ) { if ( function_exists( 'pll_get_post' ) && ! $is_term ) { $translated_item_id = pll_get_post( $element_id, $detected_language_code ); } else if ( function_exists( 'pll_get_term' ) && $is_term ) { $translated_item_id = pll_get_term( $element_id, $detected_language_code ); } $item_id = ( isset( $translated_item_id ) ) ? $translated_item_id : $item_id; } else if ( ! empty( $no_query_set ) ) { $item_id = apply_filters( 'wpml_object_id', $element_id, $element_type, false, $detected_language_code ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound } else { $item_id = apply_filters( 'wpml_object_id', $element_id, $element_type ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound } // Compare the URIs to prevent the redirect loop if ( $mode == 2 && ! empty( $item_id ) && $item_id !== $element_id ) { $detected_element_uri = Permalink_Manager_URI_Functions::get_single_uri( $element_id, false, false, $is_term ); $translated_element_uri = Permalink_Manager_URI_Functions::get_single_uri( $item_id, false, false, $is_term ); if ( ! empty( $detected_element_uri ) && ! empty( $translated_element_uri ) && $detected_element_uri !== $translated_element_uri ) { $pm_query['flag'] = 'language_mismatch'; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound } } } // C. Display "404 error" else { $item_id = 0; } } $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter_off_prior; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound return $item_id; } /** * Fix the language switcher on blog page (WPML bug) * * @param array $query * @param array $old_query * @param array $uri_parts * @param array $pm_query * @param string $content_type * * @return array */ function fix_posts_page( $query, $old_query, $uri_parts, $pm_query, $content_type ) { if ( empty( $pm_query['id'] ) || ! is_numeric( $pm_query['id'] ) ) { return $query; } // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound $blog_page_id = apply_filters( 'wpml_object_id', get_option( 'page_for_posts' ), 'page' ); $element_id = apply_filters( 'wpml_object_id', $pm_query['id'], 'page' ); // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound if ( ! empty( $blog_page_id ) && ( $blog_page_id == $element_id ) && ! isset( $query['page'] ) ) { $query['page'] = ''; } return $query; } /** * Detect the language of requested content and add it to $uri_parts array * * @param array $uri_parts * @param string $request_url * @param string $endpoints * * @return array */ function detect_uri_language( $uri_parts, $request_url, $endpoints ) { global $sitepress_settings, $polylang; if ( ! empty( $sitepress_settings['active_languages'] ) ) { $languages_list = (array) $sitepress_settings['active_languages']; } else if ( function_exists( 'pll_languages_list' ) ) { $languages_array = pll_languages_list(); $languages_list = ( is_array( $languages_array ) ) ? $languages_array : ""; } else if ( class_exists( 'TRP_Translate_Press' ) ) { $translatepress_settings = self::get_translatepress_settings(); $languages_list = $translatepress_settings['url-slugs']; } if ( ! empty( $languages_list ) && is_array( $languages_list ) ) { $languages_list = implode( "|", $languages_list ); } else { return $uri_parts; } // Fix for multidomain language configuration if ( ( isset( $sitepress_settings['language_negotiation_type'] ) && $sitepress_settings['language_negotiation_type'] == 2 ) || ( ! empty( $polylang->options['force_lang'] ) && $polylang->options['force_lang'] == 3 ) ) { if ( ! empty( $polylang->options['domains'] ) ) { $domains = (array) $polylang->options['domains']; } else if ( ! empty( $sitepress_settings['language_domains'] ) ) { $domains = (array) $sitepress_settings['language_domains']; } if ( ! empty( $domains ) ) { foreach ( $domains as &$domain ) { $domain = preg_replace( '/((http(s)?:\/\/(www\.)?)|(www\.))?(.+?)\/?$/', 'http://$6', $domain ); } $request_url = trim( str_replace( $domains, "", $request_url ), "/" ); } $default_language = ""; } else { $default_language = self::get_default_language(); } if ( ! empty( $languages_list ) ) { preg_match( "/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i", $request_url, $regex_parts ); $uri_parts['lang'] = ( ! empty( $regex_parts[1] ) ) ? $regex_parts[1] : $default_language; $uri_parts['uri'] = ( ! empty( $regex_parts[2] ) ) ? $regex_parts[2] : ""; $uri_parts['endpoint'] = ( ! empty( $regex_parts[3] ) ) ? $regex_parts[3] : ""; $uri_parts['endpoint_value'] = ( ! empty( $regex_parts[4] ) ) ? $regex_parts[4] : ""; } return $uri_parts; } /** * Append the language code to the URL directly after the domain name * * @param string $base * @param string|int|WP_Post|WP_Term $element * @param string $language_code * * @return string */ static function prepend_lang_prefix( $base, $element, $language_code = '' ) { global $sitepress_settings, $polylang; if ( ! empty( $element ) && empty( $language_code ) ) { $language_code = self::get_language_code( $element ); // Last instance - use language parameter from &_GET array $language_code = ( is_admin() && empty( $language_code ) && ! empty( $_GET['lang'] ) ) ? sanitize_key( $_GET['lang'] ) : $language_code; // phpcs:ignore WordPress.Security.NonceVerification.Recommended } // Adjust URL base if ( ! empty( $language_code ) ) { $default_language_code = self::get_default_language(); $home_url = get_home_url(); $translatepress_settings = self::get_translatepress_settings(); // Hide language code if "Use directory for default language" option is enabled $hide_prefix_in_translatepress = ( ! empty( $translatepress_settings['add-subdirectory-to-default-language'] ) && $translatepress_settings['add-subdirectory-to-default-language'] !== 'yes' ) ? true : false; $hide_prefix_in_wpml = ( isset( $sitepress_settings['urls']['directory_for_default_language'] ) && $sitepress_settings['urls']['directory_for_default_language'] != 1 ) ? true : false; $hide_prefix_in_polylang = ( ! empty( $polylang->links_model->options['hide_default'] ) ) ? true : false; $hide_prefix_for_default_lang = ( $hide_prefix_in_wpml || $hide_prefix_in_polylang || $hide_prefix_in_translatepress ) ? true : false; // A. Different domain per language if ( ( isset( $sitepress_settings['language_negotiation_type'] ) && $sitepress_settings['language_negotiation_type'] == 2 ) || ( ! empty( $polylang->options['force_lang'] ) && $polylang->options['force_lang'] == 3 ) ) { if ( ! empty( $polylang->options['domains'] ) ) { $domains = $polylang->options['domains']; } else if ( ! empty( $sitepress_settings['language_domains'] ) ) { $domains = $sitepress_settings['language_domains']; } // Replace the domain name if ( ! empty( $domains ) && ! empty( $domains[ $language_code ] ) ) { $base = trim( $domains[ $language_code ], "/" ); // Append URL scheme if ( ! preg_match( "~^(?:f|ht)tps?://~i", $base ) ) { $scheme = wp_parse_url( $home_url, PHP_URL_SCHEME ); $base = "{$scheme}://{$base}"; } } } // B. Prepend language code else if ( ! empty( $polylang->options['force_lang'] ) && $polylang->options['force_lang'] == 2 ) { if ( $hide_prefix_for_default_lang && ( $default_language_code == $language_code ) ) { return $base; } else { $base = preg_replace( '/(https?:\/\/)/', "$1{$language_code}.", $home_url ); } } // C. Append prefix else { if ( $hide_prefix_for_default_lang && ( $default_language_code == $language_code ) ) { return $base; } else { $base .= "/{$language_code}"; } } } return $base; } /** * Append language code as a $_GET parameter to the end of URL * * @param string $permalink * @param string|int|WP_Post|WP_Term $element * * @return string */ function append_lang_prefix( $permalink, $element ) { global $sitepress_settings; $language_code = self::get_language_code( $element ); $default_language_code = self::get_default_language(); // Last instance - use language parameter from &_GET array if ( is_admin() ) { $language_code = ( empty( $language_code ) && ! empty( $_GET['lang'] ) ) ? sanitize_key( $_GET['lang'] ) : $language_code; // phpcs:ignore WordPress.Security.NonceVerification.Recommended } // Append ?lang query parameter if ( isset( $sitepress_settings['language_negotiation_type'] ) && $sitepress_settings['language_negotiation_type'] == 3 ) { if ( $default_language_code == $language_code ) { return $permalink; } else if ( strpos( $permalink, "lang=" ) === false ) { $permalink .= "?lang={$language_code}"; } } return $permalink; } /** * Display the language code in a table column in Bulk Permalink Editor * * @param string $output * @param string $column * @param WP_Post|WP_Term $element * * @return string */ function uri_editor_get_lang_col( $output, $column, $element ) { $language_code = self::get_language_code( $element ); $output .= ( ! empty( $language_code ) ) ? sprintf( " | %s: %s", __( 'Language', 'permalink-manager' ), $language_code ) : ""; return $output; } /** * Add extra 'language' filter field to Bulk Permalink Editor * * @param $html * @param $content_type * * @return mixed|string */ function uri_editor_filter_lang( $html, $content_type ) { $choices = array(); if ( class_exists( 'SitePress' ) ) { $languages = apply_filters( 'wpml_active_languages', '' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Using WPML API foreach ( $languages as $l ) { $choices[ $l['language_code'] ] = $l['translated_name']; } } else if ( function_exists( 'pll_the_languages' ) ) { $languages = pll_the_languages( array( 'show_flags' => 0, 'echo' => 0, 'raw' => 1 ) ); foreach ( $languages as $l ) { $choices[ $l['slug'] ] = $l['name']; } } if ( ! empty( $choices ) ) { $choices = array_merge( array( __( 'All languages', 'permalink-manager' ) ), $choices ); $select_field = Permalink_Manager_UI_Elements::generate_option_field( 'langcode', array( 'type' => 'select', 'choices' => $choices, 'value' => ( isset( $_REQUEST['langcode'] ) ) ? esc_attr( sanitize_key( $_REQUEST['langcode'] ) ) : '' // phpcs:ignore WordPress.Security.NonceVerification.Recommended ) ); $html = sprintf( '