Projet

Général

Profil

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

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

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
  if (empty($plugin['export']['admin_title']) && !empty($schema['fields']['admin_title'])) {
85
    $plugin['export']['admin_title'] = 'admin_title';
86
  }
87
  if (empty($plugin['export']['admin_description']) && !empty($schema['fields']['admin_description'])) {
88
    $plugin['export']['admin_description'] = 'admin_description';
89
  }
90

    
91
  // Define allowed operations, and the name of the operations.
92
  $plugin['allowed operations'] += array(
93
    'edit'    => array('title' => t('Edit')),
94
    'enable'  => array('title' => t('Enable'), 'ajax' => TRUE, 'token' => TRUE),
95
    'disable' => array('title' => t('Disable'), 'ajax' => TRUE, 'token' => TRUE),
96
    'revert'  => array('title' => t('Revert')),
97
    'delete'  => array('title' => t('Delete')),
98
    'clone'   => array('title' => t('Clone')),
99
    'import'  => array('title' => t('Import')),
100
    'export'  => array('title' => t('Export')),
101
  );
102

    
103
  $plugin['menu'] += array(
104
    'menu item' => str_replace(' ', '-', $plugin['name']),
105
    'menu prefix' => 'admin/structure',
106
    'menu title' => $plugin['title'],
107
    'menu description' => '',
108
  );
109
  $base_path = ctools_export_ui_plugin_base_path($plugin);
110
  $prefix_count = count(explode('/', $plugin['menu']['menu prefix']));
111

    
112
  $plugin['menu'] += array(
113
    // Default menu items that should be declared.
114
    'items' => array(),
115
  );
116

    
117
  $plugin['menu']['items'] += array(
118
    'list callback' => array(),
119
    'list' => array(),
120
    'add' => array(),
121
    'edit callback' => array(),
122
    'edit' => array(),
123
  );
124

    
125
  $plugin['menu']['items']['list callback'] += array(
126
    'path' => '',
127
    // Menu items are translated by the menu system.
128
    // TODO: We need more flexibility in title. The title of the admin page
129
    // is not necessarily the title of the object, plus we need
130
    // plural, singular, proper, not proper, etc.
131
    'title' => $plugin['menu']['menu title'],
132
    'description' => $plugin['menu']['menu description'],
133
    'page callback' => 'ctools_export_ui_switcher_page',
134
    'page arguments' => array($plugin['name'], 'list'),
135
    'access callback' => 'ctools_export_ui_task_access',
136
    'access arguments' => array($plugin['name'], 'list'),
137
    'type' => MENU_NORMAL_ITEM,
138
  );
139

    
140
  $plugin['menu']['items']['list'] += array(
141
    'path' => 'list',
142
    'title' => 'List',
143
    'page callback' => 'ctools_export_ui_switcher_page',
144
    'page arguments' => array($plugin['name'], 'list'),
145
    'access callback' => 'ctools_export_ui_task_access',
146
    'access arguments' => array($plugin['name'], 'list'),
147
    'type' => MENU_DEFAULT_LOCAL_TASK,
148
    'weight' => -10,
149
  );
150

    
151
  $plugin['menu']['items']['add'] += array(
152
    'path' => 'add',
153
    'title' => 'Add',
154
    'page callback' => 'ctools_export_ui_switcher_page',
155
    'page arguments' => array($plugin['name'], 'add'),
156
    'access callback' => 'ctools_export_ui_task_access',
157
    'access arguments' => array($plugin['name'], 'add'),
158
    'type' => MENU_LOCAL_ACTION,
159
  );
160

    
161
  $plugin['menu']['items']['edit callback'] += array(
162
    'path' => 'list/%ctools_export_ui',
163
    'page callback' => 'ctools_export_ui_switcher_page',
164
    'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2),
165
    'load arguments' => array($plugin['name']),
166
    'access callback' => 'ctools_export_ui_task_access',
167
    'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2),
168
    'type' => MENU_CALLBACK,
169
  );
170

    
171
  $plugin['menu']['items']['edit'] += array(
172
    'path' => 'list/%ctools_export_ui/edit',
173
    'title' => 'Edit',
174
    'page callback' => 'ctools_export_ui_switcher_page',
175
    'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2),
176
    'load arguments' => array($plugin['name']),
177
    'access callback' => 'ctools_export_ui_task_access',
178
    'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2),
179
    'type' => MENU_DEFAULT_LOCAL_TASK,
180
    'weight' => -10,
181
  );
