Projet

Général

Profil

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

root / drupal7 / sites / all / modules / ctools / plugins / content_types / block / block.inc @ e4c061ad

1
<?php
2

    
3
/**
4
 * @file
5
 * Provide Drupal blocks as content.
6
 *
7
 * Since blocks don't provide all of the features we do, we have to do a little
8
 * extra work, including providing icons and categories for core blocks. Blocks
9
 * from contrib modules get to provide their own stuff, or get relegated to
10
 * the old "Miscellaneous" category.
11
 */
12

    
13
/**
14
 * Plugins are described by creating a $plugin array which will be used
15
 * by the system that includes this file.
16
 */
17
$plugin = array(
18
  // And this is just the administrative title.
19
  // All our callbacks are named according to the standard pattern and can be deduced.
20
  'title' => t('Block'),
21
  'content type' => 'ctools_block_content_type_content_type',
22
);
23

    
24
/**
25
 * Return the block content types with the specified $subtype_id.
26
 */
27
function ctools_block_content_type_content_type($subtype_id) {
28
  list($module, $delta) = explode('-', $subtype_id, 2);
29
  $module_blocks = module_invoke($module, 'block_info');
30
  if (isset($module_blocks[$delta])) {
31
    return _ctools_block_content_type_content_type($module, $delta, $module_blocks[$delta]);
32
  }
33
}
34

    
35
/**
36
 * Return all block content types available.
37
 *
38
 * Modules wanting to make special adjustments the way that CTools handles their blocks
39
 * can implement an extension to the hook_block() family, where the function name is
40
 * of the form "$module . '_ctools_block_info'".
41
 */
42
function ctools_block_content_type_content_types() {
43
  $types = &drupal_static(__FUNCTION__);
44
  if (isset($types)) {
45
    return $types;
46
  }
47

    
48
  $types = array();
49
  foreach (module_implements('block_info') as $module) {
50
    $module_blocks = module_invoke($module, 'block_info');
51
    if ($module_blocks) {
52
      foreach ($module_blocks as $delta => $block) {
53
        $info = _ctools_block_content_type_content_type($module, $delta, $block);
54
        // this check means modules can remove their blocks; particularly useful
55
        // if they offer the block some other way (like we do for views)
56
        if ($info) {
57
          $types["$module-$delta"] = $info;
58
        }
59
      }
60
    }
61
  }
62
  return $types;
63
}
64

    
65
/**
66
 * Return an info array for a specific block.
67
 */
68
function _ctools_block_content_type_content_type($module, $delta, $block) {
69
  // strip_tags used because it goes through check_plain and that
70
  // just looks bad.
71
  $info = array(
72
    'title' => strip_tags($block['info']),
73
  );
74

    
75
  // Ask around for further information by invoking the hook_block() extension.
76
  $function = $module . '_ctools_block_info';
77
  if (!function_exists($function)) {
78
    $function = 'ctools_default_block_info';
79
  }
80
  $function($module, $delta, $info);
81

    
82
  return $info;
83
}
84

    
85
/**
86
 * Load block info from the database.
87
 *
88
 * This is copied from _block_load_blocks(). It doesn't use that
89
 * function because _block_load_blocks sorts by region, and it
90
 * doesn't cache its results anyway.
91
 */
92
function _ctools_block_load_blocks() {
93
  if (!module_exists('block')) {
94
    return array();
95
  }
96

    
97
  $blocks = &drupal_static(__FUNCTION__, NULL);
98
  if (!isset($blocks)) {
99
    global $theme_key;
100

    
101
    $query = db_select('block', 'b');
102
    $result = $query
103
      ->fields('b')
104
      ->condition('b.theme', $theme_key)
105
      ->orderBy('b.region')
106
      ->orderBy('b.weight')
107
      ->orderBy('b.module')
108
      ->addTag('block_load')
109
      ->addTag('translatable')
110
      ->execute();
111

    
112
    $block_info = $result->fetchAllAssoc('bid');
113
    // Allow modules to modify the block list.
114
    drupal_alter('block_list', $block_info);
115

    
116
    $blocks = array();
117
    foreach ($block_info as $block) {
118
      $blocks["{$block->module}_{$block->delta}"] = $block;
119
    }
120
  }
121

    
122
  return $blocks;
123
}
124

    
125
/**
126
 * Fetch the stored info for a block.
127
 *
128
 * The primary reason to use this is so that modules which perform alters
129
 * can have their alters make it to the block.
130
 */
