diff --git a/features.api.php b/features.api.php index 4fb810e..66a0250 100644 --- a/features.api.php +++ b/features.api.php @@ -40,6 +40,14 @@ * 'base': Optional. An alternative base key to use when calling features * hooks for this component. Can be used for features component types that * are declared "dynamically" or are part of a family of components. + * + * 'alter_type': What type of alter hook this hook uses. 'normal' is called + * after the main hook is called. 'inline' is embeded within the default hook + * and may not be implemented by some default hooks. + * 'none' is no alter hook exists. Defaults to 'normal' + * + * 'alter_hook': What the name of the alter hook for this component is. + * Do not include the '_alter' part. Defaults to 'default_hook'. */ function hook_features_api() { return array( diff --git a/features.export.inc b/features.export.inc index 93d36a3..420bbbd 100644 --- a/features.export.inc +++ b/features.export.inc @@ -353,6 +353,16 @@ function features_get_default_hooks($component = NULL, $reset = FALSE) { } /** + * Gets the available default hooks keyed by components. + */ +function features_get_default_alter_hook($component) { + $default_hook = features_get_components($component, 'default_hook'); + $alter_hook = features_get_components($component, 'alter_hook'); + $alter_type = features_get_components($component, 'alter_type'); + return empty($alter_type) || $alter_type != 'none' ? ($alter_hook ? $alter_hook : $default_hook) : FALSE; +} + +/** * Return a code string representing an implementation of a defaults module hook. */ function features_export_render_defaults($module, $hook, $code, $args = '') { @@ -617,11 +627,13 @@ function features_get_normal($component, $module_name, $reset = FALSE) { * Get defaults for a given module/component pair. */ function features_get_default($component, $module_name = NULL, $alter = TRUE, $reset = FALSE) { + global $features_alter; static $cache = array(); features_include(); features_include_defaults($component); $default_hook = features_get_default_hooks($component); $components = features_get_components(); + $features_alter = $alter; // Collect defaults for all modules if no module name was specified. if (isset($module_name)) { @@ -653,8 +665,11 @@ function features_get_default($component, $module_name = NULL, $alter = TRUE, $r else { if ($default_hook && module_hook($m, $default_hook)) { $cache[$component][$m] = call_user_func("{$m}_{$default_hook}"); - if ($alter) { - drupal_alter($default_hook, $cache[$component][$m]); + $alter_type = features_get_components('alter_type', $component); + if ($alter && (!isset($alter_type) || $alter_type == FEATURES_ALTER_TYPE_NORMAL)) { + if ($alter_hook = features_get_default_alter_hook($component)) { + drupal_alter($alter_hook, $cache[$component][$m]); + } } } else { @@ -675,6 +690,7 @@ function features_get_default($component, $module_name = NULL, $alter = TRUE, $r $all_defaults = array_merge($all_defaults, $module_components); } } + unset($features_alter); return $all_defaults; } diff --git a/features.module b/features.module index fa82746..123c336 100644 --- a/features.module +++ b/features.module @@ -18,6 +18,9 @@ define('FEATURES_NEEDS_REVIEW', 2); define('FEATURES_REBUILDING', 3); define('FEATURES_CONFLICT', 4); define('FEATURES_DISABLED', 5); +define('FEATURES_ALTER_TYPE_NORMAL', 'normal'); +define('FEATURES_ALTER_TYPE_INLINE', 'inline'); +define('FEATURES_ALTER_TYPE_NONE', 'none'); // Duration of rebuild semaphore: 10 minutes. define('FEATURES_SEMAPHORE_TIMEOUT', 10 * 60); diff --git a/includes/features.image.inc b/includes/features.image.inc index 713a93a..9eee8db 100644 --- a/includes/features.image.inc +++ b/includes/features.image.inc @@ -9,6 +9,7 @@ function image_features_api() { 'name' => t('Image styles'), 'feature_source' => TRUE, 'default_hook' => 'image_default_styles', + 'alter_hook' => 'image_styles', ) ); } diff --git a/includes/features.node.inc b/includes/features.node.inc index af35e25..14c0816 100644 --- a/includes/features.node.inc +++ b/includes/features.node.inc @@ -9,6 +9,7 @@ function node_features_api() { 'name' => t('Content types'), 'feature_source' => TRUE, 'default_hook' => 'node_info', + 'alter_type' => FEATURES_ALTER_TYPE_INLINE, ), ); } @@ -86,6 +87,10 @@ function node_features_export_render($module, $data, $export = NULL) { } } $output[] = ' );'; + $output[] = ' global $features_alter;'; + $output[] = ' if (!isset($features_alter) || !empty($features_alter)) {'; + $output[] = ' drupal_alter(\'node_info\', $items);'; + $output[] = ' }'; $output[] = ' return $items;'; $output = implode("\n", $output); return array('node_info' => $output);