Multiple Search and Replace Operations

Using a utility snippet for multiple search-and-replace operations


In the last article, we looked at a utility snippet to perform a single search and replace operation on resources. In this one, we'll look at a utility snippet designed to perform multiple search and replace operations in a single pass using an associative array of search and replace phrases.


MODX logo

The Snippet

In the previous article, our example snippet looped through all resources on the site. We'll do that again, but with some added code to perform the multiple search and replace operation. We'll use the spelling of MODX again as our example.


$search = array(
    'modX' => 'MODX',
    'MODx' => 'MODX',
    'modx' => 'MODX',
);

$docs = $modx->getCollection('modResource');
$count = 0;
$replacements = 0;

foreach ($docs as $doc) {
    $dirty = false;
    $content = $doc->getContent();
    foreach ($search as $key => $value) {
        if (strpos($content, $key) !== false) {
            $content = str_replace($key, $value, $content, $replacements);
            $dirty = $true;
            $count+= $replacements;
        }
    }
    if ($dirty) {
        $doc->setContent($content);
        $doc->save();
    }
}

return '<h3>Replaced' . $count . 'strings</h3>';

In this version, we've added an extra loop inside the original one. The outer loop, loops through the resources. The inner one loops through the members of the search array, does the str_pos() test, and if necessary, performs one of the three replacements. We've also added the $dirty flag which is only set if at least one replacement has been made. There's no sense replacing the content or saving the resource if there were no replacements, so that happens after the end of the inner loop when the $dirty flag has been set. This is after all the replacements have been made, so we only have to modify the resource content once.

One nice thing about this code is that it will work fine and will be just as fast if you are only replacing one string. If our $search array has only one line, the inner loop will only execute once, so the code is flexible enough to handle any number of search and replace pairs.


Another Way

If you're familiar with PHP's str_replace() function, you know that we could have used two arrays and only called str_replace() once. The problem with this method is that we'd have to actually perform the str_replace(), setContent(), and save() operations on every resource of the site, even though many of the pages might not contain any of the strings we need to replace.

In case you're curious, here's an example using that method that replaces the lower-case versions of three names with an initial-cap version:

$search = array (
    'bob',
    'carol',
    'ted',
    'alice',
);

$replace = array (
    'Bob',
    'Carol',
    'Ted',
    'Alice',
);

$docs = $modx->getCollection('modResource');
$count = 0;
$replacements = 0;

foreach($docs as $doc) {
    $content = $doc->getContent();
    $content = str_replace($search, $replace, $content, $replacements);
    $doc->setContent($content);
    $doc->save();
    $count += $replacements;
}

return '<h3>Replaced' . $count . 'strings</h3>';

Coming Up

In the next article, we'll look at a way to limit the users shown shown in the user grid.


For more information on how to use MODX to create a web site, see my web site Bob's Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)



Comments (0)


Please login to comment.

  (Login)