Instantly share code, notes, and snippets.
Created
November 23, 2017 10:16
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save panoslyrakis/d8e43285b6dbb5bc7a29f9f6008ab081 to your computer and use it in GitHub Desktop.
[WordPress MultiSite General] - Fix shared terms in multisite
This file contains hidden or 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: [WordPress MultiSite General] - Fix shared terms in multisite | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: A custom solution to fix shared terms in multisite | |
* Author: Panos Lyrakis @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( ! class_exists( 'WPMUDEV_MS_Shared_Terms' ) ) { | |
class WPMUDEV_MS_Shared_Terms { | |
private static $_instance = null; | |
public static function get_instance() { | |
if( is_null( self::$_instance ) ){ | |
self::$_instance = new WPMUDEV_MS_Shared_Terms(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
add_action('network_admin_menu', array( $this, 'network_page' ) ); | |
add_action( 'admin_footer', array( $this, 'load_raw_js' ), 10 ); | |
add_action( 'wp_ajax_wpmudev_get_network_shared_terms', array( $this, 'blog_shared_terms_ajax' ), 10 ); | |
add_action( 'wp_ajax_wpmudev_split_blog_shared_terms', array( $this, 'blog_split_terms_ajax' ), 10 ); | |
} | |
public function network_page() { | |
add_submenu_page( | |
'settings.php', | |
__( 'Shared Terms' ), | |
__( 'Network Shared Terms' ), | |
'manage_network_options', | |
'wpmudev-ms-shared-terms', | |
array( $this, 'page_layout' ) | |
); | |
} | |
public function page_layout(){ | |
?> | |
<div class="wrap" style="width: 45%;float: left;"> | |
<div class="card header-card"> | |
<h1><?php _e( 'Network Shared Terms' ); ?></h1> | |
<em><?php _e( 'From here you can monitor shared terms across network sites' ); ?></em> | |
<!--<div class="notice notice-warning"> <?php _e( 'It\'s important you keep a backup of these tables first!' ); ?> </div>--> | |
</div> | |
<div class="card content-card"> | |
<table class="wp-list-blogs widefat fixed striped sites"> | |
<tr> | |
<td>Blog id</td> | |
<td>Blog name</td> | |
<td>Shared terms</td> | |
</tr> | |
<?php | |
$sites = $this->get_sites(); | |
foreach( $sites as $site ){ | |
$site_details = get_blog_details( $site->blog_id ) | |
?> | |
<tr class="blogs-row blog-id-<?php echo $site->blog_id; ?>"> | |
<td><?php echo $site->blog_id; ?></td> | |
<td><?php echo $site_details->blogname; ?></td> | |
<td><div class="wpmudev-term-item-wrap" data-blog-id="<?php echo $site->blog_id; ?>"> - </div></td> | |
</tr> | |
<?php | |
} | |
?> | |
</table> | |
</div> | |
</div> | |
<div class="wrap" style="width: 45%;float: right;"> | |
<div class="card wpmudev_blog_report"> | |
</div> | |
</div> | |
<?php | |
} | |
public function blog_shared_terms_ajax(){ | |
check_ajax_referer( 'wpmudev_get_network_shared_terms', 'security' ); | |
$blog_id = (int)$_POST['blog_id']; | |
$terms = $this->blog_shared_terms( $blog_id ); | |
$return = array( | |
'success' => true, | |
'terms_count' => count( $terms ) | |
); | |
wp_send_json( $return ); | |
} | |
public function blog_shared_terms( $blog_id ){ | |
$blog_id = (int)$blog_id; | |
return $this->get_shared_terms( $blog_id ); | |
} | |
public function get_shared_terms( $blog_id, $limit = null ) { | |
switch_to_blog( $blog_id ); | |
global $wpdb; | |
$terms = array(); | |
$terms_query = "SELECT `term_id` FROM {$wpdb->term_taxonomy} GROUP BY `term_id` HAVING COUNT(*) > 1"; | |
if( ! is_null( $limit ) && is_numeric( $limit ) ){ | |
$limit = (int) $limit; | |
$terms_query .= " LIMIT {$limit}"; | |
} | |
$term_ids = $wpdb->get_col( $terms_query ); | |
if ( ! empty( $term_ids ) ) { | |
$terms = $wpdb->get_results( | |
"SELECT tt.term_taxonomy_id, tt.term_id, t.name, tt.taxonomy, tt.count | |
FROM {$wpdb->term_taxonomy} AS tt | |
INNER JOIN {$wpdb->terms} AS t ON tt.term_id=t.term_id | |
WHERE tt.term_id IN (" . implode( ',', $term_ids ) . ')' | |
); | |
} | |
restore_current_blog(); | |
return $terms; | |
} | |
public function blog_split_terms_ajax(){ | |
check_ajax_referer( 'wpmudev_get_network_shared_terms', 'security' ); | |
$blog_id = (int)$_POST['blog_id']; | |
$step = (int)$_POST['step']; | |
$split_terms = $this->blog_split_terms( $blog_id, $step ); | |
$split_terms_count = count( $split_terms ); | |
$return = array( | |
'success' => true, | |
'terms_count' => $split_terms_count, | |
'terms_splited' => $split_terms | |
); | |
if( $split_terms_count < $step || $split_terms_count <= 0 ){ | |
$return[ 'done' ] = true; | |
} | |
wp_send_json( $return ); | |
} | |
public function blog_split_terms( $blog_id, $limit ){ | |
$terms = $this->blog_shared_terms( $blog_id, $limit ); | |
$split_terms = array(); | |
if( ! is_array( $terms ) || empty( $terms ) ){ | |
return array(); | |
} | |
switch_to_blog( $blog_id ); | |
foreach( $terms as $term ){ | |
$new_term_id = _split_shared_term( $term->term_id, $term->term_taxonomy_id ); | |
if( ! is_wp_error( $new_term_id ) ){ | |
$split_terms[] = $term->name; | |
} | |
} | |
restore_current_blog(); | |
return $split_terms; | |
} | |
public function load_raw_js(){ | |
$screen = get_current_screen(); | |
if( 'settings_page_wpmudev-ms-shared-terms-network' != $screen->id ){ | |
return; | |
} | |
$nonce = ''; | |
?> | |
<script type="text/javascript"> | |
(function($){ | |
$(document).ready(function(){ | |
WPMUDEV_MS_Shared_Terms.init(); | |
}); | |
var WPMUDEV_MS_Shared_Terms = { | |
blog_ids: [], | |
blog_ids_with_shared_terms: [], | |
blog_counter: 0, | |
terms_step: 10, | |
init: function(){ | |
this.get_blogs() | |
this.get_blogs_shared_terms() | |
}, | |
get_blogs: function(){ | |
let blogs = []; | |
$( '.wpmudev-term-item-wrap' ).each(function(){ | |
blogs.push( $(this).data('blog-id') ); | |
}); | |
this.blog_ids = blogs; | |
}, | |
get_blogs_shared_terms: function(){ | |
if( this.blog_counter >= this.blog_ids.length ){ | |
this.blog_counter = 0; | |
WPMUDEV_MS_Shared_Terms.split_network_terms(); | |
return; | |
} | |
let blog_id = this.blog_ids[ this.blog_counter ]; | |
const blog_ids_number = this.blog_ids.length | |
let blog_counter = this.blog_counter; | |
this.blog_counter++ | |
var data = { | |
action: 'wpmudev_get_network_shared_terms', | |
security: '<?php echo wp_create_nonce( "wpmudev_get_network_shared_terms" ); ?>', | |
blog_id: blog_id | |
}; | |
$.post(ajaxurl, data, function(response) { | |
if( response.success ){ | |
let el = $( '.blogs-row.blog-id-' + blog_id + ' .wpmudev-term-item-wrap' ); | |
el.html( ' ' + response.terms_count + ' ' ); | |
if( response.terms_count > 0 ){ | |
WPMUDEV_MS_Shared_Terms.blog_ids_with_shared_terms.push( blog_id ); | |
$( '.blogs-row.blog-id-' + blog_id + ' td' ).css( 'background','#d57776' ); | |
} | |
} | |
if( blog_counter < blog_ids_number ){ | |
WPMUDEV_MS_Shared_Terms.get_blogs_shared_terms(); | |
} | |
else{ | |
//It shouldn't reach here | |
//WPMUDEV_MS_Shared_Terms.split_network_terms(); | |
} | |
}); | |
}, | |
split_network_terms: function(){ | |
let blog_id = WPMUDEV_MS_Shared_Terms.blog_ids_with_shared_terms[ this.blog_counter ] | |
this.blog_counter++ | |
if( this.blog_counter > this.blog_ids_with_shared_terms.length ){ | |
alert( 'FINISHED' ) | |
} | |
else{ | |
this.split_blog_terms( blog_id ) | |
} | |
}, | |
split_blog_terms: function( blog_id ){ | |
var data = { | |
action: 'wpmudev_split_blog_shared_terms', | |
security: '<?php echo wp_create_nonce( "wpmudev_get_network_shared_terms" ); ?>', | |
blog_id: blog_id, | |
step: this.terms_step | |
}; | |
$.post(ajaxurl, data, function(response){ | |
if( response.success ){ | |
if( response.done ){ | |
WPMUDEV_MS_Shared_Terms.split_network_terms(); | |
//console.log( response.terms_splited ); | |
WPMUDEV_MS_Shared_Terms.print_report( blog_id, response.terms_splited ); | |
} | |
else{ | |
WPMUDEV_MS_Shared_Terms.split_blog_terms( blog_id ); | |
} | |
} | |
}) | |
}, | |
print_report: function( blog_id, terms_splited ){ | |
let blog_report = $( '.wpmudev_blog_report' ); | |
let term_names = ''; | |
for( let i = 0; i < terms_splited.length; i++ ){ | |
term_names += '<div>' + terms_splited[i] + '</div>'; | |
} | |
blog_report.append( '<h3>BLOG ID: ' + blog_id + '</h3>' ); | |
blog_report.append( '<div style="margin-bottom: 20px; padding:10px; border: 1px solid #ddd;">' + term_names + '</div>' ); | |
} | |
} | |
})(jQuery); | |
</script> | |
<?php | |
} | |
public function get_sites(){ | |
$sites = get_sites(); | |
return $sites; | |
} | |
} | |
add_action( 'plugins_loaded', function(){ | |
$GLOBALS['WPMUDEV_MS_Shared_Terms'] = WPMUDEV_MS_Shared_Terms::get_instance(); | |
}, 10 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment