Last active
May 11, 2020 23:02
Star
You must be signed in to star a gist
[SmartCrawl] Fix compability Sitemap and WPML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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