Mercurial > hg > rr-repo
comparison sites/all/modules/ctools/includes/export-ui.inc @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Provide a tool for creating UIs for exportable objects. | |
6 * | |
7 * See Advanced Help for documentation. | |
8 */ | |
9 | |
10 /** | |
11 * Process an export-ui plugin to provide it with defaults. | |
12 */ | |
13 function ctools_export_ui_process(&$plugin, $info) { | |
14 ctools_include('export'); | |
15 | |
16 $plugin += array( | |
17 'has menu' => TRUE, | |
18 'title' => $plugin['name'], | |
19 'export' => array(), | |
20 'allowed operations' => array(), | |
21 'menu' => array(), | |
22 'redirect' => array(), | |
23 'form' => array(), | |
24 'strings' => array(), | |
25 'list' => NULL, | |
26 'access' => 'administer site configuration', | |
27 ); | |
28 | |
29 // Provide CRUD access defaults based on the base 'access' setting: | |
30 $plugin += array( | |
31 'create access' => $plugin['access'], | |
32 'delete access' => $plugin['access'], | |
33 ); | |
34 | |
35 if (empty($plugin['has menu'])) { | |
36 return; | |
37 } | |
38 | |
39 // The following keys are required and the plugin cannot be processed | |
40 // without them. | |
41 $keys = array( | |
42 'title singular', | |
43 'title plural', | |
44 'title singular proper', | |
45 'title plural proper', | |
46 'schema', | |
47 ); | |
48 | |
49 foreach ($keys as $key) { | |
50 if (empty($plugin[$key])) { | |
51 drupal_set_message(t('The plugin definition of @plugin is missing the %key key.', array('%key' => $key, '@plugin' => $plugin['name'])), 'error'); | |
52 } | |
53 } | |
54 | |
55 // If we're on the modules page and building a menu, there is a design flaw | |
56 // in Drupal core that causes modules to be installed but the schema does | |
57 // not become available until AFTER menu rebuild. This helps smooth that | |
58 // out. This is a HACK but it should work: | |
59 $schema = ctools_export_get_schema($plugin['schema']); | |
60 | |
61 if (empty($schema)) { | |
62 // If we're updating the schema may not have been read yet, so don't report this error in that case. | |
63 if (!defined('MAINTENANCE_MODE')) { | |
64 drupal_set_message(t('The plugin definition of @plugin cannot locate schema %schema.', array('%schema' => $plugin['schema'], '@plugin' => $plugin['name'])), 'error'); | |
65 } | |
66 return; | |
67 } | |
68 | |
69 if (empty($schema['export'])) { | |
70 drupal_set_message(t('The plugin definition of @plugin uses %schema, but it has no export section.', array('%schema' => $plugin['schema'], '@plugin' => $plugin['name'])), 'error'); | |
71 return; | |
72 } | |
73 $plugin['export'] += $schema['export']; | |
74 | |
75 $plugin['export'] += array( | |
76 // Add the identifier key from the schema so we don't have to call | |
77 // ctools_export_get_schema() just for that. | |
78 'key' => $schema['export']['key'], | |
79 ); | |
80 | |
81 // Add some default fields that appear often in exports | |
82 // If these use different keys they can easily be specified in the | |
83 // $plugin. | |
84 | |
85 if (empty($plugin['export']['admin_title']) && !empty($schema['fields']['admin_title'])) { | |
86 $plugin['export']['admin_title'] = 'admin_title'; | |
87 } | |
88 if (empty($plugin['export']['admin_description']) && !empty($schema['fields']['admin_description'])) { | |
89 $plugin['export']['admin_description'] = 'admin_description'; | |
90 } | |
91 | |
92 // Define allowed operations, and the name of the operations. | |
93 $plugin['allowed operations'] += array( | |
94 'edit' => array('title' => t('Edit')), | |
95 'enable' => array('title' => t('Enable'), 'ajax' => TRUE, 'token' => TRUE), | |
96 'disable' => array('title' => t('Disable'), 'ajax' => TRUE, 'token' => TRUE), | |
97 'revert' => array('title' => t('Revert')), | |
98 'delete' => array('title' => t('Delete')), | |
99 'clone' => array('title' => t('Clone')), | |
100 'import' => array('title' => t('Import')), | |
101 'export' => array('title' => t('Export')), | |
102 ); | |
103 | |
104 $plugin['menu'] += array( | |
105 'menu item' => str_replace(' ', '-', $plugin['name']), | |
106 'menu prefix' => 'admin/structure', | |
107 'menu title' => $plugin['title'], | |
108 'menu description' => '', | |
109 ); | |
110 $base_path = ctools_export_ui_plugin_base_path($plugin); | |
111 $prefix_count = count(explode('/', $plugin['menu']['menu prefix'])); | |
112 | |
113 $plugin['menu'] += array( | |
114 // Default menu items that should be declared. | |
115 'items' => array(), | |
116 ); | |
117 | |
118 $plugin['menu']['items'] += array( | |
119 'list callback' => array(), | |
120 'list' => array(), | |
121 'add' => array(), | |
122 'edit callback' => array(), | |
123 'edit' => array(), | |
124 ); | |
125 | |
126 $plugin['menu']['items']['list callback'] += array( | |
127 'path' => '', | |
128 // Menu items are translated by the menu system. | |
129 // TODO: We need more flexibility in title. The title of the admin page | |
130 // is not necessarily the title of the object, plus we need | |
131 // plural, singular, proper, not proper, etc. | |
132 'title' => $plugin['menu']['menu title'], | |
133 'description' => $plugin['menu']['menu description'], | |
134 'page callback' => 'ctools_export_ui_switcher_page', | |
135 'page arguments' => array($plugin['name'], 'list'), | |
136 'access callback' => 'ctools_export_ui_task_access', | |
137 'access arguments' => array($plugin['name'], 'list'), | |
138 'type' => MENU_NORMAL_ITEM, | |
139 ); | |
140 | |
141 $plugin['menu']['items']['list'] += array( | |
142 'path' => 'list', | |
143 'title' => 'List', | |
144 'page callback' => 'ctools_export_ui_switcher_page', | |
145 'page arguments' => array($plugin['name'], 'list'), | |
146 'access callback' => 'ctools_export_ui_task_access', | |
147 'access arguments' => array($plugin['name'], 'list'), | |
148 'type' => MENU_DEFAULT_LOCAL_TASK, | |
149 'weight' => -10, | |
150 ); | |
151 | |
152 $plugin['menu']['items']['add'] += array( | |
153 'path' => 'add', | |
154 'title' => 'Add', | |
155 'page callback' => 'ctools_export_ui_switcher_page', | |
156 'page arguments' => array($plugin['name'], 'add'), | |
157 'access callback' => 'ctools_export_ui_task_access', | |
158 'access arguments' => array($plugin['name'], 'add'), | |
159 'type' => MENU_LOCAL_ACTION, | |
160 ); | |
161 | |
162 $plugin['menu']['items']['edit callback'] += array( | |
163 'path' => 'list/%ctools_export_ui', | |
164 'page callback' => 'ctools_export_ui_switcher_page', | |
165 'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2), | |
166 'load arguments' => array($plugin['name']), | |
167 'access callback' => 'ctools_export_ui_task_access', | |
168 'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2), | |
169 'type' => MENU_CALLBACK, | |
170 ); | |
171 | |
172 $plugin['menu']['items']['edit'] += array( | |
173 'path' => 'list/%ctools_export_ui/edit', | |
174 'title' => 'Edit', | |
175 'page callback' => 'ctools_export_ui_switcher_page', | |
176 'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2), | |
177 'load arguments' => array($plugin['name']), | |
178 'access callback' => 'ctools_export_ui_task_access', | |
179 'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2), | |
180 'type' => MENU_DEFAULT_LOCAL_TASK, | |
181 'weight' => -10, | |
182 ); | |
183 | |
184 if ($plugin['allowed operations']['import']) { | |
185 $plugin['menu']['items'] += array('import' => array()); | |
186 $plugin['menu']['items']['import'] += array( | |
187 'path' => 'import', | |
188 'title' => 'Import', | |
189 'page callback' => 'ctools_export_ui_switcher_page', | |
190 'page arguments' => array($plugin['name'], 'import'), | |
191 'access callback' => 'ctools_export_ui_task_access', | |
192 'access arguments' => array($plugin['name'], 'import'), | |
193 'type' => MENU_LOCAL_ACTION, | |
194 ); | |
195 } | |
196 | |
197 if ($plugin['allowed operations']['export']) { | |
198 $plugin['menu']['items'] += array('export' => array()); | |
199 $plugin['menu']['items']['export'] += array( | |
200 'path' => 'list/%ctools_export_ui/export', | |
201 'title' => 'Export', | |
202 'page callback' => 'ctools_export_ui_switcher_page', | |
203 'page arguments' => array($plugin['name'], 'export', $prefix_count + 2), | |
204 'load arguments' => array($plugin['name']), | |
205 'access callback' => 'ctools_export_ui_task_access', | |
206 'access arguments' => array($plugin['name'], 'export', $prefix_count + 2), | |
207 'type' => MENU_LOCAL_TASK, | |
208 ); | |
209 } | |
210 | |
211 if ($plugin['allowed operations']['revert']) { | |
212 $plugin['menu']['items'] += array('revert' => array()); | |
213 $plugin['menu']['items']['revert'] += array( | |
214 'path' => 'list/%ctools_export_ui/revert', | |
215 'title' => 'Revert', | |
216 'page callback' => 'ctools_export_ui_switcher_page', | |
217 // Note: Yes, 'delete' op is correct. | |
218 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2), | |
219 'load arguments' => array($plugin['name']), | |
220 'access callback' => 'ctools_export_ui_task_access', | |
221 'access arguments' => array($plugin['name'], 'revert', $prefix_count + 2), | |
222 'type' => MENU_CALLBACK, | |
223 ); | |
224 } | |
225 | |
226 if ($plugin['allowed operations']['delete']) { | |
227 $plugin['menu']['items'] += array('delete' => array()); | |
228 $plugin['menu']['items']['delete'] += array( | |
229 'path' => 'list/%ctools_export_ui/delete', | |
230 'title' => 'Delete', | |
231 'page callback' => 'ctools_export_ui_switcher_page', | |
232 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2), | |
233 'load arguments' => array($plugin['name']), | |
234 'access callback' => 'ctools_export_ui_task_access', | |
235 'access arguments' => array($plugin['name'], 'delete', $prefix_count + 2), | |
236 'type' => MENU_CALLBACK, | |
237 ); | |
238 } | |
239 | |
240 if ($plugin['allowed operations']['clone']) { | |
241 $plugin['menu']['items'] += array('clone' => array()); | |
242 $plugin['menu']['items']['clone'] += array( | |
243 'path' => 'list/%ctools_export_ui/clone', | |
244 'title' => 'Clone', | |
245 'page callback' => 'ctools_export_ui_switcher_page', | |
246 'page arguments' => array($plugin['name'], 'clone', $prefix_count + 2), | |
247 'load arguments' => array($plugin['name']), | |
248 'access callback' => 'ctools_export_ui_task_access', | |
249 'access arguments' => array($plugin['name'], 'clone', $prefix_count + 2), | |
250 'type' => MENU_CALLBACK, | |
251 ); | |
252 } | |
253 | |
254 if ($plugin['allowed operations']['enable']) { | |
255 $plugin['menu']['items'] += array('enable' => array()); | |
256 $plugin['menu']['items']['enable'] += array( | |
257 'path' => 'list/%ctools_export_ui/enable', | |
258 'title' => 'Enable', | |
259 'page callback' => 'ctools_export_ui_switcher_page', | |
260 'page arguments' => array($plugin['name'], 'enable', $prefix_count + 2), | |
261 'load arguments' => array($plugin['name']), | |
262 'access callback' => 'ctools_export_ui_task_access', | |
263 'access arguments' => array($plugin['name'], 'enable', $prefix_count + 2), | |
264 'type' => MENU_CALLBACK, | |
265 ); | |
266 } | |
267 | |
268 if ($plugin['allowed operations']['disable']) { | |
269 $plugin['menu']['items'] += array('disable' => array()); | |
270 $plugin['menu']['items']['disable'] += array( | |
271 'path' => 'list/%ctools_export_ui/disable', | |
272 'title' => 'Disable', | |
273 'page callback' => 'ctools_export_ui_switcher_page', | |
274 'page arguments' => array($plugin['name'], 'disable', $prefix_count + 2), | |
275 'load arguments' => array($plugin['name']), | |
276 'access callback' => 'ctools_export_ui_task_access', | |
277 'access arguments' => array($plugin['name'], 'disable', $prefix_count + 2), | |
278 'type' => MENU_CALLBACK, | |
279 ); | |
280 } | |
281 | |
282 // Define some redirects that should happen after edit/add/clone/delete operations. | |
283 $plugin['redirect'] += array( | |
284 'add' => $base_path, | |
285 'clone' => $base_path, | |
286 'edit' => $base_path, | |
287 'delete' => $base_path, | |
288 'revert' => $base_path, | |
289 'import' => $base_path, | |
290 ); | |
291 | |
292 // Define form elements. | |
293 $plugin['form'] += array( | |
294 'settings' => function_exists($plugin['name'] . '_form') ? $plugin['name'] . '_form' : '', | |
295 'validate' => function_exists($plugin['name'] . '_form_validate') ? $plugin['name'] . '_form_validate' : '', | |
296 'submit' => function_exists($plugin['name'] . '_form_submit') ? $plugin['name'] . '_form_submit' : '', | |
297 ); | |
298 | |
299 // Define strings. | |
300 | |
301 // For all strings, %title may be filled in at a later time via str_replace | |
302 // since we do not know the title now. | |
303 $plugin['strings'] += array( | |
304 'title' => array(), | |
305 'confirmation' => array(), | |
306 'help' => array(), | |
307 'message' => array(), | |
308 ); | |
309 | |
310 // Strings used in drupal_set_title(). | |
311 $plugin['strings']['title'] += array( | |
312 'add' => t('Add a new @plugin', array('@plugin' => $plugin['title singular'])), | |
313 // The "%title" will be replaced in ctools_export_ui_form(), as in this | |
314 // stage we dont have the specific exportable object. | |
315 'edit' => t('Edit @plugin %title', array('@plugin' => $plugin['title singular'])), | |
316 'clone' => t('Clone @plugin %title', array('@plugin' => $plugin['title singular'])), | |
317 | |
318 'import' => t('Import @plugin', array('@plugin' => $plugin['title singular'])), | |
319 'export' => t('Export @plugin %title', array('@plugin' => $plugin['title singular'])), | |
320 ); | |
321 | |
322 // Strings used in confirmation pages. | |
323 $plugin['strings']['confirmation'] += array( | |
324 'revert' => array(), | |
325 'delete' => array(), | |
326 'add' => array(), | |
327 'edit' => array(), | |
328 ); | |
329 | |
330 $plugin['strings']['confirmation']['revert'] += array( | |
331 'question' => t('Are you sure you want to revert %title?'), | |
332 'information' => t('This action will permanently remove any customizations made to this item.'), | |
333 'success' => t('The item has been reverted.'), | |
334 ); | |
335 | |
336 $plugin['strings']['confirmation']['delete'] += array( | |
337 'question' => t('Are you sure you want to delete %title?'), | |
338 'information' => t('This action will permanently remove this item from your database..'), | |
339 'success' => t('The item has been deleted.'), | |
340 ); | |
341 | |
342 $plugin['strings']['confirmation']['add'] += array( | |
343 'success' => t('%title has been created.'), | |
344 'fail' => t('%title could not be created.'), | |
345 ); | |
346 | |
347 $plugin['strings']['confirmation']['edit'] += array( | |
348 'success' => t('%title has been updated.'), | |
349 'fail' => t('%title could not be updated.'), | |
350 ); | |
351 | |
352 // Strings used in $forms. | |
353 $plugin['strings']['help'] += array( | |
354 'import' => t('You can import an exported definition by pasting the exported object code into the field below.'), | |
355 ); | |
356 | |
357 // Strings used in drupal_set_message(). | |
358 $plugin['strings']['message'] += array( | |
359 'enable' => t('@plugin %title was enabled.', array('@plugin' => $plugin['title singular proper'])), | |
360 'disable' => t('@plugin %title was disabled.', array('@plugin' => $plugin['title singular proper'])), | |
361 'no items' => t('There are no @titles to display.', array('@titles' => $plugin['title plural'])), | |
362 ); | |
363 } | |
364 | |
365 /** | |
366 * Get the class to handle creating a list of exportable items. | |
367 * | |
368 * If a plugin does not define a lister class at all, then the default | |
369 * lister class will be used. | |
370 * | |
371 * @return | |
372 * Either the lister class or FALSE if one could not be had. | |
373 */ | |
374 function ctools_export_ui_get_handler($plugin) { | |
375 $cache = &drupal_static(__FUNCTION__, array()); | |
376 if (empty($cache[$plugin['name']])) { | |
377 // If a list class is not specified by the plugin, fall back to the | |
378 // default ctools_export_ui plugin instead. | |
379 if (empty($plugin['handler'])) { | |
380 $default = ctools_get_export_ui('ctools_export_ui'); | |
381 $class = ctools_plugin_get_class($default, 'handler'); | |
382 } | |
383 else { | |
384 $class = ctools_plugin_get_class($plugin, 'handler'); | |
385 } | |
386 | |
387 if ($class) { | |
388 $cache[$plugin['name']] = new $class(); | |
389 $cache[$plugin['name']]->init($plugin); | |
390 } | |
391 } | |
392 return !empty($cache[$plugin['name']]) ? $cache[$plugin['name']] : FALSE; | |
393 } | |
394 | |
395 /** | |
396 * Get the base path from a plugin. | |
397 * | |
398 * @param $plugin | |
399 * The plugin. | |
400 * | |
401 * @return | |
402 * The menu path to the plugin's list. | |
403 */ | |
404 function ctools_export_ui_plugin_base_path($plugin) { | |
405 return $plugin['menu']['menu prefix'] . '/' . $plugin['menu']['menu item']; | |
406 } | |
407 | |
408 /** | |
409 * Get the path to a specific menu item from a plugin. | |
410 * | |
411 * @param $plugin | |
412 * The plugin name. | |
413 * @param $item_id | |
414 * The id in the menu items from the plugin. | |
415 * @param $export_key | |
416 * The export key of the item being edited, if it exists. | |
417 * @return | |
418 * The menu path to the plugin's list. | |
419 */ | |
420 function ctools_export_ui_plugin_menu_path($plugin, $item_id, $export_key = NULL) { | |
421 $path = $plugin['menu']['items'][$item_id]['path']; | |
422 if ($export_key) { | |
423 $path = str_replace('%ctools_export_ui', $export_key, $path); | |
424 } | |
425 return ctools_export_ui_plugin_base_path($plugin) . '/' . $path; | |
426 } | |
427 | |
428 /** | |
429 * Helper function to include CTools plugins and get an export-ui exportable. | |
430 * | |
431 * @param $plugin_name | |
432 * The plugin that should be laoded. | |
433 */ | |
434 function ctools_get_export_ui($plugin_name) { | |
435 ctools_include('plugins'); | |
436 return ctools_get_plugins('ctools', 'export_ui', $plugin_name); | |
437 | |
438 } | |
439 | |
440 /** | |
441 * Helper function to include CTools plugins and get all export-ui exportables. | |
442 */ | |
443 function ctools_get_export_uis() { | |
444 ctools_include('plugins'); | |
445 return ctools_get_plugins('ctools', 'export_ui'); | |
446 } | |
447 | |
448 /** | |
449 * Main page callback to manipulate exportables. | |
450 * | |
451 * This simply loads the object defined in the plugin and hands it off to | |
452 * a method based upon the name of the operation in use. This can easily | |
453 * be used to add more ops. | |
454 */ | |
455 function ctools_export_ui_switcher_page($plugin_name, $op) { | |
456 $args = func_get_args(); | |
457 $js = !empty($_REQUEST['js']); | |
458 | |
459 // Load the $plugin information | |
460 $plugin = ctools_get_export_ui($plugin_name); | |
461 $handler = ctools_export_ui_get_handler($plugin); | |
462 | |
463 if ($handler) { | |
464 $method = $op . '_page'; | |
465 if (method_exists($handler, $method)) { | |
466 // replace the first two arguments: | |
467 $args[0] = $js; | |
468 $args[1] = $_POST; | |
469 return call_user_func_array(array($handler, $method), $args); | |
470 } | |
471 } | |
472 else { | |
473 return t('Configuration error. No handler found.'); | |
474 } | |
475 } |