131
function _ctools_get_block_info($module, $delta) {
132
  $blocks = _ctools_block_load_blocks();
133

    
134
  $key = $module . '_' . $delta;
135
  if (isset($blocks[$key])) {
136
    return $blocks[$key];
137
  }
138
}
139

    
140
/**
141
 * Output function for the 'block' content type. Outputs a block
142
 * based on the module and delta supplied in the configuration.
143
 */
144
function ctools_block_content_type_render($subtype, $conf) {
145
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
146

    
147
  $info = _ctools_get_block_info($module, $delta);
148
  $block = module_invoke($module, 'block_view', $delta);
149

    
150
  if (!empty($info)) {
151
    // Valid PHP function names cannot contain hyphens.
152
    $block_delta = str_replace('-', '_', $delta);
153

    
154
    // Allow modules to modify the block before it is viewed, via either
155
    // hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
156
    drupal_alter(array('block_view', "block_view_{$module}_{$block_delta}"), $block, $info);
157
  }
158

    
159
  if (empty($block)) {
160
    return;
161
  }
162

    
163
  $block = (object) $block;
164
  $block->module = $module;
165
  $block->delta = $delta;
166

    
167
  if (!isset($block->title)) {
168
    if ($module == 'block' && !empty($info) && isset($info->title)) {
169
      $block->title = $info->title;
170
    }
171
    else if (isset($block->subject)) {
172
      $block->title = $block->subject;
173
    }
174
    else {
175
      $block->title = NULL;
176
    }
177
  }
178

    
179
  if (module_exists('block') && user_access('administer blocks')) {
180
    $block->admin_links = array(
181
      array(
182
        'title' => t('Configure block'),
183
        'href' => "admin/structure/block/manage/$module/$delta/configure",
184
        'query' => drupal_get_destination(),
185
      ),
186
    );
187
  }
188

    
189
  return $block;
190
}
191

    
192
/**
193
 * Empty form so we can have the default override title.
194
 */
195
function ctools_block_content_type_edit_form($form, &$form_state) {
196
  // Does nothing!
197
  return $form;
198
}
199

    
200
/**
201
 * Submit function to fix the subtype for really old panel panes.
202
 */
203
function ctools_block_content_type_edit_form_submit($form, &$form_state) {
204
  if (empty($form_state['subtype']) && isset($form_state['pane'])) {
205
    $form_state['pane']->subtype = $form_state['conf']['module'] . '-' . $form_state['conf']['delta'];
206
    unset($form_state['conf']['module']);
207
    unset($form_state['conf']['delta']);
208
  }
209
}
210

    
211
/**
212
 * Returns an edit form for a block.
213
 */
