Projet

Général

Profil

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

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

1
<?php
2

    
3
/**
4
 * @file
5
 * Content type plugin to expose all views as content.
6
 */
7

    
8
if (variable_get('ctools_content_all_views', TRUE)) {
9
  $plugin = array(
10
    'title' => t('All views'),
11
    'defaults' => array(
12
      'override_pager_settings' => FALSE,
13
      'use_pager' => FALSE,
14
      'nodes_per_page' => 10,
15
      'pager_id' => 0,
16
      'offset' => 0,
17
      'more_link' => FALSE,
18
      'feed_icons' => FALSE,
19
      'panel_args' => FALSE,
20
      'link_to_view' => FALSE,
21
      'args' => '',
22
      'url' => '',
23
    ),
24
    'add form' => array(
25
      'views_content_views_select_display' => t('Select display'),
26
      'views_content_views_content_type_edit_form' => array(
27
        'default' => TRUE, // put wrapper here, not on the previous form.
28
        'title' => t('Configure view'),
29
      ),
30
    ),
31
    'all contexts' => TRUE,
32
  );
33
}
34

    
35
/**
36
 * Return all content types available.
37
 */
38
function views_content_views_content_type_content_types($plugin) {
39
  $types = array();
40
  // It can be fairly intensive to calculate this, so let's cache this in the
41
  // cache_views table. The nice thing there is that if views ever change, that
42
  // table will always be cleared. Except for the occasional default view, so
43
  // we must use the Views caching functions in order to respect Views caching
44
  // settings.
45
  views_include('cache');
46
  $data = views_cache_get('views_content_all', TRUE);
47
  if (!empty($data->data)) {
48
    $types = $data->data;
49
  }
50

    
51
  if (empty($types)) {
52
    $views = views_get_all_views();
53

    
54
    foreach ($views as $view) {
55
      if (empty($view->disabled)) {
56
        $types[$view->name] = _views_content_views_content_type($view);
57
      }
58
    }
59

    
60
    views_cache_set('views_content_all', $types, TRUE);
61
  }
62

    
63
  return $types;
64
}
65

    
66
/**
67
 * Create the content type info array to give back to ctools for a given display.
68
 */
69
function _views_content_views_content_type($view) {
70
  $title = $view->get_human_name();
71

    
72
  $icon = 'icon_views_page_legacy.png';
73

    
74
  return array(
75
    'view' => $view->name,
76
    'title' => $title,
77
    'icon' => $icon,
78
    'description' => filter_xss_admin($view->description),
79
    'category' => t('Views'),
80
  );
81

    
82
}
83

    
84
/**
85
 * Output function for the 'views' content type.
86
 *
87
 * Outputs a view based on the module and delta supplied in the configuration.
88
 */
