Posted on

Passing Information to your Child Sites

This post is part of a tutorial on creating your own MainWP Extension

1. How to create a basic WordPress plugin
2. Turning that basic plugin into an MainWP Extension
3. Passing Information to the Child site
4. Extensions using Classes in MainWP
5. Monetizing your new Extension

This is the third post in a series of posts (Post 1, Post 2) about creating a plugin that can be used as a MainWP Extension. Once we’re done this series of blog posts, you’ll have a working plugin recognized by WordPress that is also recognized by MainWP as an extension. It will be able to interact with your WordPress installation as well as your MainWP plugin. You can see the first post about creating a basic plugin here, and the second post about turning it into a MainWP extension here.

Talking to the Main Plugin

At the very bottom of the new block of code (see the previous post about how to connect your plugin to MainWP) there is an area where we obtain the $childKey. We actually need this in order to ‘talk’ to the MainWP main plugin, and request data. Lets go ahead and see if we can get it to show on the settings page. Add this to the bottom of your my_plugin_extension_settings() function, just before the do_action:

    global $childEnabled;
    $childEnabled = apply_filters('mainwp-extension-enabled-check', __FILE__);
    if (!$childEnabled) return;
    $childKey = $childEnabled['key'];
    echo $childKey;

What you should see is a string of characters directly below the “change text” button of your settings page. We’ll try to utilize it in the next step.

Why don’t we start by taking that $childKey and then output a list of sites that the MainWP main plugin manages, then we can perform an action on those sites. Add the following just below what you just put into the above function:

 echo "<br /><br />";
 
 $sites = apply_filters('mainwp-getsites', __FILE__, $childKey);
 
 foreach ($sites as $site)
 {
 echo 'Site id: ' . $site['id'] . '<br />';
 echo 'Site name: ' . $site['name'] . '<br />';
 echo 'Site url: ' . $site['url'] . '<br />';
 }
 
 do_action('mainwp-pagefooter-extensions', __FILE__);
 }

All this does is utilize the mainwp-getsites filter (information here) and the $childKey of your extension to list the sites that are currently part of your list. If you don’t have any sites, that’s OK! Here’s an example of what it would output:

example

So how does this help us? Well, right now it doesn’t. But we can utilize the list for some things. In this example the $sites variable only returns the ID, Name, URL, and totalsize variables in the array, but using a different method we can get something else out of it. Why don’t we display an admin notice to all of the sites that we manage, letting them know that there’s an update scheduled for this upcoming weekend? Below is the function that we need to actually show the admin notice, then we need to push it to the client sites.

function my_admin_notice(){
    $textvar = get_option('test_plugin_variable', 'hello world');

    echo '<div class="updated">
       <p>'.$textvar.'</p>
    </div>';

}

add_action('admin_notices', 'my_admin_notice');

I have also gone ahead and removed the action that wrote some text to the footer of the template:

add_action( 'wp_footer', 'my_function' );

function my_function() {
  $textvar = get_option('test_plugin_variable', 'hello world');
  echo $textvar;
}

While we’re at it, we can re-write the settings page so that it will let us set and utilize the test_plugin_variable as the notice for the admin dashboard. Below is the code in its entirety, as we have made a lot of changes along the way. This will only display the admin notice once we save the changes.

function my_admin_notice(){
 $textvar = get_option('test_plugin_variable', 'Try not to panic! We have regularly scheduled updates this weekend.');
 echo '<div class="updated">
 <p>'.$textvar.'</p>
 </div>';

}

if (isset($_POST['change-clicked'])) {
 add_action('admin_notices', 'my_admin_notice');
}

$childKey = false;

add_filter('mainwp-getextensions', 'get_this_extension');
$mainWPActivated = apply_filters('mainwp-activated-check', false);

if ($mainWPActivated !== false) {
 activate_this_plugin();
} else {
 add_action('mainwp-activated', 'activate_this_plugin');
}

function get_this_extension($extensions) {
 $extensions[] = array('plugin' => __FILE__, 'callback' => 'my_plugin_extension_settings');
 return $extensions;
}

