Creating Extras for Revo 3 Part 1

This is the first in a series of articles about converting Extras for MODX Revolution 3. The techniques in the series also apply to writing new Extras.

By Bob Ray
May 3, 2022
Creating Extras for Revo 3 Part 1

This is the first in a series of articles about the issues involved in converting an Extra to run in MODX3. In this one, we’ll just look at your options. The tips and techniques we’ll cover in these articles will also be useful for any new Extras that you might write.

Do You Need to Do Anything?

The first thing to consider is whether your Extra needs to change for MODX3. If it doesn’t retrieve any MODX objects and makes no calls to methods like getObject(), getCollection(), getCount(), newObject(), runProcessor(), or newQuery(), you shouldn’t have to do anything at all. Unfortunately, it’s a rare Extra that doesn’t make at least one of those calls.

Even if your Extra does make calls that would be affected, there’s a good chance that it will still work as it should, since MODX3 has provided aliases for most of the classes you are likely to use. Your Extra will, however, put deprecation errors in the MODX error log. That’s not as bad as it sounds, because users can stop that by setting the log_deprecated System Setting to “No”. Even if they don’t, the MODX3 Deprecation Log is separate from the regular Error Log (it’s on a different tab), so the errors a less likely to be noticed.

The MODX3 Deprecation Log display generally doesn’t log duplicate errors, so if you retrieve hundreds of Resources using the MODX2 class key, there will normally be only be one entry in the log, though MODX will still go through the motions of registering the call or method used and will check to see if the deprecation has been logged already. Since the deprecations are stored in the MODX database, there will be some queries made, and the deprecated call table will store duplicates, so it could get quite large if it’s not cleared regularly.

One downside of not updating the Extra is that at some point in the future (in MODX4, or whatever it’s called), the MODX2 classes are going to be removed and your code will break. Even then, you have the option of including the core/include/deprecated.php file, so it’s likely that your code will still run.

I dislike having MODX do all the work with the deprecated calls, though the time penalty is probably quite small, so my preference is to fix them so that the code will run equally well in MODX2 and MODX3. We’ll see how in upcoming articles.

One Version or Two?

Assuming that you want to avoid the deprecation errors, the next thing you have to decide is whether you will create a separate version for MODX3 or modify the code of your Extra to run equally well in both MODX2 and MODX3. There are pros and cons for both choices. If you create a new, separate version for MODX3, you’ll just have to go through your code and correct the class keys and method calls. You’ll be able to put use statements for the MODX namespace, so many of the actual calls will remain the same. For example, a call like this:

$modx->getObject('modResource', 1);

will throw a deprecation error as is, but if you do this, it won’t:

use MODX\Revolution\modResource /* This goes at the top of your code */

/* Your existing code here */
$modx->getObject('modResource', 1); /* No deprecation error */

As long as you add the appropriate use statements for all the MODX object used in the file, none of them will cause deprecation errors. Almost all of them will take the same form (use MODX\Revolution\ObjectClass. Unless you’re dealing with mail, processors, media sources, transport packages or transport providers, that should do it. We’ll look at those exceptions later in this series.

The downside of this approach is that you’ll have to maintain two separate packages. It’s likely that some people will continue to use MODX2 for some time, so when you make improvements, bug fixes, or fixes to security issues, you’ll want to update, test, and release both packages. If you modify your Extra to run in both MODX2 and MODX3, you only need to make your changes once. You’ll still have to test it on both platforms, but you’d have to do that anyway. Note that some packages, because of their architecture, are almost impossible to modify to run on both platforms (Articles, for example). This is quite rare, though. So far, none of my packages have required a separate version.

Personally, I hate maintaining multiple versions of a package. You’re probably more organized than I am, but when I’m updating a package, I tend to make lots of related changes. Changes in Snippets for an Extra, for example, often require changes to Chunks, Resources, properties, System Settings, Lexicon Strings, CSS files, JS files, etc. That also means committing the changes to GitHub with commit messages, and changing the build files for the Extra. The odds are high that I’ll forget to make some of those changes in the other version of the Extra, and may not catch them until after it’s been released.

In the upcoming articles, we’ll look at how to handle MODX3 changes for transport packages, users, other objects, processors, mail, and media sources.


Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.