- dependency checking
- shared libraries
- compatibility checking
Summary TL:DR
I’ve developed a plugin, oik-lib: shared library management, that satisfies some of the requirements for sharing PHP logic between WordPress plugins and themes.- Its job is not to solve plugin dependencies.
- Its job is to manage requests from plugins which have dependencies on other components.
- Version 0.0.2 is now available on github.com/bobbingwide/oik-lib.
- Documentation and WordPress installable versions are available from oik-lib.
- oik base plugin – the source of the functionality on which many other plugins currently depend
- oik-bwtrace – WordPress problem determination and tracing
Overview
In this post I attempt to document the story so far for oik plugin dependency checking and the requirements I have for plugin dependency checking in general. My requirements take into account considerations for shared libraries of PHP code. Some solutions are offered, others are proposed, and some requirements are also stated. This post was originally drafted in May 2015, as a partial response to Ryan McCue’s proposals.It has now been updated to reflect the current solution, as of August 2015. My current solution helps me to solve some of the problems. But it also introduces new ones I didn’t think I had, and continues to be plagued with problems associated with backward version incompatibility, which will need to be handled using conflict checking.
Background – dependency checking
Many moons ago theoik-bwtrace
plugin existed as part of the oik plugin, along with a few other separately activatable plugins. When I split the oik base plugin up into multiple plugins, with each plugin becoming separately installable and activatable, rather than duplicating common functionality, I made each plugin dependent upon the oik base plugin.
Each plugin used basically the same logic as that which I’d developed for the oik-nivo-slider
plugin (v1.2, April 2012) dependency upon the existence and activation status of the oik base plugin (v1.12).
There were three parts to the solution:
- During normal processing dependent plugins wait until notified that it’s safe to do something; e.g. oik_loaded action
- They implement dependency checking in response to admin_notices action.
- Each plugin uses the same library functions, which they load dynamically if oik is not already providing the logic. See oik_plugin_lazy_activation()
Recently (June/July 2015)
When I was updating myoik-bwtrace
plugin recently I looked more closely at the relationship between oik
and oik-bwtrace
. I concluded that in their existing form they were partially symbiotic plugins.
oik
will work withoutoik-bwtrace
oik-bwtrace
is dependent uponoik
for bootstrap codeoik-bwtrace
is dependent uponoik
for its admin user interface- They share common logic for implementing tracing functions
oik-bwtrace
and other plugins are dependent uponoik
for the trace functions- the
oik
trace functions are dependent uponoik-bwtrace
for the actual implementation
What I actually wanted was…
oik-bwtrace should be dependent upon some functionality that’s currently delivered by the oik base plugin but should not require the whole plugin to be activated
oik
base plugin to be delivered as a set of modules or librariesoik-bwtrace
to be able to operate independently ofoik
- Peaceful coexistence between plugins requiring or delivering library functions
Introducing shared library management
I already had a solution where a plugin could indicate a hard dependency on another plugin, but I also needed a solution where a plugin could indicate a dependency on some functionality, without being too concerned about who provided it. So I developed some requirements for a shared library manager.Requirements
- Ability to request a library
- Notification actions when dependencies satisfied
- Dependency checking
- Shared delivery of library functions
- Applicable to plugins and themes
- Fallback support for standalone plugins
- Version checking
- Compatibility checking
- Plugin download and activation
Recent challenges (July 2015)
In parallel with developing theoik-lib
: shared library manager I developed the standalone solution for oik-bwtrace
.
But there were some problems.
- The upgrade path required plugins to be deactivated and reactivated. See How do I upgrade to oik-bwtrace v2.0.0?
- When updating the
oik
base plugin it effectively becomes deactivated, which can lead to these problemsFatal error: Call to undefined function ...
Since the implementing files for the bw_backtrace() or bw_trace2() functions have not been loaded, any plugins or themes which try to use these functions, before notification that it’s safe to do so, produce this error.- Alternatively, and much less problematic, any plugin that’s dependent upon oik may determine that it’s not present. Each plugin will produce a message requesting oik be installed and activated.
- Updating shared libraries to new versions can also lead to
Fatal error: Cannot redeclare
conflicts.
oik-lib
plugin a Must-Use (MU) plugin.
Outline solution for oik-lib: shared library management
- Dynamically loads the mandatory libraries delivered by the plugins
- Polls to find the libraries each plugin shares oik_query_libs filter
- Responds to requests from plugins to load libraries on demand. oik_require_lib()
- Attempts to satisfy dependencies
- Attempts to perform compatibility checking and detect conflicts
- When a library has been loaded it notifies plugins through an action hook, oik_lib_loaded action
- Plugins can respond by loading their own private libraries and/or requesting other shared libraries
- APIs to facilitate other shared library requirements: autoload, library file loading
Compatibility checking requirements
These are some of the requirements for compatibility checking.- Compatibility checking will be invoked at run-time
- Libraries can indicate their library dependencies
- Libraries can indicate their library version dependencies
- Libraries can indicate known conflicts with library versions or plugin versions
- Version checking to support semantic versioning and comparison operators
- Dependency resolution is deferred until a library is required
- First come first served approach
- If there is a compatibility or dependency problem then the API will return a WP_Error
- The WP_Error may include data indicating the cause for the problem
- No attempt to resolve the problem will be performed by oik-lib
- The calling routine should respond accordingly
- The calling routine may opt to use a fallback method
Where do we go from here?
Work to do
The solution is not yet fully implemented…- The version checking logic is still in its infancy
- There is no conflict checking
- It does not support multi-file shareable shared libraries
- There are some challenges regarding localization
Develop more real world examples
Here are more examples of oik base functionality that will be converted into shared libraries. This may enable plugins which are currently dependent to either become standalone or dependent upon a selection of alternative plugins.- Shortcode APIs, shortcode help and shortcode UI integration
- Custom post type and custom field APIs
- Admin page / settings APIs
- Admin list table APIs
- User related APIs
- jQuery library APIs
- Plugin & theme upgrade APIs
Integration with Composer
You’ll also notice that I haven’t yet mentioned Composer. To be honest, I haven’t thought enough about Composer. I can see its benefits in helping to manage the build and deployment of the shared libraries that a plugin delivers. But I can also envisage using Git submodules to do something similar. But there’s also the “where does that come from?” thing that Composer does quite well, and the automatic creation of autoloading. Suffice it to say, there’s still a lot of work to be done.Related reading
- How I would solve plugin dependencies, by Ryan McCue
- How I would solve plugin dependencies, lol I wouldn’t, by Gary Pendergast
- #22316 (Plugin Dependencies (Yet Another Plugin Dependencies Ticket)) – WordPress Trac
- Solving dependency management in WordPress plugins, by Coen Jacobs
- https://github.com/coenjacobs/wordpress-composer-installer
- tgmpluginactivation.com
- https://github.com/GaryJones/TGM-Plugin-Activation
- plugin-dependencies
- Composer in WordPress
See also
Plugin | APIs & hooks |
---|---|
oik | oik_plugin_lazy_activation() |
oik-bwtrace | bw_trace2() bw_lazy_trace2() |
oik-lib | oik_require_lib() oik_query_libs filter oik_lib_loaded action |
oik-libs | oik-libs: Shared Library Repository files |
Other potential library sources
The following plugins contain functionality that could be offered as shared libraries.- BuddyPress: xProfile
- Jetpack modules: publicize
- WooCommerce: countries and currencies
- Custom meta boxes: field types
- Authentication: Basic, OAuth, OAuth2