Projet

Général

Profil

Paste
Télécharger (15,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / panels / panels_mini / panels_mini.module @ e4c061ad

1
<?php
2

    
3
/**
4
 * @file panels_mini.module
5
 *
6
 * This module provides mini panels which are basically panels that can be
7
 * used within blocks or other panels.
8
 */
9

    
10
/**
11
 * Implementation of hook_permission().
12
 */
13
function panels_mini_permission() {
14
  return array(
15
    'create mini panels' => array(
16
      'title' => t('Create mini panels'),
17
      'description' => t('Create new mini panels'),
18
    ),
19
    'administer mini panels' => array(
20
      'title' => t('Administer mini panels'),
21
      'description' => t('Edit and delete mini panels'),
22
    ),
23
  );
24
}
25

    
26
/**
27
 * Implementation of hook_menu().
28
 */
29
function panels_mini_menu() {
30
  // Safety: go away if CTools is not at an appropriate version.
31
  if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
32
    return array();
33
  }
34

    
35
  $items['admin/structure/mini-panels/settings'] = array(
36
    'title' => 'Settings',
37
    'page callback' => 'panels_mini_settings',
38
    'access arguments' => array('create mini panels'),
39
    'type' => MENU_LOCAL_TASK,
40
  );
41

    
42
  // Also provide settings on the main panel UI
43
  $items['admin/structure/panels/settings/panels-mini'] = array(
44
    'title' => 'Mini panels',
45
    'page callback' => 'panels_mini_settings',
46
    'access arguments' => array('create mini panels'),
47
    'type' => MENU_LOCAL_TASK,
48
  );
49

    
50
  return $items;
51
}
52

    
53
/**
54
 * Settings for mini panels.
55
 */
56
function panels_mini_settings() {
57
  ctools_include('common', 'panels');
58
  return drupal_get_form('panels_common_settings', 'panels_mini');
59
}
60

    
61
// ---------------------------------------------------------------------------
62
// Allow the rest of the system access to mini panels
63

    
64
/**
65
 * Implementation of hook_block_info().
66
 */
67
function panels_mini_block_info() {
68
  // Safety: go away if CTools is not at an appropriate version.
69
  if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
70
    return array();
71
  }
72

    
73
  $blocks = array();
74

    
75
  $minis = panels_mini_load_all();
76
  foreach ($minis as $panel_mini) {
77
    if (empty($panel_mini->disabled) && (module_exists('page_manager') || empty($panel_mini->requiredcontexts))) {
78
      $blocks[$panel_mini->name] = array(
79
        'info' => t('Mini panel: "@title"', array('@title' => $panel_mini->admin_title)),
80
        'cache' => DRUPAL_NO_CACHE,
81
      );
82
    }
83
  }
84

    
85
  return $blocks;
86
}
87

    
88
/**
89
 * Implementation of hook_block_view().
90
 *
91
 * @see panels_mini_panels_mini_content_type_render().
92
 */
93
function panels_mini_block_view($delta = 0) {
94
  // static recursion protection.
95
  static $viewing = array();
96
  if (!empty($viewing[$delta])) {
97
    return;
98
  }
99
  $viewing[$delta] = TRUE;
100

    
101
  $panel_mini = panels_mini_load($delta);
102
  if (empty($panel_mini)) {
103
    // Bail out early if the specified mini panel doesn't exist.
104
    return;
105
  }
106

    
107
  ctools_include('context');
108

    
109
  $contexts = array();
110
  if (module_exists('page_manager') && $current_page = page_manager_get_current_page()) {
111
    if (!empty($current_page['contexts'])) {
112
      $contexts = ctools_context_match_required_contexts($panel_mini->requiredcontexts, $current_page['contexts']);
113
    }
114
  }
115
  drupal_alter('panels_mini_block_contexts', $contexts, $panel_mini);
116

    
117
  $panel_mini->context = $panel_mini->display->context =  ctools_context_load_contexts($panel_mini, FALSE, $contexts);
118
  $panel_mini->display->css_id = panels_mini_get_id($panel_mini->name);
119

    
120
  $block = array();
121

    
122
  $block['content'] = panels_render_display($panel_mini->display);
123
  $block['subject'] = $panel_mini->display->get_title();
124

    
125
  unset($viewing[$delta]);
126
  return $block;
127
}
128

    
129
/**
130
 * Implementation of hook_block_configure().
131
 */
132
function panels_mini_block_configure($delta = 0) {
133
  return array(
134
    'admin_shortcut' => array(
135
      '#markup' => l(t('Manage this mini-panel'), 'admin/structure/mini-panels/list/' . $delta . '/edit')
136
    ),
137
  );
138
}
139

    
140
/**
141
 * Implements hook_block_list_alter().
142
 *
143
 * Remove the block if the required contexts are not available.
144
 */
