| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | 
Features 1.x API for Drupal 7.x-------------------------------This file contains documentation for two audiences: site builders interested increating and managing features and module developers interested in integratingwith the features module.Terminology------------ A **feature module** is a Drupal module that contains the `feature` key in its`.info` file. This array describes the components that should be managed byFeatures within the module.- A **component** is a configuration object that can be exported. Examples: aview, content type or CCK field instance.- A **machine name** is a string identifier for a specific type of component andshould be unique within a single Drupal site. It should not be a numericallygenerated serial id.- An **exportable** component is one that can be used solely from a default hookin code and without an instance in the database. For example, a view that livesin code does not need an entry in the database in order to be used.- A **faux-exportable** component is one that must exist in the database inorder to be used. Any exports of this component are used to create orsynchronize entries in the database that share the same machine name.### Component statesFeatures provides some infrastructure to determine the state of components onthe site. To determine the state of a component Features keeps track of threethings using an md5 hash of- current code for the component. This is the configuration as actuallyrepresented in code by a given feature.- the most recent prior code state that differs from the current code state. Forexample, if an `svn update` changes the configuration of a view, this stores thecode state *prior* to the update.- The "normal" component state. This is the configuration represented by thecomponent as stored in the database or the default component (with any changesintroduced by `drupal_alter()`) if no database override exists.Using these three values, Features determines a component to be in one of thefollowing five states:- **Default** (`FEATURES_DEFAULT`) The object has no database entry or thedatabase entry matches the state of the component in code. This should be thedefault state of components after installing a feature. Updating the componentcan be done by altering the code definition directly.- **Overridden** (`FEATURES_OVERRIDDEN`) The code remains constant but thedatabase object does not match the state of the component in code. Changes mustbe reverted before the component can be updated from code.- **Needs review** (`FEATURES_NEEDS_REVIEW`) The previous code state, databasestate, and current code state all differ. This occurs most commonly when a userchanges one of her components and then pulls updates to her codebase. Sincethere is no way to tell whether the code state or the database state is morerecent/valid, user input is necessary to resolve this state.- **Rebuildable** (`FEATURES_REBUILDABLE`) This state only applies to**faux-exportables** and indicates that the database component must and can besafely updated from the code definition. The database entry does not match thecurrent code state but does match the previous code state. Features assumes thatin this scenario the user has made no substantive changes and the component canbe updated automatically.- **Rebuilding** (`FEATURES_REBUILDING`) This state is rarely seen and onlyapplies to **faux-exportables.** This state is shown when a`FEATURES_REBUILDABLE` component is *currently* being synced to the database.Usually this operation is very fast and short lived. However, if the operationis interrupted (e.g. the server goes down) this state will be seen until therebuild locking semaphore is cleared.How a feature is generated--------------------------At a high level Features writes the code in a feature module using the followingsteps:1. An `.info` file describing the components that should be included in aFeature is generated. It is either read from an existing feature or generatedthrough the Features UI.2. Features converts the info file into an `$export` array which contains a listof elements to be exported. Each component type is given a chance to add to theexport list as well as request that *other* components be given a second chanceto add to the `$export` array.3. If any additional components have been queued up in the `$pipe` we repeatstep 2 for each of the queued component types.4. Once a full `$export` array is populated each component renders items fromthe `$export` array to PHP code as a exportable defaults hook.5. Finally, Features writes the code into files and delivers it as adownloadable package (UI) or writes it directly to a module directory (drush).This workflow makes a variety of things possible:### Add components to a featureAdd the components to the `features` array in the feature's `.info` file and run`drush features-update`. The same operation can be performed using the*Recreate* page in the Features UI.### Remove components from a featureRemove the corresponding component lines from the feature's `.info` file and run`drush features-update`. The same operation can be performed using the*Recreate* page in the Features UI.### Rename a componentRename a component by changing its name in the feature's `.info` file and thekey and name property of the exported object in the appropriate `.inc` file inthe feature. Note that any references in other configuration objects to theprevious name should also be updated.Integrating your module with the Features API---------------------------------------------This section is for developers interested in adding Features-based managementfor the configuration objects in their modules. From the perspective ofFeatures, there are a few different ways that modules store their configuration:- In the `variable` table using `variable_set()`. If a module is using variablesfor storing configuration, these variable settings can be exported with Featuresby using the [Strongarm][1] module.  **Features integration:** Install the Strongarm module.- Using a custom table with a serial ID for identifying configuration objects.If this is the case, you will need to change your schema to use a stringidentifier / machine name for each object.  **Features integration:** Fix your schema first, then see below.- Using a custom table with a machine name identifier and custom exportableshandling (e.g. you have your own defaults hook handling and export generation).If this is the case, you will need to implement many of the features hooksyourself.  **Features integration:** `hook_features_api()`, `hook_features_export()`,`hook_features_export_render()`, `hook_features_export_options()`,`hook_features_revert()`.- Using a custom table with CTools Export API integration. If this is the case,Features will automatically have integration with your module. You can implementany of the Features hooks in order to override the default CTools exportablesintegration behavior.  **Features integration:** Automatically provided. You may implement any of theFeatures hooks where you need further customization for your configurationobject.If it isn't clear by now, we highly recommend using the [CTools][2] Export APIfor adding exportables to your module. Stella has written a [fantastic HOWTO][3]on using the CTools Export API that can get you started.An overview of Features hooks-----------------------------Extensive documentation of the hooks provided by Features is available in`features.api.php`. This section provides a short overview of each hook and itsrole.- `hook_features_api()` defines one or more component types that are availableto Features for export and a variety of settings for each type.- `hook_features_export()` processes a list of components, detecting anydependencies or further components- `hook_features_export_options()` provides an array of components that can beexported for a given type.- `hook_features_export_render()` renders a set of components to code as adefaults hook.- `hook_features_revert()` reverts components of a feature back to their defaultstate.- `hook_features_rebuild()` updates faux-exportable components back to theirdefault state. Only applies to faux-exportables.[1]: http://drupal.org/project/strongarm[2]: http://drupal.org/project/ctools[3]: http://civicactions.com/blog/2009/jul/24/using_chaos_tools_module_create_exportables
 |