features_override.features.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. /**
  3. * @file
  4. * Page callback for features override pages.
  5. */
  6. module_load_include('inc', 'features_override', 'features_override.export');
  7. /**
  8. * Implements hook_features_export_options().
  9. */
  10. function features_override_items_features_export_options() {
  11. $options = $links = array();
  12. $overrides = features_override_get_overrides();
  13. foreach ($overrides as $component => $elements) {
  14. foreach ($elements as $key => $element) {
  15. $options["{$component}.{$key}"] = "{$component} {$key} ";
  16. }
  17. }
  18. return $options;
  19. }
  20. /**
  21. * Implements hook_features_export_options().
  22. */
  23. function features_overrides_features_export_options() {
  24. $options = $sub_links = $main_links = array();
  25. drupal_add_js(drupal_get_path('module', 'features_override') . '/features_override_form.js');
  26. drupal_add_css(drupal_get_path('module', 'features_override') . '/features_override.css');
  27. $overrides = features_override_get_overrides();
  28. foreach ($overrides as $component => $elements) {
  29. foreach ($elements as $key => $element) {
  30. $identifier = "{$component}.{$key}";
  31. $identifier_spaced = "{$component} {$key} ";
  32. $main_links[features_override_encode_string($identifier)] = url('admin/structure/features/features_override/' . $component . '/' . $key);
  33. if (!empty($element['additions'])) {
  34. foreach ($element['additions'] as $change_key => $changes) {
  35. $options[$identifier . '.' . $change_key] = $identifier_spaced . ' addition: of ' . features_override_export_keys($changes['keys']);
  36. $sub_links[features_override_encode_string($identifier . '.' . $change_key)] = url('admin/structure/features/features_override/' . $component . '/' . $key, array('query' => array('key' => $change_key)));
  37. }
  38. }
  39. if (!empty($element['deletions'])) {
  40. foreach ($element['deletions'] as $change_key => $changes) {
  41. $options[$identifier . '.' . $change_key] = $identifier_spaced . ' deletion of ' . features_override_export_keys($changes['keys']);
  42. $sub_links[features_override_encode_string($identifier . '.' . $change_key)] = url('admin/structure/features/features_override/' . $component . '/' . $key, array('query' => array('key' => $change_key)));
  43. }
  44. }
  45. }
  46. }
  47. drupal_add_js(array('features_override_links' => array('main' => $main_links, 'sub' => $sub_links)), 'setting');
  48. return $options;
  49. }
  50. /**
  51. * Implements hook_features_export().
  52. */
  53. function features_override_items_features_export($data, &$export, $module_name = '') {
  54. $pipe = array('features_overrides' => array());
  55. $map = features_get_default_map('features_override_items');
  56. $map_overrides = features_get_default_map('features_overrides');
  57. static $options;
  58. if (!isset($options)) {
  59. $options = features_overrides_features_export_options();
  60. }
  61. foreach ($data as $identifier) {
  62. // If this override bundle is already provided by another module, remove the field
  63. // and add the other module as a dependency.
  64. if (isset($map[$identifier]) && $map[$identifier] != $module_name) {
  65. if (isset($export['features']['features_override_items'][$identifier])) {
  66. unset($export['features']['features_override_items'][$identifier]);
  67. }
  68. $module = $map[$identifier];
  69. $export['dependencies'][$module] = $module;
  70. }
  71. // If the field has not yet been exported, add it
  72. else {
  73. $export['features']['features_override_items'][$identifier] = $identifier;
  74. list($component, $element) = features_override_parse_identifier($identifier);
  75. // Add in all current overrides to import.
  76. foreach ($options as $option_key => $option_name) {
  77. list($options_component, $options_element, $options_keys) = features_override_parse_identifier($option_key);
  78. if ($options_element == $element && empty($map_overrides[$option_key])) {
  79. $pipe['features_overrides'][] = $option_key;
  80. }
  81. }
  82. // Add in depedency to module that defines this item.
  83. $component_map = features_get_default_map($component);
  84. if (!empty($component_map[$element])) {
  85. $export['dependencies'][$component_map[$element]] = $component_map[$element];
  86. }
  87. }
  88. }
  89. return $pipe;
  90. }
  91. /**
  92. * Implements hook_features_export().
  93. */
  94. function features_overrides_features_export($data, &$export, $module_name = '') {
  95. $pipe = array('features_overrides' => array());
  96. $map = features_get_default_map('features_overrides');
  97. static $options;
  98. foreach ($data as $identifier) {
  99. // If this override bundle is already provided by another module, remove the field
  100. // and add the other module as a dependency.
  101. if (isset($map[$identifier]) && $map[$identifier] != $module_name) {
  102. if (isset($export['features']['features_overrides'][$identifier])) {
  103. unset($export['features']['features_overrides'][$identifier]);
  104. }
  105. $module = $map[$identifier];
  106. $export['dependencies'][$module] = $module;
  107. }
  108. // If the field has not yet been exported, add it
  109. else {
  110. $export['features']['features_overrides'][$identifier] = $identifier;
  111. }
  112. }
  113. return $pipe;
  114. }
  115. /**
  116. * Implements hook_features_export_render().
  117. */
  118. function features_override_items_features_export_render($module, $data, $export = NULL) {
  119. // no code is needed for this exportable. Details are stored via features_overrides_features_export_render
  120. $list = array();
  121. /*
  122. // Go through all data collecting the items exports to create.
  123. $features_override_code = array(
  124. ' // This code is only used to work nicely with features UI.',
  125. ' $overrides = array();',
  126. );
  127. foreach ($data as $identifier) {
  128. $features_override_code[] = '';
  129. $features_override_code[] = " // Exported overrides for: $identifier";
  130. $features_override_code[] = ' $overrides[' . features_var_export($identifier) . '] = 1;';
  131. }
  132. // Create the default hook that defines all exported overrides.
  133. $features_override_code[] = '';
  134. $features_override_code[] = ' return $overrides;';
  135. $list['features_override_default_items'] = implode("\n", $features_override_code);
  136. */
  137. return $list;
  138. }
  139. /**
  140. * Implements hook_features_export_render().
  141. */
  142. function features_overrides_features_export_render($module, $data, $export = NULL) {
  143. // Remember, the code exported here is just for the Features UI to keep track
  144. // of the overridden status. All it needs to do is capture "changes".
  145. // The actual form of the output doesn't really matter.
  146. $list = $overrides_to_export = array();
  147. // Go through all data collecting the items exports to create.
  148. $features_override_code = array(
  149. ' // This code is only used for UI in features. Exported alters hooks do the magic.',
  150. ' $overrides = array();',
  151. );
  152. $last_component = '';
  153. foreach ($data as $identifier) {
  154. // Something is adding extra quote marks.
  155. list($component, $element, $keys) = features_override_parse_identifier($identifier);
  156. $component_code[$component] = isset($component_code[$component]) ? $component_code[$component] : array();
  157. $overrides_to_export[$component] = isset($overrides_to_export[$component]) ? $overrides_to_export[$component] : array();
  158. $overrides = features_override_get_overrides($component);
  159. $features_override_value = array(
  160. 'additions' => array(),
  161. 'deletions' => array()
  162. );
  163. // Just specific keys are being exported so add them if set.
  164. if (!empty($overrides[$element])) {
  165. if (isset($overrides[$element]['additions'][$keys])) {
  166. $overrides_to_export[$component][$element]['additions'][] = $overrides[$element]['additions'][$keys];
  167. $features_override_value['additions'][] = $overrides[$element]['additions'][$keys];
  168. }
  169. elseif (isset($overrides[$element]['deletions'][$keys])) {
  170. $overrides_to_export[$component][$element]['deletions'][] = $overrides[$element]['deletions'][$keys];
  171. $features_override_value['deletions'][] = $overrides[$element]['deletions'][$keys];
  172. }
  173. }
  174. if ($component != $last_component) {
  175. $features_override_code[] = '';
  176. $features_override_code[] = " // Exported overrides for: $component";
  177. }
  178. $last_component = $component;
  179. if (count($features_override_value['additions'])) {
  180. $features_override_code[] = ' $overrides["' . $identifier . '"] = ' . features_override_var_export($features_override_value['additions'][0]['value'], ' ') . ';';
  181. }
  182. else if (count($features_override_value['deletions'])) {
  183. $features_override_code[] = ' $overrides["' . $identifier . '"]["DELETED"] = TRUE;';
  184. }
  185. }
  186. // Create the default hook that defines all exported overrides.
  187. $features_override_code[] = '';
  188. $features_override_code[] = ' return $overrides;';
  189. $list['features_override_default_overrides'] = implode("\n", $features_override_code);
  190. $component_code = array();
  191. foreach ($overrides_to_export as $component => $elements) {
  192. foreach ($elements as $element => $overrides) {
  193. $component_code[$component] = isset($component_code[$component]) ? $component_code[$component] : array();
  194. $component_code[$component][] = ' if (isset($data[' . var_export($element,TRUE) . '])) {';
  195. if (!empty($overrides['additions'])) {
  196. foreach ($overrides['additions'] as $alter) {
  197. $component_code[$component][] = implode("\n", features_override_features_export_render_addition($alter, $element, $component));
  198. }
  199. }
  200. if (!empty($overrides['deletions'])) {
  201. foreach ($overrides['deletions'] as $alter) {
  202. $component_code[$component][] = implode("\n", features_override_features_export_render_deletion($alter, $element, $component));
  203. }
  204. }
  205. $component_code[$component][] = ' }';
  206. }
  207. }
  208. $info = features_get_components();
  209. foreach ($component_code as $component => $code) {
  210. $list[features_get_default_alter_hook($component) . '_alter'] = array(
  211. 'code' => implode("\n", $code),
  212. 'args' => '&$data',
  213. 'file' => 'features',
  214. );
  215. }
  216. return $list;
  217. }
  218. /**
  219. * Implements hook_features_revert().
  220. */
  221. function features_override_items_features_revert($module) {
  222. features_override_items_features_rebuild($module);
  223. }
  224. /**
  225. * Implements of hook_features_rebuild().
  226. */
  227. function features_override_items_features_rebuild($module) {
  228. _features_override_features_rebuild($module, 'features_override_items');
  229. }
  230. /**
  231. * Implements hook_features_revert().
  232. */
  233. function features_overrides_features_revert($module) {
  234. features_overrides_features_rebuild($module);
  235. }
  236. /**
  237. * Implements of hook_features_rebuild().
  238. */
  239. function features_overrides_features_rebuild($module) {
  240. _features_override_features_rebuild($module, 'features_overrides');
  241. }
  242. /**
  243. * Rebuilds fields from code defaults.
  244. *
  245. * FIXME This is reverting everything that has a change instead of this module.
  246. */
  247. function _features_override_features_rebuild($module, $component_key = 'features_override_items') {
  248. // first build list of components we are overriding
  249. $parents = array();
  250. $data = features_get_component_map();
  251. foreach ($data[$component_key] as $identifier => $component_modules) {
  252. list($component, $element) = features_override_parse_identifier($identifier);
  253. if (isset($data[$component][$element])) {
  254. foreach ($data[$component][$element] as $module_name) {
  255. $parents[$module][$component] = $module_name;
  256. }
  257. }
  258. }
  259. // first, update get_default cache so rebuild will work on latest data
  260. foreach ($parents as $module => $element) {
  261. foreach ($element as $component) {
  262. features_get_default($component, $module, TRUE, TRUE);
  263. }
  264. }
  265. // rebuild those parent components
  266. //features_rebuild($parents);
  267. }