danielebarchiesi@4: array( danielebarchiesi@4: 'default_hook' => 'mycomponent_defaults', danielebarchiesi@4: 'default_file' => FEATURES_DEFAULTS_INCLUDED, danielebarchiesi@4: 'feature_source' => TRUE, danielebarchiesi@4: 'file' => drupal_get_path('module', 'mycomponent') . '/mycomponent.features.inc', danielebarchiesi@4: ), danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Component hook. The hook should be implemented using the name of the danielebarchiesi@4: * component, not the module, eg. [component]_features_export() rather than danielebarchiesi@4: * [module]_features_export(). danielebarchiesi@4: * danielebarchiesi@4: * Process the export array for a given component. Implementations of this hook danielebarchiesi@4: * have three key tasks: danielebarchiesi@4: * danielebarchiesi@4: * 1. Determine module dependencies for any of the components passed to it danielebarchiesi@4: * e.g. the views implementation iterates over each views' handlers and danielebarchiesi@4: * plugins to determine which modules need to be added as dependencies. danielebarchiesi@4: * danielebarchiesi@4: * 2. Correctly add components to the export array. In general this is usually danielebarchiesi@4: * adding all of the items in $data to $export['features']['my_key'], but danielebarchiesi@4: * can become more complicated if components are shared between features danielebarchiesi@4: * or modules. danielebarchiesi@4: * danielebarchiesi@4: * 3. Delegating further detection and export tasks to related or derivative danielebarchiesi@4: * components. danielebarchiesi@4: * danielebarchiesi@4: * Each export processor can kickoff further export processors by returning a danielebarchiesi@4: * keyed array (aka the "pipe") where the key is the next export processor hook danielebarchiesi@4: * to call and the value is an array to be passed to that processor's $data danielebarchiesi@4: * argument. This allows an export process to start simply at a few objects: danielebarchiesi@4: * danielebarchiesi@4: * [context] danielebarchiesi@4: * danielebarchiesi@4: * And then branch out, delegating each component to its appropriate hook: danielebarchiesi@4: * danielebarchiesi@4: * [context]--------+------------+ danielebarchiesi@4: * | | | danielebarchiesi@4: * [node] [block] [views] danielebarchiesi@4: * | danielebarchiesi@4: * [CCK] danielebarchiesi@4: * | danielebarchiesi@4: * [imagecache] danielebarchiesi@4: * danielebarchiesi@4: * @param array $data danielebarchiesi@4: * An array of machine names for the component in question to be exported. danielebarchiesi@4: * @param array &$export danielebarchiesi@4: * By reference. An array of all components to be exported with a given danielebarchiesi@4: * feature. Component objects that should be exported should be added to danielebarchiesi@4: * this array. danielebarchiesi@4: * @param string $module_name danielebarchiesi@4: * The name of the feature module to be generated. danielebarchiesi@4: * @return array danielebarchiesi@4: * The pipe array of further processors that should be called. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_export($data, &$export, $module_name) { danielebarchiesi@4: // The following is the simplest implementation of a straight object export danielebarchiesi@4: // with no further export processors called. danielebarchiesi@4: foreach ($data as $component) { danielebarchiesi@4: $export['features']['mycomponent'][$component] = $component; danielebarchiesi@4: } danielebarchiesi@4: return array(); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Component hook. The hook should be implemented using the name of the danielebarchiesi@4: * component, not the module, eg. [component]_features_export() rather than danielebarchiesi@4: * [module]_features_export(). danielebarchiesi@4: * danielebarchiesi@4: * List all objects for a component that may be exported. danielebarchiesi@4: * danielebarchiesi@4: * @return array danielebarchiesi@4: * A keyed array of items, suitable for use with a FormAPI select or danielebarchiesi@4: * checkboxes element. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_export_options() { danielebarchiesi@4: $options = array(); danielebarchiesi@4: foreach (mycomponent_load() as $mycomponent) { danielebarchiesi@4: $options[$mycomponent->name] = $mycomponent->title; danielebarchiesi@4: } danielebarchiesi@4: return $options; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Component hook. The hook should be implemented using the name of the danielebarchiesi@4: * component, not the module, eg. [component]_features_export() rather than danielebarchiesi@4: * [module]_features_export(). danielebarchiesi@4: * danielebarchiesi@4: * Render one or more component objects to code. danielebarchiesi@4: * danielebarchiesi@4: * @param string $module_name danielebarchiesi@4: * The name of the feature module to be exported. danielebarchiesi@4: * @param array $data danielebarchiesi@4: * An array of machine name identifiers for the objects to be rendered. danielebarchiesi@4: * @param array $export danielebarchiesi@4: * The full export array of the current feature being exported. This is only danielebarchiesi@4: * passed when hook_features_export_render() is invoked for an actual feature danielebarchiesi@4: * update or recreate, not during state checks or other operations. danielebarchiesi@4: * @return array danielebarchiesi@4: * An associative array of rendered PHP code where the key is the name of the danielebarchiesi@4: * hook that should wrap the PHP code. The hook should not include the name danielebarchiesi@4: * of the module, e.g. the key for `hook_example` should simply be `example` danielebarchiesi@4: * The values in the array can also be in the form of an associative array danielebarchiesi@4: * with the required key of 'code' and optional key of 'args', if 'args' need danielebarchiesi@4: * to be added to the hook. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_export_render($module_name, $data, $export = NULL) { danielebarchiesi@4: $code = array(); danielebarchiesi@4: $code[] = '$mycomponents = array();'; danielebarchiesi@4: foreach ($data as $name) { danielebarchiesi@4: $code[] = " \$mycomponents['{$name}'] = " . features_var_export(mycomponent_load($name)) .";"; danielebarchiesi@4: } danielebarchiesi@4: $code[] = "return \$mycomponents;"; danielebarchiesi@4: $code = implode("\n", $code); danielebarchiesi@4: return array('mycomponent_defaults' => $code); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Component hook. The hook should be implemented using the name of the danielebarchiesi@4: * component, not the module, eg. [component]_features_export() rather than danielebarchiesi@4: * [module]_features_export(). danielebarchiesi@4: * danielebarchiesi@4: * Revert all component objects for a given feature module. danielebarchiesi@4: * danielebarchiesi@4: * @param string $module_name danielebarchiesi@4: * The name of the feature module whose components should be reverted. danielebarchiesi@4: * @return boolean danielebarchiesi@4: * TRUE or FALSE for whether the components were successfully reverted. danielebarchiesi@4: * NOTE: This return value is no longer used in the latest Features so danielebarchiesi@4: * modules should no longer count on this value danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_revert($module_name) { danielebarchiesi@4: $mycomponents = module_invoke($module_name, 'mycomponent_defaults'); danielebarchiesi@4: if (!empty($mycomponents)) { danielebarchiesi@4: foreach ($mycomponents as $mycomponent) { danielebarchiesi@4: mycomponent_delete($mycomponent); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Component hook. The hook should be implemented using the name of the danielebarchiesi@4: * component, not the module, eg. [component]_features_export() rather than danielebarchiesi@4: * [module]_features_export(). danielebarchiesi@4: * danielebarchiesi@4: * Rebuild all component objects for a given feature module. Should only be danielebarchiesi@4: * implemented for 'faux-exportable' components. danielebarchiesi@4: * danielebarchiesi@4: * This hook is called at points where Features determines that it is safe danielebarchiesi@4: * (ie. the feature is in state `FEATURES_REBUILDABLE`) for your module to danielebarchiesi@4: * replace objects in the database with defaults that you collect from your danielebarchiesi@4: * own defaults hook. See API.txt for how Features determines whether a danielebarchiesi@4: * rebuild of components is possible. danielebarchiesi@4: * danielebarchiesi@4: * @param string $module_name danielebarchiesi@4: * The name of the feature module whose components should be rebuilt. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_rebuild($module_name) { danielebarchiesi@4: $mycomponents = module_invoke($module_name, 'mycomponent_defaults'); danielebarchiesi@4: if (!empty($mycomponents)) { danielebarchiesi@4: foreach ($mycomponents as $mycomponent) { danielebarchiesi@4: mycomponent_save($mycomponent); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the final array of Component names to be exported, just prior to danielebarchiesi@4: * the rendering of defaults. Allows modules a final say in whether or not danielebarchiesi@4: * certain Components are exported (the Components' actual data, however, danielebarchiesi@4: * cannot be altered by this hook). danielebarchiesi@4: * danielebarchiesi@4: * @param array &$export danielebarchiesi@4: * By reference. An array of all component names to be exported with a given danielebarchiesi@4: * feature. danielebarchiesi@4: * @param array $module_name danielebarchiesi@4: * The name of the feature module to be generated. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_export_alter(&$export, $module_name) { danielebarchiesi@4: // Example: do not allow the page content type to be exported, ever. danielebarchiesi@4: if (!empty($export['features']['node']['page'])) { danielebarchiesi@4: unset($export['features']['node']['page']); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the pipe array for a given component. This hook should be implemented danielebarchiesi@4: * with the name of the component type in place of `component` in the function danielebarchiesi@4: * name, e.g. `features_pipe_views_alter()` will alter the pipe for the Views danielebarchiesi@4: * component. danielebarchiesi@4: * danielebarchiesi@4: * @param array &$pipe danielebarchiesi@4: * By reference. The pipe array of further processors that should be called. danielebarchiesi@4: * @param array $data danielebarchiesi@4: * An array of machine names for the component in question to be exported. danielebarchiesi@4: * @param array &$export danielebarchiesi@4: * By reference. An array of all components to be exported with a given danielebarchiesi@4: * feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_pipe_COMPONENT_alter(&$pipe, $data, $export) { danielebarchiesi@4: if (in_array($data, 'my-node-type')) { danielebarchiesi@4: $pipe['dependencies'][] = 'mymodule'; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the pipe array for a given component. danielebarchiesi@4: * danielebarchiesi@4: * @param array &$pipe danielebarchiesi@4: * By reference. The pipe array of further processors that should be called. danielebarchiesi@4: * @param array $data danielebarchiesi@4: * An array of machine names for the component in question to be exported. danielebarchiesi@4: * @param array &$export danielebarchiesi@4: * By reference. An array of all components to be exported with a given danielebarchiesi@4: * feature. danielebarchiesi@4: * danielebarchiesi@4: * The component being exported is contained in $export['component']. danielebarchiesi@4: * The module being exported contained in $export['module_name']. danielebarchiesi@4: */ danielebarchiesi@4: function hook_features_pipe_alter(&$pipe, $data, $export) { danielebarchiesi@4: if ($export['component'] == 'node' && in_array($data, 'my-node-type')) { danielebarchiesi@4: $pipe['dependencies'][] = 'mymodule'; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @defgroup features_component_alter_hooks Feature's component alter hooks danielebarchiesi@4: * @{ danielebarchiesi@4: * Hooks to modify components defined by other features. These come in the form danielebarchiesi@4: * hook_COMPONENT_alter where COMPONENT is the default_hook declared by any of danielebarchiesi@4: * components within features. danielebarchiesi@4: * danielebarchiesi@4: * CTools also has a variety of hook_FOO_alters. danielebarchiesi@4: * danielebarchiesi@4: * Note: While views is a component of features, it declares it's own alter danielebarchiesi@4: * function which takes a similar form: danielebarchiesi@4: * hook_views_default_views_alter(&$views) danielebarchiesi@4: */ danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default fields right before they are cached into the database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$fields danielebarchiesi@4: * By reference. The fields that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_field_default_fields_alter(&$fields) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default fieldgroup groups right before they are cached into the danielebarchiesi@4: * database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$groups danielebarchiesi@4: * By reference. The fieldgroup groups that have been declared by another danielebarchiesi@4: * feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_fieldgroup_default_groups_alter(&$groups) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default filter formats right before they are cached into the danielebarchiesi@4: * database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$formats danielebarchiesi@4: * By reference. The formats that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_filter_default_formats_alter(&$formats) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default menus right before they are cached into the database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$menus danielebarchiesi@4: * By reference. The menus that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_menu_default_menu_custom_alter(&$menus) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default menu links right before they are cached into the database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$links danielebarchiesi@4: * By reference. The menu links that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_menu_default_menu_links_alter(&$links) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default menu items right before they are cached into the database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$items danielebarchiesi@4: * By reference. The menu items that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_menu_default_items_alter(&$items) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default vocabularies right before they are cached into the danielebarchiesi@4: * database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$vocabularies danielebarchiesi@4: * By reference. The vocabularies that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_taxonomy_default_vocabularies_alter(&$vocabularies) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default permissions right before they are cached into the danielebarchiesi@4: * database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$permissions danielebarchiesi@4: * By reference. The permissions that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_user_default_permissions_alter(&$permissions) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Alter the default roles right before they are cached into the database. danielebarchiesi@4: * danielebarchiesi@4: * @param &$roles danielebarchiesi@4: * By reference. The roles that have been declared by another feature. danielebarchiesi@4: */ danielebarchiesi@4: function hook_user_default_roles_alter(&$roles) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @} danielebarchiesi@4: */ danielebarchiesi@4: danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @defgroup features_module_hooks Feature module hooks danielebarchiesi@4: * @{ danielebarchiesi@4: * Hooks invoked on Feature modules when that module is enabled, disabled, danielebarchiesi@4: * rebuilt, or reverted. These are ONLY invoked on the Features module on danielebarchiesi@4: * which these actions are taken. danielebarchiesi@4: */ danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module before that module is danielebarchiesi@4: * reverted. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that is about to be reverted. danielebarchiesi@4: */ danielebarchiesi@4: function hook_pre_features_revert($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module after that module is danielebarchiesi@4: * reverted. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that has just been reverted. danielebarchiesi@4: */ danielebarchiesi@4: function hook_post_features_revert($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module before that module is danielebarchiesi@4: * rebuilt. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that is about to be rebuilt. danielebarchiesi@4: */ danielebarchiesi@4: function hook_pre_features_rebuild($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module after that module is danielebarchiesi@4: * rebuilt. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that has just been rebuilt. danielebarchiesi@4: */ danielebarchiesi@4: function hook_post_features_rebuild($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module before that module is danielebarchiesi@4: * disabled. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that is about to be disabled. danielebarchiesi@4: */ danielebarchiesi@4: function hook_pre_features_disable_feature($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module after that module is danielebarchiesi@4: * disabled. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that has just been disabled. danielebarchiesi@4: */ danielebarchiesi@4: function hook_post_features_disable_feature($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module before that module is danielebarchiesi@4: * enabled. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that is about to be enabled. danielebarchiesi@4: */ danielebarchiesi@4: function hook_pre_features_enable_feature($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Feature module hook. Invoked on a Feature module after that module is danielebarchiesi@4: * enabled. danielebarchiesi@4: * danielebarchiesi@4: * @param $component danielebarchiesi@4: * String name of the component that has just been enabled. danielebarchiesi@4: */ danielebarchiesi@4: function hook_post_features_enable_feature($component) { danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @} danielebarchiesi@4: */