function my_plugin_extension_settings() {
 do_action('mainwp-pageheader-extensions', __FILE__);
 
 $textvar = get_option('test_plugin_variable', 'Try not to panic! We have regularly scheduled updates this weekend.');
 
 if (isset($_POST['change-clicked'])) {
 update_option( 'test_plugin_variable', $_POST['footertext'] );
 $textvar = get_option('test_plugin_variable', 'hello world');
 } 
 
 ?>
 <div class="wrap">
 <h1>Admin Notice</h1>
 <p>This simple plugin will set and ouput an admin notice to the dashboard. Change the text below:</p>
 <form action="<?php echo str_replace('%7E', '~', $_SERVER['REQUEST_URI']); ?>" method="post">
 Admin Notice:<input type="text" value="<?php echo $textvar; ?>" name="footertext" placeholder="hello world"><br />
 <input name="change-clicked" type="hidden" value="1" />
 <input type="submit" value="Change Text" />
 </form>
 </div>
 <?
 
 global $childEnabled;
 $childEnabled = apply_filters('mainwp-extension-enabled-check', __FILE__);
 if (!$childEnabled) return;
 $childKey = $childEnabled['key'];
 //echo $childKey; // this is hidden for now, but we can utilize it
 echo "<br /><br />";
 
 $sites = apply_filters('mainwp-getsites', __FILE__, $childKey);
 
 /*
 // we also don't need this at this point, let's figure out the admin notice first.
 foreach ($sites as $site)
 {
 echo 'Site id: ' . $site['id'] . '<br />';
 echo 'Site name: ' . $site['name'] . '<br />';
 echo 'Site url: ' . $site['url'] . '<br />';
 }
 */
 do_action('mainwp-pagefooter-extensions', __FILE__);
 }

function activate_this_plugin() {
 global $childEnabled;
 $childEnabled = apply_filters('mainwp-extension-enabled-check', __FILE__);
 if (!$childEnabled) return;

 $childKey = $childEnabled['key'];
 
 //Code to initialize your plugin
}

So after changing the textbox, it will show you the following:

adminnotice

We will also need a piece of code that performs another action, this time listing the sites as a select box:

<div id="uploader_select_sites_box" class="mainwp_config_box_right">                                            
        <?php do_action('mainwp_select_sites_box', __("Select Sites", 'mainwp'), 'checkbox', true, true, 'mainwp_select_sites_box_right', "", array(), array()); ?>													
    </div>

We’ll add the above line of code inside the form action tags of the settings page, and as soon as you select a box you’ll get the output similar to the following (this is using print_r on the $_POST variable):

[change-clicked] => 1 [select_by] => site [selected_sites] => Array ( [0] => 4 ) )

This gives us an array of child sites, which we can use to push information, so I’m going to go ahead and move the code that gets the childkey into a function by itself, and use the hook that checks for posted data to loop through each of the child sites and post our admin notice. I’ll also add a checkbox to remove the notice after we’re done.

We are utilizing a feature of the child plugin called a “code_snippet” – where we can save, run, and delete code that can help us do things on child sites. For instance, email us when something happens, deactivate or activate a plugin, change something to do with WordPress itself using actions or filters.

More about code snippets can be found here.

The method used to call the code snippet and save it is a combination of an array and some information that we need from the extension, as well as a child site ID.

$information = apply_filters('mainwp_fetchurlauthed', __FILE__, $childKey, $websiteId, 'code_snippet', $post_data2);

/*the function we are calling is mainwp_fetchurlauthed, which will execute the function 
"filter_fetchUrlAuthed". It will pass an array of $post_data to the child site, then wait 
for a response. The $childKey is found using the above code and should be stored in a way 
you can use it, or called from a function so you can use it (see get_childkey below). 
The $websiteId can be pulled from the above code, in the array 'selected_sites'. The 
function that we are executing on the child site is called 'code_snippet' which has a 
few different options that can be selected through the post array.*/
        $post_data = array(
            'action' => 'save_snippet', //this is the action for code_snippet, you can save, run, or delete a snippet.
            'type' => 'B', //if the type is set to "C", it will save it to the wp_config file. Be Careful!
            'slug' => 'adminnotice', //this allows us to add/remove snippets based around the slug. 
            'code' => $adminnotice, //the piece of code that we need to execute on the child site, shown in the code below.
        );

The full code is below, with notations. Feel free to email me with any questions.

<?php
/**
 * Plugin Name: Child Site Admin Notices
 * Plugin URI: http://www.brendancarr.ca
 * Description: This plugin sends and removes admin notices to child sites from within your MainWP dashboard.
 * Version: 1.0.0
 * Author: Brendan Carr
 * Author URI: http://www.brendancarr.ca
 * License: GPL2
 */

$textvar = get_option('test_plugin_variable', 'Try not to panic! We have regularly scheduled updates this weekend.'); // this retrieves the text in the box we just saved.

$adminnotice="

function my_admin_notice(){
	echo '<div class="updated"><p>".$textvar."</p></div>';
}
add_action('admin_notices', 'my_admin_notice');

"; // creates the function we need on the child site, including the text variable.

function get_childkey(){ // retrieves the childkey as a function that we can call
	global $childEnabled;
    $childEnabled = apply_filters('mainwp-extension-enabled-check', __FILE__);
    if (!$childEnabled) return;
    $childKey = $childEnabled['key'];
	return $childKey;
}

