Modernizing Extras: Conversion Cheat Sheet

A Cheat Sheet for converting Extras for Revo 3.

By Bob Ray  |  July 20, 2022  |  3 min read
Modernizing Extras: Conversion Cheat Sheet

This is a series of articles to help MODX Extras Authors to update their code for MODX Revolution 3.x while making it easy to maintain a version that works with Revo 2.x, too. This is the final article in a series on converting Extras to run in Revo 3. The article contains a quick summary of the tips and techniques presented in the previous nine articles.

The first section below is for code that’s meant to run in Revo 3 only. The second section is for code that will run in both Revo 2 and Revo 3. For more details, refer back to the previous articles.

Separate Package for Revo 3

These can be done with a use statement, or with the fully qualified name and no use statement.

Resources, Users, and Elements in Revo 3

Use the classes as in Revo 2 (modResource, modChunk, modUser, etc.) with these use statements.

use MODX\Revolution\modResource;
use MODX\Revolution\modUser;
use MODX\Revolution\modSnippet;
use MODX\Revolution\modPlugin;
use MODX\Revolution\modChunk;
use MODX\Revolution\modTemplate;
use MODX\Revolution\modTemplateVar;
use MODX\Revolution\modCategory;

Transport Packages and Providers

use MODX\Revolution\Transport\modTransportPackage;
use MODX\Revolution\Transport\modTransportProvider;

Media Sources

use MODX\Revolution\Sources\modMediaSource;
use MODX\Revolution\Sources\modMediaFileSource;


use MODX\Revolution\Processors\Processor;
use MODX\Revolution\Processors\Resource\GetList;
use MODX\Revolution\Processors\Resource\Delete;
use MODX\Revolution\Processors\Element\Update;
use MODX\Revolution\Processors\Element\Snippet\Remove;
use MODX\Revolution\Processors\Element\Template\Update;
use MODX\Revolution\Processors\Element\Category\Create;
use MODX\Revolution\Processors\Security\Login;
use MODX\Revolution\Processors\Security\User\GetList;
use MODX\Revolution\Processors\Security\User\Create;
use MODX\Revolution\Processors\Source\Create; // Media Source
use MODX\Revolution\Processors\Context\Remove;
use MODX\Revolution\Processors\Workspace\Packages\GetList;
use MODX\Revolution\Processors\Workspace\Providers\GetList;


Code for Revo 3 only:

use MODX\Revolution\Mail\modPHPMailer;

if (!$modx->services->has('mail')) {
    $modx->services->add('mail', new modPHPMailer($modx));
/* Set mail fields */
$mail = $modx->services->get('mail');
$mail->set(modMail::MAIL_FROM, $email);
$mail->set(modMail::MAIL_FROM_NAME, $name);
/* etc. */

/* Send */
if (!$sent = $mail->send()) {
    $err = 'Error: ' . $mail->mailer->ErrorInfo;
    $this->modx->log(xPDO::LOG_LEVEL_ERROR, $err);
    return 'Failure';
} else {
    return 'Mail sent';

Single Package for Both Revo 2 and Revo 3

For code that will run in both Revo 2 and Revo 3


Prefix MODX 2-style class names with these prefixes:

$isMODX3 = $modx->getVersionData()['version'] >= 3;
if ($isMODX3) {
    $transportPrefix = 'MODX\Revolution\Transport\\';
    $mediaSourcePrefix = 'MODX\Revolution\Sources\\'
    /* Almost everything else (e.g., Users, Resources, Elements) */
    $classPrefix = 'MODX\Revolution\\';
} else {
    $transportPrefix = 'transport.';
    $mediaSourcePrefix = 'sources.'
    /* Almost everything else (e.g., Users, Resources, Elements) */
    $classPrefix = '';

Processors and Extending MODX Objects

Use a pair of abstract dynamic parent classes (replace BaseProcessor with the name of the class you’re extending.

Processor example:

$isMODX3 = $modx->getVersionData()['version'] >= 3;

if ($isMODX3) {
    abstract class DynamicBaseProcessorParent extends MODX\Revolution\Processors\Processor {}
} else {
    include 'C:\xampp\htdocs\addons\core\model\modx\modprocessor.class.php';
    abstract class DynamicBaseProcessorParent extends modProcessor {}
class MyProcessor extends DynamicBaseProcessorParent {
  /* Your class code here */

See the Revo 3 section above for the Revo 3 fully qualified processor class names.

Extending the modUser class example:

if ($isMODX3) {
    abstract class DynamicUserParent extends MODX\Revolution\modUser {}
} else {
    abstract class DynamicUserParent extends modUser {}
class MyUserClass extends DynamicUserParent {
   /* Your class code here */

(See the earlier article on extending objects for more detail.)


Instantiate a modPhpMailer class as follows:

$isMODX3 = $modx->getVersionData()['version'] >= 3;

if ($isMODX3) {
    if (!$modx->services->has('mail')) {
        $modx->services->add('mail', new MODX\Revolution\Mail\modPhpMailer($modx));
    $mail = $modx->services->get('mail');
} else {
    $mail = $modx->getService('mail', 'mail.modPhpMailer');

Use the $mail object as usual to send the mail. (See the previous article for more details.)

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.