Using composer to install 3rd party libraries for your WordPress plugin feels like state of the art in comparison to other php projects. To get there you set your minimum required php version up to 5.3, introduced namespaces and introduced composer. You spend hours tuning your plugin and made use of well known libraries like pimple, twig and an orm library. Good job! Really? Not at all – Everything seems to be smooth until you leave your narrow plugin context and realize that there are other plugins out there that also use libraries.
The Problem
The problem is you (and other plugin developers using composer) commit their vendor directory with the libraries to the WordPress plugin repository. These libraries usually define their namespace – you and other developers might use the same library and use (require) the same namespace:
1 2 | namespace MyAwesomePlugin\Core\Plugin; use Pimple\Container; |
1 2 | namespace TheirAwesomePlugin\Core\Plugin; use Pimple\Container; |
This is actually not the problem yet. Both use Pimple and thanks to composer autoloading Pimple is loaded from one of the both plugins.
Things become weird when you require another version of pimple that make incompatible API changes (so usually a major release). I think the impact is obvious – depending on your or their pimple library is loaded your plugin breaks or you make the other plugin break. With “break” I mean hopefully you get a php error for calling an not existent function – but if you be out of luck the internals of the function changed an it just behaves different than the version you developed with.
The Solution
Anyway you have to somehow embed these libraries into your own namespace to avoid these kind of issue. As far as I know there is no way to do this with composer ( maybe since it’s against the nature of dependency management ).
Or use composer for require-dev dependencies only. Or use composer and move the libraries automated into your plugin sources, rename namespaces and don’t break anything while doing so.
I am at my wit’s end: Don’t use composer.. copy all libraries into your plugin sources and prefix all namespaces with MyAwesomePlugin.
For example Pimple would become:
1 | namespace MyAwesomePlugin\Pimple\Container; |
This way I can be sure composer loads my library version for sure because the namespace is unique.
WordPress + Composer = No
WordPress has no integration for dependency management.
I encourage you to read Better Dependency Management In Team-Based WordPress Projects With Composer if you want to read a more detailed introduction into the problem.
I appreciate any discussion and advice!
Update
These are the steps I have taken.