afragen / wp-dependency-installer

A lightweight class to add to WordPress plugins/themes to automatically install plugin dependencies.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Static method (or other) to use this class for auto installing/activating plugins based on another trigger

JiveDig opened this issue · comments

This class is quite amazing, thanks again!

Here's my use-case, but could be really convenient for other situations...
I have a base plugin that has other addon plugins that can run with it. I'd love to build a settings (addons) page where a user can click a button (maybe it actually submits a form? idk) and that triggers the class to do its magic, which finds the zip, downloads, installs, and (optionally?) activates the plugin.

It seems like the functionality is already there, it would just need to get restructured to use the instance of that class and a static method... or helper function... or whatever.

Hopefully that makes sense. Thoughts?

It makes sense. I'm thinking the simplest way to do this is to create a function that passes an array that would look like the decoded JSON file.

I don't have an immediate rush to figure something out for my current use case, but is there anything I can help with here?

I'll have to think about how to refactor a bit to allow for both types of input.

Can your settings page create a JSON string exactly like what would be in wp-dependencies.json?

Well, i'm much more of a php guy... thinking I'd build an array of $_POST/config data and run WP_Dependency_Installer::do_the_thing( $args ); But i'm certainly at your mercy here. I'm sure I could figure out how to create a JSON string, probably the same way I was thinking, but end it with wp_json_encode?

Take a look at develop and let me know what you think.
You would pass an associative array ( $config ) with exact same values as JSON file to

WP_Dependency_Installer::instance()->register( $config ) ;

instead of calling

WP_Dependency_Installer::instance()->run(); 

Hey Andy, sorry for not testing yet... I'm still finishing the main dev of the project i will actually need this for. Did it get merged or just closed?

It's already been merged. Please re-open if not working as above.

Hey Andy, I'm back to this.

I have an ajax call running some PHP where I'd like to force install some plugins.

I have this:

$register = WP_Dependency_Installer::instance()->register(
	[
		[
			'name'     => 'GitHub Updater',
			'host'     => 'github',
			'slug'     => 'github-updater/github-updater.php',
			'uri'      => 'afragen/github-updater',
			'branch'   => 'develop',
			'required' => true,
			'token'    => null,
		],
		[
			'name'     => 'Mai Portfolio',
			'host'     => 'github',
			'slug'     => 'maithemewp/mai-portfolio.php',
			'uri'      => 'maithemewp/mai-portfolio',
			'branch'   => 'master',
			'required' => true,
			'token'    => null,
		],
	]
);

but neither are being loaded.

When I dump the returned object I get this:

WP_Dependency_Installer {#957 ▼
  -config: array:4 [▼
    "mai-engine/mai-engine.php" => array:9 [▼
      "name" => "Mai Engine"
      "host" => "github"
      "slug" => "mai-engine/mai-engine.php"
      "uri" => "maithemewp/mai-engine"
      "branch" => "master"
      "optional" => false
      "source" => ""
      "sources" => array:1 [▼
        0 => ""
      ]
      "download_link" => "https://api.github.com/repos/maithemewp/mai-engine/zipball/master"
    ]
    "github-updater/github-updater.php" => array:9 [▼
      "name" => "GitHub Updater"
      "host" => "github"
      "slug" => "github-updater/github-updater.php"
      "uri" => "afragen/github-updater"
      "branch" => "develop"
      "required" => true
      "token" => null
      "source" => ""
      "sources" => array:1 [▼
        0 => ""
      ]
    ]
    "maithemewp/mai-portfolio.php" => array:9 [▼
      "name" => "Mai Portfolio"
      "host" => "github"
      "slug" => "maithemewp/mai-portfolio.php"
      "uri" => "maithemewp/mai-portfolio"
      "branch" => "master"
      "required" => true
      "token" => null
      "source" => ""
      "sources" => array:1 [▼
        0 => ""
      ]
    ]
    "genesis-enews-extended/plugin.php" => array:6 [▼
      "name" => "Genesis eNews Extended"
      "host" => "wordpress"
      "slug" => "genesis-enews-extended/plugin.php"
      "uri" => "https://wordpress.org/plugins/genesis-enews-extended/"
      "source" => ""
      "sources" => array:1 [▼
        0 => ""
      ]
    ]
  ]
  -current_slug: null
  -notices: []
}

Any clues from that info?

The other 2 plugins are dependencies from the theme itself and separate from what I'm trying to do. I'd like to force install only the plugins I pass directly to WP_Dependency_Installer::instance()->register()

Not quite sure. Not at a computer for a bit but not sure why plugins not referenced in a configuration are even there.

