comparison sites/all/modules/features/includes/features.ctools.inc @ 4:ce11bbd8f642

added modules
author danieleb <danielebarchiesi@me.com>
date Thu, 19 Sep 2013 10:38:44 +0100
parents
children
comparison
equal deleted inserted replaced
3:b28be78d8160 4:ce11bbd8f642
1 <?php
2
3 function ctools_features_declare_functions($reset = FALSE) {
4 /**
5 * This is called by Features to ensure ctools component functions are defined
6 * Dynamically declare functions under a ctools component's namespace if they are not already declared.
7 */
8 if (function_exists('_ctools_features_get_info')) {
9 foreach (_ctools_features_get_info(NULL, $reset) as $component => $info) {
10 $code = '';
11 if (!function_exists("{$info['module']}_features_api")) {
12 $code .= 'function '. $info['module'] .'_features_api() { return ctools_component_features_api("'. $info['module'] .'"); }';
13 }
14
15 // ctools component with owner defined as "ctools"
16 if (!function_exists("{$component}_features_api") && $info['module'] === 'ctools') {
17 $code .= 'function '. $component .'_features_api() { return ctools_component_features_api("'. $component .'"); }';
18 }
19
20 if (!function_exists("{$component}_features_export")) {
21 $code .= 'function '. $component .'_features_export($data, &$export, $module_name = "") { return ctools_component_features_export("'. $component .'", $data, $export, $module_name); }';
22 }
23 if (!function_exists("{$component}_features_export_options")) {
24 $code .= 'function '. $component .'_features_export_options() { return ctools_component_features_export_options("'. $component .'"); }';
25 }
26 if (!function_exists("{$component}_features_export_render")) {
27 $code .= 'function '. $component .'_features_export_render($module, $data, $export = NULL) { return ctools_component_features_export_render("'. $component .'", $module, $data, $export); }';
28 }
29 if (!function_exists("{$component}_features_revert")) {
30 $code .= 'function '. $component .'_features_revert($module) { return ctools_component_features_revert("'. $component .'", $module); }';
31 }
32 eval($code);
33 }
34 }
35 }
36
37 /**
38 * Implements hook_features_api().
39 */
40 function ctools_features_api() {
41 return array(
42 'ctools' => array(
43 'name' => 'CTools export API',
44 'feature_source' => TRUE,
45 'duplicates' => FEATURES_DUPLICATES_ALLOWED,
46 // CTools API integration does not include a default hook declaration as
47 // it is not a proper default hook.
48 // 'default_hook' => 'ctools_plugin_api',
49 ),
50 );
51 }
52
53 /**
54 * Implements hook_features_export().
55 * Adds references to the ctools mothership hook, ctools_plugin_api().
56 */
57 function ctools_features_export($data, &$export, $module_name = '') {
58 // Add ctools dependency
59 $export['dependencies']['ctools'] = 'ctools';
60
61 // Add the actual ctools components which will need to be accounted for in
62 // hook_ctools_plugin_api(). The components are actually identified by a
63 // delimited list of values: `module_name:api:current_version`
64 foreach ($data as $component) {
65 if ($info = _ctools_features_get_info($component)) {
66 $identifier = "{$info['module']}:{$info['api']}:{$info['current_version']}";
67 $export['features']['ctools'][$identifier] = $identifier;
68 }
69 }
70
71 return array();
72 }
73
74 /**
75 * Implements hook_features_export_render().
76 * Adds the ctools mothership hook, ctools_plugin_api().
77 */
78 function ctools_features_export_render($module, $data) {
79 $component_exports = array();
80 foreach ($data as $component) {
81 $code = array();
82 if ($info = _ctools_features_get_info($component)) {
83 // For background on why we change the output for hook_views_api()
84 // see http://drupal.org/node/1459120.
85 if ($info['module'] == 'views') {
86 $code[] = ' return array("api" => "3.0");';
87 }
88 else {
89 $code[] = ' if ($module == "'. $info['module'] .'" && $api == "'. $info['api'] .'") {';
90 $code[] = ' return array("version" => "'. $info['current_version'] .'");';
91 $code[] = ' }';
92 }
93 }
94 ctools_include('plugins');
95 $plugin_api_hook_name = ctools_plugin_api_get_hook($info['module'], $info['api']);
96
97 if (key_exists($plugin_api_hook_name, $component_exports)) {
98 $component_exports[$plugin_api_hook_name]['code'] .= "\n" . implode("\n", $code);
99 }
100 else {
101 $component_exports[$plugin_api_hook_name] = array(
102 'code' => implode("\n", $code),
103 'args' => '$module = NULL, $api = NULL',
104 );
105 }
106 }
107
108 return $component_exports;
109
110 }
111
112 /**
113 * Master implementation of hook_features_api() for all ctools components.
114 *
115 * Note that this master hook does not use $component like the others, but uses the
116 * component module's namespace instead.
117 */
118 function ctools_component_features_api($module_name) {
119 $api = array();
120 foreach (_ctools_features_get_info() as $component => $info) {
121 // if module owner is set to "ctools" we need to compare the component
122 if ($info['module'] == $module_name || ($info['module'] === 'ctools' && $component == $module_name) ) {
123 $api[$component] = $info;
124 }
125 }
126 return $api;
127 }
128
129 /**
130 * Master implementation of hook_features_export_options() for all ctools components.
131 */
132 function ctools_component_features_export_options($component) {
133 $options = array();
134
135 ctools_include('export');
136 $schema = ctools_export_get_schema($component);
137 if ($schema && $schema['export']['bulk export']) {
138 if (!empty($schema['export']['list callback']) && function_exists($schema['export']['list callback'])) {
139 $options = $schema['export']['list callback']();
140 }
141 else {
142 $options = _ctools_features_export_default_list($component, $schema);
143 }
144 }
145 asort($options);
146 return $options;
147 }
148
149 /**
150 * Master implementation of hook_features_export() for all ctools components.
151 */
152 function ctools_component_features_export($component, $data, &$export, $module_name = '') {
153 // Add the actual implementing module as a dependency
154 $info = _ctools_features_get_info();
155 if ($module_name !== $info[$component]['module']) {
156 $export['dependencies'][$info[$component]['module']] = $info[$component]['module'];
157 }
158
159 // Add the components
160 foreach ($data as $object_name) {
161 if ($object = _ctools_features_export_crud_load($component, $object_name)) {
162 // If this object is provided as a default by a different module, don't
163 // export and add that module as a dependency instead.
164 if (!empty($object->export_module) && $object->export_module !== $module_name) {
165 $export['dependencies'][$object->export_module] = $object->export_module;
166 if (isset($export['features'][$component][$object_name])) {
167 unset($export['features'][$component][$object_name]);
168 }
169 }
170 // Otherwise, add the component.
171 else {
172 $export['features'][$component][$object_name] = $object_name;
173 }
174 }
175 }
176
177 // Let CTools handle API integration for this component.
178 return array('ctools' => array($component));
179 }
180
181 /**
182 * Master implementation of hook_features_export_render() for all ctools components.
183 */
184 function ctools_component_features_export_render($component, $module, $data) {
185 // Reset the export display static to prevent clashes.
186 drupal_static_reset('panels_export_display');
187
188 ctools_include('export');
189 $schema = ctools_export_get_schema($component);
190
191 if (function_exists($schema['export']['to hook code callback'])) {
192 $export = $schema['export']['to hook code callback']($data, $module);
193 $code = explode("{\n", $export);
194 array_shift($code);
195 $code = explode('}', implode($code, "{\n"));
196 array_pop($code);
197 $code = implode('}', $code);
198 }
199 else {
200 $code = ' $export = array();'."\n\n";
201 foreach ($data as $object_name) {
202 if ($object = _ctools_features_export_crud_load($component, $object_name)) {
203 $identifier = $schema['export']['identifier'];
204 $code .= _ctools_features_export_crud_export($component, $object, ' ');
205 $code .= " \$export[" . ctools_var_export($object_name) . "] = \${$identifier};\n\n";
206 }
207 }
208 $code .= ' return $export;';
209 }
210
211 return array($schema['export']['default hook'] => $code);
212 }
213
214 /**
215 * Master implementation of hook_features_revert() for all ctools components.
216 */
217 function ctools_component_features_revert($component, $module) {
218 if ($objects = features_get_default($component, $module)) {
219 foreach ($objects as $name => $object) {
220 // Some things (like views) do not use the machine name as key
221 // and need to be loaded explicitly in order to be deleted.
222 $object = ctools_export_crud_load($component, $name);
223 if ($object && ($object->export_type & EXPORT_IN_DATABASE)) {
224 _ctools_features_export_crud_delete($component, $object);
225 }
226 }
227 }
228 }
229
230 /**
231 * Helper function to return various ctools information for components.
232 */
233 function _ctools_features_get_info($identifier = NULL, $reset = FALSE) {
234 static $components;
235 if (!isset($components) || $reset) {
236 $components = array();
237 $modules = features_get_info();
238 ctools_include('export');
239 drupal_static('ctools_export_get_schemas', NULL, $reset);
240 foreach (ctools_export_get_schemas_by_module() as $module => $schemas) {
241 foreach ($schemas as $table => $schema) {
242 if ($schema['export']['bulk export']) {
243 // Let the API owner take precedence as the owning module.
244 $api_module = isset($schema['export']['api']['owner']) ? $schema['export']['api']['owner'] : $module;
245 $components[$table] = array(
246 'name' => isset($modules[$api_module]->info['name']) ? $modules[$api_module]->info['name'] : $api_module,
247 'default_hook' => $schema['export']['default hook'],
248 'default_file' => FEATURES_DEFAULTS_CUSTOM,
249 'module' => $api_module,
250 'feature_source' => TRUE,
251 );
252 if (isset($schema['export']['api'])) {
253 $components[$table] += array(
254 'api' => $schema['export']['api']['api'],
255 'default_filename' => $schema['export']['api']['api'],
256 'current_version' => $schema['export']['api']['current_version'],
257 );
258 }
259 }
260 }
261 }
262 }
263
264 // Return information specific to a particular component.
265 if (isset($identifier)) {
266 // Identified by the table name.
267 if (isset($components[$identifier])) {
268 return $components[$identifier];
269 }
270 // New API identifier. Allows non-exportables related CTools APIs to be
271 // supported by an explicit `module:api:current_version` key.
272 else if (substr_count($identifier, ':') === 2) {
273 list($module, $api, $current_version) = explode(':', $identifier);
274 // If a schema component matches the provided identifier, provide that
275 // information. This also ensures that the version number is up to date.
276 foreach ($components as $table => $info) {
277 if ($info['module'] == $module && $info['api'] == $api && $info['current_version'] >= $current_version) {
278 return $info;
279 }
280 }
281 // Fallback to just giving back what was provided to us.
282 return array('module' => $module, 'api' => $api, 'current_version' => $current_version);
283 }
284 return FALSE;
285 }
286
287 return $components;
288 }
289
290 /**
291 * Wrapper around ctools_export_crud_export() for < 1.7 compatibility.
292 */
293 function _ctools_features_export_crud_export($table, $object, $indent = '') {
294 return ctools_api_version('1.7') ? ctools_export_crud_export($table, $object, $indent) : ctools_export_object($table, $object, $indent);
295 }
296
297 /**
298 * Wrapper around ctools_export_crud_load() for < 1.7 compatibility.
299 */
300 function _ctools_features_export_crud_load($table, $name) {
301 if (ctools_api_version('1.7')) {
302 return ctools_export_crud_load($table, $name);
303 }
304 elseif ($objects = ctools_export_load_object($table, 'names', array($name))) {
305 return array_shift($objects);
306 }
307 return FALSE;
308 }
309
310 /**
311 * Wrapper around ctools_export_default_list() for < 1.7 compatibility.
312 */
313 function _ctools_features_export_default_list($table, $schema) {
314 if (ctools_api_version('1.7')) {
315 return ctools_export_default_list($table, $schema);
316 }
317 elseif ($objects = ctools_export_load_object($table, 'all')) {
318 return drupal_map_assoc(array_keys($objects));
319 }
320 return array();
321 }
322
323 /**
324 * Wrapper around ctools_export_crud_delete() for < 1.7 compatibility.
325 */
326 function _ctools_features_export_crud_delete($table, $object) {
327 if (ctools_api_version('1.7')) {
328 ctools_export_crud_delete($table, $object);
329 }
330 else {
331 $schema = ctools_export_get_schema($table);
332 $export = $schema['export'];
333 db_query("DELETE FROM {{$table}} WHERE {$export['key']} = '%s'", $object->{$export['key']});
334 }
335 }
336
337 /**
338 * Implements hook_features_export_render() for page_manager.
339 */
340 function page_manager_pages_features_export_render($module, $data) {
341 // Reset the export display static to prevent clashes.
342 drupal_static_reset('panels_export_display');
343
344 // Ensure that handlers have their code included before exporting.
345 page_manager_get_tasks();
346 return ctools_component_features_export_render('page_manager_pages', $module, $data);
347 }
348
349 /**
350 * Implements hook_features_revert() for page_manager.
351 */
352 function page_manager_pages_features_revert($module) {
353 if ($pages = features_get_default('page_manager_pages', $module)) {
354 require_once drupal_get_path('module', 'ctools') . '/page_manager/plugins/tasks/page.inc';
355 foreach ($pages as $page) {
356 page_manager_page_delete($page);
357 }
358 }
359 }
360
361 /**
362 * Implements hook_features_pipe_COMPONENT_alter() for views_view.
363 */
364 function views_features_pipe_views_view_alter(&$pipe, $data, $export) {
365 // @todo Remove this check before next stable release.
366 if (!function_exists('views_plugin_list')) {
367 return;
368 }
369
370 $map = array_flip($data);
371 foreach (views_plugin_list() as $plugin) {
372 foreach ($plugin['views'] as $view_name) {
373 if (isset($map[$view_name])) {
374 $pipe['dependencies'][$plugin['module']] = $plugin['module'];
375 }
376 }
377 }
378 }