Project

General

Profile

Paste
Download (18.4 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / ctools / views_content / plugins / content_types / views.inc @ 96a203dd

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
 * Return a single content type.
68
 */
69
function views_content_views_content_type_content_type($subtype, $plugin) {
70
  $view = views_get_view($name);
71
  if (empty($view)) {
72
    return;
73
  }
74

    
75
  return _views_content_views_content_type($view);
76
}
77

    
78
/**
79
 * Create the content type info array to give back to ctools for a given display.
80
 */
81
function _views_content_views_content_type($view) {
82
  $title = $view->get_human_name();
83

    
84
  $icon = 'icon_views_page_legacy.png';
85

    
86
  return array(
87
    'view' => $view->name,
88
    'title' => $title,
89
    'icon' => $icon,
90
    'description' => filter_xss_admin($view->description),
91
    'category' => t('Views'),
92
  );
93

    
94
}
95

    
96
/**
97
 * Output function for the 'views' content type.
98
 *
99
 * Outputs a view based on the module and delta supplied in the configuration.
100
 */
101
function views_content_views_content_type_render($subtype, $conf, $panel_args, $contexts) {
102
  if (!is_array($contexts)) {
103
    $contexts = array($contexts);
104
  }
105

    
106
  $view = _views_content_views_update_conf($conf, $subtype);
107

    
108
  if (empty($view) || !is_object($view) || empty($view->display_handler)) {
109
    return;
110
  }
111

    
112
  if (!$view->display_handler->access($GLOBALS['user'])) {
113
    return;
114
  }
115

    
116
  $arguments = explode('/', $_GET['q']);
117
  $args = $conf['args'];
118

    
119
  foreach ($arguments as $id => $arg) {
120
    $args = str_replace("%$id", $arg, $args);
121
  }
122

    
123
  foreach ($panel_args as $id => $arg) {
124
    if (is_string($arg)) {
125
      $args = str_replace("@$id", $arg, $args);
126
    }
127
  }
128

    
129
  $args = preg_replace(',/?(%\d|@\d),', '', $args);
130
  $args = $args ? explode('/', $args) : array();
131

    
132
  if ($conf['panel_args'] && is_array($panel_args)) {
133
    $args = array_merge($panel_args, $args);
134
  }
135

    
136
  if (isset($conf['context']) && is_array($conf['context'])) {
137
    foreach ($conf['context'] as $count => $context_info) {
138
      if (!strpos($context_info, '.')) {
139
        // old skool: support pre-converter contexts as well.
140
        $cid = $context_info;
141
        $converter = '';
142
      }
143
      else {
144
        list($cid, $converter) = explode('.', $context_info, 2);
145
      }
146
      if (!empty($contexts[$cid])) {
147
        $arg = ctools_context_convert_context($contexts[$cid], $converter, array('sanitize' => FALSE));
148
        array_splice($args, $count, 0, array($arg));
149
      }
150
      else {
151
        // Make sure we put an argument in even if it was not there.
152
        $arg = NULL;
153
      }
154
    }
155
  }
156

    
157
  $view->set_arguments($args);
158

    
159
  if ($conf['url']) {
160
    $view->override_path = $conf['url'];
161
  }
162

    
163
  $block = new stdClass();
164
  $block->module = 'views';
165
  $block->delta  = $view->name . '-' . $view->current_display;
166

    
167
  if (!empty($conf['link_to_view'])) {
168
    $block->title_link = $view->get_url();
169
  }
170

    
171
  if (!empty($conf['more_link'])) {
172
    $block->more = array('href' => $view->get_url());
173
    $view->display_handler->set_option('use_more', FALSE);
174
  }
175

    
176
  // Only set use_pager if they differ, this way we can avoid overwriting the
177
  // pager type that Views uses.
178
  if ($conf['override_pager_settings']) {
179
    if (method_exists($view, 'init_pager')) {
180
      // Views 3 version
181
      $view->set_items_per_page($conf['nodes_per_page']);
182
      $view->set_offset($conf['offset']);
183

    
184
      $pager = $view->display_handler->get_option('pager');
185
      if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) {
186
        $pager['type'] = 'full';
187
      }
188
      elseif (!$conf['use_pager'] && $pager['type'] != 'none' && $pager['type'] != 'some') {
189
        $pager['type'] = $view->get_items_per_page() ? 'some' : 'none';
190
      }
191

    
192
      if ($conf['use_pager']) {
193
        if (!isset($pager['options']['id']) || $pager['options']['id'] != $conf['pager_id']) {
194
          $pager['options']['id'] = $conf['pager_id'];
195
        }
196
      }
197

    
198
      $view->display_handler->set_option('pager', $pager);
199
    }
200
    else {
201
      if (!$view->display_handler->get_option('use_pager') || empty($conf['use_pager'])) {
202
        $view->display_handler->set_option('use_pager', $conf['use_pager']);
203
      }
204
      $view->display_handler->set_option('pager_element', $conf['pager_id']);
205
      $view->display_handler->set_option('items_per_page', $conf['nodes_per_page']);
206
      $view->display_handler->set_option('offset', $conf['offset']);
207
    }
208
  }
209

    
210
  $stored_feeds = drupal_add_feed();
211
  $block->content = $view->preview();
212
  $block->title = $view->get_title();
213

    
214
  if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) {
215
    return;
216
  }
