Projet

Général

Profil

Paste
Télécharger (14,3 ko) Statistiques
| Branche: | Révision:

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

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
    elseif (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 the administrative title for a type.
213
 */
214
function ctools_block_content_type_admin_title($subtype, $conf) {
215
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
216
  $block = module_invoke($module, 'block_info');
217
  if (empty($block) || empty($block[$delta])) {
218
    return t('Deleted/missing block @module-@delta', array('@module' => $module, '@delta' => $delta));
219
  }
220

    
221
  // The block description reported by hook_block() is plain text, but the title
222
  // reported by this hook should be HTML.
223
  $title = check_plain($block[$delta]['info']);
224
  return $title;
225
}
226

    
227
/**
228
 * Output function for the 'block' content type. Outputs a block
229
 * based on the module and delta supplied in the configuration.
230
 */
231
function ctools_block_content_type_admin_info($subtype, $conf) {
232
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
233
  $block = (object) module_invoke($module, 'block_view', $delta);
234

    
235
  if (!empty($block)) {
236
    // Sanitize the block because <script> tags can hose javascript up:
237
    if (!empty($block->content)) {
238
      $block->content = filter_xss_admin(render($block->content));
239
    }
240

    
241
    if (!empty($block->subject)) {
242
      $block->title = $block->subject;
243
    }
244
    elseif (empty($block->title)) {
245
      $block->title = t('No title');
246
    }
247
    return $block;
248
  }
249
}
250

    
251
function _ctools_block_get_module_delta($subtype, $conf) {
252
  if (strpos($subtype, '-')) {
253
    return explode('-', $subtype, 2);
254
  }
255
  else {
256
    return array($conf['module'], $conf['delta']);
257
  }
258
}
259

    
260
/**
261
 * Provide default icon and categories for blocks when modules don't do this
262
 * for us.
263
 */
264
function ctools_default_block_info($module, $delta, &$info) {
265
  $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');
266

    
267
  if (in_array($module, $core_modules)) {
268
    $info['icon'] = 'icon_core_block.png';
269
    $info['category'] = t('Miscellaneous');
270
  }
271
  else {
272
    $info['icon'] = 'icon_contrib_block.png';
273
    $info['category'] = t('Miscellaneous');
274
  }
275
}
276

    
277
/**
278
 * These are all on behalf of modules that don't implement ctools but that
279
 * we care about.
280
 */
281
function menu_ctools_block_info($module, $delta, &$info) {
282
  $info['icon'] = 'icon_core_block_menu.png';
283
  $info['category'] = t('Menus');
284
  if ($delta == 'primary-links' || $delta == 'secondary-links') {
285
    $info['icon'] = 'icon_core_primarylinks.png';
286
  }
287
}
288

    
289
function forum_ctools_block_info($module, $delta, &$info) {
290
  $info['category'] = t('Activity');
291
  switch ($delta) {
292
    case 'active':
293
      $info['icon'] = 'icon_core_activeforumtopics.png';
294
      break;
295

    
296
    case 'new':
297
      $info['icon'] = 'icon_core_newforumtopics.png';
298
      break;
299

    
300
    default:
301
      // Safety net.
302
      ctools_default_block_info($module, $delta, $info);
303
  }
304
}
305

    
306
function profile_ctools_block_info($module, $delta, &$info) {
307
  // Hide the author information block which isn't as rich as what we can
308
  // do with context.
309
  $info = NULL;
310
}
311

    
312
function book_ctools_block_info($module, $delta, &$info) {
313
  $info['title'] = t('Book navigation menu');
314
  $info['icon'] = 'icon_core_block_menu.png';
315
  $info['category'] = t('Node');
316
}
317

    
318
function blog_ctools_block_info($module, $delta, &$info) {
319
  $info['icon'] = 'icon_core_recentblogposts.png';
320
  $info['category'] = t('Activity');
321
}
322

    
323
function poll_ctools_block_info($module, $delta, &$info) {
324
  $info['icon'] = 'icon_core_recentpoll.png';
325
  $info['category'] = t('Activity');
326
}
327

    
328
function comment_ctools_block_info($module, $delta, &$info) {
329
  $info['icon'] = 'icon_core_recentcomments.png';
330
  $info['category'] = t('Activity');
331
}
332

    
333
function search_ctools_block_info($module, $delta, &$info) {
334
  $info['icon'] = 'icon_core_searchform.png';
335
  $info['category'] = t('Widgets');
336
}
337

    
338
function node_ctools_block_info($module, $delta, &$info) {
339
  $info['icon'] = 'icon_core_syndicate.png';
340
  $info['category'] = t('Widgets');
341
}
342

    
343
function aggregator_ctools_block_info($module, $delta, &$info) {
344
  $info['icon'] = 'icon_core_syndicate.png';
345
  $info['category'] = t('Feeds');
346
}
347

    
348
function block_ctools_block_info($module, $delta, &$info) {
349
  $info['icon'] = 'icon_core_block_empty.png';
350
  $info['category'] = t('Custom blocks');
351

    
352
  // The title of custom blocks from the block module is stored in the
353
  // {block} table. Look for it in the default theme as a reasonable
354
  // default value for the title.
355
  $block_info_cache = &drupal_static(__FUNCTION__);
356
  if (!isset($block_info_cache)) {
357
    $block_info_cache = db_select('block', 'b')
358
      ->fields('b')
359
      ->condition('b.module', 'block')
360
      ->condition('b.theme', variable_get('theme_default', 'bartik'))
361
      ->addTag('block_load')
362
      ->addTag('translatable')
363
      ->execute()
364
      ->fetchAllAssoc('delta');
365
  }
366

    
367
  if (isset($block_info_cache[$delta])) {
368
    $info['defaults'] = array(
369
      'override_title' => TRUE,
370
      'override_title_text' => $block_info_cache[$delta]->title,
371
    );
372
  }
373
}
374

    
375
function user_ctools_block_info($module, $delta, &$info) {
376
  $info['category'] = t('Activity');
377
  switch ($delta) {
378
    case 'login':
379
      $info['icon'] = 'icon_core_userlogin.png';
380
      $info['category'] = t('Widgets');
381
      // Provide a custom render callback, because the default login block
382
      // will not render on /user, /user/login, or any other URL beginning
383
      // /user (unless it's a user-specific page such as /user/123).
384
      $info['render callback'] = 'ctools_user_login_pane_render';
385
      break;
386

    
387
    case 'new':
388
      $info['icon'] = 'icon_core_whosnew.png';
389
      break;
390

    
391
    case 'online':
392
      $info['icon'] = 'icon_core_whosonline.png';
393
      break;
394

    
395
    default:
396
      // Safety net.
397
      ctools_default_block_info($module, $delta, $info);
398
  }
399
}
400

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

    
406
function statistics_ctools_block_info($module, $delta, &$info) {
407
  $info['icon'] = 'icon_core_popularcontent.png';
408
  $info['category'] = t('Activity');
409
}
410

    
411
function system_ctools_block_info($module, $delta, &$info) {
412
  // Remove the main content fake block.
413
  if ($delta == 'main') {
414
    $info = NULL;
415
    return;
416
  }
417

    
418
  $menus = array('main-menu', 'management', 'navigation', 'user-menu');
419

    
420
  if (in_array($delta, $menus)) {
421
    $info['icon'] = 'icon_core_block_menu.png';
422
    $info['category'] = t('Menus');
423

    
424
    if ($delta == 'navigation') {
425
      $info['icon'] = 'icon_core_navigation.png';
426
    }
427

    
428
    return;
429
  }
430

    
431
  $info['icon'] = 'icon_core_drupal.png';
432
  if ($delta == 'help') {
433
    $info['category'] = t('Page elements');
434
    return;
435
  }
436

    
437
  $info['category'] = t('Widgets');
438
}
439

    
440
function ctools_user_login_pane_render($subtype, $conf, $panel_args, $contexts) {
441
  list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
442

    
443
  // The login form is only visible to anonymous users.
444
  global $user;
445
  if ($user->uid) {
446
    return;
447
  }
448

    
449
  $info = new stdClass();
450
  $info->module = $module;
451
  $info->delta = $delta;
452

    
453
  $block = array();
454
  $block['subject'] = t('User login');
455
  // Manually set the content (rather than invoking block_view) because the
456
  // block implementation won't render on certain URLs.
457
  $block['content'] = drupal_get_form('user_login_block');
458

    
459
  // Allow modules to modify the block before it is viewed, via either
460
  // hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
461
  drupal_alter(array('block_view', "block_view_{$module}_{$delta}"), $block, $info);
462
  $block = (object) $block;
463

    
464
  if (empty($block)) {
465
    return;
466
  }
467

    
468
  $block->module = $module;
469
  $block->delta = $delta;
470

    
471
  // $block->title is not set for the blocks returned by block_block() (the
472
  // Block module adds the title in block_list() instead), so we look it up
473
  // manually, unless the title is overridden and does not use the %title
474
  // placeholder.
475
  if ($module == 'block') {
476
    $block->title = $info->title;
477
  }
478
  elseif (isset($block->subject)) {
479
    $block->title = $block->subject;
480
  }
481
  else {
482
    $block->title = NULL;
483
  }
484

    
485
  if (isset($block->subject)) {
486
    $block->title = $block->subject;
487
  }
488
  else {
489
    $block->title = NULL;
490
  }
491

    
492
  if (user_access('administer blocks')) {
493
    $block->admin_links = array(
494
      array(
495
        'title' => t('Configure block'),
496
        'href' => "admin/structure/block/manage/$module/$delta/configure",
497
        'query' => drupal_get_destination(),
498
      ),
499
    );
500
  }
501

    
502
  return $block;
503
}