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 85ad3d82 Assos Assos
<?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 96a203dd Assos Assos
        array_splice($args, $count, 0, array($arg));
137 85ad3d82 Assos Assos
      }
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
}