145
function panels_mini_block_list_alter(&$blocks) {
146
  if (module_exists('page_manager')) {
147
    $current_page = page_manager_get_current_page();
148
  }
149
  foreach ($blocks as $key => $block) {
150
    if ($block->module != 'panels_mini') {
151
      // This block was added by a contrib module, leave it in the list.
152
      continue;
153
    }
154

    
155
    $panel_mini = panels_mini_load($block->delta);
156
    if (empty($panel_mini)) {
157
      // Bail out early if the specified mini panel doesn't exist.
158
      unset($blocks[$key]);
159
      continue;
160
    }
161

    
162
    if (!empty($panel_mini->requiredcontexts)) {
163
      if (!$current_page || empty($current_page['contexts'])) {
164
        unset($blocks[$key]);
165
        continue;
166
      }
167
      else {
168
        $required = array();
169
        foreach ($panel_mini->requiredcontexts as $context) {
170
          $info = ctools_get_context($context['name']);
171
          $required[] = new ctools_context_required($context['identifier'], $info['context name']);
172
        }
173
        if (!ctools_context_match_requirements($current_page['contexts'], $required)) {
174
          unset($blocks[$key]);
175
          continue;
176
        }
177
      }
178
    }
179
  }
180
}
181

    
182
/**
183
 * Implements hook_get_pane_links_alter().
184
 */
185
function panels_mini_get_pane_links_alter(&$links, $pane, $content_type) {
186
  if ($pane->type == 'panels_mini') {
187
    $links['top']['edit_panels_mini'] = array(
188
      'title' => t('Edit mini panel'),
189
      'href' => url('admin/structure/mini-panels/list/' . $pane->subtype . '/edit/content', array('absolute' => TRUE)),
190
      'attributes' => array('target' => array('_blank')),
191
    );
192
  }
193
}
194

    
195
/**
196
 * Implements hook_contextual_links_view_alter().
197
 */
198
function panels_mini_contextual_links_view_alter(&$element, $items) {
199

    
200
  // Add contextual links to all mini panel blocks with bid property.
201
  if (isset($element['#element']['#block']) && isset($element['#element']['#block']->bid) && strpos((string) $element['#element']['#block']->bid, 'panels_mini') === 0) {
202

    
203
    $admin_pages = array(
204
      t('Configure mini panel settings') => 'basic',
205
      t('Configure mini panel context') => 'context',
206
      t('Configure mini panel layout') => 'layout',
207
      t('Configure mini panel content') => 'content',
208
    );
209

    
210
    foreach ($admin_pages as $title => $tail) {
211
      $element['#links']['mini-panels-' . $tail] = array(
212
        'title' => $title,
213
        'href' => 'admin/structure/mini-panels/list/' . $element['#element']['#block']->delta . '/edit/' . $tail,
214
        'query' => drupal_get_destination(),
215
      );
216
    }
217
  }
218
}
219

    
220
/**
221
 * Statically store all used IDs to ensure all mini panels get a unique id.
222
 */
223
function panels_mini_get_id($name) {
224
  $id_cache = &drupal_static(__FUNCTION__, array());
225

    
226
  $id = 'mini-panel-' . $name;
227
  if (!empty($id_cache[$name])) {
228
    $id .= "-" . $id_cache[$name]++;
229
  }
230
  else {
231
    $id_cache[$name] = 1;
232
  }
233

    
234
  return $id;
235
}
236

    
237
// ---------------------------------------------------------------------------
238
// Database functions.
239

    
240
/**
241
 * Create a new page with defaults appropriately set from schema.
242
 */
243
function panels_mini_new($set_defaults = TRUE) {
244
  ctools_include('export');
245
  return ctools_export_new_object('panels_mini', $set_defaults);
246
}
247

    
248
/**
249
 * Load a single mini panel.
250
 */
251
function panels_mini_load($name) {
252
  $cache = &drupal_static('panels_mini_load_all', array());
253

    
254
  // We use array_key_exists because failed loads will be NULL and
255
  // isset() will try to load it again.
256
  if (!array_key_exists($name, $cache)) {
257
    ctools_include('export');
258
    $result = ctools_export_load_object('panels_mini', 'names', array($name));
259
    if (isset($result[$name])) {
260
      if (empty($result[$name]->display)) {
261
        $result[$name]->display = panels_load_display($result[$name]->did);
262
        if (!empty($result[$name]->title) && empty($result[$name]->display->title)) {
263
          $result[$name]->display->title = $result[$name]->title;
264
        }
265
      }
266
      $cache[$name] = $result[$name];
267
      if (!empty($result[$name]->title) && empty($result[$name]->admin_title)) {
268
        $cache[$name]->admin_title = $result[$name]->title;
269
      }
270
    }
271
    else {
272
      $cache[$name] = NULL;
273
    }
274
  }
275

    
276
  if (isset($cache[$name])) {
277
    return $cache[$name];
278
  }
279
}
280

    
281
/**
282
 * Load all mini panels.
283
 */