182

    
183
  if ($plugin['allowed operations']['import']) {
184
    $plugin['menu']['items'] += array('import' => array());
185
    $plugin['menu']['items']['import'] += array(
186
      'path' => 'import',
187
      'title' => 'Import',
188
      'page callback' => 'ctools_export_ui_switcher_page',
189
      'page arguments' => array($plugin['name'], 'import'),
190
      'access callback' => 'ctools_export_ui_task_access',
191
      'access arguments' => array($plugin['name'], 'import'),
192
      'type' => MENU_LOCAL_ACTION,
193
    );
194
  }
195

    
196
  if ($plugin['allowed operations']['export']) {
197
    $plugin['menu']['items'] += array('export' => array());
198
    $plugin['menu']['items']['export'] += array(
199
      'path' => 'list/%ctools_export_ui/export',
200
      'title' => 'Export',
201
      'page callback' => 'ctools_export_ui_switcher_page',
202
      'page arguments' => array($plugin['name'], 'export', $prefix_count + 2),
203
      'load arguments' => array($plugin['name']),
204
      'access callback' => 'ctools_export_ui_task_access',
205
      'access arguments' => array($plugin['name'], 'export', $prefix_count + 2),
206
      'type' => MENU_LOCAL_TASK,
207
    );
208
  }
209

    
210
  if ($plugin['allowed operations']['revert']) {
211
    $plugin['menu']['items'] += array('revert' => array());
212
    $plugin['menu']['items']['revert'] += array(
213
      'path' => 'list/%ctools_export_ui/revert',
214
      'title' => 'Revert',
215
      'page callback' => 'ctools_export_ui_switcher_page',
216
      // Note: Yes, 'delete' op is correct.
217
      'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2),
218
      'load arguments' => array($plugin['name']),
219
      'access callback' => 'ctools_export_ui_task_access',
220
      'access arguments' => array($plugin['name'], 'revert', $prefix_count + 2),
221
      'type' => MENU_CALLBACK,
222
    );
223
  }
224

    
225
  if ($plugin['allowed operations']['delete']) {
226
    $plugin['menu']['items'] += array('delete' => array());
227
    $plugin['menu']['items']['delete'] += array(
228
      'path' => 'list/%ctools_export_ui/delete',
229
      'title' => 'Delete',
230
      'page callback' => 'ctools_export_ui_switcher_page',
231
      'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2),
232
      'load arguments' => array($plugin['name']),
233
      'access callback' => 'ctools_export_ui_task_access',
234
      'access arguments' => array($plugin['name'], 'delete', $prefix_count + 2),
235
      'type' => MENU_CALLBACK,
236
    );
237
  }
238

    
239
  if ($plugin['allowed operations']['clone']) {
240
    $plugin['menu']['items'] += array('clone' => array());
241
    $plugin['menu']['items']['clone'] += array(
242
      'path' => 'list/%ctools_export_ui/clone',
243
      'title' => 'Clone',
244
      'page callback' => 'ctools_export_ui_switcher_page',
245
      'page arguments' => array($plugin['name'], 'clone', $prefix_count + 2),
246
      'load arguments' => array($plugin['name']),
247
      'access callback' => 'ctools_export_ui_task_access',
248
      'access arguments' => array($plugin['name'], 'clone', $prefix_count + 2),
249
      'type' => MENU_CALLBACK,
250
    );
251
  }
252

    
253
  if ($plugin['allowed operations']['enable']) {
254
    $plugin['menu']['items'] += array('enable' => array());
255
    $plugin['menu']['items']['enable'] += array(
256
      'path' => 'list/%ctools_export_ui/enable',
257
      'title' => 'Enable',
258
      'page callback' => 'ctools_export_ui_switcher_page',
259
      'page arguments' => array($plugin['name'], 'enable', $prefix_count + 2),
260
      'load arguments' => array($plugin['name']),
261
      'access callback' => 'ctools_export_ui_task_access',
262
      'access arguments' => array($plugin['name'], 'enable', $prefix_count + 2),
263
      'type' => MENU_CALLBACK,
264
    );
265
  }
