Sometimes, you may encounter a bug or an unwanted functionality in a PHP vendor dependency, and forking the package and maintaining upstream changes can be too cumbersome. In such cases, using composer-patches is a good solution.
Composer-patches is a handy Composer plugin that applies diff patches to specific packages during installation.
Basically, you store a diff patch in your project, specify which vendor package it should be applied to in your composer.json
, and the plugin will apply the patch to the original code of the vendor package after it got installed by composer.
The documentation provides detailed instructions on how to set up the plugin.
In short, you need:
- Install the plugin (we’re using the v2 beta) with:
composer require cweagans/composer-patches:^2.0.0-beta2
- Create a patch. The plugin relies on Git as the patcher, so you can use Git to generate the patch file. (See below)
However, I recommend using another package to create the patch file:
https://github.com/symplify/vendor-patches
This package provides an opinionated but reasonable way to create and store your patches. vendor-patches takes care of the correct paths in the patch file, which might not be immediately obvious: Pathes should be relative to the vendor package root and not relative to your projects root dir. - Add the patch instructions to your
composer.json
by including apatches
section underextra
. For example:
"extra": {
"patches": {
"oxid-esales/oxideshop-ce": {
"Disable user registration due to spam attacks": "./patches/disable-registerUser.patch"
}
}
}
Code language: JavaScript (javascript)
On your next composer install
the vendor package will be patched and the vendor’s
code will be altered according the patch.
Some notes: If you encounter the error:
Could not apply patch! Skipping. The error was: Cannot apply patch disable-registerUser.patch
You might have incorrect paths in your patch file. As mentioned above, the paths need to be relative to the vendor root directory, not your project’s root directory.
So to manually create the diff patches, run this command:
diff --git a/source/Application/Component/UserComponent.php b/source/Application/Component/UserComponent.php
This is wrong usage from project root dir:
diff --git a/vendor/oxid-esales/oxideshop-ce/source/Application/Component/UserComponent.php b/vendor/oxid-esales/oxideshop-ce/source/Application/Component/UserComponent.php
Happy patching! :)