WWHD - Common Problems with Updating Add-ons from EE2 to EE3

Welcome to another edition of What Would Hop Do!

Here at Hop we have spent a fair amount of time getting old add-ons working with new sites. And while many of you have upgraded to EE5, there are still a surprising number of sites still running on older versions of EE, often because of a lonely neglected plugin that’s got them stuck in the past. Old add-ons aren’t actually that hard to upgrade, and we’ve put together a small list of critical things to watch out for when modernizing an old add-on.

Moving from Expression Engine 2 to 3 is the biggest leap an add-on has to make, and there are some standard steps to go through that will get you most, if not all, the way to a current working chunk of code.

Blank screen displaying with the text “No direct script access allowed”

You’re going to see this line a lot at the top of every add-on built for EE1/EE2:

if (!defined('EXT')) {
    exit('No direct script access allowed');

In the old days, the global variable EXT was defined in index.php, but that’s no longer the case. Now, things are neatly abstracted away into the Extension class. Before removing this chunk of code, you will need to look for instances of the global and update them.

To find the offending add-on that needs this, you can either use the search function of your editor, or run grep -rnw 'EXT' inside the system/user/addons/ directory.

Then, you’ll want to change the code like so:

- $EXT->last_call
+ $this->extensions->last_call

Replace old initialization method with __construct

A lot of old add-ons were built to use a function with the same name as the class for initialization. In EE3 and forward, we instead use a __contruct() function, as seen here:

class Cartthrob_multi_location_mcp {
- function Cartthrob_multi_location_mcp()
+ public function __construct()

No more reference assignment

Replace all instances of =& with = as seen here:

- $this->EE =& get_instance();
+ $this->EE = get_instance();

Additionally while you’re cleaning that up, you should also be changing all instances of $this->EE to ee().

Error in trace: Resource already loaded

If you get errors that say something is already loaded, like a package or module or helper, add this line:

ee()->remove('get_settings'); // if you unload the get_settings library
ee()->load->library('get_settings'); // then you can load it again

Use CP/URL service to rewrite url paths

Replace manually constructed control panel URLs with dynamically generated URLs by using the CP/URL service:

Something that looks like:


Should be replaced with:


Check the EE Documentation for more info on the CP/URL service.

update() function for extensions and fieldtypes

Extension and Fieldtype add-ons are expected to have their own tables and versions saved. Even if your add-on doesn’t require any custom tables, you’ll still need an update() function present.

Create an empty update() function in the upd file and let it simply return true;

PHP 7 error reporting

PHP 7 changes how most errors are reported by PHP. Instead of reporting errors through the traditional error reporting mechanism used by PHP 5.6, most errors are now reported by throwing Error exceptions. You may need to write additional logic to check if a given variable is empty or null.

Thanks For Reading

I hope some of these tips have been useful to you! As always if you spot any mistakes, or have a better way to do something, please let us know in the comments. We’re always looking for ways to improve! 😊


Have a Project for Us?

Request a Proposal