217

    
218
  if (!empty($conf['feed_icons'])) {
219
    $new_feeds = drupal_add_feed();
220
    if ($diff = array_diff(array_keys($new_feeds), array_keys($stored_feeds))) {
221
      foreach ($diff as $url) {
222
        $block->feeds[$url] = $new_feeds[$url];
223
      }
224
    }
225
  }
226

    
227
  $view->destroy();
228
  return $block;
229
}
230

    
231
/**
232
 * Returns an edit form for a block.
233
 */
234
function views_content_views_select_display($form, &$form_state) {
235
  $view = views_get_view($form_state['subtype_name']);
236
  if (empty($view)) {
237
    return;
238
  }
239

    
240
  $displays = array();
241
  foreach ($view->display as $id => $display) {
242
    // Content pane views should never be used this way.
243
    if ($display->display_plugin != 'panel_pane') {
244
      $displays[$id] = views_content_get_display_label($view, $id);
245
    }
246
  }
247

    
248
  $form['display'] = array(
249
    '#type' => 'select',
250
    '#title' => t('Display'),
251
    '#options' => $displays,
252
    '#description' => t('Choose which display of this view you wish to use.')
253
  );
254

    
255
  return $form;
256
}
257

    
258
/**
259
 * Submit the basic view edit form.
260
 *
261
 * This just dumps everything into the $conf array.
262
 */
263
function views_content_views_select_display_submit(&$form, &$form_state) {
264
  $form_state['conf']['display'] = $form_state['values']['display'];
265
}
266

    
267
/**
268
 * Returns an edit form for a block.
269
 */
270
function views_content_views_content_type_edit_form($form, &$form_state) {
271
  $conf = $form_state['conf'];
272
  $view = _views_content_views_update_conf($conf, $form_state['subtype_name']);
273

    
274
  if (empty($view) || !is_object($view)) {
275
    $form['markup'] = array('#value' => t('Broken/missing/deleted view.'));
276
    return;
277
  }
278

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

    
281
  // @todo
282
  // If using the older format, just a context is listed. We should go through
283
  // and check for that and forcibly set them to the right converter so that
284
  // it doesn't get changed to some whacky default. Oooor just let it get changed
285
  // to 'no context', I suppose.
286

    
287
  $required = array();
288
  if (isset($view->display_handler) && $arguments = $view->display_handler->get_handlers('argument')) {
289
    foreach ($arguments as $arg) {
290
      $required[] = new ctools_context_optional($arg->ui_name(), 'any');
291
    }
292
  }
293

    
294
  if ($required) {
295
    $form['context'] = ctools_context_converter_selector($form_state['contexts'], $required, isset($conf['context']) ? $conf['context'] : array());
296
  }
297

    
298
  $form['link_to_view'] = array(
299
    '#type' => 'checkbox',
300
    '#default_value' => $conf['link_to_view'],
301
    '#title' => t('Link title to view'),
302
  );
303

    
304
  $form['more_link'] = array(
305
    '#type' => 'checkbox',
306
    '#default_value' => $conf['more_link'],
307
    '#title' => t('Provide a "more" link that links to the view'),
308
    '#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.'),
309
  );
310

    
311
  $form['feed_icons'] = array(
312
    '#type' => 'checkbox',
313
    '#default_value' => $conf['feed_icons'],
314
    '#title' => t('Display feed icons'),
315
  );
316

    
317
  $form['pager_settings'] = array(
318
    '#type' => 'fieldset',
319
    '#collapsible' => FALSE,
320
    '#title' => t('Custom pager settings'),
321
  );
322

    
323
  $form['pager_settings']['override_pager_settings'] = array(
324
    '#type' => 'checkbox',
325
    '#title' => t('Use different pager settings from view settings'),
326
    '#default_value' => $conf['override_pager_settings'],
327
    '#id' => 'override-pager-checkbox',
328
  );