Tested a bit tonight. If I run the same code directly on admin_init it works, but it doesn't seem to work during an ajax call. I'm wondering if the necessary hooks aren't firing or some other setup prior to register() needs to happen. Seems like it should work, but I'm missing something.

Can you share the code used in the Ajax call so I can test when I have time?

Thanks

I partially got it working now. I needed to run the admin_init() method too. So this is mostly working:

$wpdi = WP_Dependency_Installer::instance( __DIR__ );
$wpdi->register( $plugins );
$wpdi->admin_init();

Does that seem risky?

If not, I can move ahead with this, I'm just looking to return the success/error message for printing, but I don't get anything with $wpdi->notices.

Have you tried the following?

$wpdi = WP_Dependency_Installer::instance( __DIR__ );
$wpdi->register( $plugins )->run();

If that works it would seem less risky as it's following the normal flow. I should probably document this better if it works.

You could call the above as follows also.

WP_Dependency_Installer::instance( __DIR__ )->register( $plugins )->run();

It appears I did document it 😉
https://github.com/afragen/wp-dependency-installer/wiki/Configuration#associative-array-config

Just tested. Unfortunately it didn't work. It appears to register the dependencies, but won't trigger the actual download/install/activation, which is what I'm going for.

To clarify, this for an ajax step in our setup wizard. On click it runs ajax function which needs to force install/require the plugins that are checked. It works with the admin_init() method but it feels like the class could be able to do this directly with a new method or something. Not sure :)

Screenshot on 2021-04-27 at 17-08-59

Are you trying to individually ask to install both plugins or does the user select?

Why not just have a notice describing what was automatically installed?

Calling an Ajax method to run an an Ajax method seems problematic. But I'm not an Ajax expert by a long shot.

The user picks which ones, and I want to pass that data to this method to install. I’m thinking/hoping that this class/method wouldn’t do the Ajax in this scenario. I want to call a php/method directly that downloads/installs/activates.

It seems like you want 2 different things. You want the user to pick which plugin to install in your wizard and then have the library install them. I don't think it will work as you expect as you would need to have the user activate after the installation.

It might be easier to add more info to your setup instructions and just use the built in installation stuff. If you send the user to the plugins.php page after your wizard they will see the notices requesting installation.

I get what you are saying but it doesn't make sense to go that route for a setup wizard. WPDI already can install and activate a plugin at the click of a link. I was just hoping to abstract the logic that happens after a link is clicked and allow us to use that logic directly. So WPDI would just separate the concerns a bit further.

Concern A: Suggest or require plugins to be installed.
Concern B: Handle the download/installation/activation of said plugins.

If those were separate static methods/functions the class could handle the heavy lifting but we could build our own flows.

It's already working well as I wanted it to, but I need to call $wpdi->admin_init(); to do it.

Another great use-case that I was hoping to implement is something like an "Add-ons" page (you could even do it in GTU). See Gravity Forms as an example:

Screenshot on 2021-04-27 at 23-02-02

Click "Install" and the plugin is automatically installed and activated. Super simple for the user. Simple for dev if we could just make an ajax call and $wpdi->register( $plugins )->install() and $wpdi->register( $plugins )->activate().

WPDI is a bit out of my league to refactor, but it seems like it's so close to allowing this functionality, which would open a new world for it without changing much of the internals of what it's actually doing.

I don't think it will work as you expect as you would need to have the user activate after the installation.

Worth breaking this down more too.

My initial config that "recommends" these plugins as optional can remain as-is.

During the setup wizard, if they choose to install some plugins, I'm forcing required to true before passing it to WPDI. Since they took an action to choose to install these plugins, I force it as required before wpdi->register( $plugins ) so it actually installs/activates.

I was just looking through the flow and I don't really see an issue with how you're doing it. Only thing is the user won't really get a notification.

How did you code the action button?

I do like the idea about how GF does this but I have zero ability to code the cards.

It would be great to have a table like GF and after the Install switch the button to Activate just like core does in the Add plugins. Re-using core methods would be great.

WP_Dependency_Installer::instance( __DIR__ )->register( $plugins )->run()->admin_init();

I wonder if that would also allow for notices to display.

I find myself wanting to create just such an Add On tab inside of GHU to install the new API plugins.

What's the simplest method of adding a button that will run the installation code?

Ha! I was gonna whip something up quickly but had some 🔥 🔥 🔥 to put out and got caught up.

I’m curious now!

It's in the git-updater branch in the Add_Ons.php

Back here to say this is working really well. Here's a rough, working version.

WP_Dependency_Installer::instance()->register( $config )->admin_init();

^ is the ticket.

CleanShot 2022-01-11 at 11 41 07

Thanks again! I think this is good to close, though it may want to be added to the documentation :)