Categories


Archives


Recent Posts


Categories


Replicating Code Pool Overrides in Magento 2

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

(With apologies to whomever originally posted this technique – I can’t seem to find your original article. If you’d like link/credit just let me know)

As companies start to go ahead with Magento 2 builds and Magento 2 upgrades, more an more developers are wondering what to do about the missing code pools from Magento 1. If you’re not familiar with them, code pools allowed you to completely replace a Magento 1 class file with your own version. If you wanted to replace the Mage_Core_Model_Url file at

app/code/core/Mage/Core/Model/Url.php 

all you needed to do was put your new file in the local code pool

app/code/local/Mage/Core/Model/Url.php 

Behind the scenes, the code pool functionality was just another folder added to PHP’s include_path.

Magento 2 did away with code pools, and this was probably the right call. Code pools created a big problem when it came time for point release upgrades. If the file in core changed, it was up to the system owner to merge those changes into the local version manually. Even without upgrades, it was possible to change the behavior of the class in subtle ways that might not break the pages you were working on, but would break the system when the class was used in a different context.

Despite all that – sometimes a code pool override was the only way to do what you needed to do. While code pools don’t exist in Magento 2, composer does.

Replace Class Files with Composer’s Autoloading Feature

If you’ve worked your way through my Laravel, Composer, and the State of Autoloading series, you know that most modern PHP applications use composer based autoloaders. It turns out that with some light abuse of the files autoloader, you can replace any class definition file with one of your own. High level, all you need to do is

  1. Copy the original class to a different location on your system
  2. Add that class path to your project’s main composer.json file
  3. Run composer dumpautoload (Composer runs this automatically whenever you run composer install or `composer update)

For example, if you wanted to replace the Magento/Directory/Block/Currency class with one of your own, all you’d need to do is copy the class to a different location on your system

$ mkdir -p app/overrides/Magento/Directory/Block/
$ cp vendor/magento/module-directory/Block/Currency.php app/overrides/Magento/Directory/Block/Currency.php

There’s nothing magic about the app/override folder – you can place this new definition file anywhere.

Next, add that path to your project’s main composer.json file

#File: composer.json
"autoload": {
    /* ... */
    "files": [
        /* ... */,
        "app/overrides/Magento/Directory/Block/Currency.php"
    ]
},    

Finally, tell composer to regenerate the autoloader configuration.

$ composer dumpautoload

You’ll know its worked if you see entries for your file in the generated autoloader includes.

vendor/composer/autoload_files.php
147:    '6d881679c080d9d32d99dfc737decaa4' => $baseDir . '/app/overrides/Magento/Directory/Block/Currency.php',

vendor/composer/autoload_static.php
148:        '6d881679c080d9d32d99dfc737decaa4' => __DIR__ . '/../..' . '/app/overrides/Magento/Directory/Block/Currency.php',

This works because once PHP has loaded a class definition file, it will never run the standard autoload routines for that class again. Since the files autoloader runs first, it will always win.

Is this a Good Idea?

When I first saw this technique circulating I wasn’t wild about it. While class overrides were expedient in Magento 1, they were often the cause of endless ongoing maintenance, weird bugs, and extension compatibility problems for Magento system owners.

However – even though code pool overrides are no longer a thing, Magento 2 has proven to have its own set of ongoing maintenance and extension compatibility challenges. If this technique helps your small team keep paces with a larger team of Magento developers, I’d say its worth considering the tradeoffs.

Copyright © Alan Storm 1975 – 2018 All Rights Reserved

Originally Posted: 16th May 2017