284
function panels_mini_load_all($reset = FALSE) {
285
  $cache = &drupal_static('panels_mini_load_all', array());
286
  static $all_loaded = FALSE;
287

    
288
  // We check our own private static because individual minis could have
289
  // been loaded prior to load all and we need to know that.
290
  if (!$all_loaded || $reset) {
291
    $all_loaded = TRUE;
292
    if ($reset) {
293
      $cache = array();
294
    }
295

    
296
    ctools_include('export');
297
    $minis = ctools_export_load_object('panels_mini');
298
    $dids = array();
299
    foreach ($minis as $mini) {
300
      if (empty($cache[$mini->name])) {
301
        if (!empty($mini->did)) {
302
          $dids[$mini->did] = $mini->name;
303
        }
304
        else {
305
        // Translate old style titles into new titles.
306
          if (!empty($mini->title) && empty($mini->display->title)) {
307
            $mini->display->title = $mini->title;
308
          }
309
        }
310
        // Translate old style titles into new titles.
311
        if (isset($mini->title) && empty($mini->admin_title)) {
312
          $mini->admin_title = $mini->title;
313
        }
314
        $cache[$mini->name] = $mini;
315
      }
316
    }
317

    
318
    $displays = panels_load_displays(array_keys($dids));
319
    foreach ($displays as $did => $display) {
320
      if (!empty($cache[$dids[$did]]->title) && empty($display->title)) {
321
        $display->title = $cache[$dids[$did]]->title;
322
      }
323
      $cache[$dids[$did]]->display = $display;
324
    }
325
  }
326

    
327
  // Strip out NULL entries that may have been added by panels_mini_load().
328
  return array_filter($cache);
329
}
330

    
331
/**
332
 * Write a mini panel to the database.
333
 */
334
function panels_mini_save(&$mini) {
335
  if (!empty($mini->display)) {
336
    $display = panels_save_display($mini->display);
337
    $mini->did = $display->did;
338
  }
339

    
340
  $update = (isset($mini->pid) && $mini->pid != 'new') ? array('pid') : array();
341
  drupal_write_record('panels_mini', $mini, $update);
342

    
343
  return $mini;
344
}
345

    
346
/**
347
 * Remove a mini panel.
348
 */
349
function panels_mini_delete($mini) {
350
  db_delete('panels_mini')
351
    ->condition('name', $mini->name)
352
    ->execute();
353

    
354
  if (db_table_exists('block') && $mini->type != t('Overridden')) {
355
    // Also remove from block table as long as there isn't a default that may appear.
356
    db_delete('block')
357
      ->condition('delta', $mini->name)
358
      ->condition('module', 'panels_mini')
359
      ->execute();
360
  }
361
  return panels_delete_display($mini->did);
362
}
363

    
364
/**
365
 * Export a mini panel.
366
 */
367
function panels_mini_export($mini, $indent = '') {
368
  ctools_include('export');
369
  $output = ctools_export_object('panels_mini', $mini, $indent);
370
  // Export the primary display
371
  $display = !empty($mini->display) ? $mini->display : panels_load_display($mini->did);
372
  $output .= panels_export_display($display, $indent);
373
  $output .= $indent . '$mini->display = $display' . ";\n";
374
  return $output;
375
}
376

    
377
/**
378
 * Remove the block version of mini panels from being available content types.
379
 */
380
function panels_mini_ctools_block_info($module, $delta, &$info) {
381
  $info = NULL;
382
}
383

    
384
/**
385
 * Implementation of hook_ctools_plugin_directory() to let the system know
386
 * we implement task and task_handler plugins.
387
 */
388
function panels_mini_ctools_plugin_directory($module, $plugin) {
389
  if ($module == 'ctools' && ($plugin == 'content_types' || $plugin == 'export_ui')) {
390
    return 'plugins/' . $plugin;
391
  }
392
}
393

    
394
/**
395
 * Get the display cache for the panels_mini plugin.
396
 */
