On my webform, there are two kinds of address-fields a user can give. But since it's a complex webform (Drupal) it's kind of hard to achieve. Every time a user adds an extra address, the form is regenerated and there will be a new item added to the $address_afl
and $address_bev
-array. Is it possible to compress this code so the foreach-loop starts looping with the highest value (either $address_afl
or$address_bev
)
$address_afl = $form['field_afl_dienst_adressen']['und'];
$i = 0;
foreach($address_afl as $value) {
if (is_array($value)) {
$test = array_keys($value);
if(is_array($test)) {
foreach ($test as $z) {
if (strpos($z, '#') === 0) continue;
if (isset($form['field_afl_dienst_adressen']['und'][$i][$z])) {
$form['field_afl_dienst_adressen']['und'][$i][$z]['#prefix'] = "<div class='address-publicatie-$z'>";
$form['field_afl_dienst_adressen']['und'][$i][$z]['#suffix'] = "</div>";
}
}
}
}
$i++;
}
$address_bev = $form['field_bevoegde_adressen']['und'];
$i = 0;
foreach($address_bev as $value) {
if (is_array($value)) {
$test = array_keys($value);
if(is_array($test)) {
foreach ($test as $z) {
if (strpos($z, '#') === 0) continue;
if (isset($form['field_afl_dienst_adressen']['und'][$i][$z])) {
$form['field_bevoegde_adressen']['und'][$i][$z]['#prefix'] = "<div class='address-publicatie-$z'>";
$form['field_bevoegde_adressen']['und'][$i][$z]['#suffix'] = "</div>";
}
}
}
}
$i++;
}
2 Answers 2
I don't quite exactly understand the logic, but you could extract out at least one method which removes lots of code duplication. I've inverted some conditions (which improves code readability) and placed some comments into the code too.
function processValue(&$form, $value, $i, &$form_sub) {
if (!is_array($value)) {
return;
}
// TODO: rename test to $keys or something more meaningful
$test = array_keys($value);
if (!is_array($test)) {
// TODO: is it possible? according to the documentation
// array_keys() always returns array
return;
}
foreach ($test as $z) {
if (strpos($z, '#') === 0) {
continue;
}
if (!isset($form['field_afl_dienst_adressen']['und'][$i][$z])) {
continue;
}
$form_sub[$i][$z]['#prefix'] = "<div class='address-publicatie-$z'>";
$form_sub[$i][$z]['#suffix'] = "</div>";
}
}
$address_afl = $form['field_afl_dienst_adressen']['und'];
$i = 0;
foreach($address_afl as $value) {
processValue($form, $value, $i, $form['field_afl_dienst_adressen']['und']);
$i++;
}
$address_bev = $form['field_bevoegde_adressen']['und'];
$i = 0;
foreach($address_bev as $value) {
processValue($form, $value, $i, $form['field_bevoegde_adressen']);
$i++;
}
A possible bug: both foreach
has the following condition with the same $form
index:
if (isset($form['field_afl_dienst_adressen']['und'][$i][$z])) ...
Maybe you want to change the second one to
if (isset($form['field_bevoegde_adressen']['und'][$i][$z])) ...
It would make possible some other refactorings (fewer parameters etc.), as Victor T. suggested.
You should be able to factor all those duplicates down into 2 function calls.
I think palacsint's observation is correct that $test
is always an array here. In fact, I'm not sure I see why you don't just use the keys in $value
directly. It doesn't appear the keys get changed in the loop.
if (is_array($value)) {
$test = array_keys($value);
if(is_array($test)) {
foreach ($test as $z) {
This refactor is similar to palacsint's suggestion but taken further.
function name_needed(&$addr_src)
{
$i = -1;
foreach($addr_src as $next)
{
++$i;
if (!is_array($next)) continue;
foreach($next as $z => $_)
{
if (strpos($z, '#') === 0 || !isset($addr_src[$i][$z])) continue;
$addr_src[$i][$z]['#prefix'] = "<div class='address-publicatie-$z'>";
$addr_src[$i][$z]['#suffix'] = "</div>";
}
}
}
name_needed($form['field_afl_adressen']['und']);
name_needed($form['field_bevoegde_adressen']['und']);
-
\$\begingroup\$ I've also thought of moving a little bit further, but in both
foreach
the if condition uses the same key. Check my update for the details. \$\endgroup\$palacsint– palacsint2011年12月22日 10:47:01 +00:00Commented Dec 22, 2011 at 10:47
if
is should not be at the same level as the first. However, array_keys always returns an array so you don't need the secondif
and they should be deleted. \$\endgroup\$