Avoid Trashing Properties With setProperties

Learn to safely write code that sets specific properties in Elements without losing any others in the process.

By Bob Ray
January 25, 2022
Avoid Trashing Properties With setProperties

Sometimes, as a MODX developer, you may want to change a single Element property while retaining the other properties. For example, some developers who use custom Snippets and Plugins may want to change the Element properties during the upgrade of the Extra. Of course, there could be many other use cases for this method.

In this scenario, we want to change the value of a single property of a MODX Element (usually a Snippet) in code. There is no setProperty() method in MODX, so we may expect this code to do the job:

<?php
/* Don't use this code! */
$snippet = $modx->getObject('modSnippet', array('name' => 'someSnippet'));
$props = $snippet->getProperties();
$props['someKey'] = 'someValue';
$snippet->setProperties($props);
$snippet->save();

It looks innocent enough, but it will trash all the other properties of the Snippet.

Why?

When you send the properties array to setProperties(), it will contain just the someKey Element and its value. The setProperties() code will replace all existing properties with the new array.

Preventing this disaster is easy enough. You just need to send a second argument to the setProperties() method.

<?php
/* This code is fine */
$props = $snippet->getProperties();
$props['someKey'] = 'someValue';
$snippet->setProperties($props, true);

Sending true as the second argument in the setProperties() call tells MODX to merge the properties you are sending with the existing ones. That will prevent any of the current values from being trashed. It’s easy to do, but also easy to forget.

What About Using get('properties')?

You can also solve the problem by using get('properties') instead of getProperties(), but it’s much less convenient. When you call get('properties'), MODX returns an array of arrays rather than a simple array of keys and values. With getProperties(), you get an array like this:

array(
    'name1' => 'value1',
    'name2' => 'value2,
}

With get('properties'), you get an array like this:

array (
    'name1' = array(
        'name' => 'name1'
        'value' => 'value1',
        /* more fields here */
    ),
    'name2' = array(
        'name' => 'name1'
        'value' => 'value1',
        /* more fields here */
    ),
)

Since each array member is a property with an array of fields, using get('properties') means that setting the value requires code like this:

$props['name1']['value'] = 'someValue'

Since you seldom want to set any field other than the value field, it’s usually easier just to use getProperties() and setProperties($properties, true).


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.