4 * WP SEO by Yoast sitemap filter class
8 class WPML_WPSEO_XML_Sitemaps_Filter {
9 /** @var SitePress $sitepress */
13 * WPML_URL_Converter object.
15 * @var WPML_URL_Converter
17 private $wpml_url_converter;
20 * @var WPML_Debug_BackTrace
25 * WPSEO_XML_Sitemaps_Filter constructor.
27 * @param SitePress $sitepress
28 * @param stdClass $wpml_url_converter
29 * @param WPML_Debug_BackTrace $back_trace
31 public function __construct( $sitepress, $wpml_url_converter, WPML_Debug_BackTrace $back_trace = null ) {
32 $this->sitepress = $sitepress;
33 $this->wpml_url_converter = $wpml_url_converter;
34 $this->back_trace = $back_trace;
37 public function init_hooks() {
38 global $wpml_query_filter;
40 if ( $this->is_per_domain() ) {
41 add_filter( 'wpml_get_home_url', array( $this, 'get_home_url_filter' ), 10, 1 );
42 add_filter( 'wpseo_posts_join', array( $wpml_query_filter, 'filter_single_type_join' ), 10, 2 );
43 add_filter( 'wpseo_posts_where', array( $wpml_query_filter, 'filter_single_type_where' ), 10, 2 );
44 add_filter( 'wpseo_typecount_join', array( $wpml_query_filter, 'filter_single_type_join' ), 10, 2 );
45 add_filter( 'wpseo_typecount_where', array( $wpml_query_filter, 'filter_single_type_where' ), 10, 2 );
47 add_filter( 'wpseo_sitemap_page_content', array( $this, 'add_languages_to_sitemap' ) );
48 // Remove posts under hidden language.
49 add_filter( 'wpseo_xml_sitemap_post_url', array( $this, 'exclude_hidden_language_posts' ), 10, 2 );
52 if ( $this->is_per_directory() ) {
53 add_filter( 'wpml_get_home_url', array( $this, 'maybe_return_original_url_in_get_home_url_filter' ), 10, 2 );
56 add_filter( 'wpseo_enable_xml_sitemap_transient_caching', array( $this, 'transient_cache_filter' ), 10, 0 );
57 add_filter( 'wpseo_build_sitemap_post_type', array( $this, 'wpseo_build_sitemap_post_type_filter' ) );
58 add_action( 'wpseo_xmlsitemaps_config', array( $this, 'list_domains' ) );
59 add_filter( 'wpseo_sitemap_entry', array( $this, 'exclude_translations_of_static_home_page' ), 10, 3 );
63 * Add home page urls for languages to sitemap.
64 * Do this only if configuration language per domain option is not used.
66 public function add_languages_to_sitemap() {
68 $default_lang = $this->sitepress->get_default_language();
69 $active_langs = $this->sitepress->get_active_languages();
70 unset( $active_langs[ $default_lang ] );
72 foreach ( $active_langs as $lang_code => $lang_data ) {
73 $output .= $this->sitemap_url_filter( $this->wpml_url_converter->convert_url( home_url( '/' ), $lang_code ) );
79 * Update home_url for language per-domain configuration to return correct URL in sitemap.
81 * @param string $home_url
83 * @return bool|mixed|string
85 public function get_home_url_filter( $home_url ) {
86 return $this->wpml_url_converter->convert_url( $home_url, $this->sitepress->get_current_language() );
89 public function list_domains() {
90 $ls_languages = $this->sitepress->get_ls_languages();
91 if ( $ls_languages && $this->is_per_domain() ) {
93 echo '<h3>' . esc_html__( 'WPML', 'sitepress' ) . '</h3>';
94 echo esc_html__( 'Sitemaps for each language can be accessed below. You need to submit all these sitemaps to Google.', 'sitepress' );
95 echo '<table class="wpml-sitemap-translations" style="margin-left: 1em; margin-top: 1em;">';
97 $base_style = "style=\"
98 background-image:url('%s');
99 background-repeat: no-repeat;
100 background-position: 2px center;
101 background-size: 16px;
107 foreach ( $ls_languages as $lang ) {
108 $url = $lang['url'] . 'sitemap_index.xml';
112 echo 'href="' . esc_url( $url ) . '" ';
113 echo 'target="_blank" ';
114 echo 'class="button-secondary" ';
115 echo sprintf( $base_style, esc_url( $lang['country_flag_url'] ) );
117 echo esc_html( $lang['translated_name'] );
129 public function is_per_domain() {
130 return WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
136 private function is_per_directory() {
137 return WPML_LANGUAGE_NEGOTIATION_TYPE_DIRECTORY === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
140 public function transient_cache_filter() {
144 public function wpseo_build_sitemap_post_type_filter( $type ) {
145 global $sitepress_settings;
146 // Before to build the sitemap and as we are on front-end
147 // just make sure the links won't be translated
148 // The setting should not be updated in DB
149 $sitepress_settings['auto_adjust_ids'] = 0;
151 if ( ! $this->is_per_domain() ) {
152 remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ) );
155 remove_filter( 'category_link', array( $this->sitepress, 'category_link_adjust_id' ), 1 );
161 * Exclude posts under hidden language.
163 * @param string $url Post URL.
164 * @param stdClass $post Object with some post information.
168 public function exclude_hidden_language_posts( $url, $post ) {
169 // Check that at least ID is set in post object.
170 if ( ! isset( $post->ID ) ) {
174 // Get list of hidden languages.
175 $hidden_languages = $this->sitepress->get_setting( 'hidden_languages', array() );
177 // If there are no hidden languages return original URL.
178 if ( empty( $hidden_languages ) ) {
182 // Get language information for post.
183 $language_info = $this->sitepress->post_translations()->get_element_lang_code( $post->ID );
185 // If language code is one of the hidden languages return empty string to skip the post.
186 if ( in_array( $language_info, $hidden_languages, true ) ) {
194 * Convert URL to sitemap entry format.
196 * @param string $url URl to prepare for sitemap.
200 public function sitemap_url_filter( $url ) {
201 $url = htmlspecialchars( $url );
203 $output = "\t<url>\n";
204 $output .= "\t\t<loc>" . $url . "</loc>\n";
206 $output .= "\t\t<changefreq>daily</changefreq>\n";
207 $output .= "\t\t<priority>1.0</priority>\n";
208 $output .= "\t</url>\n";
216 * @param $post_object
218 * @return string|bool
220 public function exclude_translations_of_static_home_page( $url, $type, $post_object ) {
221 if ( 'post' !== $type || $this->is_per_domain() ) {
224 $page_on_front = (int) get_option( 'page_on_front' );
225 if ( $page_on_front ) {
226 $translations = $this->sitepress->post_translations()->get_element_translations( $page_on_front );
227 unset( $translations[ $this->sitepress->get_default_language() ] );
228 if ( in_array( $post_object->ID, $translations, true ) ) {
236 * @param string $home_url
237 * @param string $original_url
241 public function maybe_return_original_url_in_get_home_url_filter( $home_url, $original_url ) {
243 array( 'WPSEO_Post_Type_Sitemap_Provider', 'get_home_url' ),
244 array( 'WPSEO_Sitemaps_Router', 'get_base_url' ),
245 array( 'WPSEO_Sitemaps_Renderer', '__construct' ),
248 foreach ( $places as $place ) {
249 if ( $this->get_back_trace()->is_class_function_in_call_stack( $place[0], $place[1] ) ) {
250 return $original_url;
258 * @return WPML_Debug_BackTrace
260 private function get_back_trace() {
261 if ( null === $this->back_trace ) {
262 $this->back_trace = new WPML_Debug_BackTrace( phpversion() );
265 return $this->back_trace;