Create and Apply Patches to Magento 2
Create and Apply Patches to Magento 2

Create and Apply Patches to Magento 2

Published April 23, 2019 in Classy Llama
One Step Checkout
April 22, 2019
More Sites, Same Staff, Less Maintenance
May 23, 2019

This article covers how to create and apply patches to Magento 2. This article assumes you’re using Composer to install Magento (the second method listed in the “How to get the Magento software” table here), which is the method I recommend for any merchant running Magento on a production site.

If you install Magento using Composer, it’s impossible to directly edit the core files in a way that will cause those edits to persist, as they are never committed to version control, but are instead pulled in with Composer. However, with the help of the Composer plugin composer-patches, it’s possible to apply patches in a manner that will cause those changes to be tracked within version control.

The most common use case for patching the core of Magento is that you’ve encountered a core bug, and that’s the use case we’re going to assume in this article. There are rare occasions where a patch may be necessary to do other things, such as tweak core functionality or do something that’s not possible with a preference, plugin, event, or other standard Magento development method. However, this should not be done lightly and only when all other options have been exhausted.

First, let’s talk about some of the ways that you can create/obtain a patch:

Creating Patches

Github

One of the great things about Magento 2 is the fact that it’s an open source platform with a very active community. Chances are if you’ve run into an issue with the core application, someone else has as well. If you search for an issue or pull request on the Magento 2 Github account, you can often find a pull request or a specific commit that looks like it will fix your issue. For example, if you’re using Magento 2.1.9 or earlier, you might run into an issue where it’s impossible to save a product in the admin with a negative quantity. If you search for this issue on the Magento Github, you might come across this issue. If you look towards the bottom of that issue, you’ll see a link to this commit. You can turn commit and pull request pages into a patch by appending “.patch” to the URL. (For example: https://github.com/magento/magento2/commit/11bcdcc83d6d5d3adc4151cfefd62b6f4cdcd680.patch) In the Applying Patches section below, we’ll cover how to apply a patch like this to Magento.

Magento Support

When Magento Commerce merchants run into core issues, they can submit issues to Magento Support, who will commonly reply with patches to solve those issues. When dealing with Magento Support, you should request patches that can be applied to Magento installed via Composer. In other words, patches with paths mapped to the vendor/*** directories, rather than app/code/Magento.

Custom Patch

There are occasions when a core bug needs to be fixed by editing core code. While some core bugs are more appropriately fixed by writing a plugin/preference/etc., to circumvent the issue, some times writing a patch is a better course of action. The benefit of writing a core patch is that if the underlying code changes in a future release, the patch should fail to apply, thereby alerting you that the patch should be removed/changed. Creating a patch may also take less time, depending on the nature of what is being fixed.

There are several ways patches can be created for files that are not tracked by Git, but here is one way to do it (the example is assuming you want to patch the vendor/magento/module-catalog/Setup/UpgradeSchema.php file):

When naming patches, use a name that allows the patch to be easily linked back to the source issue, such as github-issue-6474.patch or MAGETWO-56699.patch. If there is no source issue to link to, you can use a short dash-delimited description of the issue.

Preparing Patches

To apply patches using composer-patches, there are a couple of prerequisites:

  1. Paths in the patch file must be relative to the Composer package that you’re planning to patch. For example, if you need to patch the \Magento\CatalogInventory\Model\Stock class, the path in your patch needs to be Model/Stock.php, not vendor/magento/module-catalog-inventory/Model/Stock.php.
  2. You’ll need to ensure that a patch file is only changing files in a single Composer package. If a patch applies to multiple Composer packages, you’ll need to split the patch file into multiple patch files.

For example, let’s say you’re running into the issue linked to in the Github section above. Here is how you’d prepare the patch file:

  1. Download the https://github.com/magento/magento2/commit/11bcdcc83d6d5d3adc4151cfefd62b6f4cdcd680.patch file
  2. You’ll see that the patch applies to both app/code/Magento/CatalogInventory and app/code/Magento/Ui. Those directories won’t exist in your installation, but the corresponding paths will: vendor/magento/module-catalog-inventory and vendor/magento/ui. Since those are two separate composer packages, you’ll need to split the contents of that file into two separate files.
  3. You’ll then need to find all instances of app/code/Magento/CatalogInventory and app/code/Magento/Ui and delete them since the patch file must be relative to the composer package.
  4. Here is what the two resulting files should look like:
    github-9139_module-catalog-inventory.patch
    github-9139_module-ui.patch

Applying Patches

Follow these steps to apply a patch to a Magento site:

  1. Create a patches/ directory in the root of your Magento installation.
  2. Move the patch(es) you want to apply to the patches/ directory.
  3. Run this command in the root of your local project:
  4. Open the composer.json file at the root of your Magento installation and edit the existing extra object to look like this, specifying the Composer package to apply the patch(es) to as well as a description of the patch(es) and a reference to the file location:

    The composer-exit-on-patch-failure option is important to enable so that if a patch fails to apply, Composer will return a non-zero exit code. If you’re using an automated deployment tool like Capistrano, this is helpful as it will prevent a deployment from succeeding. A common scenario where this might occur is if a patch is applied to fix something that then gets fixed in a new release of Magento. The patch will fail to apply when that new version of Magento is deployed because the changes will be contained in the new release. In that scenario, the failing patch would need to be removed.
  5. Run composer install to apply the patch(es).
  6. Run composer update <PACKAGE NAME> (e.g. composer update magento/module-catalog-inventory) to update the composer lock file. The lock file tracks which patches have been applied to each composer package in an extra > patches_applied object.
  7. Add the composer.jsoncomposer.lock, and the newly added patches/*** patch file to your version control system, commit, and then push the changes.

Now, whenever you deploy your Magento application to development, stage, or production environments, those patches should get applied whenever “composer install” is run.

Conclusion

Now that you know how to apply patches to Magento 2, enjoy squashing those core bugs. If you have any questions about anything in this article, feel free to hit me up on Twitter.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Most Recent PostsView all
September 17, 2019

Five Essential Components of Successful eCommerce Search

Having an effective on-site search strategy is more important than ever for today’s online retailers. According to a blog by Econsultancy, 30% of users on eCommerce […]
August 13, 2019

Automation Emails – The Key to Easy Email

Email is one of the most powerful tools in marketing. It can quickly become one of your top revenue generators and, if done right, provide you […]
August 2, 2019

Tombow’s Magento 1 to Magento 2 Migration