397
function _panels_mini_panels_cache_get($key) {
398
  ctools_include('export-ui');
399
  $plugin = ctools_get_export_ui('panels_mini');
400
  $handler = ctools_export_ui_get_handler($plugin);
401
  if (!$handler) {
402
    return;
403
  }
404

    
405
  $item = $handler->edit_cache_get($key);
406
  if (!$item) {
407
    $item = ctools_export_crud_load($handler->plugin['schema'], $key);
408
  }
409

    
410
  return array($handler, $item);
411
}
412

    
413
/**
414
 * Get display edit cache for the panels mini export UI
415
 *
416
 * The key is the second half of the key in this form:
417
 * panels_mini:TASK_NAME:HANDLER_NAME;
418
 */
419
function panels_mini_panels_cache_get($key) {
420
  ctools_include('common', 'panels');
421
  list($handler, $item) = _panels_mini_panels_cache_get($key);
422
  if (isset($item->mini_panels_display_cache)) {
423
    return $item->mini_panels_display_cache;
424
  }
425

    
426
  $cache = new stdClass();
427
  $cache->display = $item->display;
428
  $cache->display->context = ctools_context_load_contexts($item);
429
  $cache->display->cache_key = 'panels_mini:' . $key;
430
  $cache->content_types = panels_common_get_allowed_types('panels_mini', $cache->display->context);
431
  $cache->display_title = TRUE;
432

    
433
  // @TODO support locking
434
  $cache->locked = FALSE;
435

    
436
  return $cache;
437
}
438

    
439
/**
440
 * Store a display edit in progress in the page cache.
441
 */
442
function panels_mini_panels_cache_set($key, $cache) {
443
  list($handler, $item) = _panels_mini_panels_cache_get($key);
444
  $item->mini_panels_display_cache = $cache;
445
  $handler->edit_cache_set_key($item, $key);
446
}
447

    
448
/**
449
 * Save all changes made to a display using the panels mini UI cache.
450
 */
451
function panels_mini_panels_cache_clear($key, $cache) {
452
  list($handler, $item) = _panels_mini_panels_cache_get($key);
453
  $handler->edit_cache_clear($item);
454
}
455

    
456
/**
457
 * Save all changes made to a display using the panels mini UI cache.
458
 */
459
function panels_mini_panels_cache_save($key, $cache) {
460
  list($handler, $item) = _panels_mini_panels_cache_get($key);
461
  $item->display = $cache->display;
462
  panels_mini_save($item);
463

    
464
  $handler->edit_cache_clear($item);
465
}
466

    
467
/**
468
 * Break the lock on a panels mini page.
469
 */
470
function panels_mini_panels_cache_break_lock($key, $cache) {
471
}
472

    
473
/**
474
 * Implementation of hook_panels_dashboard_blocks().
475
 *
476
 * Adds mini panels information to the Panels dashboard.
477
 */
478
function panels_mini_panels_dashboard_blocks(&$vars) {
479
  $vars['links']['panels_mini'] = array(
480
    'title' => l(t('Mini panel'), 'admin/structure/mini-panels/add'),
481
    'description' => t('Mini panels are small content areas exposed as blocks, for when you need to have complex block layouts or layouts within layouts.'),
482
    'weight' => -1,
483
  );
484

    
485
  // Load all mini panels and their displays.
486
  $panel_minis = panels_mini_load_all();
487
  $count = 0;
488
  $rows = array();
489

    
490
  foreach ($panel_minis as $panel_mini) {
491
    $rows[] = array(
492
      check_plain($panel_mini->admin_title),
493
      array(
494
        'data' => l(t('Edit'), "admin/structure/mini-panels/list/$panel_mini->name/edit"),
495
        'class' => 'links',
496
      ),
497
    );
498

    
499
    // Only show 10.
500
    if (++$count >= 10) {
501
      break;
502
    }
503
  }
504

    
505
  if ($rows) {
506
    $content = theme('table', array('rows' => $rows, 'attributes' => array('class' => 'panels-manage')));
507
  }
508
  else {
509
    $content = '<p>' . t('There are no mini panels.') . '</p>';
510
  }
511

    
512
  $vars['blocks']['panels_mini'] = array(
513
    'weight' => -100,
514
    'title' => t('Manage mini panels'),
515
    'link' => l(t('Go to list'), 'admin/structure/mini-panels'),
516
    'content' => $content,
517
    'class' => 'dashboard-mini-panels',
518
    'section' => 'left',
519
  );
520

    
521
}
522

    
523
/**
524
 * Implements template_preprocess_ctools_wizard_trail().
525
 *
526
 * Customize the divider used in the CTools wizard to build the edit pages for
527
 * Mini Panels as a stop-gap measure until the UX can be completely re-done.
528
 */
529
function panels_mini_preprocess_ctools_wizard_trail(&$variables) {
530
  $variables['divider'] = ' | ';
531
  drupal_add_css(drupal_get_path('module', 'panels_mini') . '/panels_mini.css');
532
}