Understanding the MODX getOption() Method

How to use the MODX getOption() method to pull data from any array.

By Bob Ray  |  February 28, 2023  |  9 min read
Understanding the MODX getOption() Method

The $modx->getOption() method is the workhorse of MODX Snippet code. There are over 1,300 instances of it in my core/components/ directory. It’s used in almost any non-trivial Snippet and many Plugins as well. You may have some idea how it works, but there are some quirks and features that you may not know about.

Using getOption() For Settings

In its simplest form, $modx->getOption() is often used to get the value of a MODX System Setting:

$value = $modx->getOption(SETTING NAME);

If the System Setting is found, $value will be set to its value. If not, it will be set to null. But what if you want to set a default value to use when the setting is not found?

$value = $modx->getOption(SETTING NAME, null, 'default value');

The code above will return the value of the System Setting, or the default value if the Setting is not found. There’s a catch, though, what if you want to use the default value if the setting exists, but is empty? The code above will return an empty string. You could check the return value to see if it’s empty, but there’s an easier way. There’s a little-known fourth argument for getOption() called $skipEmpty in the method’s declaration. It’s a boolean argument, and when it’s set to true, the method will return the default value if the setting doesn’t exist or is an empty string (it won’t affect numbers, even 0—they will always be returned as is).

$value = $modx->getOption(SETTING NAME, null, 'default value', true);

PHP considers a variable containing the number 0 to be empty, but the getOption() method is smart enough not to do that. If the fourth argument is set to true and the setting exists and is set to 0, getOption() will return it rather than use the default value. On the other hand, it will return the default value if the property is an empty string even though the property exists (i.e., isset() would return true).

You might be wondering about the null we put as the second argument. The getOption() method can also be used to search the $scriptProperties array, or in fact, any array at all (more on that in a bit). The second argument is the array to search. If it’s set to null, getOption() looks only at the MODX Settings.

Settings?

If you’re paying close attention, you may have noticed that the last sentence above said, “MODX Settings” rather than “MODX System Settings”. The getOption() method will actually check all User Settings, User Group Settings, Context Settings, and System Settings (in that order) when used as above.

Actually, it doesn’t check those four groups of settings in turn, though the result is the same. On every request, MODX creates a big array of settings. First, it gets the array of all System Settings, then it overwrites any of them that match current Context Settings (if any) with the Context Setting values, then it overwrites any of them that match Usergroup Settings for the current user’s User Groups (if any) with the values of the user Group Settings, then it overwrites any of them that match User Settings for the current user (if any) with the values of the User Settings. The resulting array is stored in the $modx->config array and that array is what getOption() checks if the second argument is null or only the first argument is sent. The result is the Context Settings override System Settings and User Settings override Context Settings.

Settings for the user’s Primary Group, will take precedence over all other Usergroup Settings. What if the setting doesn’t exist in the user’s Primary User Group, and the Setting exists in more than one User Group the user belongs to, and the Settings have different values? In that case, MODX will use the last one found. That generally means it will use the one from the User Group with the lowest number in the rank field.

Using getOption() With Snippet Properties

This is probably the most common use of getOption() in MODX. When you send properties in a Snippet tag, they are available in the Snippet as the $scriptProperties array, and getOption() is often used to retrieve them. It makes for shorter, easier to understand, and safer code.

If you look at older MODX code, written before getOption() existed, you might find the first part of a Snippet riddled with code like this example:

$defaultCount = 10;
if (isset($scriptProperties['count'])) {
    if ($scriptProperties['count'] === '0') }
       $count = 0;
    } elseif (!empty($scriptProperties['count'])) {
        $count = $scriptProperties['count']
    } else {
        $count = $defaultCount;
    }
} else {
    $count = $defaultCount;
}

There are a variety of ways to write this code, but no matter how you do it, it’s a lot of code, it’s difficult to follow, and there are a lot of ways to get it wrong, especially if you have to do it for every property that might be sent in the Snippet tag. Enter $modx->getOption(). The code below does exactly the same thing in a single line:

$count = $modx->getOption('count', $scriptProperties, 10, true);

Other Arrays

It’s a little-known fact, but getOption() can actually be used to find a value in any simple PHP associative array. The value sent in the second argument doesn’t have to be the $scriptProperties array, it can be any array (though if it’s a nested array, you may need some extra code). Consider the following example:

$a = array(
    'color1' => 'Red',
    'color2' => 'Blue',
    'color3' => 'Green',
);

$color1 = $modx->getOption('color1', $a, 'Gray');
$color2 = $modx->getOption('color2', $a, 'Gray);
$color5 = $modx->getOption('color5', $a, 'Gray);

The code above will set the three variables to Red, Blue, and Gray. What if, however, the array keys are numbers, not strings? This will actually work too:

$a = array(
    1 => 'Red',
    2 => 'Blue',
    4 => 'Green',
);

$color1 = $modx->getOption('1', $a, 'Gray');
$color2 = $modx->getOption('2', $a, 'Gray);
$color5 = $modx->getOption('5', $a, 'Gray);

Notice that in the example above, we’ve used quoted strings for the first argument to getOption(). That argument must always be a string. It doesn’t seem like it should work, but it does because of PHP’s loose typing of variables. The following, however, would not work because getOption() tests the first argument with is_string() and returns the default value if it’s not a string:

$color1 = $modx->getOption(1, $a, 'Gray');

Another Cool Use

You don’t see this very often, but if you think about the code examples above, there’s no reason you can’t use getOption() to get the values of request and session variables. This is particularly useful since we now live in a world where checking the value of one of those variables without using isset() first will throw a PHP E_NOTICE warning error on many platforms. Using getOption() solves that problem and gives you a convenient way to set a default value for when the variable isn’t set. Here are a few examples:

$option = $modx->getOption('secret_key', $_SESSION, null);
$option = $modx->getOption('product_id', $_GET, 0);
$option = $modx->getOption('user_email', $_POST, '', true);

Be sure to read the “Potential Gotcha” section below if you plan to use this method.

But Wait, There’s More

A truly little-known (and little used) fact is that the first argument to getOption() can also be an array. Consider this code:

$a = array(
    1 => 'Red',
    2 => 'Blue',
    4 => 'Green',
);

$colors = $modx->getOption(array('1','2','5', $a, 'Gray'));

With the code above, getOption() will return the following array:

Array (
    [1] => Red
    [2] => Blue
    [5] => Gray
)

If getOption() is called with an array as the first argument, it will call itself recursively with each array member and build the array to return. I’ve never seen this option used in MODX, since the array you send in the second argument is already an array and contains all the information you need. In addition, the keys of the original array are lost in the process.

Potential Gotcha

There is another aspect of getOption() that could have you tearing your hair out if you don’t know about it. The getOption() method is a MODX method, not a generic PHP function. It has certain ideas about what you want. Most of the time, it works as expected, but it helps to be aware of exactly what it’s doing.

When getOption() doesn’t find the key you’re looking for, it doesn’t give up and return the default value. Instead, it searches the MODX Settings. This means that if you search for a Snippet property, $_POST value or $_GET variable called emailSender and the property is not set, you’ll get back the value of the MODX emailSender System Setting (or a User Setting, Usergroup Setting, or Context Setting if there is one). This might be what you want to happen, but if it’s not, it can be very confusing. You shouldn’t use properties with the same name as MODX Settings unless you actually want this behavior.


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.