214
//function ctools_block_content_type_edit_form($id, $parents, $conf) {
215
//  if (user_access('administer advanced pane settings')) {
216
//    $form['block_visibility'] = array(
217
//      '#type' => 'checkbox',
218
//      '#title' => t('Use block visibility settings (see block config)'),
219
//      '#default_value' => !empty($conf['block_visibility']),
220
//      '#description' => t('If checked, the block visibility settings for this block will apply to this block.'),
221
//    );
222
//    // Module-specific block configurations.
223
//    if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
224
//      // Specifically modify a couple of core block forms.
225
//      if ($module == 'block') {
226
//        unset($settings['submit']);
227
//        $settings['info']['#type'] = 'value';
228
//        $settings['info']['#value'] = $settings['info']['#default_value'];
229
//      }
230
//      ctools_admin_fix_block_tree($settings);
231
//      $form['block_settings'] = array(
232
//        '#type' => 'fieldset',
233
//        '#title' => t('Block settings'),
234
//        '#description' => t('Settings in this section are global and are for all blocks of this type, anywhere in the system.'),
235
//        '#tree' => FALSE,
236
//      );
237
//
238
//
239
//      $form['block_settings'] += $settings;
240
//    }
241
//  }
242
//
243
//  return $form;
244
//}
245

    
246
//function ctools_admin_submit_block(&$form_values) {
247
//  if (!empty($form_values['block_settings'])) {
248
//    module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values['block_settings']);
249
//  }
250
//}
251
//
252
///**
253
// * Because form api cannot collapse just part of a tree, and the block settings
254
// * assume no tree, we have to collapse the tree ourselves.
255
// */
256
//function ctools_admin_fix_block_tree(&$form, $key = NULL) {
257
//  if ($key) {
258
//    if (!empty($form['#parents'])) {
259
//      $form['#parents'] = array_merge(array('configuration', 'block_settings'), $form['#parents']);
260
//    }
261
//    else if (empty($form['#tree'])) {
262
//      $form['#parents'] = array('configuration', 'block_settings', $key);
263
//    }
264
//  }
265
//
266
//  if (isset($form['#type']) && $form['#type'] == 'textarea' && !empty($form['#rows']) && $form['#rows'] > 10) {
267
//    $form['#rows'] = 10;
268
//  }
269
//
270
//  foreach (element_children($form) as $key) {
271
//    ctools_admin_fix_block_tree($form[$key], $key);
272
//  }
273
//}
274

    
275
/**
276
 * Returns the administrative title for a type.
277
 */
278
function ctools_block_content_type_admin_title($subtype, $conf) {
279
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
280
  $block = module_invoke($module, 'block_info');
281
  if (empty($block) || empty($block[$delta])) {
282
    return t('Deleted/missing block @module-@delta', array('@module' => $module, '@delta' => $delta));
283
  }
284

    
285
  // The block description reported by hook_block() is plain text, but the title
286
  // reported by this hook should be HTML.
287
  $title = check_plain($block[$delta]['info']);
288
  return $title;
289
}
290

    
291
/**
292
 * Output function for the 'block' content type. Outputs a block
293
 * based on the module and delta supplied in the configuration.
294
 */
295
function ctools_block_content_type_admin_info($subtype, $conf) {
296
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
297
  $block = (object) module_invoke($module, 'block_view', $delta);
298

    
299
  if (!empty($block)) {
300
    // Sanitize the block because <script> tags can hose javascript up:
301
    if (!empty($block->content)) {
302
      $block->content = filter_xss_admin(render($block->content));
303
    }
304

    
305
    if (!empty($block->subject)) {
306
      $block->title = $block->subject;
307
    }
308
    elseif (empty($block->title)) {
309
      $block->title = t('No title');
310
    }
311
    return $block;
312
  }
313
}
314

    
315
function _ctools_block_get_module_delta($subtype, $conf) {
316
  if (strpos($subtype, '-')) {
317
    return explode('-', $subtype, 2);
318
  }
319
  else {
320
    return array($conf['module'], $conf['delta']);
321
  }
322
}
323

    
324
/**
325
 * Provide default icon and categories for blocks when modules don't do this
326
 * for us.
327
 */
