Search code examples
phpwordpressmultisite

Wordpress Multisite call plugin function on different site


I am working on a Wordpress plugin, which has to trigger some actions on a different site within the Wordpress Multisite network.

  • Site A
  • Site B: changes Site A

For example I switch the site to change the user role on a different site with (code on Site B):

switch_to_blog(1); //to Site A
//Change the user's role
restore_current_blog();

This works fine, but now I want to call a plugin's function. So I want to call a function of a plugin which is activated on Site A from Site B. The switch_to_blog() function only switches the database and not the loaded plugins. So how can I achieve my goal? I tried to activate the Plugin on Site B, but this does not work. I have full access to both sites.


Solution

  • Unfortunately, it doesn't appear that this will ever make it into Core: Trac ticket #14941 (and everyone knows palindromic ticket numbers are sealed in stone, lol).

    To be honest your best bet is to trigger the function to run by some other method, such as triggering a custom action on the target site. So go ahead and run the function you have now, but add a GET or POST request to the target blog URL (I'll use file_get_contents as an example, but you should use a POST method with nonces if you're able)

    function trigger_function_on_blog( $blog_id, $user_id ){
        $blog_url = get_site_url( $blog_id );
        switch_to_blog( $blog_id );
    
        $user_id = wp_update_user( array( 'ID' => $user_id, 'role' => 'new_role' ) );
        file_get_contents( $blog_url . '?auth=m50667' );
    
        restore_current_blog();
    }
    
    // Modify User: 2 on Blog: 1
    trigger_function_on_blog( 1, 2 );
    

    Now your function runs normally, but also requests the targeted site directly. On your target site you just need to make sure the function only triggers when $_GET['auth'] equals m50667 (or your other and better validation methods are met).

    You'd probably want to use a MU Plugin for this, since functions.php is theme-dependent, and Multi-Site allows separate themes.

    So go ahead and create /mu-plugins/custom-functions.php and it will run all the time, always, no activation required, and inside it put the logic you want to run:

    if ( ! defined( 'ABSPATH' ) ) exit; // Prevent direct file access
    
    add_action( 'init', 'faux_switch_to_blog_function' );
    function faux_switch_to_blog_function(){
        if( $_GET['auth'] === 'm50667' ){ // Make sure this request is authorized by us
            if( function_exists( 'some_plugin_function' ) ){
                some_plugin_function();
            }
        }
    }
    

    Now, when any-site.example.com?auth=m50667 is triggered by the trigger_function_on_blog(), the faux_switch_to_blog_function() will run on the target site, and you should have access to any functions and hooks available to that site.

    PLEASE NOTE:

    I want to stress that I don't necessarily recommend using $_GET authorization with file_get_contents, especially if you're running anything quasi-sensitive on the individual blogs. I'd look at using wp_remote_post, stream_context_create or cURL along with WP Nonces to make sure nothing fishy is going on and the actions are authorized.

    I purely used file_get_contents to keep the example succinct.