Projet

Général

Profil

Paste
Télécharger (16,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ctools / includes / export-ui.inc @ e4c061ad

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
}