89
function views_content_views_content_type_render($subtype, $conf, $panel_args, $contexts) {
90
  if (!is_array($contexts)) {
91
    $contexts = array($contexts);
92
  }
93

    
94
  $view = _views_content_views_update_conf($conf, $subtype);
95

    
96
  if (empty($view) || !is_object($view) || empty($view->display_handler)) {
97
    return;
98
  }
99

    
100
  if (!$view->display_handler->access($GLOBALS['user'])) {
101
    return;
102
  }
103

    
104
  $arguments = explode('/', $_GET['q']);
105
  $args = $conf['args'];
106

    
107
  foreach ($arguments as $id => $arg) {
108
    $args = str_replace("%$id", $arg, $args);
109
  }
110

    
111
  foreach ($panel_args as $id => $arg) {
112
    if (is_string($arg)) {
113
      $args = str_replace("@$id", $arg, $args);
114
    }
115
  }
116

    
117
  $args = preg_replace(',/?(%\d|@\d),', '', $args);
118
  $args = $args ? explode('/', $args) : array();
119

    
120
  if ($conf['panel_args'] && is_array($panel_args)) {
121
    $args = array_merge($panel_args, $args);
122
  }
123

    
124
  if (isset($conf['context']) && is_array($conf['context'])) {
125
    foreach ($conf['context'] as $count => $context_info) {
126
      if (!strpos($context_info, '.')) {
127
        // Old skool: support pre-converter contexts as well.
128
        $cid = $context_info;
129
        $converter = '';
130
      }
131
      else {
132
        list($cid, $converter) = explode('.', $context_info, 2);
133
      }
134
      if (!empty($contexts[$cid])) {
135
        $arg = ctools_context_convert_context($contexts[$cid], $converter, array('sanitize' => FALSE));
136
        array_splice($args, $count, 0, array($arg));
137
      }
138
      else {
139
        // Make sure we put an argument in even if it was not there.
140
        $arg = NULL;
141
      }
142
    }
143
  }
144

    
145
  $view->set_arguments($args);
146

    
147
  if ($conf['url']) {
148
    $view->override_path = $conf['url'];
149
  }
150

    
151
  $block = new stdClass();
152
  $block->module = 'views';
153
  $block->delta = $view->name . '-' . $view->current_display;
154

    
155
  if (!empty($conf['link_to_view'])) {
156
    $block->title_link = $view->get_url();
157
  }
158

    
159
  if (!empty($conf['more_link'])) {
160
    $block->more = array('href' => $view->get_url());
161
    $view->display_handler->set_option('use_more', FALSE);
162
  }
163

    
164
  // Only set use_pager if they differ, this way we can avoid overwriting the
165
  // pager type that Views uses.
166
  if ($conf['override_pager_settings']) {
167
    if (method_exists($view, 'init_pager')) {
168
      // Views 3 version.
169
      $view->set_items_per_page($conf['nodes_per_page']);
170
      $view->set_offset($conf['offset']);
171

    
172
      $pager = $view->display_handler->get_option('pager');
173
      if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) {
174
        $pager['type'] = 'full';
175
      }
176
      elseif (!$conf['use_pager']) {
177
        $pager['type'] = $view->get_items_per_page() ? 'some' : 'none';
178
      }
179

    
180
      if ($conf['use_pager']) {
181
        if (!isset($pager['options']['id']) || $pager['options']['id'] != $conf['pager_id']) {
182
          $pager['options']['id'] = $conf['pager_id'];
183
        }
184
      }
185

    
186
      $view->display_handler->set_option('pager', $pager);
187
    }
188
    else {
189
      if (!$view->display_handler->get_option('use_pager') || empty($conf['use_pager'])) {
190
        $view->display_handler->set_option('use_pager', $conf['use_pager']);
191
      }
192
      $view->display_handler->set_option('pager_element', $conf['pager_id']);
193
      $view->display_handler->set_option('items_per_page', $conf['nodes_per_page']);
194
      $view->display_handler->set_option('offset', $conf['offset']);
195
    }
196
  }
197

    
198
  $stored_feeds = drupal_add_feed();
199
  $block->content = $view->preview();
200
  $block->title = $view->get_title();
201

    
202
  if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) {
203
    return;
204
  }
205

    
206
  if (!empty($conf['feed_icons'])) {
207
    $new_feeds = drupal_add_feed();
208
    if ($diff = array_diff(array_keys($new_feeds), array_keys($stored_feeds))) {
209
      foreach ($diff as $url) {
210
        $block->feeds[$url] = $new_feeds[$url];
211
      }
212
    }
213
  }
214

    
215
  $view->destroy();
216
  return $block;
217
}
218

    
219
/**
220
 * Returns an edit form for a block.
221
 */
222
function views_content_views_select_display($form, &$form_state) {
223
  $view = views_get_view($form_state['subtype_name']);
224
  if (empty($view)) {
225
    return;
226
  }
227

    
228
  $displays = array();
229
  foreach ($view->display as $id => $display) {
230
    // Content pane views should never be used this way.
231
    if ($display->display_plugin != 'panel_pane') {
232
      $displays[$id] = views_content_get_display_label($view, $id);
233
    }
234
  }
235

    
236
  $form['display'] = array(
237
    '#type' => 'select',
238
    '#title' => t('Display'),
239
    '#options' => $displays,
240
    '#description' => t('Choose which display of this view you wish to use.'),
241
  );
242

    
243
  return $form;
244
}
245

    
246
/**
247
 * Submit the basic view edit form.
248
 *
249
 * This just dumps everything into the $conf array.
250
 */
251
function views_content_views_select_display_submit(&$form, &$form_state) {
252
  $form_state['conf']['display'] = $form_state['values']['display'];
253
}
254

    
255
/**
256
 * Returns an edit form for a block.
257
 */
