Project

General

Profile

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

root / drupal7 / sites / all / modules / ds / views / views_plugin_ds_entity_view.inc @ 6e9292aa

1
<?php
2

    
3
/**
4
 * @file
5
 * Provides the Display Suite views entity style plugin.
6
 */
7

    
8
/**
9
 * Plugin which defines the view mode on the resulting entity object.
10
 */
11
class views_plugin_ds_entity_view extends views_plugin_row {
12

    
13
  protected $group_count;
14

    
15
  function init(&$view, &$display, $options = NULL) {
16
    parent::init($view, $display, $options);
17
    $this->base_table = $view->base_table;
18
    // Special case for apachesolr_views.
19
    if ($this->base_table == 'apachesolr') {
20
      $this->base_table = 'node';
21
    }
22
    $this->base_field = $this->ds_views_3_support();
23

    
24
    $this->group_count = 0;
25
  }
26

    
27
  // Return base_field based on base_table. It might not be
28
  // the cleanest solution, it's the fastest though.
29
  function ds_views_3_support() {
30
    if (strpos($this->base_table, 'eck_') === 0) {
31
      // Base tables of entities created by entity construction kit (eck)
32
      // are prefixed with 'eck_' and the base field is always 'id'.
33
      $this->entity_type = str_replace('eck_', '', $this->base_table);
34
      return 'id';
35
    }
36

    
37
    $base_table_fields = array(
38
      'node' => array('field' => 'nid', 'entity_type' => 'node'),
39
      'comment' => array('field' => 'cid', 'entity_type' => 'comment'),
40
      'users' => array('field' => 'uid', 'entity_type' => 'user'),
41
      'apachesolr' => array('field' => 'nid', 'entity_type' => 'node'),
42
      'taxonomy_term_data' => array('field' => 'tid', 'entity_type' => 'taxonomy_term'),
43
      'file_managed' => array('field' => 'fid', 'entity_type' => 'file'),
44
      'micro' => array('field' => 'mid', 'entity_type' => 'micro'),
45
    );
46
    $this->entity_type = isset($base_table_fields[$this->base_table]) ? $base_table_fields[$this->base_table]['entity_type'] : 'node';
47
    return isset($base_table_fields[$this->base_table]) ? $base_table_fields[$this->base_table]['field'] : 'nid';
48
  }
49

    
50
  function option_definition() {
51
    $options = parent::option_definition();
52
    $options['view_mode'] = array('default' => 'teaser');
53
    $options['load_comments'] = array('default' => FALSE);
54
    $options['alternating'] = array('default' => FALSE);
55
    $options['changing'] = array('default' => FALSE);
56
    $options['grouping'] = array('default' => FALSE);
57
    $options['advanced'] = array('default' => FALSE);
58
    $options['delta_fieldset'] = array(
59
      'contains' => array(
60
        'delta_fields' => array('default' => FALSE),
61
      ),
62
    );
63
    $options['grouping_fieldset'] = array(
64
      'contains' => array(
65
        'grouping' => array('default' => FALSE, 'bool' => TRUE),
66
        'group_odd_even' => array('default' => FALSE, 'bool' => TRUE),
67
        'group_field' => array('default' => ''),
68
        'group_field_function' => array('default' => ''),
69
      ),
70
    );
71
    $options['default_fieldset'] = array(
72
      'contains' => array(
73
        'view_mode' => array('default' => ''),
74
      ),
75
    );
76
    $options['switch_fieldset'] = array(
77
      'contains' => array(
78
        'switch' => array('default' => FALSE, 'bool' => TRUE),
79
      ),
80
    );
81
    $options['alternating_fieldset'] = array(
82
      'contains' => array(
83
        'alternating' => array('default' => FALSE, 'bool' => TRUE),
84
        'allpages' => array('default' => FALSE, 'bool' => TRUE),
85
        'item' => array(
86
          'default' => array(),
87
          'export' => 'ds_item_export_option',
88
        ),
89
      ),
90
    );
91
    $options['advanced_fieldset'] = array(
92
      'contains' => array(
93
        'advanced' => array('default' => FALSE, 'bool' => TRUE),
94
      ),
95
    );
96
    return $options;
97
  }
98

    
99
  /**
100
   * Custom export function for alternating_fieldset items.
101
   */
102
  function ds_item_export_option($indent, $prefix, $storage, $option, $definition, $parents) {
103
    $output = '';
104
    $definition = array('default' => 'teaser');
105
    foreach ($storage as $key => $value) {
106
      if (strstr($key, 'item_') !== FALSE) {
107
        $output .= parent::export_option($indent, $prefix, $storage, $key, $definition, $parents);
108
      }
109
    }
110
    return $output;
111
  }
112

    
113
  function options_form(&$form, &$form_state) {
114
    parent::options_form($form, $form_state);
115

    
116
    $view_mode_options = array();
117
    $entity_type = $this->view->base_table;
118
    // In case we're working with users or managed files, change the entity type variable.
119
    if ($entity_type == 'users') $entity_type = 'user';
120
    if ($entity_type == 'file_managed') $entity_type = 'file';
121
    $entity_view_modes = ds_entity_view_modes($entity_type);
122
    foreach ($entity_view_modes as $key => $view_mode) {
123
      $view_mode_options[$key] = $view_mode['label'];
124
    }
125

    
126
    // Default view mode & load comments.
127
    $form['default_fieldset'] = array(
128
      '#type' => 'fieldset',
129
      '#title' => t('Default view mode'),
130
      '#collapsible' => TRUE,
131
      '#collapsed' => ($this->options['advanced']),
132
    );
133
    $form['default_fieldset']['view_mode'] = array(
134
      '#type' => 'select',
135
      '#default_value' => $this->options['view_mode'],
136
      '#options' => $view_mode_options,
137
      '#description' => t('Select the default view mode for this view.')
138
    );
139
    if ($entity_type == 'node') {
140
      $form['default_fieldset']['load_comments'] = array(
141
        '#title' => t('Comments'),
142
        '#type' => 'checkbox',
143
        '#description' => t('Load comments for every node to display.'),
144
        '#default_value' => isset($this->options['load_comments']) ? $this->options['load_comments'] : FALSE,
145
        '#access' => module_exists('comment'),
146
      );
147
    }
148

    
149
    // Use view mode of display settings.
150
    if ($entity_type == 'node' && variable_get('ds_extras_switch_view_mode', FALSE)) {
151
      $form['switch_fieldset'] = array(
152
        '#type' => 'fieldset',
153
        '#title' => t('Use view mode of display settings'),
154
        '#collapsible' => TRUE,
155
        '#collapsed' => !$this->options['switch_fieldset']['switch'],
156
      );
157
      $form['switch_fieldset']['switch'] = array(
158
        '#type' => 'checkbox',
159
        '#title' => t('Use view mode of display settings'),
160
        '#default_value' => $this->options['switch_fieldset']['switch'],
161
        '#description' => t('Use the alternative view mode selected in the display settings tab.')
162
      );
163
    }
164

    
165
    // Changing view modes.
166
    $form['alternating_fieldset'] = array(
167
      '#type' => 'fieldset',
168
      '#title' => t('Alternating view mode'),
169
      '#collapsible' => TRUE,
170
      '#collapsed' => !$this->options['alternating'],
171
    );
172
    $form['alternating_fieldset']['alternating'] = array(
173
      '#type' => 'checkbox',
174
      '#title' => t('Use the changing view mode selector'),
175
      '#default_value' => $this->options['alternating'],
176
    );
177
    $form['alternating_fieldset']['allpages'] = array(
178
      '#type' => 'checkbox',
179
      '#title' => t('Use this configuration on every page. Otherwhise the default view mode is used as soon you browse away from the first page of this view.'),
180
      '#default_value' => (isset($this->options['alternating_fieldset']['allpages'])) ? $this->options['alternating_fieldset']['allpages'] : FALSE,
181
    );
182

    
183
    $limit = $this->view->display_handler->get_option('items_per_page');
184
    $pager = $this->view->display_handler->get_plugin('pager');
185
    $limit = (isset($pager->options['items_per_page'])) ? $pager->options['items_per_page'] : 0;
186
    if ($limit == 0 || $limit > 20) {
187
      $form['alternating_fieldset']['disabled'] = array(
188
        '#markup' => t('This option is disabled because you have unlimited items or listing more than 20 items.'),
189
      );
190
      $form['alternating_fieldset']['alternating']['#disabled'] = TRUE;
191
      $form['alternating_fieldset']['allpages']['#disabled'] = TRUE;
192
    }
193
    else {
194
      $i = 1;
195
      $a = 0;
196
      while ($limit != 0) {
197
        $form['alternating_fieldset']['item_' . $a] = array(
198
          '#title' => t('Item @nr', array('@nr' => $i)),
199
          '#type' => 'select',
200
          '#default_value' => (isset($this->options['alternating_fieldset']['item_' . $a])) ? $this->options['alternating_fieldset']['item_' . $a] : 'teaser',
201
          '#options' => $view_mode_options,
202
        );
203
        $limit--;
204
        $a++;
205
        $i++;
206
      }
207
    }
208

    
209
    // Grouping rows.
210
    $sorts = $this->view->display_handler->get_option('sorts');
211
    $groupable = !empty($sorts) && $this->options['grouping'];
212
    $form['grouping_fieldset'] = array(
213
      '#type' => 'fieldset',
214
      '#title' => t('Group data'),
215
      '#collapsible' => TRUE,
216
      '#collapsed' => !$groupable,
217
    );
218
    $form['grouping_fieldset']['grouping'] = array(
219
      '#type' => 'checkbox',
220
      '#title' => t('Group data on a field. The value of this field will be displayed too.'),
221
      '#default_value' => $groupable,
222
    );
223

    
224
    if (!empty($sorts)) {
225
      $sort_options = array();
226
      foreach ($sorts as $key => $sort) {
227
        $sort_name = drupal_ucfirst($sort['field']);
228
        $sort_options[$sort['table'] . '|' . $sort['field']] = $sort_name;
229
      }
230

    
231
      $form['grouping_fieldset']['group_field'] = array(
232
        '#type' => 'select',
233
        '#options' => $sort_options,
234
        '#default_value' => isset($this->options['grouping_fieldset']['group_field']) ? $this->options['grouping_fieldset']['group_field'] : '',
235
      );
236

    
237
      $form['grouping_fieldset']['group_field_function'] = array(
238
        '#type' => 'textfield',
239
        '#title' => 'Heading function',
240
        '#description' => check_plain(t('The value of the field can be in a very raw format (eg, date created). Enter a custom function which you can use to format that value. The value and the object will be passed into that function eg. custom_function($raw_value, $object);')),
241
        '#default_value' => isset($this->options['grouping_fieldset']['group_field_function']) ? $this->options['grouping_fieldset']['group_field_function'] : '',
242
      );
243
    }
244
    else {
245
      $form['grouping_fieldset']['grouping']['#disabled'] = TRUE;
246
      $form['grouping_fieldset']['grouping']['#description'] = t('Grouping is disabled because you do not have any sort fields.');
247
    }
248

    
249
    $form['grouping_fieldset']['group_odd_even'] = array(
250
      '#type' => 'checkbox',
251
      '#title' => t('Add odd/even group classes to the individual group elements'),
252
      '#default_value' => FALSE,
253
    );
254

    
255
    // Advanced function.
256
    $delta_fields = array();
257
    $field_api_fields = field_info_instances($this->entity_type);
258
    foreach ($field_api_fields as $bundle => $fields) {
259
      foreach ($fields as $field_name => $instance_info) {
260
        $field_info = field_info_field($field_name);
261
        if ($field_info['cardinality'] != 1) {
262
          $delta_fields[$field_name] = $field_name;
263
        }
264
      }
265
    }
266
    $form['delta_fieldset'] = array(
267
      '#type' => 'fieldset',
268
      '#title' => t('Delta fields'),
269
      '#collapsible' => TRUE,
270
      '#collapsed' => empty($this->options['delta_fields']),
271
    );
272
    $form['delta_fieldset']['delta_fields'] = array(
273
      '#type' => 'select',
274
      '#title' => t('Select fields'),
275
      '#description' => t('Select fields which "delta" value should be added to the result row. On the manage display of an entity you can decide to look for this delta value to only print that row.'),
276
      '#options' => $delta_fields,
277
      '#multiple' => TRUE,
278
      '#default_value' => !empty($this->options['delta_fields']) ? $this->options['delta_fields'] : '',
279
    );
280

    
281
    // Advanced function.
282
    $form['advanced_fieldset'] = array(
283
      '#type' => 'fieldset',
284
      '#title' => t('Advanced view mode'),
285
      '#collapsible' => TRUE,
286
      '#collapsed' => !$this->options['advanced'],
287
    );
288
    $form['advanced_fieldset']['advanced'] = array(
289
      '#type' => 'checkbox',
290
      '#title' => t('Use the advanced view mode selector'),
291
      '#description' => t('This gives you the opportunity to have full control of a list for really advanced features.<br /> There is no UI for this, you need to create a function named like this: ds_views_row_adv_@VIEWSNAME($entity, $view_mode, $load_comments).<br />See <a href="http://drupal.org/node/697320#ds_views_row_adv_VIEWSNAME">http://drupal.org/node/697320#ds_views_row_adv_VIEWSNAME</a> for an example.', array('@VIEWSNAME' => $this->view->name)),
292
      '#default_value' => $this->options['advanced'],
293
    );
294
  }
295

    
296
  /**
297
   * Validate view mode type selector.
298
   */
299
  function options_validate(&$form, &$form_state) {
300
    if (($form_state['values']['row_options']['alternating_fieldset']['alternating'] || $form_state['values']['row_options']['grouping_fieldset']['grouping']) && $form_state['values']['row_options']['advanced_fieldset']['advanced']) {
301
      form_set_error('advanced', t('You can not have changing/grouping and advanced enabled at the same time'));
302
    }
303
  }
304

    
305
  /**
306
   * Reset all fieldsets except for changing.
307
   */
308
  function options_submit(&$form, &$form_state) {
309
    $form_state['values']['row_options']['load_comments'] = $form_state['values']['row_options']['default_fieldset']['load_comments'];
310
    $form_state['values']['row_options']['view_mode'] = $form_state['values']['row_options']['default_fieldset']['view_mode'];
311
    $form_state['values']['row_options']['switch'] = isset($form_state['values']['row_options']['switch_fieldset']) ? $form_state['values']['row_options']['switch_fieldset']['switch'] : FALSE;
312
    $form_state['values']['row_options']['alternating'] = $form_state['values']['row_options']['alternating_fieldset']['alternating'];
313
    $form_state['values']['row_options']['grouping'] = $form_state['values']['row_options']['grouping_fieldset']['grouping'];
314
    $form_state['values']['row_options']['advanced'] = $form_state['values']['row_options']['advanced_fieldset']['advanced'];
315
    $form_state['values']['row_options']['delta_fields'] = $form_state['values']['row_options']['delta_fieldset']['delta_fields'];
316
  }
317

    
318
  /**
319
   * Query method.
320
   */
321
  function query() {
322
    parent::query();
323
    $this->delta_fields = array();
324
    $delta_fields = $this->options['delta_fieldset']['delta_fields'];
325
    if (!empty($delta_fields)) {
326
      foreach ($delta_fields as $field) {
327
        $field_name = 'field_data_' . $field;
328
        $field_name_delta = $field_name . '_delta';
329
        $this->view->query->add_field($field_name, 'delta');
330
        $this->delta_fields[$field] = $field_name_delta;
331
      }
332
    }
333
  }
334

    
335
  /**
336
   * Preload all entities.
337
   */
338
  function pre_render($values) {
339
    $ids = array();
340
    foreach ($values as $row) {
341
      $ids[] = $row->{$this->field_alias};
342
    }
343

    
344
    switch ($this->base_table) {
345
      case 'node':
346
        $this->entities = node_load_multiple($ids);
347
        break;
348
      case 'comment':
349
        $this->entities = comment_load_multiple($ids);
350
        break;
351
      case 'users':
352
        $this->entities = user_load_multiple($ids);
353
        break;
354
      case 'taxonomy_term_data':
355
        $this->entities = taxonomy_term_load_multiple($ids);
356
        if (function_exists('i18n_taxonomy_localize_terms')) {
357
          global $language;
358
          foreach($this->entities as $index => &$entity) {
359
            $entity = i18n_taxonomy_localize_terms($entity, $language->language);
360
          }
361
        }
362
        break;
363
      case 'file_managed':
364
        $this->entities = file_load_multiple($ids);
365
        break;
366
      case 'micro':
367
        $this->entities = entity_load($this->base_table, $ids);
368
        break;
369
    }
370
  }
371

    
372
  /**
373
   * Render each $row.
374
   */
375
  function render($row) {
376
    // Set a variable to indicate if comments need to be loaded or not.
377
    $load_comments = isset($this->options['load_comments']) ? $this->options['load_comments'] : FALSE;
378

    
379
    // The advanced selector searches for a function called
380
    // ds_views_row_adv_VIEWSNAME. Return the row immediately.
381
    if ($this->options['advanced']) {
382
      $row_function = 'ds_views_row_adv_' . $this->view->name;
383
      if (function_exists($row_function)) {
384
        return $row_function($this->entities[$row->{$this->field_alias}], $this->options['view_mode'], $load_comments);
385
      }
386
    }
387

    
388
    // Keep a static group array.
389
    static $grouping = array();
390
    $view_name = $this->view->name . '_' . $this->view->current_display;
391
    $group_value_content = '';
392

    
393
    // Default view mode.
394
    $view_mode = $this->options['view_mode'];
395

    
396
    // Display settings view mode.
397
    if ($this->options['switch_fieldset']['switch']) {
398
      if (!empty($this->entities[$row->{$this->field_alias}]->ds_switch)) {
399
        $view_mode = $this->entities[$row->{$this->field_alias}]->ds_switch;
400
      }
401
    }
402

    
403
    // Change the view mode per row.
404
    if ($this->options['alternating']) {
405
      // Check for paging to determine the view mode.
406
      if (isset($_GET['page']) && isset($this->options['alternating_fieldset']['allpages']) && !$this->options['alternating_fieldset']['allpages']) {
407
        $view_mode = $this->options['view_mode'];
408
      }
409
      else {
410
        $view_mode = isset($this->options['alternating_fieldset']['item_' . $this->view->row_index]) ? $this->options['alternating_fieldset']['item_' . $this->view->row_index] : $this->options['view_mode'];
411
      }
412
    }
413

    
414
    // Give modules a chance to alter the $view_mode. Use $view_mode by ref.
415
    $context = array(
416
      'entity' => $this->entities[$row->{$this->field_alias}],
417
      'view_name' => $this->view->name,
418
      'display' => $this->view->current_display
419
    );
420
    drupal_alter('ds_views_view_mode', $view_mode, $context);
421
    // Call the row render function.
422
    $content = $this->ds_views_row_render_entity($view_mode, $row, $load_comments);
423

    
424
    // Keep a static grouping for this view.
425
    if ($this->options['grouping']) {
426

    
427
      $group_field = $this->options['grouping_fieldset']['group_field'];
428

    
429
      // New way of creating the alias.
430
      if (strpos($group_field, '|') !== FALSE) {
431
        list($ftable, $ffield) = explode('|', $group_field);
432
        $group_field = $this->view->sort[$ffield]->table_alias . '_' . $this->view->sort[$ffield]->real_field;
433
      }
434

    
435
      // Note, the keys in the $row object are cut of at 60 chars.
436
      // see views_plugin_query_default.inc.
437
      if (drupal_strlen($group_field) > 60) {
438
        $group_field = drupal_substr($group_field, 0, 60);
439
      }
440

    
441
      $raw_group_value = isset($row->{$group_field}) ? $row->{$group_field} : '';
442
      $group_value = $raw_group_value;
443
      // Special function to format the heading value.
444
      if (!empty($this->options['grouping_fieldset']['group_field_function'])) {
445
        $function = $this->options['grouping_fieldset']['group_field_function'];
446
        if (function_exists($function)) {
447
          $group_value = $function($raw_group_value, $this->entities[$row->{$this->field_alias}]);
448
        }
449
      }
450
      if (!isset($grouping[$view_name][$group_value])) {
451
        $group_value_content = '<h2 class="grouping-title">' . $group_value . '</h2>';
452
        $grouping[$view_name][$group_value] = $group_value;
453
        $this->group_count++;
454
      }
455
    }
456

    
457
    // Grouping.
458
    if (!empty($grouping[$view_name])) {
459
      if (!empty($group_value_content)) {
460
        $content = $group_value_content . $content;
461
      }
462
      $classes = array('grouping-content');
463
      if ($this->options['grouping_fieldset']['group_odd_even']) {
464
        if ($this->group_count % 2 == 0) {
465
          $classes[] = 'even';
466
        }
467
        else {
468
          $classes[] = 'odd';
469
        }
470
      }
471

    
472
      $content = '<div class="' . implode(' ', $classes) . '">' . $content . '</div>';
473
    }
474

    
475
    // Return the content.
476
    return $content;
477
  }
478

    
479
  /**
480
   * Render a discrete entity based with the selected view mode.
481
   *
482
   * @param $view_mode
483
   *   The view mode which is set in the Views' options.
484
   * @param $row
485
   *   The current active row object being rendered.
486
   *
487
   * @return $content
488
   *   An entity view rendered as HTML
489
   */
490
  function ds_views_row_render_entity($view_mode, $row, $load_comments) {
491

    
492
    // Add delta fields if necessary.
493
    if (!empty($this->delta_fields)) {
494
      $ds_delta = array();
495
      foreach ($this->delta_fields as $field_name => $delta_field) {
496
        $ds_delta[$field_name] = $row->{$delta_field};
497
      }
498
      $this->entities[$row->{$this->field_alias}]->ds_delta = $ds_delta;
499
    }
500

    
501
    $row_function = 'ds_views_row_render_' . $this->base_table;
502
    $content = $row_function($this->entities[$row->{$this->field_alias}], $view_mode, $load_comments);
503
    // Allow other modules to modify the entity render array in context.
504
    $context = array(
505
      'row' => $row,
506
      'view' => &$this->view,
507
      'view_mode' => $view_mode,
508
      'load_comments' => $load_comments,
509
    );
510
    drupal_alter('ds_views_row_render_entity', $content, $context);
511
    return drupal_render($content);
512
  }
513
}
514

    
515
/**
516
 * Render the node through the entity plugin.
517
 */