266

    
267
  if ($plugin['allowed operations']['disable']) {
268
    $plugin['menu']['items'] += array('disable' => array());
269
    $plugin['menu']['items']['disable'] += array(
270
      'path' => 'list/%ctools_export_ui/disable',
271
      'title' => 'Disable',
272
      'page callback' => 'ctools_export_ui_switcher_page',
273
      'page arguments' => array($plugin['name'], 'disable', $prefix_count + 2),
274
      'load arguments' => array($plugin['name']),
275
      'access callback' => 'ctools_export_ui_task_access',
276
      'access arguments' => array($plugin['name'], 'disable', $prefix_count + 2),
277
      'type' => MENU_CALLBACK,
278
    );
279
  }
280

    
281
  // Define some redirects that should happen after edit/add/clone/delete operations.
282
  $plugin['redirect'] += array(
283
    'add' => $base_path,
284
    'clone' => $base_path,
285
    'edit' => $base_path,
286
    'delete' => $base_path,
287
    'revert' => $base_path,
288
    'import' => $base_path,
289
  );
290

    
291
  // Define form elements.
292
  $plugin['form'] += array(
293
    'settings' => function_exists($plugin['name'] . '_form') ? $plugin['name'] . '_form' : '',
294
    'validate' => function_exists($plugin['name'] . '_form_validate') ? $plugin['name'] . '_form_validate' : '',
295
    'submit' => function_exists($plugin['name'] . '_form_submit') ? $plugin['name'] . '_form_submit' : '',
296
  );
297

    
298
  // Define strings.
299
  // For all strings, %title may be filled in at a later time via str_replace
300
  // since we do not know the title now.
301
  $plugin['strings'] += array(
302
    'title' => array(),
303
    'confirmation' => array(),
304
    'help' => array(),
305
    'message' => array(),
306
  );
307

    
308
  // Strings used in drupal_set_title().
309
  $plugin['strings']['title'] += array(
310
    'add' => t('Add a new @plugin', array('@plugin' => $plugin['title singular'])),
311
    // The "%title" will be replaced in ctools_export_ui_form(), as in this
312
    // stage we dont have the specific exportable object.
313
    'edit' => t('Edit @plugin %title', array('@plugin' => $plugin['title singular'])),
314
    'clone' => t('Clone @plugin %title', array('@plugin' => $plugin['title singular'])),
315

    
316
    'import' => t('Import @plugin', array('@plugin' => $plugin['title singular'])),
317
    'export' => t('Export @plugin %title', array('@plugin' => $plugin['title singular'])),
318
  );
319

    
320
  // Strings used in confirmation pages.
321
  $plugin['strings']['confirmation'] += array(
322
    'revert' => array(),
323
    'delete' => array(),
324
    'add' => array(),
325
    'edit' => array(),
326
  );
327

    
328
  $plugin['strings']['confirmation']['revert'] += array(
329
    'question' => t('Are you sure you want to revert %title?'),
330
    'information' => t('This action will permanently remove any customizations made to this item.'),
331
    'success' => t('The item has been reverted.'),
332
  );
333

    
334
  $plugin['strings']['confirmation']['delete'] += array(
335
    'question' => t('Are you sure you want to delete %title?'),
336
    'information' => t('This action will permanently remove this item from your database.'),
337
    'success' => t('The item has been deleted.'),
338
  );
339

    
340
  $plugin['strings']['confirmation']['add'] += array(
341
    'success' => t('%title has been created.'),
342
    'fail' => t('%title could not be created.'),
343
  );
344

    
345
  $plugin['strings']['confirmation']['edit'] += array(
346
    'success' => t('%title has been updated.'),
347
    'fail' => t('%title could not be updated.'),
348
  );
349

    
350
  // Strings used in $forms.
351
  $plugin['strings']['help'] += array(
352
    'import' => t('You can import an exported definition by pasting the exported object code into the field below.'),
353
  );
354

    
355
  // Strings used in drupal_set_message().
356
  $plugin['strings']['message'] += array(
357
    'enable' => t('@plugin %title was enabled.', array('@plugin' => $plugin['title singular proper'])),
358
    'disable' => t('@plugin %title was disabled.', array('@plugin' => $plugin['title singular proper'])),
359
    'no items' => t('There are no @titles to display.', array('@titles' => $plugin['title plural'])),
360
  );