258
function views_content_views_content_type_edit_form($form, &$form_state) {
259
  $conf = $form_state['conf'];
260
  $view = _views_content_views_update_conf($conf, $form_state['subtype_name']);
261

    
262
  if (empty($view) || !is_object($view)) {
263
    $form['markup'] = array('#value' => t('Broken/missing/deleted view.'));
264
    return;
265
  }
266

    
267
  $form_state['title'] = t('Configure view @view (@display)', array('@view' => $view->get_human_name(), '@display' => views_content_get_display_label($view, $view->current_display)));
268

    
269
  // @todo
270
  // If using the older format, just a context is listed. We should go through
271
  // and check for that and forcibly set them to the right converter so that
272
  // it doesn't get changed to some whacky default. Oooor just let it get changed
273
  // to 'no context', I suppose.
274
  $required = array();
275
  if (isset($view->display_handler) && $arguments = $view->display_handler->get_handlers('argument')) {
276
    foreach ($arguments as $arg) {
277
      $required[] = new ctools_context_optional($arg->ui_name(), 'any');
278
    }
279
  }
280

    
281
  if ($required) {
282
    $form['context'] = ctools_context_converter_selector($form_state['contexts'], $required, isset($conf['context']) ? $conf['context'] : array());
283
  }
284

    
285
  $form['link_to_view'] = array(
286
    '#type' => 'checkbox',
287
    '#default_value' => $conf['link_to_view'],
288
    '#title' => t('Link title to view'),
289
  );
290

    
291
  $form['more_link'] = array(
292
    '#type' => 'checkbox',
293
    '#default_value' => $conf['more_link'],
294
    '#title' => t('Provide a "more" link that links to the view'),
295
    '#description' => t('This is independent of any more link that may be provided by the view itself; if you see two more links, turn this one off. Views will only provide a more link if using the "block" type, however, so if using embed, use this one.'),
296
  );
297

    
298
  $form['feed_icons'] = array(
299
    '#type' => 'checkbox',
300
    '#default_value' => $conf['feed_icons'],
301
    '#title' => t('Display feed icons'),
302
  );
303

    
304
  $form['pager_settings'] = array(
305
    '#type' => 'fieldset',
306
    '#collapsible' => FALSE,
307
    '#title' => t('Custom pager settings'),
308
  );
309

    
310
  $form['pager_settings']['override_pager_settings'] = array(
311
    '#type' => 'checkbox',
312
    '#title' => t('Use different pager settings from view settings'),
313
    '#default_value' => $conf['override_pager_settings'],
314
    '#id' => 'override-pager-checkbox',
315
  );
316

    
317
  if ($view->display_handler->get_option('use_ajax')) {
318
    $form['pager_settings']['warning'] = array(
319
      '#value' => '<div>' . t('<strong>Warning: </strong> This view has AJAX enabled. Overriding the pager settings will work initially, but when the view is updated via AJAX, the original settings will be used. You should not override pager settings on Views with the AJAX setting enabled.') . '</div>',
320
    );
321
  }
322

    
323
  $form['pager_settings']['use_pager'] = array(
324
    '#prefix' => '<div class="container-inline">',
325
    '#type' => 'checkbox',
326
    '#title' => t('Use pager'),
327
    '#default_value' => $conf['use_pager'],
328
    '#id' => 'use-pager-checkbox',
329
    '#dependency' => array('override-pager-checkbox' => array(1)),
330
  );
331
  $form['pager_settings']['pager_id'] = array(
332
    '#type' => 'textfield',
333
    '#default_value' => $conf['pager_id'],
334
    '#title' => t('Pager ID'),
335
    '#size' => 4,
336
    '#id' => 'use-pager-textfield',
337
    '#dependency' => array('override-pager-checkbox' => array(1), 'use-pager-checkbox' => array(1)),
338
    '#dependency_count' => 2,
339
    '#suffix' => '</div>',
340
  );
341

    
342
  $form['pager_settings']['nodes_per_page'] = array(
343
    '#type' => 'textfield',
344
    '#default_value' => $conf['nodes_per_page'],
345
    '#size' => 4,
346
    '#title' => t('Num posts'),
347
    '#dependency' => array('override-pager-checkbox' => array(1)),
348
  );
349

    
350
  $form['pager_settings']['offset'] = array(
351
    '#type' => 'textfield',
352
    '#default_value' => $conf['offset'],
353
    '#title' => t('Offset'),
354
    '#size' => 4,
355
    '#description' => t('The number of items to skip and not display.'),
356
    '#dependency' => array('override-pager-checkbox' => array(1)),
357
  );
358

    
359
  $form['panel_args'] = array(
360
    '#type' => 'checkbox',
361
    '#title' => t('Send arguments'),
362
    '#default_value' => $conf['panel_args'],
363
    '#description' => t('Select this to send all arguments from the panel directly to the view. If checked, the panel arguments will come after any context arguments above and precede any additional arguments passed in through the Arguments field below. Note that arguments do not include the base URL; only values after the URL or set as placeholders are considered arguments.'),
364
  );
365

    
366
  $form['args'] = array(
367
    '#type' => 'textfield',
368
    '#default_value' => $conf['args'],
369
    '#title' => t('Arguments'),
370
    '#size' => 30,
371
    '#description' => t('Additional arguments to send to the view as if they were part of the URL in the form of arg1/arg2/arg3. You may use %0, %1, ..., %N to grab arguments from the URL. Or use @0, @1, @2, ..., @N to use arguments passed into the panel. Note: use these values only as a last resort. In future versions of Panels these may go away.'),
372
  );
373

    
374
  $form['url'] = array(
375
    '#type' => 'textfield',
376
    '#default_value' => $conf['url'],
377
    '#title' => t('Override URL'),
378
    '#size' => 30,
379
    '#description' => t('If this is set, override the View URL; this can sometimes be useful to set to the panel URL'),
380
  );
381

    
382
  $view->destroy();
383
  return $form;
384
}
385

    
386
/**
387
 * Store form values in $conf.
388
 */
389
function views_content_views_content_type_edit_form_submit(&$form, &$form_state) {
390
  // Copy everything from our defaults.
391
  foreach (array_keys($form_state['plugin']['defaults']) as $key) {
392
    $form_state['conf'][$key] = $form_state['values'][$key];
393
  }
394
}
395

    
396
/**
397
 * Returns the administrative title for a type.
398
 */
399
function views_content_views_content_type_admin_title($subtype, $conf) {
400
  $view = _views_content_views_update_conf($conf, $subtype);
401

    
402
  if (!is_object($view)) {
403
    return t('Deleted/missing view @view', array('@view' => $view));
404
  }
405

    
406
  $title = views_content_get_display_label($view, $view->current_display);
407
  return t('View: @name', array('@name' => $view->get_human_name() . ': ' . $title));
408
}
409

    
410
/**
411
 * Returns the administrative title for a type.
412
 */
413
function views_content_views_content_type_admin_info($subtype, $conf, $contexts) {
414
  $view = _views_content_views_update_conf($conf, $subtype);
415

    
416
  if (!is_object($view)) {
417
    return t('Deleted/missing view @view', array('@view' => $view));
418
  }
419

    
420
  $display = empty($conf['display']) ? $view->current_display : $conf['display'];
421
  $block = new stdClass();
422

    
423
  $block->title = t('View information');
424

    
425
  $block->content = '<ul>';
426
  $block->content .= '<li>' . t('Using display @display.', array('@display' => views_content_get_display_label($view, $display))) . '</li>';
427

    
428
  if (!empty($conf['context']) && $arguments = $view->display_handler->get_handlers('argument')) {
429
    $argument = reset($arguments);
430
    foreach ($conf['context'] as $count => $context_info) {
431
      if (!$argument) {
432
        break;
433
      }
434

    
435
      if (!strpos($context_info, '.')) {
436
        // Old skool: support pre-converter contexts as well.
437
        $cid = $context_info;
438
        $converter = '';
439
      }
440
      else {
441
        list($cid, $converter) = explode('.', $context_info, 2);
442
      }
443

    
444
      if (!empty($contexts[$cid])) {
445
        $converters = ctools_context_get_converters($cid . '.', $contexts[$cid]);
446
        $converter = !empty($converters[$context_info]) ? $converters[$context_info] : t('Default');
447
        $block->content .= '<li>' . t('Argument @arg using context @context converted into @converter', array(
448
          '@arg' => $argument->ui_name(),
449
          '@context' => $contexts[$cid]->get_identifier(),
450
          '@converter' => $converter,
451
        )) . '</li>';
452
      }
453
      $argument = next($arguments);
454
    }
455
  }
456

    
457
  $block->content .= '<li>' . t('@count items displayed.', array('@count' => $conf['nodes_per_page'])) . '</li>';
458
  if ($conf['use_pager']) {
459
    $block->content .= '<li>' . t('With pager.') . '</li>';
460
  }
461
  else {
462
    $block->content .= '<li>' . t('Without pager.') . '</li>';
463
  }
464

    
465
  if ($conf['offset']) {
466
    $block->content .= '<li>' . t('Skipping first @count results', array('@count' => $conf['offset'])) . '</li>';
467
  }
468
  if ($conf['more_link']) {
469
    $block->content .= '<li>' . t('With more link.') . '</li>';
470
  }
471
  if ($conf['feed_icons']) {
472
    $block->content .= '<li>' . t('With feed icon.') . '</li>';
473
  }
474
  if ($conf['panel_args']) {
475
    $block->content .= '<li>' . t('Sending arguments.') . '</li>';
476
  }
477
  if ($conf['args']) {
478
    $block->content .= '<li>' . t('Using arguments: @args', array('@args' => $conf['args'])) . '</li>';
479
  }
480
  if ($conf['url']) {
481
    $block->content .= '<li>' . t('Using url: @url', array('@url' => $conf['url'])) . '</li>';
482
  }
483

    
484
  $view->destroy();
485
  return $block;
486
}
487

    
488
/**
489
 * Update the $conf to deal with updates from Drupal 5.
490
 *
491
 * @param &$conf
492
 *   The $conf array to modify.
493
 * @param $subtype
494
 *   The subtype in use. This should just be the view name, but in older
495
 *   versions it was the view name with a dash and the display ID.
496
 *   If this is the case, we can use it to correct the 'display' setting
497
 *   in the $conf.
498
 *
499
 * @return
500
 *   The $view with the initialized display. If the $view could not be
501
 *   loaded, the name attempted will be loaded for use in errors.
502
 *   Correct error checking on this function checks against is_object().
503
 */