328
function ctools_default_block_info($module, $delta, &$info) {
329
  $core_modules = array('aggregator', 'block', 'blog', 'blogapi', 'book', 'color', 'comment', 'contact', 'drupal', 'filter', 'forum', 'help', 'legacy', 'locale', 'menu', 'node', 'path', 'ping', 'poll', 'profile', 'search', 'statistics', 'taxonomy', 'throttle', 'tracker', 'upload', 'user', 'watchdog', 'system');
330

    
331
  if (in_array($module, $core_modules)) {
332
    $info['icon'] = 'icon_core_block.png';
333
    $info['category'] = t('Miscellaneous');
334
  }
335
  else {
336
    $info['icon'] = 'icon_contrib_block.png';
337
    $info['category'] = t('Miscellaneous');
338
  }
339
}
340

    
341
// These are all on behalf of modules that don't implement ctools but that
342
// we care about.
343
function menu_ctools_block_info($module, $delta, &$info) {
344
  $info['icon'] = 'icon_core_block_menu.png';
345
  $info['category'] = t('Menus');
346
  if ($delta == 'primary-links' || $delta == 'secondary-links') {
347
    $info['icon'] = 'icon_core_primarylinks.png';
348
  }
349
}
350

    
351
function forum_ctools_block_info($module, $delta, &$info) {
352
  $info['category'] = t('Activity');
353
  switch ($delta) {
354
    case 'active':
355
      $info['icon'] = 'icon_core_activeforumtopics.png';
356
      break;
357

    
358
    case 'new':
359
      $info['icon'] = 'icon_core_newforumtopics.png';
360
      break;
361

    
362
    default:
363
      // safety net
364
      ctools_default_block_info($module, $delta, $info);
365
  }
366
}
367

    
368
function profile_ctools_block_info($module, $delta, &$info) {
369
  // Hide the author information block which isn't as rich as what we can
370
  // do with context.
371
  $info = NULL;
372
}
373

    
374
function book_ctools_block_info($module, $delta, &$info) {
375
  // Hide the book navigation block which isn't as rich as what we can
376
  // do with context.
377
  $info = NULL;
378
}
379

    
380
function blog_ctools_block_info($module, $delta, &$info) {
381
  $info['icon'] = 'icon_core_recentblogposts.png';
382
  $info['category'] = t('Activity');
383
}
384

    
385
function poll_ctools_block_info($module, $delta, &$info) {
386
  $info['icon'] = 'icon_core_recentpoll.png';
387
  $info['category'] = t('Activity');
388
}
389

    
390
function comment_ctools_block_info($module, $delta, &$info) {
391
  $info['icon'] = 'icon_core_recentcomments.png';
392
  $info['category'] = t('Activity');
393
}
394

    
395
function search_ctools_block_info($module, $delta, &$info) {
396
  $info['icon'] = 'icon_core_searchform.png';
397
  $info['category'] = t('Widgets');
398
}
399

    
400
function node_ctools_block_info($module, $delta, &$info) {
401
  $info['icon'] = 'icon_core_syndicate.png';
402
  $info['category'] = t('Widgets');
403
}
404

    
405
function aggregator_ctools_block_info($module, $delta, &$info) {
406
  $info['icon'] = 'icon_core_syndicate.png';
407
  $info['category'] = t('Feeds');
408
}
409

    
410
function block_ctools_block_info($module, $delta, &$info) {
411
  $info['icon'] = 'icon_core_block_empty.png';
412
  $info['category'] = t('Custom blocks');
413

    
414
  // The title of custom blocks from the block module is stored in the
415
  // {block} table. Look for it in the default theme as a reasonable
416
  // default value for the title.
417
  $block_info_cache = drupal_static(__FUNCTION__);
418
  if (!isset($block_info_cache)) {
419
    $block_info_cache = db_select('block', 'b')
420
      ->fields('b')
421
      ->condition('b.module', 'block')
422
      ->condition('b.theme', variable_get('theme_default', 'bartik'))
423
      ->addTag('block_load')
424
      ->addTag('translatable')
425
      ->execute()
426
      ->fetchAllAssoc('delta');
427
  }
428

    
429
  if (isset($block_info_cache[$delta])) {
430
    $info['defaults'] = array(
431
      'override_title' => TRUE,
432
      'override_title_text' => $block_info_cache[$delta]->title,
433
    );
434
  }
435
}
436

    
437
function user_ctools_block_info($module, $delta, &$info) {
438
  $info['category'] = t('Activity');
439
  switch ($delta) {
440
    case 'login':
441
      $info['icon'] = 'icon_core_userlogin.png';
442
      $info['category'] = t('Widgets');
443
      // Provide a custom render callback, because the default login block
444
      // will not render on /user, /user/login, or any other URL beginning
445
      // /user (unless it's a user-specific page such as /user/123).
446
      $info['render callback'] = 'ctools_user_login_pane_render';
447
      break;
448

    
449
    case 'new':
450
      $info['icon'] = 'icon_core_whosnew.png';
451
      break;
452

    
453
    case 'online':
454
      $info['icon'] = 'icon_core_whosonline.png';
455
      break;
456

    
457
    default:
458
      // safety net
459
      ctools_default_block_info($module, $delta, $info);
460
  }
461
}
462

    
463
function locale_ctools_block_info($module, $delta, &$info) {
464
  $info['icon'] = 'icon_core_languageswitcher.png';
465
  $info['category'] = t('Widgets');
466
}
467

    
468
function statistics_ctools_block_info($module, $delta, &$info) {
469
  $info['icon'] = 'icon_core_popularcontent.png';
470
  $info['category'] = t('Activity');
471
}
472

    
473
function system_ctools_block_info($module, $delta, &$info) {
474
  // Remove the main content fake block.
475
  if ($delta == 'main') {
476
    $info = NULL;
477
    return;
478
  }
479

    
480
  $menus = array('main-menu', 'management', 'navigation', 'user-menu');
481

    
482
  if (in_array($delta, $menus)) {
483
    $info['icon'] = 'icon_core_block_menu.png';
484
    $info['category'] = t('Menus');
485

    
486
    if ($delta == 'navigation') {
487
      $info['icon'] = 'icon_core_navigation.png';
488
    }
489

    
490
    return;
491
  }
492

    
493
  $info['icon'] = 'icon_core_drupal.png';
494
  if ($delta == 'help') {
495
    $info['category'] = t('Page elements');
496
    return;
497
  }
498

    
499
  $info['category'] = t('Widgets');
500
}
501

    
502
function ctools_user_login_pane_render($subtype, $conf, $panel_args, $contexts) {
503
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
504

    
505
  // The login form is only visible to anonymous users.
506
  global $user;
507
  if ($user->uid) {
508
    return;
509
  }
510

    
511
  $info = new stdClass;
512
  $info->module = $module;
513
  $info->delta = $delta;
514

    
515
  $block = array();
516
  $block['subject'] = t('User login');
517
  // Manually set the content (rather than invoking block_view) because the
518
  // block implementation won't render on certain URLs.
519
  $block['content'] = drupal_get_form('user_login_block');
520

    
521
  // Allow modules to modify the block before it is viewed, via either
522
  // hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
523
  drupal_alter(array('block_view', "block_view_{$module}_{$delta}"), $block, $info);
524
  $block = (object) $block;
525

    
526
  if (empty($block)) {
527
    return;
528
  }
529

    
530
  $block->module = $module;
531
  $block->delta = $delta;
532

    
533
  // $block->title is not set for the blocks returned by block_block() (the
534
  // Block module adds the title in block_list() instead), so we look it up
535
  // manually, unless the title is overridden and does not use the %title
536
  // placeholder.
537
  if ($module == 'block') {
538
    $block->title = $info->title;
539
  }
540
  else if (isset($block->subject)) {
541
    $block->title = $block->subject;
542
  }
543
  else {
544
    $block->title = NULL;
545
  }
546

    
547
  if (isset($block->subject)) {
548
    $block->title = $block->subject;
549
  }
550
  else {
551
    $block->title = NULL;
552
  }
553

    
554
  if (user_access('administer blocks')) {
555
    $block->admin_links = array(
556
      array(
557
        'title' => t('Configure block'),
558
        'href' => "admin/structure/block/manage/$module/$delta/configure",
559
        'query' => drupal_get_destination(),
560
      ),
561
    );
562
  }
563

    
564
  return $block;
565
}