Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[SmartCrawl] Fix compability Sitemap and WPML
<?php
/**
* Plugin Name: [SmartCrawl] Fix compability Sitemap and WPML
* Description: [SmartCrawl] Fix compability Sitemap and WPML
* Task: 0/11289012348292/1175010935729045
* Author: Thobk @ WPMUDEV
* Author URI: https://premium.wpmudev.org
* License: GPLv2 or later
*/
if ( ! defined( 'ABSPATH' ) ) { exit; } elseif ( defined( 'WP_CLI' ) && WP_CLI ) { return; }
add_action( 'after_setup_theme', 'wpmudev_sc_fix_conflict_wpml', 100 );
function wpmudev_sc_fix_conflict_wpml() {
if ( defined( 'SMARTCRAWL_VERSION' ) && defined('ICL_SITEPRESS_VERSION') && class_exists('SitePress') && class_exists('Smartcrawl_Settings') ) {
class WPMUDEV_SC_WPML{
private $wpml_filter = 0;
private $current_language;
private $home_url;
private $translated_elements;
private $post_types;
private $other_home_pages = [];
public function __construct(){
// check enabled sitemap
// return;
if( ! ( Smartcrawl_Settings::get_setting( 'sitemap' )
&& smartcrawl_is_allowed_tab( Smartcrawl_Settings::TAB_SITEMAP ) ) ){
return;
}
add_action( 'wds_before_sitemap_rebuild', array( $this, 'add_wpml_filter' ) );
add_action( 'wp', array( $this, 'maybe_disable_wpml_filter' ), 1000 );
// $this->add_wpml_filter();
}
public function add_wpml_filter(){
$this->wpml_filter = 1;
// remove old filters
remove_filter( 'wds_full_sitemap_items', array( Smartcrawl_Compatibility::get(), 'add_wpml_homepage_versions' ) );
remove_filter( 'wds_partial_sitemap_items', array( Smartcrawl_Compatibility::get(), 'add_wpml_homepage_versions_to_full' ), 10, 3 );
// switch to default language
global $sitepress, $wpdb;
$current_language = $sitepress->get_current_language();
$default_language = $sitepress->get_default_language();
if( $current_language !== $default_language ){
$sitepress->switch_lang( $default_language );
$this->current_language = $current_language;
}
// retrive translated elements
$element_types = array();
$smartcrawl_options = Smartcrawl_Settings::get_options();
// post types
$raw = get_post_types( array(
'public' => true,
'show_ui' => true,
) );
$post_types = [];
foreach ( $raw as $type ) {
if ( ! empty( $smartcrawl_options[ 'post_types-' . $type . '-not_in_sitemap' ] ) ) {
continue;
}
$post_types[] = $type;
$element_types[] = 'post_'. $type;
}
if( $element_types ){
$translated_elements = $wpdb->get_results(
$wpdb->prepare(
"SELECT element_id, language_code, element_type FROM {$wpdb->prefix}icl_translations WHERE language_code <> %s AND element_id <> trid AND element_type IN ('".join("','", $element_types)."') LIMIT %d;", $default_language, SMARTCRAWL_SITEMAP_POST_LIMIT
)
);
$this->translated_elements = [];
foreach( $translated_elements as $element ){
// if( $default_language === $element->language_code ){
// $this->translated_elements['default'][ $element->trid ] = $element->element_id;
// }else{
$this->translated_elements[ $element->element_id ] = $element;
// }
}
// set home url
$this->home_url = trailingslashit( home_url() );
// get home pages
if( 'page' === get_option( 'show_on_front' ) ){
$home_page = get_option( 'page_on_front' );
if( $home_page ){
$languages = $sitepress->get_active_languages();
foreach( $languages as $lang ){
if( $lang['code'] !== $default_language ){
$home = $sitepress->get_object_id( $home_page, 'page', 0, $lang['code'] );
if( $home ){
$this->other_home_pages[ $home ] = $home_page;
if( ! isset( $this->translated_elements[ $home ] ) ){
$this->translated_elements[ $home ] = (object) array(
'element_id' => $home,
'element_type' => 'page',
'language_code' => $lang['code'],
);
}
}
}
}
}
}
}
/**
* Convert short url to full url to fix not found post, e.g:
* If we had a translated page: https://sample.com/fr/abc
* If we search post by short url /fr/abc will not found
* But will work on the full url
*/
add_filter( 'url_to_postid', array( $this, 'convert_to_full_url'), 0 );
// change priority for home pages
add_filter( 'wds-post-priority', array( $this, 'set_priority_home_pages' ), 10, 2 );
// re-sort home pages
if( $this->other_home_pages ){
add_filter( 'wds_full_sitemap_items', array( $this, 'sort_by_priority' ) );
add_filter( 'wds_partial_sitemap_items', array( $this, 'sort_home_pages_partial_sitemap' ), 10, 3 );
}
/**
* Filter get_permerlink
*/
$this->post_types = $post_types;
foreach( $post_types as $type ){
$link_filter = $this->get_filter_link_by_type( $type );
add_filter( $link_filter, array( $this, 'maybe_convert_permalink_link'), 10, 2 );
}
}
public function convert_to_full_url( $url ){
if( ! preg_match( '/^https?:\/\//', $url ) ){
$url = $this->home_url . ltrim( $url, '/' );
}
return $url;
}
public function get_filter_link_by_type( $type ){
if( ! in_array( $type, array('post','page','attachment') ) ){
$type = 'post_type';
}
return "{$type}_link";
}
public function maybe_convert_permalink_link( $url, $post ){
$post_id = is_a( $post, 'WP_Post' ) ? $post->ID : $post;
if( $this->translated_elements && isset( $this->translated_elements[ $post_id ] ) ){
$element = $this->translated_elements[ $post_id ];
global $sitepress;
$link_filter = $this->get_filter_link_by_type( str_replace('post_', '', $element->element_type ) );
remove_filter( $link_filter, array( $this, 'maybe_convert_permalink_link'), 10, 2 );
if( $this->other_home_pages && isset( $this->other_home_pages[ $post_id ] ) ){
$url = $sitepress->convert_url( $this->home_url , $element->language_code );
}else{
$url = $sitepress->convert_url_string( $url, $element->language_code );
}
add_filter( $link_filter, array( $this, 'maybe_convert_permalink_link'), 10, 2 );
}
return $url;
}
public function set_priority_home_pages( $priority, $post ){
if( $this->other_home_pages && isset( $this->other_home_pages[ $post->ID ] ) ){
$priority = 1;
}
return $priority;
}
public function sort_home_pages_partial_sitemap( $items, $type, $page_number ){
if ( ! ( $type === 'post' && $page_number === 1 ) ) {
return $items;
}
return $this->sort_by_priority( $items );
}
public function sort_by_priority( $items ){
usort($items, function( $item1, $item2 ){
$compare = $item2->get_priority() - $item1->get_priority();
// if it's the same priority, sort by last modified time, don't apply for home page
if( 0 === $compare && $item1->get_priority() !== 1 ){
$compare = $item2->get_last_modified() - $item1->get_last_modified();
}
return $compare > 0 ? 1 : ( $compare < 0 ? -1 : 0 );
});
return $items;
}
public function maybe_disable_wpml_filter(){
if( $this->wpml_filter ){
// maybe need to switch back the original language
if( $this->current_language ){
global $sitepress;
$sitepress->switch_lang( $this->current_language );
// reset
$this->current_language = null;
}
// remove url_to_postid filter
remove_filter( 'url_to_postid', array( $this, 'convert_to_full_url'), 0 );
foreach( $this->post_types as $type ){
$link_filter = $this->get_filter_link_by_type( $type );
remove_filter( $link_filter, array( $this, 'maybe_convert_permalink_link'), 10, 2 );
}
// reset wpml_filter
$this->wpml_filter = 0;
}
}
}
$run = new WPMUDEV_SC_WPML;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment