2

I'm self-hosting a premium Wordpress plugin. I'm trying to get update info to the install of the plugin by having the plugin contact one of my web servers, exchanging JSON info. It all works exactly as it should, with one annoying problem.

add_filter('pre_set_site_transient_update_plugins', 'MyPlugin_check_for_plugin_update');

function MyPlugin_check_for_plugin_update($checked_data) {
    global $wp_version;

    if (empty($checked_data->checked)) {
       return $checked_data;
    }    
    if (isset($checked_data->response[MYPLUGIN_BASE]) || isset($checked_data->no_update[MYPLUGIN_BASE])) 
    {
        return $checked_data;
    }
    //snip - contact the api server get a $response, verify the json

    if (isset($response->new_version)) {
        if (version_compare(MYPLUGIN_VERSION, $response->new_version, '<')) {
            $checked_data->response [MYPLUGIN_BASE] = $response;
        } else {
            $checked_data->no_update [MYPLUGIN_BASE] = $response;
        }
    }
    return $checked_data;
}

So, when a plugin update check is run, this function looks for the 'checked' array passed to it that looks like this:

https://pastebin.com/ZebefppF

If the array that's passed to the function contains the 'checked' array (just once per plugin update check from what I can tell) the function runs the API check and adds the plugin data to either the 'response' or 'no-update' arrays depending on whether there's a new version or not.

I've seen the function called several times when a plugin update check is run. As long as my plugin update data is NOT already in the array when 'checked' is passed, it gets added by the api call to my server and my plugin update info shows up exactly where it's supposed to with exactly the data it's supposed to have.

Where things go awry:

If the plugin update data is already in the 'response' or 'no-update' array when it's passed to the function, like this:

https://pastebin.com/R1VwJzWm

it doesn't seem to matter what I do, it gets removed. You may notice in the code above I've tried to return the array if it finds the plugin data in it. I've tried letting it pass through the function and add the update info back onto it again and it still gets removed (or not added because the key already exists).

So, here's the question. If my plugin's update info is already in that 'response' or 'no-update' array, how exactly am I supposed to keep it there? Or am I being really stupid and not seeing something?

God I hope I made this understandable. I'm confused now.

1 Answer 1

1

Ok, this is a working solution but a hacky one. First, the explanation.

After much gnashing of teeth and error logging I've discovered that the filter 'pre_set_site_transient_update_plugins' is called at least twice during a plugin update check. Sometimes, the passed array has the 'checked' array attached to it, sometimes it does not. I have no idea why but when it does NOT have the checked array, the site transient 'update_plugins' does.

It appears that the only way to keep my plugin update in that transient is to return it with the 'checked' array included. Again, no idea why. So, I cheat:

$transient = get_site_transient('update_plugins');

if (empty($checked_data->checked)) {
   if (empty($transient->checked)) {
       return $checked_data;
   } else {
       $checked_data = $transient;
   }
}

// proceed to get the plugin update data

So, I check to see if either one has the 'checked' array and if it does, I use that one to add my plugin data to.

The net result is, my plugin update shows up where its supposed to and even through subsequent checks, it doesn't get removed.

If you know of a proper solution, PLEASE let me know. Somehow, I kinda expect this to fail at some point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.