361
}
362

    
363
/**
364
 * Get the class to handle creating a list of exportable items.
365
 *
366
 * If a plugin does not define a lister class at all, then the default
367
 * lister class will be used.
368
 *
369
 * @return
370
 *   Either the lister class or FALSE if one could not be had.
371
 */
372
function ctools_export_ui_get_handler($plugin) {
373
  $cache = &drupal_static(__FUNCTION__, array());
374
  if (empty($cache[$plugin['name']])) {
375
    // If a list class is not specified by the plugin, fall back to the
376
    // default ctools_export_ui plugin instead.
377
    if (empty($plugin['handler'])) {
378
      $default = ctools_get_export_ui('ctools_export_ui');
379
      $class = ctools_plugin_get_class($default, 'handler');
380
    }
381
    else {
382
      $class = ctools_plugin_get_class($plugin, 'handler');
383
    }
384

    
385
    if ($class) {
386
      $cache[$plugin['name']] = new $class();
387
      $cache[$plugin['name']]->init($plugin);
388
    }
389
  }
390
  return !empty($cache[$plugin['name']]) ? $cache[$plugin['name']] : FALSE;
391
}
392

    
393
/**
394
 * Get the base path from a plugin.
395
 *
396
 * @param $plugin
397
 *   The plugin.
398
 *
399
 * @return
400
 *   The menu path to the plugin's list.
401
 */
402
function ctools_export_ui_plugin_base_path($plugin) {
403
  return $plugin['menu']['menu prefix'] . '/' . $plugin['menu']['menu item'];
404
}
405

    
406
/**
407
 * Get the path to a specific menu item from a plugin.
408
 *
409
 * @param $plugin
410
 *   The plugin name.
411
 * @param $item_id
412
 *   The id in the menu items from the plugin.
413
 * @param $export_key
414
 *   The export key of the item being edited, if it exists.
415
 *
416
 * @return
417
 *   The menu path to the plugin's list.
418
 */
419
function ctools_export_ui_plugin_menu_path($plugin, $item_id, $export_key = NULL) {
420
  $path = $plugin['menu']['items'][$item_id]['path'];
421
  if ($export_key) {
422
    $path = str_replace('%ctools_export_ui', $export_key, $path);
423
  }
424
  return ctools_export_ui_plugin_base_path($plugin) . '/' . $path;
425
}
426

    
427
/**
428
 * Helper function to include CTools plugins and get an export-ui exportable.
429
 *
430
 * @param $plugin_name
431
 *   The plugin that should be loaded.
432
 */
433
function ctools_get_export_ui($plugin_name) {
434
  ctools_include('plugins');
435
  return ctools_get_plugins('ctools', 'export_ui', $plugin_name);
436
}
437

    
438
/**
439
 * Helper function to include CTools plugins and get all export-ui exportables.
440
 */
441
function ctools_get_export_uis() {
442
  ctools_include('plugins');
443
  return ctools_get_plugins('ctools', 'export_ui');
444
}
445

    
446
/**
447
 * Main page callback to manipulate exportables.
448
 *
449
 * This simply loads the object defined in the plugin and hands it off to
450
 * a method based upon the name of the operation in use. This can easily
451
 * be used to add more ops.
452
 */
453
function ctools_export_ui_switcher_page($plugin_name, $op) {
454
  $args = func_get_args();
455
  $js = !empty($_REQUEST['js']);
456

    
457
  // Load the $plugin information.
458
  $plugin = ctools_get_export_ui($plugin_name);
459
  if (!$plugin) {
460
    return t('Configuration error. No plugin found: %plugin_name.', array('%plugin_name' => $plugin_name));
461
  }
462

    
463
  $handler = ctools_export_ui_get_handler($plugin);
464
  if (!$handler) {
465
    return t('Configuration error. No handler found.');
466
  }
467

    
468
  $method = $op . '_page';
469
  if (method_exists($handler, $method)) {
470
    // Replace the first two arguments:
471
    $args[0] = $js;
472
    $args[1] = $_POST;
473
    return call_user_func_array(array($handler, $method), $args);
474
  }
475
}