[Extension Request] Addition of Client Reports [Tokens] for MainWP Code Snippets "return info from child sites"

Posted for Ua Vandercar

Facebook Post: https://www.facebook.com/groups/MainWPUsers/permalink/3037494836347170/?comment_id=3037554539674533&reply_comment_id=3039133136183340

It would be great to see a customizable merge tag introduced to Client Reports that would call to a specific Code Snippet instance ( that returns info from child sites ) and inserts the resulting HTML output into the report.

So for example, if I have a code snippet that return the installed WordPress Version or Site Heath Score or anything I’d like to pull from the site ( let’s say the snippet has an ID of 27 ), I could then, in a client report, add a merge tag - let’s say [code.snippet:27] - that adds the HTML output to that specific snippet.

It would open so any possibilities! Thanks for your consideration of this idea.

I’ve recently started using MainWP having spent many years using ManageWP, and the main reason for changing is the reporting flexibility in MainWP - the reports in ManageWP are not very good. I’ve spent a lot of time putting a report template together that [almost] exactly matches my hand-crafted PDF reports, most of which is automatically filled out, but not all.

I’ve got a code snippet that returns information from the child site that I then have to manually add to additional tokens, which then get added to the report. Not a problem if you don’t have many sites to do this on but it soon becomes unwieldy so the addition of this would be amazing and such a time-saver!

2 Likes

Hello, would you be so kind as to share this snippet?
It would be very useful, while waiting for the reports client plugin to evolve.
In advance thank you

Hi,

Here’s an example of one of the snippet sections I put together. This creates a table of all plugins on the child site. Once I’ve run the snippet I copy the HTML from the table into a token, which in turn is then called in my report template to show the table in the report:

//
// Get Plugins Information
//
include_once( 'wp-admin/includes/plugin.php' );

echo "<table cellspacing='0' class='detailsTable'><thead><tr><th>Plugin Name</th><th>Version</th></tr></thead><tbody>";

$all_plugins = get_plugins();

// Get active plugins
$active_plugins = get_option('active_plugins');

// Assemble array of name, version, and whether plugin is active (boolean)
$activePluginsCount = 0;
$inactivePluginsCount = 0;
foreach ( $all_plugins as $key => $value ) {
    $is_active = ( in_array( $key, $active_plugins ) ) ? true : false;
    $plugins[ $key ] = array(
        'name'    => $value['Name'],
        'version' => $value['Version'],
        'active'  => $is_active,
    );
	
	if ( $is_active == 1 ) {
		$activeValue = "";
		$activePluginsCount = $activePluginsCount + 1;
	} else {
		$activeValue = "<span class='inactive'>*</span>";
		$inactivePluginsCount = $inactivePluginsCount + 1;
	}
	echo "<tr><td>" . $value['Name'] . " " . $activeValue . "</td><td>" . $value['Version'] . "</td></tr>";
}

echo "</tbody></table>";

I do similar to detail installed themes, total post/page counts, users etc., all being added to the report through different tokens. It saves me a lot of time having to get that information manually from all of the sites I managed.

As I said, if you have lots and lots of sites you need to generate reports for, even saving the time gathering the information, it’s still a little time-consuming having to do this. Having the ability to run custom code snippets from within the report template - gathering the information from the site as the report is created - would be awesome and lead to endless possibilities for the reports people could create.

2 Likes

Hello, gentlemen! I’ve coded up a solution for this that seems to work with some initial testing (though I’ve not tested with the most recent versions). It’s pretty awesome to be able to pull info from child sites in this way. Got me excited! I provided this to the MainWP team a short while ago for possible inclusion in the Code Snippet extension, but seeing as you struck the conversation back up, I figured I’d make it available here, as well.

/**
 *  Filter report tokens to include tokens for code snippets that return information from child sites
 *  Code snippet tokens should be formatted as [code.snippet:{{snippet-id}}] where {{snippet-id}} is replaced by the actual code snippet ID.
 */
add_filter( 'mainwp_pro_reports_custom_tokens', [ $this, 'insert_code_snippet_tokens' ], 10, 3 );
add_filter( 'mainwp_client_reports_custom_tokens', [ $this, 'insert_code_snippet_tokens' ], 10, 3 );

public function insert_code_snippet_tokens( $report_tokens, $report, $site ) {

   // Might this be needed to ensure snippets are queried properly and run on multi user installs?
   // Or would this introduce a security issue?
   // add_filter( 'mainwp_is_multi_user', '__return_false', 20 );

   // Check that Code Snippets extension is active (would not be needed if code lives in Code Snippet extension)
   if ( class_exists( 'MainWP_CS_DB' ) ) {

      // Get all snippets
      $snippets = (new MainWP_CS_DB())->get_codesnippet_by();

      // Loop through the snippets
      foreach ( $snippets as $key => $snippet ) {

         // Only add custom tokens for snippets which Return Information
         if ( $snippet->type == 'R' ) {

            // Prepare and run code on site for which report is being generated
            // Code has been duplicated from MainWP_CS->run_snippet() but does not use $_POST variables for site and code
            $code = preg_replace( '|^[\s]*<\?(php)?|', '', $snippet->code );
      		$code = preg_replace( '|\?>[\s]*$|', '', $code );
      		$code = trim( $code );
      		if ( empty( $site['id'] ) ) {
      			die( json_encode( 'FAIL' ) );
      		} else if ( empty( $code ) ) {
      			die( json_encode( 'CODEEMPTY' ) );
      		}

      		global $mainWPCSExtensionActivator;

            $response = apply_filters( 'mainwp_fetchurlauthed', $mainWPCSExtensionActivator->get_child_file(), $mainWPCSExtensionActivator->get_child_key(), $site['id'], 'code_snippet', [ 'action' => 'run_snippet', 'code' => $code ] );

            // Set token content conditional on response
            $insert = $response['status'] == 'SUCCESS' ? $response['result'] : '';

            // Define the custom token
            $report_tokens["[code.snippet:{$snippet->id}]"] = $insert;

         }

      }

   }

   return $report_tokens;

}