I'll start by describing the problem: You can't use strongarm to set a portion of an array variable (for instance theme settings).

The problem with coming up with a solution for this is that some modules implementing hook_strongarm may actually want to wipe out the complete array, whereas others may only want to change one key of an array.

My only idea would be to add a new hook called hook_strongarm_info or something that might return an array of settings for each variable key:

/**
 * Implementation of hook_strongarm_info().
 */
function foo_strongarm_info() {
  $items = array();

  $items['theme_settings'] = array(
    'union' => TRUE,  // Attempts to union the two arrays
    'recurse' => TRUE, // Unions recursively
    'weakarm' => FALSE,  // if TRUE, Variable is override-able by default
  );

  return $items;
}

Then to actually recursively union the arrays, something like this might work:

/**
 * Union two arrays recursively
 */
function stongarm_union_recursive($array1, $array2) {
  foreach ($array2 as $key => $value) {
    if (is_array($value)) {
      $array1[$key] = stongarm_union_recursive($array1[$key], $array2[$key]);
    }
    else {
      $array1[$key] = $value;
    }
  }
  return $array1;
}

Comments

q0rban’s picture

Better function for recursive union:

/**
 * Helper function to union two arrays recursively
 */
function _strongarm_union_recursive($array1, $array2) {
  foreach ($array2 as $key => $value) {
    if (!isset($array1[$key])) {
      $array1[$key] = $value;
      continue;
    }
    $value = is_array($value) ? _strongarm_union_recursive($array1[$key], $value) : $value;

    if (is_numeric($key)) {
      $array1[] = $value;
    }
    else {
      $array1[$key] = $value;
    }
  }
  return $array1;
}
yhahn’s picture

Assigned: Unassigned » yhahn

Very interesting. Will keep this in mind for the ctools-based work.

jmiccolis’s picture

Version: 6.x-1.0-beta3 » 6.x-2.0-beta1

Bumping version to the 2.0 branch.

mrfelton’s picture

Yes, this is the case for the vertical_tabs module, which stores the settings for every single node type in one keyed array, making it impossible to strongarm the variable for particular node types only.

yhahn’s picture

Status: Active » Closed (won't fix)

I've thought hard about this, including trying to identify "mergable" variables by a different syntax (e.g. foo[bar] or +foo) but all these methods fail on the basis that none would be compatible with the way CTools export API works.

Either we drop CTools export API as our mechanism for exportable variables or we suck it up and live with lame solutions like hook_strongarm_alter(). Choosing the latter.