518
function ds_views_row_render_node($entity, $view_mode, $load_comments) {
519
  $node_display = node_view($entity, $view_mode);
520
  if ($load_comments && module_exists('comment')) {
521
    $node_display['comments'] = comment_node_page_additions($entity);
522
  }
523
  return $node_display;
524
}
525

    
526
/**
527
 * Render the comment through the entity plugin.
528
 */
529
function ds_views_row_render_comment($entity, $view_mode, $load_comments) {
530
  $node = node_load($entity->nid);
531
  $element = comment_view($entity, $node, $view_mode);
532
  return $element;
533
}
534

    
535
/**
536
 * Render the user through the entity plugin.
537
 */
538
function ds_views_row_render_users($entity, $view_mode, $load_comments) {
539
  $element = user_view($entity, $view_mode);
540
  return $element;
541
}
542

    
543
/**
544
 * Render the taxonomy term through the entity plugin.
545
 */
546
function ds_views_row_render_taxonomy_term_data($entity, $view_mode, $load_comments) {
547
  $element = taxonomy_term_view($entity, $view_mode);
548
  return $element;
549
}
550

    
551
/**
552
 * Render the file through the entity plugin.
553
 */
554
function ds_views_row_render_file_managed($entity, $view_mode, $load_comments) {
555
  $element = file_view($entity, $view_mode);
556
  return $element;
557
}
558

    
559
/**
560
 * Render the micro through the entity plugin.
561
 */
562
function ds_views_row_render_micro($entity, $view_mode, $load_comments) {
563
  $element = micro_view($entity, $view_mode);
564
  return $element;
565
}