How to make your plugin have universal settings on Multisite WordPress?

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:

Multisite Option on my WordPress Plugin (Check Amazon Links)

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!

How to embed C3.js Javascript Charts in WordPress Posts

I’ve been working with C3.js graphs for an admin website and thought it would be fun to use it on this WordPress blog.  You can use most Javascript libraries in WordPress, but it takes a little more work.  If you know how to write Javascript, then you’ll find that C3.js offers a relatively easy way to create custom pie charts, timeseries charts, line and bar graphs, etc.   Here’s an example of a graph created with C3.js.  I used real historical weather data to compare the record high July 2015 temperatures to average temperatures.

Tacoma, WA: Record High July 2015 Temperatures

Here’s how I created the above graph.

First, I downloaded the c3 and d3 libraries (you can get the zip file on github). I unzipped the file and put the c3.css, c3.min.js, d3.min.js files into the root directory of my wordpress theme.

Side note: I am using a child theme, as you should too, to prevent problems if your theme gets automatically updated.  If you are not familiar with child themes, check out this WordPress tutorial.

Next, I added the following code to my functions.php file:

functions.php


add_action( 'wp_enqueue_scripts', 'add_c3_scripts' );

function add_c3_scripts() {
	$d3_url =  get_stylesheet_directory_uri() . '/d3.min.js';
	$c3_url =  get_stylesheet_directory_uri() . '/c3.min.js';
	$c3_css =  get_stylesheet_directory_uri() . '/c3.css';
	$my_graphs_url =  get_stylesheet_directory_uri() . '/my_graphs.js';
	wp_enqueue_script( 'd3', $d3_url );
	wp_enqueue_script( 'c3', $c3_url, 'd3' );
	wp_enqueue_script( 'my_graphs', $my_graphs_url, 'c3' );
	wp_enqueue_style( 'c3', $c3_css );
}

Next, I create the my_graphs.js file in the root directory of my theme.  For better organization, you could put this in a scripts folder and change the above url accordingly.

In the my_graphs.js file, I write a Javascript function which creates a C3 chart.  It looks like this:

my_graphs.js


function july_2015_graph() {
    var chart = c3.generate({
        bindto: '#july_2015_graph',
        color: {
            pattern: ['#396ab1', '#cc2529']
        },
        data: {
            x: 'x',
            columns: [
                ['x', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ,16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
                ['Average', 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 72, 72, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 75, 75, 75]
            ],
            type: 'spline'
        },
        axis: {
            x: {
                label: 'Date'
            },
            y: {
                label: 'Temperature (F)',
                min: 65,
                max: 95
            }
        },
        transition: {
            duration: 100
        }
    });

    setTimeout(function () {
        chart.load({
            columns: [
                ['2015', 89, 92, 92, 91, 91, 84, 83, 87, 81, 71, 72, 78, 79, 81, 80, 79, 80, 91, 94, 80, 75, 74, 77, 75, 71, 71, 75, 81, 88, 92, 95]
            ]
        });
    }, 1000);

}

The “bindto:” line at the top of that code segment tells the c3.js Javascript Library where to put the graph.

To display the graph in this post, I edit the post in “text” mode (select the text tab at the top of the wordpress post editor) and add this code:


<div id="july_2015_graph"></div>
<script type="text/javascript">
july_2015_graph();
</script>

 

For more information about how to use Javascript with WordPress, check out this page: Using Javascript in WordPress