Understanding the MODX getOption() Method

An inside look at the MODX getOption() method, with some things about it you almost certainly didn't know.

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(<i>setting name</i>, 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(<i>setting name</i>, 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.


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.

The ability to create Usergroup Settings is new in MODX 2.3. There were some bugs in that feature that were addressed in MODX 2.3.2, so if you intend use it, make sure you have the latest version of MODX Revolution.

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

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, 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:

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

The variable, $scriptProperties is a pain to type. It's also long enough that it can keep a statement from being displayed on a single line. In a lot of MODX code, you'll see that the author has assigned that variable to one that's shorter and easier to type. Here are some common examples:

$sp = $scriptProperties;
$config = $scriptProperties;
$props = $scriptProperties;

Or, in a class:
$this->sp = $scriptProperties;
$this->config = $scriptProperties;
$this->props = $scriptProperties;

You will sometimes see =& used instead of = in these cases. This is called a "reference" assignment. It sets the first variable to the actual address of the second one. In some languages, this would make things faster, but in PHP, it usually makes things slower. The only time it should be used in MODX is if you plan to alter the variable and want the original variable to change too. References to the $modx variable are often done this way because changes to that variable need to be available somewhere else. It's never necessary for the $scriptProperties array if you're just getting values from it.

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.

Is That It?

Actually, no. There are a few quirks of getOption() that relate specifically to snippet properties sent in a snippet tag. We'll look at those in the next article.

Comments (1)

  1. Susan OttwellAug 17, 2014 at 03:40 AM

    This came in handy just now. Suppose you have a snippet that creates a folder or a file. You need to set its permissions, but how do you do that and make sure your snippet will always set the correct permissions for the environment? By default MODX will use 755, but a system setting can change that. The system settings only exist if a different set of permissions was selected on installation, or the settings were manually created. But it's best to cover all eventualities, since a file or folder with bad permissions can ruin your whole day.

    $perms = $modx->getOption('new_folder_permissions', null, '0755', true);
    if (!@mkdir($fullpath, $perms, true)) { ...

Please login to comment.