While updating my Check Amazon Links plugin to work with WordPress Multisite, I struggled with how I could make my plugin settings universal across all network installs. More specifically, I wanted it to be an option that could be turned on and off. I tried to find a way to implement a hook or filter for when the plugin options were being updated via the settings page, but I had so much trouble with that, that I finally decided to use some Javascript. Yay for javascript! Sometimes it’s the easier option.
First, I added the option to my settings page, but only on multisite installs. Here’s what it looks like:
Next, I wrote the Javascript (jQuery) code to respond to submit events:
jQuery(document).ready(function () {
var option_page_name = jQuery('input[name=option_page]').val();
if (typeof(option_page_name) != "undefined") {
if(option_page_name === 'amazon_link_plugin_options') {
jQuery('form').submit(function(e) {
var update_all = jQuery('select[name="azlc_multisite_same[toggle]"]').val();
if(update_all === '1') {
jQuery.post(ajaxurl, 'action=azlc_ms', function(){});
}
});
}
}
});
As you see, my code checks the page name to insure that it only sends the AJAX request if it’s MY plugin’s page. I add that javascript code to a javascript file I already enqueue.
Here’s the PHP WordPress Backend code for handling the Ajax request:
if(is_multisite()) {
add_action('wp_ajax_azlc_ms', 'azlc_ms');
}
function azlc_ms() {
add_site_option( 'azlc_update_from', get_current_blog_id() );
}
And here’s the PHP WordPress code the updates the options:
if(is_multisite()) {
add_action('plugins_loaded', 'azlc_multisite');
}
function azlc_multisite() {
global $wpdb;
// check for flag
// I call this a flag because its existence means that this code needs to run.
// You could write this to make it more human readable
$blog_id = get_site_option('azlc_update_from');
if($blog_id) {
// switch to the blog to copy the actions from
switch_to_blog($blog_id);
$options = get_option('azlc_plugin_options');
// copy settings to all sites
AmazonLinkCheckerCore::copy_settings_from($blog_id, 'azlc_plugin_options', $options );
// remove flag
delete_site_option('azlc_update_from');
// switch back
restore_current_blog();
}
}
And here’s the code that actually does the copying:
public static function copy_settings_from($source_id, $option_name, $option_value) {
global $wpdb;
$sql = "SELECT blog_id FROM $wpdb->blogs";
$blog_ids = $wpdb->get_col($sql);
foreach($blog_ids as $blog_id) {
// update option on other blogs
if($blog_id!=$source_id) {
switch_to_blog($blog_id);
update_option($option_name, $option_value);
}
}
restore_current_blog();
}
Related Tutorial
Don’t miss this related article: How to Enable WordPress Multisite for your Plugin
Your feedback is important
I write this blog with sincere hope that I can help other WordPress developers. Please let me know if this helped you, or if I made a bad error. Thanks!
[…] If you have a settings page, it will appear on each blog. If you want to make the settings universal across all network blogs, you will have to implement a way to copy the settings from one blog to all. Read this tutorial: How to make your plugin have universal settings on Multisite WordPress. […]