if (isset($_POST['change-clicked'])) { // this is where the magic happens - when we hit the button, it executes on the child sites.
	if (count($_POST['selected_sites'] > 0)) { //makes sure a child site has been selected
	
		update_option( 'test_plugin_variable', $_POST['adminnotice'] );
		$textvar = get_option('test_plugin_variable', 'Try not to panic! We have regularly scheduled updates this weekend.');
			
		echo '<div class="updated">';
		//print_r($_POST);
		
	    $childKey = get_childkey();                   
	
        $post_data1 = array( // this saves the snippet to the database, where the Child plugin can execute it.
            'action' => 'save_snippet',
            'type' => 'B',
            'slug' => 'adminnotice',
            'code' => $adminnotice,

        );

        $post_data2 = array( //this removes the snippet after we're done with it, based on the checkbox in the form.
            'action' => 'delete_snippet',
            'type' => 'B',
            'slug' => 'adminnotice',
            'code' => $adminnotice,

        );
	        
	     $sites = $_POST['selected_sites'];
	     foreach ($sites as $site) {
		     $websiteId = $site;
		     if (isset($_POST['remove-clicked'])) {
			    $information = apply_filters('mainwp_fetchurlauthed', __FILE__, $childKey, $websiteId, 'code_snippet', $post_data2);
			    echo "<p>The notice has been removed from your child site!</p>"; 
		     } else {
		     	//echo "<br>Executing on Child site ID#".$websiteId.":<br>";
			 	$information = apply_filters('mainwp_fetchurlauthed', __FILE__, $childKey, $websiteId, 'code_snippet', $post_data1);
			 	//print_r($information); // this is the return information from after we execute the code.
			 	if ($information['status'] == "SUCCESS") {echo "<p>The notice has been posted to your child site!</p>";}
		     }
		     
	     }                     
		 
		 echo "</div>";
	 }
}

$childKey = false;

add_filter('mainwp-getextensions', 'get_this_extension');
$mainWPActivated = apply_filters('mainwp-activated-check', false);

if ($mainWPActivated !== false) {
    activate_this_plugin();
} else {
    add_action('mainwp-activated', 'activate_this_plugin');
}

function get_this_extension($extensions) {
    $extensions[] = array('plugin' =>  __FILE__, 'callback' => 'my_plugin_extension_settings');
    return $extensions;
}
   
function my_plugin_extension_send($adminNotice, $childKey, $siteIDs, $addremove) {
/*
$adminNotice is a line of text
$childKey is called by the function get_childkey()
$siteIDs would be an array based on the $_POST variables selected_sites
$addremove could be a switch to save or delete the snippet from your child site
*/
}

function my_plugin_extension_settings() {
    do_action('mainwp-pageheader-extensions', __FILE__);
    
    $textvar = get_option('test_plugin_variable', 'Try not to panic! We have regularly scheduled updates this weekend.');
	
	?>
    <div class="wrap">
      <h1>Admin Notice</h1>
      <p>This simple plugin will set and ouput an admin notice to the dashboard. Change the text below:</p>
      <form action="<?php echo str_replace('%7E', '~', $_SERVER['REQUEST_URI']); ?>" method="post">
	    Admin Notice:<input type="text" value="<?php echo $textvar; ?>" name="adminnotice" placeholder="hello world"><br />
	    <input name="change-clicked" type="hidden" value="1" />
	    Remove Notice: <input name="remove-clicked" type="checkbox" /><br />
        <input type="submit" value="Post Notice" />
        <div id="uploader_select_sites_box" class="mainwp_config_box_right">                                            
        	<?php do_action('mainwp_select_sites_box', __("Select Sites", 'mainwp'), 'checkbox', true, true, 'mainwp_select_sites_box_right', "", array(), array()); ?>
    	</div>
      </form>
    </div>
    
        <?
    
	    do_action('mainwp-pagefooter-extensions', __FILE__);
	}

function activate_this_plugin() {
  global $childEnabled;
  $childEnabled = apply_filters('mainwp-extension-enabled-check', __FILE__);
  if (!$childEnabled) return;

  $childKey = $childEnabled['key']; // You can store this in another way! Maybe as a WordPress variable, or in a class.
  
  //Code to initialize your plugin
}

?>

 

Once it’s all said and done, we can execute the notice on the child site, and also remove it. Here’s what it looks like when it’s done – I have also added some debug information to it to make sure it is working properly, in case you’re wondering about the variables in the header. I also used an eval() code directly after line 21 to test the function on the main installation, which is also not a part of the above code. You’ll notice a function called “my_plugin_extension_send” – why don’t you try to wrap some of the code that is in the $_POST hook into that function, and see if you can clean up that part of the plugin a little? Let me know how you do!

 

finaladminnotice

In the next post, we will look at styling your Extension so it doesn’t have the default icon, adding documentation pages and using the activation path that MainWP has so you can secure your Extension using an API key.

Here’s what it looks like in the dashboard currently. Thanks for reading!

styling

Get MainWP News and Notifications

Brendan
Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.