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 @ e4c061ad

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'] && $pager['type'] != 'none' && $pager['type'] != 'some') {
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

    
275
  $required = array();
276
  if (isset($view->display_handler) && $arguments = $view->display_handler->get_handlers('argument')) {
277
    foreach ($arguments as $arg) {
278
      $required[] = new ctools_context_optional($arg->ui_name(), 'any');
279
    }
280
  }
281

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

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

    
292
  $form['more_link'] = array(
293
    '#type' => 'checkbox',
294
    '#default_value' => $conf['more_link'],
295
    '#title' => t('Provide a "more" link that links to the view'),
296
    '#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.'),
297
  );
298

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

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

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

    
318
  if ($view->display_handler->get_option('use_ajax')) {
319
    $form['pager_settings']['warning'] = array(
320
      '#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>',
321
    );
322
  }
323

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

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

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

    
360
  $form['panel_args'] = array(
361
    '#type' => 'checkbox',
362
    '#title' => t('Send arguments'),
363
    '#default_value' => $conf['panel_args'],
364
    '#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.'),
365
  );
366

    
367
  $form['args'] = array(
368
    '#type' => 'textfield',
369
    '#default_value' => $conf['args'],
370
    '#title' => t('Arguments'),
371
    '#size' => 30,
372
    '#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.'),
373
  );
374

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
531
  if (empty($view)) {
532
    return $name;
533
  }
534

    
535
  $view->set_display($display);
536
  // $view->current_display will now reflect this value.
537

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

    
555
  return $view;
556
}