In this tutorial we will cover how to create a patch and then configure composer to apply that patch when the module is installed.
Why?
Sometimes there are fixes you need to apply to code that isn't directly in source control. This method allows you to keep these files out of source control whilst still being able to manage (in source control) the changes to these files.
Scenario
We need to set the default value of $_skipSaleableCheck within vendor/magento/module-catalog/Helper/Product.php to true
Code snippet of file to be changed.
/**
* Catalog category helper
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class Product extends \Magento\Framework\Url\Helper\Data
{
const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
const XML_PATH_AUTO_GENERATE_MASK = 'catalog/fields_masks';
/**
* Flag that shows if Magento has to check product to be saleable (enabled and/or inStock)
*
* @var boolean
*/
protected $_skipSaleableCheck = false;
...
Prerequisites
- [cweagans/composer-patches](https://packagist.org/packages/cweagans/composer-patches) must be installed.
- You have a "patches" directory. We usually keep this at the root of the project `/patches`
- If you are using MDOQ managed Magento hosting, then this work should be carried on a development instance. If you are not, then this work should be carried out in your development environment.
Steps
1. Make a copy of the file you intend to patch
cd ~/htddocs
cp vendor/magento/module-catalog/Helper/Product.php vendor/magento/module-catalog/Helper/Product.php.orig
2. Make the changes you require to the file (not the newly created .orig file)
`vendor/magento/module-catalog/Helper/Product.php` is now
/**
* Catalog category helper
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class Product extends \Magento\Framework\Url\Helper\Data
{
const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
const XML_PATH_AUTO_GENERATE_MASK = 'catalog/fields_masks';
/**
* Flag that shows if Magento has to check product to be saleable (enabled and/or inStock)
*
* @var boolean
*/
protected $_skipSaleableCheck = true;
...
3. Change into the module directory
cd vendor/magento/module-catalog;
4. Create the diff (patch file) we usually us ticket numbers from our project management system though you can use anything unique that works for you
diff -u Helper/Product.php.orig Helper/Product.php > 1001-hot-fix.patch
**N.B** Here you would replace `1001-hot-fix.patch` with an appropriate name.
5. Open the patch file and remove the "`.orig`" from the patch file.
If you open `1001-hot-fix.patch` you will see it contains
--- Helper/Product.php.orig 2020-09-11 14:17:15.708644077 +0100
+++ Helper/Product.php 2020-09-11 14:17:30.301170128 +0100
@@ -29,7 +29,7 @@
*
* @var boolean
*/
- protected $_skipSaleableCheck = false;
+ protected $_skipSaleableCheck = true;
/**
* @var array
We need to remove `.orig` so that the file looks like
--- Helper/Product.php 2020-09-11 14:17:15.708644077 +0100
+++ Helper/Product.php 2020-09-11 14:17:30.301170128 +0100
@@ -29,7 +29,7 @@
*
* @var boolean
*/
- protected $_skipSaleableCheck = false;
+ protected $_skipSaleableCheck = true;
/**
* @var array
**N.B** there will be a line ending at the end of the file. You need to ensure that this is maintained. It isn't showed in the snippets as it is just an empty line.
6. Undo the changes you made to the file.
mv Helper/Product.php.orig Helper/Product.php
7. Move the patch file into your patches directory
Note: the /patches directory is in the project root/patches
mv 1001-hot-fix.patch ~/htdocs/patches/
8. Update the patch config within the project `composer.json`
To do this we need to know the module name, in this case it is `magento/module-catalog`. If you are unsure it can be found in the modules `composer.json`
`vendor/magento/module-catalog/composer.json`
{
"name": "magento/module-catalog",
...
Now open `/composer.json`.
You are looking for `patches` under the `extra` node. If yours doesn't exist you can paste the code below in. If it does exist, you will need to add the new bits in.
"extra": {
"patches": {
"magento/module-catalog": {
"Change default _skipSaleableCheck": "patches/1001-hot-fix.patch"
}
}
}
You can specify multiple patches for the same module, if unsure please see [here](https://packagist.org/packages/cweagans/composer-patches)
9. Remove the module code from vendor.
rm -rf vendor/magento/module-catalog
10. Reinstall using composer
composer install --no-dev
You should see the following
Package operations: 1 install, 0 updates, 0 removals
Gathering patches for root package.
Gathering patches for dependencies. This might take a minute.
- Installing magento/module-catalog (103.0.5): Downloading (100%)
- Applying patches for magento/module-catalog
patches/1001-hot-fix.patch (Change default _skipSaleableCheck)
If you check `vendor/magento/module-catalog/Helper/Product.php` you will see the changes from the patch file have been applied.
11. You should now commit all the files you have changed to source control. In this case it would be:
- `/patches/1001-hot-fix.patch`
- `/composer.json`
This should complete your patch.