329

    
330
  if ($view->display_handler->get_option('use_ajax')) {
331
    $form['pager_settings']['warning'] = array(
332
      '#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>',
333
    );
334
  }
335

    
336
  $form['pager_settings']['use_pager'] = array(
337
    '#prefix' => '<div class="container-inline">',
338
    '#type' => 'checkbox',
339
    '#title' => t('Use pager'),
340
    '#default_value' => $conf['use_pager'],
341
    '#id' => 'use-pager-checkbox',
342
    '#dependency' => array('override-pager-checkbox' => array(1)),
343
  );
344
  $form['pager_settings']['pager_id'] = array(
345
    '#type' => 'textfield',
346
    '#default_value' => $conf['pager_id'],
347
    '#title' => t('Pager ID'),
348
    '#size' => 4,
349
    '#id' => 'use-pager-textfield',
350
    '#dependency' => array('override-pager-checkbox' => array(1), 'use-pager-checkbox' => array(1)),
351
    '#dependency_count' => 2,
352
    '#suffix' => '</div>',
353
  );
354

    
355
  $form['pager_settings']['nodes_per_page'] = array(
356
    '#type' => 'textfield',
357
    '#default_value' => $conf['nodes_per_page'],
358
    '#size' => 4,
359
    '#title' => t('Num posts'),
360
    '#dependency' => array('override-pager-checkbox' => array(1)),
361
  );
362

    
363
  $form['pager_settings']['offset'] = array(
364
    '#type' => 'textfield',
365
    '#default_value' => $conf['offset'],
366
    '#title' => t('Offset'),
367
    '#size' => 4,
368
    '#description' => t('The number of items to skip and not display.'),
369
    '#dependency' => array('override-pager-checkbox' => array(1)),
370
  );
371

    
372
  $form['panel_args'] = array(
373
    '#type' => 'checkbox',
374
    '#title' => t('Send arguments'),
375
    '#default_value' => $conf['panel_args'],
376
    '#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.'),
377
  );
378

    
379
  $form['args'] = array(
380
    '#type' => 'textfield',
381
    '#default_value' => $conf['args'],
382
    '#title' => t('Arguments'),
383
    '#size' => 30,
384
    '#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.'),
385
  );
386

    
387
  $form['url'] = array(
388
    '#type' => 'textfield',
389
    '#default_value' => $conf['url'],
390
    '#title' => t('Override URL'),
391
    '#size' => 30,
392
    '#description' => t('If this is set, override the View URL; this can sometimes be useful to set to the panel URL'),
393
  );
394

    
395
  $view->destroy();
396
  return $form;
397
}
398

    
399
/**
400
 * Store form values in $conf.
401
 */
402
function views_content_views_content_type_edit_form_submit(&$form, &$form_state) {
403
  // Copy everything from our defaults.
404
  foreach (array_keys($form_state['plugin']['defaults']) as $key) {
405
    $form_state['conf'][$key] = $form_state['values'][$key];
406
  }
407
}
408

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

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

    
419
  $title = views_content_get_display_label($view, $view->current_display);
420
  return t('View: @name', array('@name' => $view->get_human_name() . ': ' . $title));
421
}
422

    
423
/**
424
 * Returns the administrative title for a type.
425
 */
