Skip to content

Instantly share code, notes, and snippets.

@wpmudev-sls
Last active September 14, 2022 04:16
Show Gist options
  • Save wpmudev-sls/d14cbe94eef14de670b7c9e0a77631b2 to your computer and use it in GitHub Desktop.
Save wpmudev-sls/d14cbe94eef14de670b7c9e0a77631b2 to your computer and use it in GitHub Desktop.
[SmartCrawl Pro] Multilingual sitemap (WPML integration)
<?php
/**
* Plugin Name: [SmartCrawl Pro] Multilingual sitemap (WPML integration)
* Description: Improves the SmartCrawl sitemaps with multilingual-ready capabilities when the WPML plugin is present
* Author: Anderson Salas @ WPMUDEV
* Task: SLS-4082
* Author URI: https://premium.wpmudev.org
* License: GPLv2 or later
*/
add_action( 'plugins_loaded', function() {
if ( ! class_exists( 'Smartcrawl_Sitemap_Post_Fetcher' ) ) {
return; // SmartCrawl is not installed/enabled.
}
if ( ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
return; // WPML is not installed/enabled.
}
add_filter( 'wds_partial_sitemap_items', function( $items, $type, $page ) {
global $wpdb;
// ---------------------------------------------------------------------------- //
// Modify this array with the Custom Post Types to be translated in the Sitemap
// or leave it as a blank array to use all the public available types
// ---------------------------------------------------------------------------- //
$allowed_types = array();
// ---------------------------------------------------------------------------- //
if ( empty( $allowed_types ) ) {
$allowed_types = get_post_types(
array(
'show_ui' => true,
'public' => true,
)
);
unset( $allowed_types['post'] );
unset( $allowed_types['page'] );
unset( $allowed_types['attachment'] );
$allowed_types = array_keys( $allowed_types );
}
if ( empty( $allowed_types ) || ( ! empty( $allowed_types ) && ! in_array( $type, $allowed_types ) ) ) {
return $items; // Type not allowed.
}
if ( empty( $items ) ) {
return $items; // Nothing to handle.
}
$grouped_items = array();
foreach( $items as $item ) {
if ( ! isset( $grouped_items[ $item->get_location() ] ) ) {
$grouped_items[ $item->get_location() ] = array(
'id' => url_to_postid( $item->get_location() ),
'variants' => array(),
'item' => $item,
);
} else {
$grouped_items[ $item->get_location() ]['variants'][ $item->get_last_modified() ] = $item;
}
}
if ( empty( $items ) ) {
return $items;
}
$p = $wpdb->prefix;
$ids_in = implode( ',', array_column( $grouped_items, 'id' ) );
$query = "SELECT
(
SELECT
element_id
FROM
{$p}icl_translations
WHERE
trid = t.trid
AND element_type = 'post_$type'
AND source_language_code IS NULL LIMIT 1
) parent_id,
p.id post_id,
p.guid post_url,
t.language_code post_lang,
UNIX_TIMESTAMP( p.post_modified_gmt ) post_date
FROM
{$p}icl_translations t
LEFT JOIN {$p}posts p ON p.ID = t.element_id
WHERE
trid IN (
SELECT
trid
FROM
{$p}icl_translations
WHERE
element_id IN ($ids_in)
AND element_type = 'post_$type'
AND p.post_status = 'publish'
)
AND t.element_id NOT IN ($ids_in)";
$posts = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
if ( empty( $posts ) ) {
return $items; // Empty result set (probably due to a DB query error).
}
$result = array();
$replacements = array();
foreach( $grouped_items as &$item ) {
$item_url = $item['item']->get_location();
$item['item']->set_location( $item_url . '%MLSM_' . $item['id'] . '%' );
$result[] = $item['item'];
$replacement = '</loc>';
foreach( $posts as $post ) {
if( $item['id'] === (int) $post['parent_id'] ) {
//$post_date = (int) $post['post_date'];
//if ( isset( $item['variants'][ $post_date ] ) ) {
//$new_url = apply_filters( 'wpml_permalink', $post['post_url'], $post['post_lang'] );
$new_url = apply_filters( 'wpml_permalink', $item_url, $post['post_lang'] );
$replacement .= "\n" . '<xhtml:link rel="alternate" hreflang="' . $post['post_lang'] . '" href="' . $new_url . '" />';
//}
}
}
$replacements[ '%MLSM_' . $item['id'] . '%</loc>' ] = $replacement;
}
$xml = Smartcrawl_Simple_Renderer::load( 'sitemap/sitemap-general-xml', array( 'items' => $result, ) );
$xml = str_ireplace( array_keys( $replacements ), array_values( $replacements ), $xml );
if ( false === strpos( $xml, 'xmlns:xhtml=' ) ) {
$xml = str_ireplace( '<urlset', '<urlset xmlns:xhtml="http://www.w3.org/1999/xhtml" ', $xml );
}
// Cache this XML output.
$sitemap_cache = Smartcrawl_Sitemap_Cache::get();
$sitemap_cache->set_cached( $type, $page, $xml );
$is_gzip_supported = stripos( (string) smartcrawl_get_array_value( $_SERVER, 'HTTP_ACCEPT_ENCODING' ), 'gzip' ) !== false;
$is_gzip_request = ! empty( get_query_var( 'wds_sitemap_gzip' ) );
if ( ! headers_sent() ) {
status_header( 200 );
// Prevent the search engines from indexing the XML Sitemap.
header( 'X-Robots-Tag: noindex, follow' );
header( 'Content-Type: text/xml; charset=UTF-8' );
if (
$is_gzip_supported
&& function_exists( 'gzencode' )
&& $is_gzip_request
) {
header( 'Content-Encoding: gzip' );
$xml = gzencode( $xml );
}
die( $xml );
}
return $result;
}, 10, 3 );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment