Roll 1.x branch back before 1.1UI was merged
[project/features.git] / features.api.php
1 <?php
2
3 /**
4 * Main info hook that features uses to determine what components are provided
5 * by the implementing module.
6 *
7 * @return array
8 * An array of components, keyed by the component name. Each component can
9 * define several keys:
10 *
11 * 'file': Optional path to a file to include which contains the rest
12 * of the features API hooks for this module.
13 *
14 * 'default_hook': The defaults hook for your component that is called
15 * when the cache of default components is generated. Examples include
16 * hook_views_default_views() or hook_context_default_contexts().
17 *
18 * 'default_file': The file-writing behavior to use when exporting this
19 * component. May be one of 3 constant values:
20 *
21 * FEATURES_DEFAULTS_INCLUDED_COMMON: write hooks/components to
22 * `.features.inc` with other components. This is the default behavior
23 * if this key is not defined.
24 *
25 * FEATURES_DEFAULTS_INCLUDED: write hooks/components to a component-
26 * specific include named automatically by features.
27 *
28 * FEATURES_DEFAULTS_CUSTOM: write hooks/components to a component-
29 * specific include with a custom name provided. If your module provides
30 * large amounts of code that should not be parsed often (only on specific
31 * cache clears/rebuilds, for example) you should use the 2nd or 3rd
32 * options to split your component into its own include.
33 *
34 * 'default_filename': The filename to use when 'default_file' is set to
35 * FEATURES_DEFAULTS_CUSTOM.
36 *
37 * 'feature_source': Boolean value for whether this component should be
38 * offered as an option on the initial feature creation form.
39 *
40 * 'base': Optional. An alternative base key to use when calling features
41 * hooks for this component. Can be used for features component types that
42 * are declared "dynamically" or are part of a family of components.
43 *
44 * 'alter_type': What type of alter hook this hook uses. 'normal' is called
45 * after the main hook is called. 'inline' is embeded within the default hook
46 * and may not be implemented by some default hooks.
47 * 'none' is no alter hook exists. Defaults to 'normal'
48 *
49 * 'alter_hook': What the name of the alter hook for this component is.
50 * Do not include the '_alter' part. Defaults to 'default_hook'.
51 */
52 function hook_features_api() {
53 return array(
54 'mycomponent' => array(
55 'default_hook' => 'mycomponent_defaults',
56 'default_file' => FEATURES_DEFAULTS_INCLUDED,
57 'feature_source' => TRUE,
58 'file' => drupal_get_path('module', 'mycomponent') . '/mycomponent.features.inc',
59 ),
60 );
61 }
62
63 /**
64 * Component hook. The hook should be implemented using the name ot the
65 * component, not the module, eg. [component]_features_export() rather than
66 * [module]_features_export().
67 *
68 * Process the export array for a given component. Implementations of this hook
69 * have three key tasks:
70 *
71 * 1. Determine module dependencies for any of the components passed to it
72 * e.g. the views implementation iterates over each views' handlers and
73 * plugins to determine which modules need to be added as dependencies.
74 *
75 * 2. Correctly add components to the export array. In general this is usually
76 * adding all of the items in $data to $export['features']['my_key'], but
77 * can become more complicated if components are shared between features
78 * or modules.
79 *
80 * 3. Delegating further detection and export tasks to related or derivative
81 * components.
82 *
83 * Each export processor can kickoff further export processors by returning a
84 * keyed array (aka the "pipe") where the key is the next export processor hook
85 * to call and the value is an array to be passed to that processor's $data
86 * argument. This allows an export process to start simply at a few objects:
87 *
88 * [context]
89 *
90 * And then branch out, delegating each component to its appropriate hook:
91 *
92 * [context]--------+------------+
93 * | | |
94 * [node] [block] [views]
95 * |
96 * [CCK]
97 * |
98 * [imagecache]
99 *
100 * @param array $data
101 * An array of machine names for the component in question to be exported.
102 * @param array &$export
103 * By reference. An array of all components to be exported with a given
104 * feature. Component objects that should be exported should be added to
105 * this array.
106 * @param string $module_name
107 * The name of the feature module to be generated.
108 * @return array
109 * The pipe array of further processors that should be called.
110 */
111 function hook_features_export($data, &$export, $module_name) {
112 // The following is the simplest implementation of a straight object export
113 // with no further export processors called.
114 foreach ($data as $component) {
115 $export['features']['mycomponent'][$component] = $component;
116 }
117 return array();
118 }
119
120 /**
121 * Component hook. The hook should be implemented using the name ot the
122 * component, not the module, eg. [component]_features_export() rather than
123 * [module]_features_export().
124 *
125 * List all objects for a component that may be exported.
126 *
127 * @return array
128 * A keyed array of items, suitable for use with a FormAPI select or
129 * checkboxes element.
130 */
131 function hook_features_export_options() {
132 $options = array();
133 foreach (mycomponent_load() as $mycomponent) {
134 $options[$mycomponent->name] = $mycomponent->title;
135 }
136 return $options;
137 }
138
139 /**
140 * Component hook. The hook should be implemented using the name ot the
141 * component, not the module, eg. [component]_features_export() rather than
142 * [module]_features_export().
143 *
144 * Render one or more component objects to code.
145 *
146 * @param string $module_name
147 * The name of the feature module to be exported.
148 * @param array $data
149 * An array of machine name identifiers for the objects to be rendered.
150 * @param array $export
151 * The full export array of the current feature being exported. This is only
152 * passed when hook_features_export_render() is invoked for an actual feature
153 * update or recreate, not during state checks or other operations.
154 * @return array
155 * An associative array of rendered PHP code where the key is the name of the
156 * hook that should wrap the PHP code. The hook should not include the name
157 * of the module, e.g. the key for `hook_example` should simply be `example`
158 * The values in the array can also be in the form of an associative array
159 * with the required key of 'code' and optional key of 'args', if 'args' need
160 * to be added to the hook.
161 */
162 function hook_features_export_render($module_name, $data, $export = NULL) {
163 $code = array();
164 $code[] = '$mycomponents = array();';
165 foreach ($data as $name) {
166 $code[] = " \$mycomponents['{$name}'] = " . features_var_export(mycomponent_load($name)) .";";
167 }
168 $code[] = "return \$mycomponents;";
169 $code = implode("\n", $code);
170 return array('mycomponent_defaults' => $code);
171 }
172
173 /**
174 * Component hook. The hook should be implemented using the name ot the
175 * component, not the module, eg. [component]_features_export() rather than
176 * [module]_features_export().
177 *
178 * Revert all component objects for a given feature module.
179 *
180 * @param string $module_name
181 * The name of the feature module whose components should be reverted.
182 * @return boolean
183 * TRUE or FALSE for whether the components were successfully reverted.
184 */
185 function hook_features_revert($module_name) {
186 $mycomponents = module_invoke($module_name, 'mycomponent_defaults');
187 if (!empty($mycomponents)) {
188 foreach ($mycomponents as $mycomponent) {
189 mycomponent_delete($mycomponent);
190 }
191 }
192 }
193
194 /**
195 * Component hook. The hook should be implemented using the name ot the
196 * component, not the module, eg. [component]_features_export() rather than
197 * [module]_features_export().
198 *
199 * Rebuild all component objects for a given feature module. Should only be
200 * implemented for 'faux-exportable' components.
201 *
202 * This hook is called at points where Features determines that it is safe
203 * (ie. the feature is in state `FEATURES_REBUILDABLE`) for your module to
204 * replace objects in the database with defaults that you collect from your
205 * own defaults hook. See API.txt for how Features determines whether a
206 * rebuild of components is possible.
207 *
208 * @param string $module_name
209 * The name of the feature module whose components should be rebuilt.
210 */
211 function hook_features_rebuild($module_name) {
212 $mycomponents = module_invoke($module_name, 'mycomponent_defaults');
213 if (!empty($mycomponents)) {
214 foreach ($mycomponents as $mycomponent) {
215 mycomponent_save($mycomponent);
216 }
217 }
218 }
219
220 /**
221 * Alter the final array of Component names to be exported, just prior to
222 * the rendering of defaults. Allows modules a final say in whether or not
223 * certain Components are exported (the Components' actual data, however,
224 * cannot be altered by this hook).
225 *
226 * @param array &$export
227 * By reference. An array of all component names to be exported with a given
228 * feature.
229 * @param array $module_name
230 * The name of the feature module to be generated.
231 */
232 function hook_features_export_alter(&$export, $module_name) {
233 // Example: do not allow the page content type to be exported, ever.
234 if (!empty($export['features']['node']['page'])) {
235 unset($export['features']['node']['page']);
236 }
237 }
238
239 /**
240 * Alter the pipe array for a given component. This hook should be implemented
241 * with the name of the component type in place of `component` in the function
242 * name, e.g. `features_pipe_views_alter()` will alter the pipe for the Views
243 * component.
244 *
245 * @param array &$pipe
246 * By reference. The pipe array of further processors that should be called.
247 * @param array $data
248 * An array of machine names for the component in question to be exported.
249 * @param array &$export
250 * By reference. An array of all components to be exported with a given
251 * feature.
252 */
253 function hook_features_pipe_COMPONENT_alter(&$pipe, $data, $export) {
254 if (in_array($data, 'my-node-type')) {
255 $pipe['dependencies'][] = 'mymodule';
256 }
257 }
258
259 /**
260 * Alter the pipe array for a given component.
261 *
262 * @param array &$pipe
263 * By reference. The pipe array of further processors that should be called.
264 * @param array $data
265 * An array of machine names for the component in question to be exported.
266 * @param array &$export
267 * By reference. An array of all components to be exported with a given
268 * feature.
269 *
270 * The component being exported is contained in $export['component'].
271 * The module being exported contained in $export['module_name'].
272 */
273 function hook_features_pipe_alter(&$pipe, $data, $export) {
274 if ($export['component'] == 'node' && in_array($data, 'my-node-type')) {
275 $pipe['dependencies'][] = 'mymodule';
276 }
277 }
278
279 /**
280 * @defgroup features_component_alter_hooks Feature's component alter hooks
281 * @{
282 * Hooks to modify components defined by other features. These come in the form
283 * hook_COMPONENT_alter where COMPONENT is the default_hook declared by any of
284 * components within features.
285 *
286 * CTools also has a variety of hook_FOO_alters.
287 *
288 * Note: While views is a component of features, it declares it's own alter
289 * function which takes a similar form:
290 * hook_views_default_views_alter(&$views)
291 */
292
293 /**
294 * Alter the default fields right before they are cached into the database.
295 *
296 * @param &$fields
297 * By reference. The fields that have been declared by another feature.
298 */
299 function hook_field_default_fields_alter(&$fields) {
300 }
301
302 /**
303 * Alter the default fieldgroup groups right before they are cached into the
304 * database.
305 *
306 * @param &$groups
307 * By reference. The fieldgroup groups that have been declared by another
308 * feature.
309 */
310 function hook_fieldgroup_default_groups_alter(&$groups) {
311 }
312
313 /**
314 * Alter the default filter formats right before they are cached into the
315 * database.
316 *
317 * @param &$formats
318 * By reference. The formats that have been declared by another feature.
319 */
320 function hook_filter_default_formats_alter(&$formats) {
321 }
322
323 /**
324 * Alter the default menus right before they are cached into the database.
325 *
326 * @param &$menus
327 * By reference. The menus that have been declared by another feature.
328 */
329 function hook_menu_default_menu_custom_alter(&$menus) {
330 }
331
332 /**
333 * Alter the default menu links right before they are cached into the database.
334 *
335 * @param &$links
336 * By reference. The menu links that have been declared by another feature.
337 */
338 function hook_menu_default_menu_links_alter(&$links) {
339 }
340
341 /**
342 * Alter the default menu items right before they are cached into the database.
343 *
344 * @param &$items
345 * By reference. The menu items that have been declared by another feature.
346 */
347 function hook_menu_default_items_alter(&$items) {
348 }
349
350 /**
351 * Alter the default vocabularies right before they are cached into the
352 * database.
353 *
354 * @param &$vocabularies
355 * By reference. The vocabularies that have been declared by another feature.
356 */
357 function hook_taxonomy_default_vocabularies_alter(&$vocabularies) {
358 }
359
360 /**
361 * Alter the default permissions right before they are cached into the
362 * database.
363 *
364 * @param &$permissions
365 * By reference. The permissions that have been declared by another feature.
366 */
367 function hook_user_default_permissions_alter(&$permissions) {
368 }
369
370 /**
371 * Alter the default roles right before they are cached into the database.
372 *
373 * @param &$roles
374 * By reference. The roles that have been declared by another feature.
375 */
376 function hook_user_default_roles_alter(&$roles) {
377 }
378
379 /**
380 * @}
381 */