Strongarm allows you to gracefully export arrays in multiple modules. Features calls the export of the same variable from multiple places a conflict.

This is bothersome. I'm not sure what to say about a decent fix, but it seems to me that Strongarm specifically is a case where the answer is "module weight", and don't report it's conflicts as an issue.

Example: Adding a block as a default dashboard option in OA. I could write the export by hand if I had no other variables, instead, I run the export and delete all the blocks whose settings I don't want to meddle with. If I read the code right, Strongarm processes this all into a nice array.

Comments

jmiccolis’s picture

Strongarm allows you to gracefully export arrays in multiple modules.

I'm pretty sure this isn't true anymore. ...are you thinking of the old strongarm version?

yhahn’s picture

Status: Active » Postponed (maintainer needs more info)
Grayside’s picture

Title: Strongarm Export Conflict » Strongarming a Strongarmed Variable
Project: Features » Strongarm
Version: 6.x-1.x-dev » 6.x-2.0
Category: support » feature
Priority: Minor » Normal
Status: Postponed (maintainer needs more info) » Active

I was thinking of the 1.x line. Changing this to a feature request.

There are two general use cases for which I would like one feature to be able to modify a variable that is already strongarmed.

First, variable arrays often change as you add more of /something/ to the system. Create a feature that adds a new content type? You might want it to be a book type, or a casetracker project type. The current implementation of Strongarm and Features conflicts means this use case cannot be handled gracefully in exportables.

Second, "progressive enhancement" by features. If I want one feature to tweak another feature's variable settings, how do I do it? Use case: it's an Atrium site, so I want to use an OG token for something or other. Is the best practice intended to be creating a feature that largely overlaps another? That seems like it would be potentially confusing to maintain, and redundant in the case of features that call for a bunch of code in .module.

The alternative is a bunch of variable_set'ing in hook_install()? That seems backwards.

Grayside’s picture

Title: Strongarming a Strongarmed Variable » Strongarming a Strongarmed Variable [hook_strongarm_alter()]

I should probably have titled this something more like hook_strongarm_alter().

yhahn’s picture

? There is a hook_strongarm_alter().

Grayside’s picture

I do not see it. Is it invoked in strongarm.module somewhere?

yhahn’s picture

It's built into the CTools export.inc API

/**
 * Call the hook to get all default objects of the given type from the
 * export. If configured properly, this could include loading up an API
 * to get default objects.
 */
function _ctools_export_get_defaults($table, $export) {
  $cache = &ctools_static(__FUNCTION__, array());

  if (!isset($cache[$table])) {
    $cache[$table] = array();

    if ($export['default hook']) {
      if (!empty($export['api'])) {
        ctools_include('plugins');
        $info = ctools_plugin_api_include($export['api']['owner'], $export['api']['api'],
          $export['api']['minimum_version'], $export['api']['current_version']);
        $modules = array_keys($info);
      }
      else {
        $modules = module_implements($export['default hook']);
      }

      foreach ($modules as $module) {
        $function = $module . '_' . $export['default hook'];
        if (function_exists($function)) {
          foreach ((array) $function($export) as $name => $object) {
            // Record the module that provides this exportable.
            $object->export_module = $module;

            if (empty($export['api'])) {
              $cache[$table][$name] = $object;
            }
            else {
              // If version checking is enabled, ensure that the object can be used.
              if (isset($object->api_version) &&
                $object->api_version >= $export['api']['minimum_version'] &&
                $object->api_version <= $export['api']['current_version']) {
                $cache[$table][$name] = $object;
              }
            }
          }
        }
      }

      drupal_alter($export['default hook'], $cache[$table]);
    }
  }

  return $cache[$table];
}
Grayside’s picture

Status: Active » Fixed

Oh.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

cweagans’s picture

Status: Closed (fixed) » Active

Sorry for opening a really old issue, but hook_strongarm_alter is not a good solution here. I recently stumbled across this post when trying to build a feature that adds to an existing strongarm variable. What ensued was not pretty.

First thing that happened was that all variable components on all of my features appeared as Overridden. That's less than ideal, but I could deal with that.

The second thing that happened was that if the "article" feature defined a strongarmed variable (foo="article"), and the "event" feature tried to alter the variable "foo" to be "article, event", and the "article" feature was re-exported, the combined value ("article, event") would be the new strongarmed variable in the article feature. So basically, every time I did a drush fu article, variable foo would be re-exported with an additional ", event" appended to the end.

This is not a good solution. I'll try to come up with something better if I have time.

Grayside’s picture

Status: Active » Closed (fixed)

This is not strongarm specific, but a standard part of how Features works. There are numerous issues in the Features queue, and the Features Override module is specifically targetting addressing this.