0

I made a custom plugin for inserting staging / production versions of a Google Tag Manager container based on the server's IP address.

How do I make it compatible with WP-CLI so it will update when I run the wp plugin update --all command?

8
  • you would do this the same way you'd make it update with the standard updater as they both use the same mechanism, WP 5.8 introduced the needed APIs and filters so the answer will be in the release notes and make blogs. What that is though I don't quite remember though so I can't write an answer below, but maybe that'll help someone to write up something :)
    – Tom J Nowell
    Jan 17, 2022 at 22:25
  • @TomJNowell I have only ever made personal use plugins and never had issues with manual updates. Since using WP-CLI I'm trying to move towards more automated but haven't solved this piece yet. Jan 17, 2022 at 22:41
  • Did you submit to the Worpress Repository already?
    – rudtek
    Jan 17, 2022 at 22:45
  • @rudtek no it's just for personal use to help simplify our internal management of servers. I am operating on the assumption it's possible to have WP-CLI update a plugin that's not in the WordPress Plugin directory ... but I haven't found the how yet Jan 17, 2022 at 22:49
  • see make.wordpress.org/core/2021/06/29/…
    – Tom J Nowell
    Jan 18, 2022 at 2:55

2 Answers 2

3

You would implement this:

https://make.wordpress.org/core/2021/06/29/introducing-update-uri-plugin-header-in-wordpress-5-8/

First you would add a Update URI: header to your plugin with a custom domain.

Second, you would add a filter to your plugin, using the filter name update_plugins_{$hostname} where {$hostname} is the value you gave your Update URI: . E.g. Update URI: example.com would have the filter update_plugins_example.com.

In this filter, you would then run some code that checks if there is an update for your plugin. When your code is finished running, it will return the answer.

https://developer.wordpress.org/reference/hooks/update_plugins_hostname/

The value you return will need to be an array containing the values in the parameter section. Or it can return false to indicate there are not updates.

The second and third parameters can be used to figure out which plugin WP is asking for update information.

There are very few examples of this filter being used, it's very new and the documentation describes how to use it instead of demonstrating.

Here's some untested pseudocode of what I think such a filter might look like:

add_filter( 'update_plugins_example.com', function( $update, array $plugin_data, string $plugin_file, $locales ) {
    // only check this plugin
    if ( $plugin_file !== 'myplugin.php' ) {
        return $update;
    }

    // already done update check elsewhere
    if ( ! empty( $update ) ) {
        return $update;
    }

    // CODE GOES HERE TO FIND UPDATE, maybe ask a server what
    // the latest version number is and call `version_compare`?
    $is_update_available = true;

    // no updates found
    if ( ! $is_update_available ) {
        return false;
    }

    // Update found?
    return [
        'slug' => 'myplugin',
        'version' => '9000',
        'url' => 'example.com/myplugin/',
        'package' => 'example.com/newversion.zip',
    ];
}, 10, 4 );

As for the actual checking of the update, that depends entirely on you, there is no canonical correct way to do that.

For example, you could toss a coin and return gibberish values. You could make a HTTP request to a file on a server to fetch the latest version number and compare it to the version installed. You could implement a license key check, or ping Githubs API for release versions, etc. It is entirely up to you.

3
  • 1
    Nice work, Tom!
    – jdm2112
    Jan 20, 2022 at 14:53
  • Very much appreciated. Digging into this now. This already clarifies so much about it. Thank you kindly. Jan 21, 2022 at 14:24
  • if you need to make any minor adjustments let me know, it was frustrating being unable to find any examples of this and having to build my own so I'd like this one to be as good as possible :)
    – Tom J Nowell
    Jan 21, 2022 at 15:05
0

Support for plugins that do not reside on wordpress.org appears to be supported by wp plugin install and MAY also be supported by wp plugin update. Daniel addresses a syntax issue with that feature here: https://github.com/wp-cli/wp-cli/issues/2170

Documentation for install indicates acceptance of a plugin slug (.org) or the path/URL to the ZIP file: https://developer.wordpress.org/cli/commands/plugin/install/

Have you tried wp plugin update "your_plugin_url"?

Daniel also references the ability of non-WP.org plugins to introduce an update in his answer to a tangentially related question on Github:

For a non-WordPress.org plugin to introduce an update, it needs to filter the update_plugins transient to return what's called a "download offer" for the plugin.

WP Remote has a relevant piece of support documentation: https://wpremote.com/support-center/integrating-wp-remote/adding-wp-remote-support-premium-theme-plugin/

Here's a direct link: https://github.com/wp-cli/wp-cli/issues/1662

Hope that helps.

9
  • those WP CLI issues predate the update mechanism introduced in WP 5.8 that changed this, see make.wordpress.org/core/2021/06/29/…
    – Tom J Nowell
    Jan 18, 2022 at 2:55
  • @jdm2112 I have tried wp plugin update [url] using both a path to a directory containing the plugin, and using a path to a zip containing a plugin. I have also added the Update URI: header, trying both a path and a .zip. The contents of the directory and the zip have a higher version number in the header as well. I feel like it's missing something small that I am personally unaware of, which indicates to WP-CLI that there is an update available ... Jan 18, 2022 at 14:22
  • @TomJNowell and @jdm2112 I also tried using the --url= flag with and without quotes around the url to the dir and the zip to no avail. Jan 18, 2022 at 14:44
  • Reading the notes on 5.8 update that Tom shared, updating non .org plugins appears to be intentionally blocked now. If the value of this new field matches any URI other than https://wordpress.org/plugins/{$slug}/ or w.org/plugin/{$slug}, WordPress will not attempt to update it.
    – jdm2112
    Jan 18, 2022 at 16:21
  • 1
    It seems like the current best solution is to wp plugin delete [slug] then wp plugin install [url] which isn't entirely ideal, but it appears its where we are at. Jan 18, 2022 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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