426
function views_content_views_content_type_admin_info($subtype, $conf, $contexts) {
427
  $view = _views_content_views_update_conf($conf, $subtype);
428

    
429
  if (!is_object($view)) {
430
    return t('Deleted/missing view @view', array('@view' => $view));
431
  }
432

    
433
  $display = empty($conf['display']) ? $view->current_display : $conf['display'];
434
  $block = new stdClass();
435

    
436
  $block->title = t('View information');
437

    
438
  $block->content = '<ul>';
439
  $block->content .= '<li>' . t('Using display @display.', array('@display' => views_content_get_display_label($view, $display))) . '</li>';
440

    
441
  if (!empty($conf['context']) && $arguments = $view->display_handler->get_handlers('argument')) {
442
    $argument = reset($arguments);
443
    foreach ($conf['context'] as $count => $context_info) {
444
      if (!$argument) {
445
        break;
446
      }
447

    
448
      if (!strpos($context_info, '.')) {
449
        // old skool: support pre-converter contexts as well.
450
        $cid = $context_info;
451
        $converter = '';
452
      }
453
      else {
454
        list($cid, $converter) = explode('.', $context_info, 2);
455
      }
456

    
457
      if (!empty($contexts[$cid])) {
458
        $converters = ctools_context_get_converters($cid . '.', $contexts[$cid]);
459
        $converter = !empty($converters[$context_info]) ? $converters[$context_info] : t('Default');
460
        $block->content .= '<li>' . t('Argument @arg using context @context converted into @converter', array(
461
          '@arg' => $argument->ui_name(), '@context' => $contexts[$cid]->get_identifier(),
462
          '@converter' => $converter)) . '</li>';
463
      }
464
      $argument = next($arguments);
465
    }
466
  }
467

    
468
  $block->content .= '<li>' . t('@count items displayed.', array('@count' => $conf['nodes_per_page'])) . '</li>';
469
  if ($conf['use_pager']) {
470
    $block->content .= '<li>' . t('With pager.') . '</li>';
471
  }
472
  else {
473
    $block->content .= '<li>' . t('Without pager.') . '</li>';
474
  }
475

    
476
  if ($conf['offset']) {
477
    $block->content .= '<li>' . t('Skipping first @count results', array('@count' => $conf['offset'])) . '</li>';
478
  }
479
  if ($conf['more_link']) {
480
    $block->content .= '<li>' . t('With more link.') . '</li>';
481
  }
482
  if ($conf['feed_icons']) {
483
    $block->content .= '<li>' . t('With feed icon.') . '</li>';
484
  }
485
  if ($conf['panel_args']) {
486
    $block->content .= '<li>' . t('Sending arguments.') . '</li>';
487
  }
488
  if ($conf['args']) {
489
    $block->content .= '<li>' . t('Using arguments: @args', array('@args' => $conf['args'])) . '</li>';
490
  }
491
  if ($conf['url']) {
492
    $block->content .= '<li>' . t('Using url: @url', array('@url' => $conf['url'])) . '</li>';
493
  }
494

    
495
  $view->destroy();
496
  return $block;
497
}
498

    
499
/**
500
 * Update the $conf to deal with updates from Drupal 5.
501
 *
502
 * @param &$conf
503
 *   The $conf array to modify.
504
 * @param $subtype
505
 *   The subtype in use. This should just be the view name, but in older
506
 *   versions it was the view name with a dash and the display ID.
507
 *   If this is the case, we can use it to correct the 'display' setting
508
 *   in the $conf.
509
 * @return
510
 *   The $view with the initialized display. If the $view could not be
511
 *   loaded, the name attempted will be loaded for use in errors.
512
 *   Correct error checking on this function checks against is_object().
513
 */
514
function _views_content_views_update_conf(&$conf, $subtype) {
515
  $plugin = ctools_get_content_type('views');
516

    
517
  // Special: Existing content types get a different default than new ones:
518
  if (!empty($conf) && !isset($conf['override_pager_settings'])) {
519
    $conf['override_pager_settings'] = TRUE;
520
  }
521

    
522
  // Make sure that our defaults are always set if there is no
523
  // previous setting. This helps updates go more smoothly.
524
  foreach ($plugin['defaults'] as $key => $value) {
525
    if (!isset($conf[$key])) {
526
      $conf[$key] = $value;
527
    }
528
  }
529

    
530
  if (strpos($subtype, '-')) {
531
    list($name, $display) = explode('-', $subtype);
532
    $view = views_get_view($name);
533
    if (!isset($conf['display'])) {
534
      $conf['display'] = $display;
535
    }
536
  }
537
  else {
538
    $name = $subtype;
539
    $view = views_get_view($subtype);
540
    $display = isset($conf['display']) ? $conf['display'] : 'default';
541
  }
542

    
543
  if (empty($view)) {
544
    return $name;
545
  }
546

    
547
  $view->set_display($display);
548
  // $view->current_display will now reflect this value.
549

    
550
  // If set NOT to override, go ahead and refresh from the view.
551
  if (empty($conf['override_pager_settings'])) {
552
    if (method_exists($view, 'init_pager')) {
553
      $pager = $view->display_handler->get_option('pager');
554
      $conf['use_pager'] = $pager['type'] != 'none' && $pager['type'] != 'some';
555
      $conf['pager_id'] = isset($pager['options']['id']) ? $pager['options']['id'] : 0;
556
      $conf['offset'] = isset($pager['options']['offset']) ? $pager['options']['offset'] : 0;
557
      $conf['nodes_per_page'] = isset($pager['options']['items_per_page']) ? $pager['options']['items_per_page'] : 0;
558
    }
559
    else {
560
      $conf['use_pager'] = $view->display_handler->get_option('use_pager');
561
      $conf['pager_id'] = $view->display_handler->get_option('element_id');
562
      $conf['nodes_per_page'] = $view->display_handler->get_option('items_per_page');
563
      $conf['offset'] = $view->display_handler->get_option('offset');
564
    }
565
  }
566

    
567
  return $view;
568
}