features.api.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. <?php
  2. /**
  3. * Main info hook that features uses to determine what components are provided
  4. * by the implementing module.
  5. *
  6. * @return array
  7. * An array of components, keyed by the component name. Each component can
  8. * define several keys:
  9. *
  10. * 'file': Optional path to a file to include which contains the rest
  11. * of the features API hooks for this module.
  12. *
  13. * 'default_hook': The defaults hook for your component that is called
  14. * when the cache of default components is generated. Examples include
  15. * hook_views_default_views() or hook_context_default_contexts().
  16. *
  17. * 'default_file': The file-writing behavior to use when exporting this
  18. * component. May be one of 3 constant values:
  19. *
  20. * FEATURES_DEFAULTS_INCLUDED_COMMON: write hooks/components to
  21. * `.features.inc` with other components. This is the default behavior
  22. * if this key is not defined.
  23. *
  24. * FEATURES_DEFAULTS_INCLUDED: write hooks/components to a component-
  25. * specific include named automatically by features.
  26. *
  27. * FEATURES_DEFAULTS_CUSTOM: write hooks/components to a component-
  28. * specific include with a custom name provided. If your module provides
  29. * large amounts of code that should not be parsed often (only on specific
  30. * cache clears/rebuilds, for example) you should use the 2nd or 3rd
  31. * options to split your component into its own include.
  32. *
  33. * 'default_filename': The filename to use when 'default_file' is set to
  34. * FEATURES_DEFAULTS_CUSTOM.
  35. *
  36. * 'feature_source': Boolean value for whether this component should be
  37. * offered as an option on the initial feature creation form.
  38. *
  39. * 'base': Optional. An alternative base key to use when calling features
  40. * hooks for this component. Can be used for features component types that
  41. * are declared "dynamically" or are part of a family of components.
  42. *
  43. * 'alter_type': What type of alter hook this hook uses. 'normal' is called
  44. * after the main hook is called. 'inline' is embedded within the default hook
  45. * and may not be implemented by some default hooks.
  46. * 'none' is no alter hook exists. Defaults to 'normal'
  47. *
  48. * 'alter_hook': What the name of the alter hook for this component is.
  49. * Do not include the '_alter' part. Defaults to 'default_hook'.
  50. */
  51. function hook_features_api() {
  52. return array(
  53. 'mycomponent' => array(
  54. 'default_hook' => 'mycomponent_defaults',
  55. 'default_file' => FEATURES_DEFAULTS_INCLUDED,
  56. 'feature_source' => TRUE,
  57. 'file' => drupal_get_path('module', 'mycomponent') . '/mycomponent.features.inc',
  58. ),
  59. );
  60. }
  61. /**
  62. * Component hook. The hook should be implemented using the name of the
  63. * component, not the module, eg. [component]_features_export() rather than
  64. * [module]_features_export().
  65. *
  66. * Process the export array for a given component. Implementations of this hook
  67. * have three key tasks:
  68. *
  69. * 1. Determine module dependencies for any of the components passed to it
  70. * e.g. the views implementation iterates over each views' handlers and
  71. * plugins to determine which modules need to be added as dependencies.
  72. *
  73. * 2. Correctly add components to the export array. In general this is usually
  74. * adding all of the items in $data to $export['features']['my_key'], but
  75. * can become more complicated if components are shared between features
  76. * or modules.
  77. *
  78. * 3. Delegating further detection and export tasks to related or derivative
  79. * components.
  80. *
  81. * Each export processor can kickoff further export processors by returning a
  82. * keyed array (aka the "pipe") where the key is the next export processor hook
  83. * to call and the value is an array to be passed to that processor's $data
  84. * argument. This allows an export process to start simply at a few objects:
  85. *
  86. * [context]
  87. *
  88. * And then branch out, delegating each component to its appropriate hook:
  89. *
  90. * [context]--------+------------+
  91. * | | |
  92. * [node] [block] [views]
  93. * |
  94. * [CCK]
  95. * |
  96. * [imagecache]
  97. *
  98. * @param array $data
  99. * An array of machine names for the component in question to be exported.
  100. * @param array &$export
  101. * By reference. An array of all components to be exported with a given
  102. * feature. Component objects that should be exported should be added to
  103. * this array.
  104. * @param string $module_name
  105. * The name of the feature module to be generated.
  106. * @return array
  107. * The pipe array of further processors that should be called.
  108. */
  109. function hook_features_export($data, &$export, $module_name) {
  110. // The following is the simplest implementation of a straight object export
  111. // with no further export processors called.
  112. foreach ($data as $component) {
  113. $export['features']['mycomponent'][$component] = $component;
  114. }
  115. return array();
  116. }
  117. /**
  118. * Component hook. The hook should be implemented using the name of the
  119. * component, not the module, eg. [component]_features_export() rather than
  120. * [module]_features_export().
  121. *
  122. * List all objects for a component that may be exported.
  123. *
  124. * @return array
  125. * A keyed array of items, suitable for use with a FormAPI select or
  126. * checkboxes element.
  127. */
  128. function hook_features_export_options() {
  129. $options = array();
  130. foreach (mycomponent_load() as $mycomponent) {
  131. $options[$mycomponent->name] = $mycomponent->title;
  132. }
  133. return $options;
  134. }
  135. /**
  136. * Component hook. The hook should be implemented using the name of the
  137. * component, not the module, eg. [component]_features_export() rather than
  138. * [module]_features_export().
  139. *
  140. * Render one or more component objects to code.
  141. *
  142. * @param string $module_name
  143. * The name of the feature module to be exported.
  144. * @param array $data
  145. * An array of machine name identifiers for the objects to be rendered.
  146. * @param array $export
  147. * The full export array of the current feature being exported. This is only
  148. * passed when hook_features_export_render() is invoked for an actual feature
  149. * update or recreate, not during state checks or other operations.
  150. * @return array
  151. * An associative array of rendered PHP code where the key is the name of the
  152. * hook that should wrap the PHP code. The hook should not include the name
  153. * of the module, e.g. the key for `hook_example` should simply be `example`
  154. * The values in the array can also be in the form of an associative array
  155. * with the required key of 'code' and optional key of 'args', if 'args' need
  156. * to be added to the hook. Alternate it can be an associative array in the
  157. * same style as hook_features_export_files() to add additional files.
  158. */
  159. function hook_features_export_render($module_name, $data, $export = NULL) {
  160. $code = array();
  161. $code[] = '$mycomponents = array();';
  162. foreach ($data as $name) {
  163. $code[] = " \$mycomponents['{$name}'] = " . features_var_export(mycomponent_load($name)) .";";
  164. }
  165. $code[] = "return \$mycomponents;";
  166. $code = implode("\n", $code);
  167. return array('mycomponent_defaults' => $code);
  168. }
  169. /**
  170. * Component hook. The hook should be implemented using the name of the
  171. * component, not the module, eg. [component]_features_export() rather than
  172. * [module]_features_export().
  173. *
  174. * Revert all component objects for a given feature module.
  175. *
  176. * @param string $module_name
  177. * The name of the feature module whose components should be reverted.
  178. * @return boolean
  179. * TRUE or FALSE for whether the components were successfully reverted.
  180. * NOTE: This return value is no longer used in the latest Features so
  181. * modules should no longer count on this value
  182. */
  183. function hook_features_revert($module_name) {
  184. $mycomponents = module_invoke($module_name, 'mycomponent_defaults');
  185. if (!empty($mycomponents)) {
  186. foreach ($mycomponents as $mycomponent) {
  187. mycomponent_delete($mycomponent);
  188. }
  189. }
  190. }
  191. /**
  192. * Component hook. The hook should be implemented using the name of the
  193. * component, not the module, eg. [component]_features_export() rather than
  194. * [module]_features_export().
  195. *
  196. * Rebuild all component objects for a given feature module. Should only be
  197. * implemented for 'faux-exportable' components.
  198. *
  199. * This hook is called at points where Features determines that it is safe
  200. * (ie. the feature is in state `FEATURES_REBUILDABLE`) for your module to
  201. * replace objects in the database with defaults that you collect from your
  202. * own defaults hook. See API.txt for how Features determines whether a
  203. * rebuild of components is possible.
  204. *
  205. * @param string $module_name
  206. * The name of the feature module whose components should be rebuilt.
  207. */
  208. function hook_features_rebuild($module_name) {
  209. $mycomponents = module_invoke($module_name, 'mycomponent_defaults');
  210. if (!empty($mycomponents)) {
  211. foreach ($mycomponents as $mycomponent) {
  212. mycomponent_save($mycomponent);
  213. }
  214. }
  215. }
  216. /**
  217. * Invoked before a restore operation is run.
  218. *
  219. * This hook is called before any of the restore operations on the components is
  220. * run.
  221. *
  222. * @param string $op
  223. * The operation that is triggered: revert, rebuild, disable, enable
  224. * @param array $items
  225. * The items handled by the operation.
  226. */
  227. function hook_features_pre_restore($op, $items) {
  228. if ($op == 'rebuild') {
  229. // Use features rebuild to rebuild the features independent exports too.
  230. entity_defaults_rebuild();
  231. }
  232. }
  233. /**
  234. * Invoked after a restore operation is run.
  235. *
  236. * This hook is called after any of the restore operations on the components is
  237. * run.
  238. *
  239. * @param string $op
  240. * The operation that is triggered: revert, rebuild, disable, enable
  241. * @param array $items
  242. * The items handled by the operation.
  243. */
  244. function hook_features_post_restore($op, $items) {
  245. if ($op == 'rebuild') {
  246. // Use features rebuild to rebuild the features independent exports too.
  247. entity_defaults_rebuild();
  248. }
  249. }
  250. /**
  251. * Alter the final array of Component names to be exported, just prior to
  252. * the rendering of defaults. Allows modules a final say in whether or not
  253. * certain Components are exported (the Components' actual data, however,
  254. * cannot be altered by this hook).
  255. *
  256. * @param array &$export
  257. * By reference. An array of all component names to be exported with a given
  258. * feature.
  259. * @param array $module_name
  260. * The name of the feature module to be generated.
  261. */
  262. function hook_features_export_alter(&$export, $module_name) {
  263. // Example: do not allow the page content type to be exported, ever.
  264. if (!empty($export['features']['node']['page'])) {
  265. unset($export['features']['node']['page']);
  266. }
  267. }
  268. /**
  269. * Alter the pipe array for a given component. This hook should be implemented
  270. * with the name of the component type in place of `component` in the function
  271. * name, e.g. `features_pipe_views_alter()` will alter the pipe for the Views
  272. * component.
  273. *
  274. * @param array &$pipe
  275. * By reference. The pipe array of further processors that should be called.
  276. * @param array $data
  277. * An array of machine names for the component in question to be exported.
  278. * @param array &$export
  279. * By reference. An array of all components to be exported with a given
  280. * feature.
  281. */
  282. function hook_features_pipe_COMPONENT_alter(&$pipe, $data, $export) {
  283. if (in_array($data, 'my-node-type')) {
  284. $pipe['dependencies'][] = 'mymodule';
  285. }
  286. }
  287. /**
  288. * Alter the pipe array for a given component.
  289. *
  290. * @param array &$pipe
  291. * By reference. The pipe array of further processors that should be called.
  292. * @param array $data
  293. * An array of machine names for the component in question to be exported.
  294. * @param array &$export
  295. * By reference. An array of all components to be exported with a given
  296. * feature.
  297. *
  298. * The component being exported is contained in $export['component'].
  299. * The module being exported contained in $export['module_name'].
  300. */
  301. function hook_features_pipe_alter(&$pipe, $data, $export) {
  302. if ($export['component'] == 'node' && in_array('my-node-type', $data)) {
  303. $pipe['dependencies'][] = 'mymodule';
  304. }
  305. }
  306. /**
  307. * Add extra files to the exported file.
  308. *
  309. * @return array
  310. * An array of files, keyed by file name that will appear in feature and
  311. * with either file_path key to indicate where to copy the file from or
  312. * file_content key to indicate the contents of the file.
  313. */
  314. function hook_features_export_files($module_name, $export) {
  315. return array('css/main.css' => array('file_content' => 'body {background-color:blue;}'));
  316. }
  317. /**
  318. * Alter the extra files added to the export.
  319. */
  320. function hook_features_export_files_alter(&$files, $module_name, $export) {
  321. $files['css/main.css']['file_content'] = 'body {background-color:black;}';
  322. }
  323. /**
  324. * @defgroup features_component_alter_hooks Feature's component alter hooks
  325. * @{
  326. * Hooks to modify components defined by other features. These come in the form
  327. * hook_COMPONENT_alter where COMPONENT is the default_hook declared by any of
  328. * components within features.
  329. *
  330. * CTools also has a variety of hook_FOO_alters.
  331. *
  332. * Note: While views is a component of features, it declares it's own alter
  333. * function which takes a similar form:
  334. * hook_views_default_views_alter(&$views)
  335. */
  336. /**
  337. * Deprecated as of 7.x-2.0.
  338. *
  339. * Alter the default fields right before they are cached into the database.
  340. *
  341. * @param &$fields
  342. * By reference. The fields that have been declared by another feature.
  343. */
  344. function hook_field_default_fields_alter(&$fields) {
  345. }
  346. /**
  347. * Alter the base fields right before they are cached into the database.
  348. *
  349. * @param &$fields
  350. * By reference. The fields that have been declared by another feature.
  351. */
  352. function hook_field_default_field_bases_alter(&$fields) {
  353. }
  354. /**
  355. * Alter the field instances right before they are cached into the database.
  356. *
  357. * @param &$fields
  358. * By reference. The fields that have been declared by another feature.
  359. */
  360. function hook_field_default_field_instances_alter(&$fields) {
  361. }
  362. /**
  363. * Alter the default fieldgroup groups right before they are cached into the
  364. * database.
  365. *
  366. * @param &$groups
  367. * By reference. The fieldgroup groups that have been declared by another
  368. * feature.
  369. */
  370. function hook_fieldgroup_default_groups_alter(&$groups) {
  371. }
  372. /**
  373. * Alter the default filter formats right before they are cached into the
  374. * database.
  375. *
  376. * @param &$formats
  377. * By reference. The formats that have been declared by another feature.
  378. */
  379. function hook_filter_default_formats_alter(&$formats) {
  380. }
  381. /**
  382. * Alter the default menus right before they are cached into the database.
  383. *
  384. * @param &$menus
  385. * By reference. The menus that have been declared by another feature.
  386. */
  387. function hook_menu_default_menu_custom_alter(&$menus) {
  388. }
  389. /**
  390. * Alter the default menu links right before they are cached into the database.
  391. *
  392. * @param &$links
  393. * By reference. The menu links that have been declared by another feature.
  394. */
  395. function hook_menu_default_menu_links_alter(&$links) {
  396. }
  397. /**
  398. * Alter the default menu items right before they are cached into the database.
  399. *
  400. * @param &$items
  401. * By reference. The menu items that have been declared by another feature.
  402. */
  403. function hook_menu_default_items_alter(&$items) {
  404. }
  405. /**
  406. * Alter the default vocabularies right before they are cached into the
  407. * database.
  408. *
  409. * @param &$vocabularies
  410. * By reference. The vocabularies that have been declared by another feature.
  411. */
  412. function hook_taxonomy_default_vocabularies_alter(&$vocabularies) {
  413. }
  414. /**
  415. * Alter the default permissions right before they are cached into the
  416. * database.
  417. *
  418. * @param &$permissions
  419. * By reference. The permissions that have been declared by another feature.
  420. */
  421. function hook_user_default_permissions_alter(&$permissions) {
  422. }
  423. /**
  424. * Alter the default roles right before they are cached into the database.
  425. *
  426. * @param &$roles
  427. * By reference. The roles that have been declared by another feature.
  428. */
  429. function hook_user_default_roles_alter(&$roles) {
  430. }
  431. /**
  432. * @}
  433. */
  434. /**
  435. * @defgroup features_module_hooks Feature module hooks
  436. * @{
  437. * Hooks invoked on Feature modules when that module is enabled, disabled,
  438. * rebuilt, or reverted. These are ONLY invoked on the Features module on
  439. * which these actions are taken.
  440. */
  441. /**
  442. * Feature module hook. Invoked on a Feature module before that module is
  443. * reverted.
  444. *
  445. * @param $component
  446. * String name of the component that is about to be reverted.
  447. */
  448. function hook_pre_features_revert($component) {
  449. }
  450. /**
  451. * Feature module hook. Invoked on a Feature module after that module is
  452. * reverted.
  453. *
  454. * @param $component
  455. * String name of the component that has just been reverted.
  456. */
  457. function hook_post_features_revert($component) {
  458. }
  459. /**
  460. * Feature module hook. Invoked on a Feature module before that module is
  461. * rebuilt.
  462. *
  463. * @param $component
  464. * String name of the component that is about to be rebuilt.
  465. */
  466. function hook_pre_features_rebuild($component) {
  467. }
  468. /**
  469. * Feature module hook. Invoked on a Feature module after that module is
  470. * rebuilt.
  471. *
  472. * @param $component
  473. * String name of the component that has just been rebuilt.
  474. */
  475. function hook_post_features_rebuild($component) {
  476. }
  477. /**
  478. * Feature module hook. Invoked on a Feature module before that module is
  479. * disabled.
  480. *
  481. * @param $component
  482. * String name of the component that is about to be disabled.
  483. */
  484. function hook_pre_features_disable_feature($component) {
  485. }
  486. /**
  487. * Feature module hook. Invoked on a Feature module after that module is
  488. * disabled.
  489. *
  490. * @param $component
  491. * String name of the component that has just been disabled.
  492. */
  493. function hook_post_features_disable_feature($component) {
  494. }
  495. /**
  496. * Feature module hook. Invoked on a Feature module before that module is
  497. * enabled.
  498. *
  499. * @param $component
  500. * String name of the component that is about to be enabled.
  501. */
  502. function hook_pre_features_enable_feature($component) {
  503. }
  504. /**
  505. * Feature module hook. Invoked on a Feature module after that module is
  506. * enabled.
  507. *
  508. * @param $component
  509. * String name of the component that has just been enabled.
  510. */
  511. function hook_post_features_enable_feature($component) {
  512. }
  513. /**
  514. * @}
  515. */