504
function _views_content_views_update_conf(&$conf, $subtype) {
505
  $plugin = ctools_get_content_type('views');
506

    
507
  // Special: Existing content types get a different default than new ones:
508
  if (!empty($conf) && !isset($conf['override_pager_settings'])) {
509
    $conf['override_pager_settings'] = TRUE;
510
  }
511

    
512
  // Make sure that our defaults are always set if there is no
513
  // previous setting. This helps updates go more smoothly.
514
  foreach ($plugin['defaults'] as $key => $value) {
515
    if (!isset($conf[$key])) {
516
      $conf[$key] = $value;
517
    }
518
  }
519

    
520
  if (strpos($subtype, '-')) {
521
    list($name, $display) = explode('-', $subtype);
522
    $view = views_get_view($name);
523
    if (!isset($conf['display'])) {
524
      $conf['display'] = $display;
525
    }
526
  }
527
  else {
528
    $name = $subtype;
529
    $view = views_get_view($subtype);
530
    $display = isset($conf['display']) ? $conf['display'] : 'default';
531
  }
532

    
533
  if (empty($view)) {
534
    return $name;
535
  }
536

    
537
  $view->set_display($display);
538
  // $view->current_display will now reflect this value.
539
  // If set NOT to override, go ahead and refresh from the view.
540
  if (empty($conf['override_pager_settings'])) {
541
    if (method_exists($view, 'init_pager')) {
542
      $pager = $view->display_handler->get_option('pager');
543
      $conf['use_pager'] = $pager['type'] != 'none' && $pager['type'] != 'some';
544
      $conf['pager_id'] = isset($pager['options']['id']) ? $pager['options']['id'] : 0;
545
      $conf['offset'] = isset($pager['options']['offset']) ? $pager['options']['offset'] : 0;
546
      $conf['nodes_per_page'] = isset($pager['options']['items_per_page']) ? $pager['options']['items_per_page'] : 0;
547
    }
548
    else {
549
      $conf['use_pager'] = $view->display_handler->get_option('use_pager');
550
      $conf['pager_id'] = $view->display_handler->get_option('element_id');
551
      $conf['nodes_per_page'] = $view->display_handler->get_option('items_per_page');
552
      $conf['offset'] = $view->display_handler->get_option('offset');
553
    }
554
  }
555

    
556
  return $view;
557
}