Plugin dependencies

Our stated goal for ClassicPress v2 is to move core functionality into core plugins. Obviously, this will require a plugin directory, which is now in the planning stages in this subforum.

Perhaps less obviously, we will need to support some form of plugin dependencies in our directory.

Why? To use a strawman example, let’s say that you install Jetpack on a ClassicPress site that has the XML-RPC module disabled or removed entirely. It won’t work.

The ideal user experience here would be to automatically register that “Jetpack has a dependency on ClassicPress Core XML-RPC”, and automatically install and activate the XML-RPC plugin before installing and activating Jetpack.

There are hundreds of other examples using existing plugins, and developers will also be able to make use of plugin dependencies to distribute common code only once.

Also, implementing this at the platform level will give all developers a standard way of re-using plugin code across their projects.

The directory servers will need to understand the basics of plugin dependencies, but most of the work will likely happen on the client side (the ClassicPress PHP code):

  • ClassicPress should install and activate a requested plugin’s dependencies before installing and activating the plugin itself
  • ClassicPress should prevent you from disabling a plugin that is depended upon by other plugins (or show a clear prompt indicating that multiple plugins will be disabled)

There are a number of existing solutions that we can draw from here. To name just a few: composer for PHP, apt on Debian-based Linux, npm for JavaScript, and go get for Go.

Many of these solutions also handle dependency versions. We’re probably not ready to do this yet - just supporting all of the cases around “plugin X depends on plugin Y” will be difficult enough already. Also, some package management systems (like npm) support having multiple versions of a plugin installed to satisfy different parts of a dependency tree, but this isn’t compatible with the way plugins work.

Plugin dependencies and the decisions we make around what works and how will affect many parts of the directory.

For one example: Any time we consider de-listing a plugin due to inactivity, security problems, or any other reason, we will also need to consider the effects on existing installations that have this plugin installed, as well as other existing plugins that depend on the plugin we’re trying to disable. Original discussion on this specific point here.

2 Likes

One thing that sometimes bothers me when dealing with dependencies is the silent nature of installation.

This is geared more towards the typical end user. Using XML-RPC example, if a plugin installs XML-RPC plugin as a dependency and it is enabled silently, it can be abused by nefarious parties as we all know. That’s why it’s recommended to disable it and block access in WP.

Should certain features trigger a notice that it is enabled when installed as a dependency silently?

XML-RPC and API are two possible core plugins that should warn user of possible security issues associated with them when enabled.

I don’t know what the best way is to deal with this, or if it is an issue worth considering. Just wanted to bring it up for discussion.

5 Likes

I think good messaging around what the system is doing and why will help.

“Activating XPack will also install and activate the following plugins as dependencies: ClassicPress Core XML-RPC, …”

Then in the plugins screen show a list of each plugin’s dependencies, and show an appropriate message when you try to disable a plugin that would end up requiring others to be disabled too.

Some people still won’t read that messaging, but we can at least provide the information.

3 Likes

I agree with all of that with the exception of handling dependency resolution - we should do that server-side, not client-side.

There are 3 main reasons for that:

  1. Security. Server-side gives us possibilities we don’t have client-side; this is something to thrash out in private before bringing it to the community for review.

  2. Separation of concerns. This isn’t something we should have to update core to fix or tweak. We can build and test a linear multiple plugin installer in core once and be pretty sure it’s right.

  3. Last but not least: we’ll have done 90% of the work anyway as part of checking for circular dependencies.

2 Likes

Another benefit of having dependency logic on the server:

  1. We’ll be able to add dependencies for existing plugins on our core plugins as we identify them, without having to push changes to clients.

The exact split is not clear to me yet, but we’ll probably still need the things I mentioned on the client regardless:

1 Like

Very hand-wavey, but roughly the server returns an ordered list of plugins to install and the client works through them in order.

Client-side dependencies are relatively easy too, as it only has to deal with what’s installed. I’ve already done a PoC for most of that.

2 Likes

Just thinking how the plugin list might look after installing a few plugins with dependencies…and a few with a lot of extensions… it might get unwieldy. Perhaps dependencies could be listed in a dedicated view.

All (21) | Active (13) | Inactive (8) | Recently Active (2) | Update Available (1) |
Dependencies (2)

Another approach might be to list dependencies under their dependent plugins (rather than completely by alphabetical order) and then indent, color, or iconize them in some way.

1 Like

I like it under the dependent plugins, only thing I would say if we do go this route I think it should be way smaller and potentially only list the plugin name and maybe the author with a hyperlink to the plugin page for more details.

1 Like

I have no preference either way. However it is implemented, it may be a good idea to leave the Settings link (if there is one) for each of the dependencies.

We only have to list dependencies 1 level deep - there are unlikely to be very many. We can just add them to the list of links - it works well. I did a PoC what seems like ages ago now: GitHub - invisnet/ClassicPress at v2

2 Likes

For reference: