In the previous article, we saw how to use explode() to create a simple array of names. In this one, we'll send an extra bit of information along with each name to demonstrate how to create an associative array where the key is the username and the value is the email address.
Here's the snippet tag with the usernames and email addresses:
[[SetUserEmails?
&names=`BobRay:bobray@somewhere.com,JohnDoe:johndoe@gmail.com,JaneRoe:janeroe@aol.com`
]]
Splitting Them Up
Notice that we have two delimiters in the names property. We use a comma to separate the users from each other. We use a colon to separate the username and the email address for each user. In our code, we'll need to call explode() twice — once for each delimiter. We'll create the final associative array as we go along. The final array we want looks like this:
$nameArray = array(
'BobRay' => 'bobray@somewhere.com',
'JohnDoe' => 'johndoe@gmail.com',
'JaneRoe' => 'janeroe@aol.com',
);
The Code
Here's the code of our SetUserEmails snippet:
$names = $modx->getOption('names', $scriptProperties, '');
$nameArray = explode(',', $names);
$finalArray = array();
foreach ($nameArray as $user) {
/* user looks like this: 'BobRay:bobray@somewhere.com' */
$couple = explode(':', $user);
/* The $couple array looks like this:
$couple = array(
0 => 'BobRay'
1 => 'bobray@somewhere.com',
);
*/
$finalArray[$couple[0]] = $couple[1];
}
/* Now we have the final array as shown above */
foreach($finalArray as $key => $value) {
$currentUser = $modx->getObject('modUser', array('username' => $key));
if ($currentUser) {
$profile = $currentUser->getOne('Profile');
if ($profile) {
$profile->set('email', $value);
$profile->save();
}
}
}
When foreach() is used with two variables after the as as we've done at the end of the code above, the first variable will be set to the left-hand member of the array element and the second will be set to the right-hand member. The variables
the variable names are arbitrary, but $key and $value (or $k and $v) are often used for this.
Sanity Checks
We've skipped some important sanity checks and the trim() function in the code above. This code will break with a PHP error if the snippet property is not formatted correctly or if the user has added a space after any of the commas. Here's a longer version that is much less likely to crash if things aren't quite right. It also includes some output to report on what happened:
$output = '';
$names = $modx->getOption('names', $scriptProperties, '');
/* We don't need trim() here because we're triming both parts below */
$nameArray = explode(',', $names);
$finalArray = array();
foreach ($nameArray as $user) {
/* $user looks like this on the first pass: 'BobRay:bobray@somewhere.com' */
/* Bail if there's no colon */
if (strpos($user, ':') === false) {
return 'Unable to parse names property';
}
$couple = array_map('trim', explode(':', $user));
/* The $couple array looks like this on the first pass:
$couple = array(
0 => 'BobRay'
1 => 'bobray@somewhere.com',
);
*/
/* Add the pair to the final array */
$finalArray[$couple[0]] = $couple[1];
}
/* Now we have the final array as shown above */
foreach($finalArray as $key => $value) {
$currentUser = $modx->getObject('modUser', array('username' => $key));
if ($currentUser) {
$profile = $currentUser->getOne('Profile');
if ($profile) {
$profile->set('email', $value);
$profile->save();
$output .= '<br />User ' . $key . ' assigned email ' . $value;
} else {
$output .= '<br />User ' . $key . ' has no profile';
}
} else {
$output .= '<br />User ' . $key . ' not found';
}
}
return $output;
We're using the strpos() function (which is much faster than strstr()) in the code above to make sure each user's section has a colon in it. If we didn't do this, we'd have to call isset() on $couple[1] to keep the code from crashing if no colon was present for that user. Without a colon, the $couple array would look like this:
$couple = array(
0 => 'BobRaybobray@somewhere.com',
);
PHP would throw an error when we tried to reference $couple[1], since it doesn't exist.
Coming Up
In this article and the previous one, we saw how to create arrays from a delimited string using explode(), but what if you want to go the other way? What if you want to display a delimited string based on an array? In the next article, we'll see how to do that using explode()'s fraternal twin: implode().

Comments (0)
Please login to comment.