Projet

Général

Profil

Paste
Télécharger (20,8 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ds / views / views_plugin_ds_entity_view.inc @ 74f6bef0

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

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

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

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

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

    
108
  function options_form(&$form, &$form_state) {
109
    parent::options_form($form, $form_state);
110

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

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

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

    
160
    // Changing view modes.
161
    $form['alternating_fieldset'] = array(
162
      '#type' => 'fieldset',
163
      '#title' => t('Alternating view mode'),
164
      '#collapsible' => TRUE,
165
      '#collapsed' => !$this->options['alternating'],
166
    );
167
    $form['alternating_fieldset']['alternating'] = array(
168
      '#type' => 'checkbox',
169
      '#title' => t('Use the changing view mode selector'),
170
      '#default_value' => $this->options['alternating'],
171
    );
172
    $form['alternating_fieldset']['allpages'] = array(
173
      '#type' => 'checkbox',
174
      '#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.'),
175
      '#default_value' => (isset($this->options['alternating_fieldset']['allpages'])) ? $this->options['alternating_fieldset']['allpages'] : FALSE,
176
    );
177

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

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

    
219
    if (!empty($sorts)) {
220
      $sort_options = array();
221
      foreach ($sorts as $key => $sort) {
222
        $sort_name = drupal_ucfirst($sort['field']);
223
        $sort_options[$sort['table'] . '|' . $sort['field']] = $sort_name;
224
      }
225

    
226
      $form['grouping_fieldset']['group_field'] = array(
227
        '#type' => 'select',
228
        '#options' => $sort_options,
229
        '#default_value' => isset($this->options['grouping_fieldset']['group_field']) ? $this->options['grouping_fieldset']['group_field'] : '',
230
      );
231

    
232
      $form['grouping_fieldset']['group_field_function'] = array(
233
        '#type' => 'textfield',
234
        '#title' => 'Heading function',
235
        '#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);')),
236
        '#default_value' => isset($this->options['grouping_fieldset']['group_field_function']) ? $this->options['grouping_fieldset']['group_field_function'] : '',
237
      );
238
    }
239
    else {
240
      $form['grouping_fieldset']['grouping']['#disabled'] = TRUE;
241
      $form['grouping_fieldset']['grouping']['#description'] = t('Grouping is disabled because you do not have any sort fields.');
242
    }
243

    
244
    // Advanced function.
245
    $delta_fields = array();
246
    $field_api_fields = field_info_instances($this->entity_type);
247
    foreach ($field_api_fields as $bundle => $fields) {
248
      foreach ($fields as $field_name => $instance_info) {
249
        $field_info = field_info_field($field_name);
250
        if ($field_info['cardinality'] != 1) {
251
          $delta_fields[$field_name] = $field_name;
252
        }
253
      }
254
    }
255
    $form['delta_fieldset'] = array(
256
      '#type' => 'fieldset',
257
      '#title' => t('Delta fields'),
258
      '#collapsible' => TRUE,
259
      '#collapsed' => empty($this->options['delta_fields']),
260
    );
261
    $form['delta_fieldset']['delta_fields'] = array(
262
      '#type' => 'select',
263
      '#title' => t('Select fields'),
264
      '#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.'),
265
      '#options' => $delta_fields,
266
      '#multiple' => TRUE,
267
      '#default_value' => !empty($this->options['delta_fields']) ? $this->options['delta_fields'] : '',
268
    );
269

    
270
    // Advanced function.
271
    $form['advanced_fieldset'] = array(
272
      '#type' => 'fieldset',
273
      '#title' => t('Advanced view mode'),
274
      '#collapsible' => TRUE,
275
      '#collapsed' => !$this->options['advanced'],
276
    );
277
    $form['advanced_fieldset']['advanced'] = array(
278
      '#type' => 'checkbox',
279
      '#title' => t('Use the advanced view mode selector'),
280
      '#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)),
281
      '#default_value' => $this->options['advanced'],
282
    );
283
  }
284

    
285
  /**
286
   * Validate view mode type selector.
287
   */
288
  function options_validate(&$form, &$form_state) {
289
    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']) {
290
      form_set_error('advanced', t('You can not have changing/grouping and advanced enabled at the same time'));
291
    }
292
  }
293

    
294
  /**
295
   * Reset all fieldsets except for changing.
296
   */
297
  function options_submit(&$form, &$form_state) {
298
    $form_state['values']['row_options']['load_comments'] = $form_state['values']['row_options']['default_fieldset']['load_comments'];
299
    $form_state['values']['row_options']['view_mode'] = $form_state['values']['row_options']['default_fieldset']['view_mode'];
300
    $form_state['values']['row_options']['switch'] = isset($form_state['values']['row_options']['switch_fieldset']) ? $form_state['values']['row_options']['switch_fieldset']['switch'] : FALSE;
301
    $form_state['values']['row_options']['alternating'] = $form_state['values']['row_options']['alternating_fieldset']['alternating'];
302
    $form_state['values']['row_options']['grouping'] = $form_state['values']['row_options']['grouping_fieldset']['grouping'];
303
    $form_state['values']['row_options']['advanced'] = $form_state['values']['row_options']['advanced_fieldset']['advanced'];
304
    $form_state['values']['row_options']['delta_fields'] = $form_state['values']['row_options']['delta_fieldset']['delta_fields'];
305
  }
306

    
307
  /**
308
   * Query method.
309
   */
310
  function query() {
311
    parent::query();
312
    $this->delta_fields = array();
313
    $delta_fields = $this->options['delta_fieldset']['delta_fields'];
314
    if (!empty($delta_fields)) {
315
      foreach ($delta_fields as $field) {
316
        $field_name = 'field_data_' . $field;
317
        $field_name_delta = $field_name . '_delta';
318
        $this->view->query->add_field($field_name, 'delta');
319
        $this->delta_fields[$field] = $field_name_delta;
320
      }
321
    }
322
  }
323

    
324
  /**
325
   * Preload all entities.
326
   */
327
  function pre_render($values) {
328
    $ids = array();
329
    foreach ($values as $row) {
330
      $ids[] = $row->{$this->field_alias};
331
    }
332

    
333
    switch ($this->base_table) {
334
      case 'node':
335
        $this->entities = node_load_multiple($ids);
336
        break;
337
      case 'comment':
338
        $this->entities = comment_load_multiple($ids);
339
        break;
340
      case 'users':
341
        $this->entities = user_load_multiple($ids);
342
        break;
343
      case 'taxonomy_term_data':
344
        $this->entities = taxonomy_term_load_multiple($ids);
345
        if (function_exists('i18n_taxonomy_localize_terms')) {
346
          global $language;
347
          foreach($this->entities as $index => &$entity) {
348
            $entity = i18n_taxonomy_localize_terms($entity, $language->language);
349
          }
350
        }
351
        break;
352
      case 'file_managed':
353
        $this->entities = file_load_multiple($ids);
354
        break;
355
      case 'micro':
356
        $this->entities = entity_load($this->base_table, $ids);
357
        break;
358
    }
359
  }
360

    
361
  /**
362
   * Render each $row.
363
   */
364
  function render($row) {
365

    
366
    // Set a variable to indicate if comments need to be loaded or not.
367
    $load_comments = isset($this->options['load_comments']) ? $this->options['load_comments'] : FALSE;
368

    
369
    // The advanced selector searches for a function called
370
    // ds_views_row_adv_VIEWSNAME. Return the row immediately.
371
    if ($this->options['advanced']) {
372
      $row_function = 'ds_views_row_adv_' . $this->view->name;
373
      if (function_exists($row_function)) {
374
        return $row_function($this->entities[$row->{$this->field_alias}], $this->options['view_mode'], $load_comments);
375
      }
376
    }
377

    
378
    // Keep a static group array.
379
    static $grouping = array();
380
    $view_name = $this->view->name . '_' . $this->view->current_display;
381
    $group_value_content = '';
382

    
383
    // Default view mode.
384
    $view_mode = $this->options['view_mode'];
385

    
386
    // Display settings view mode.
387
    if ($this->options['switch_fieldset']['switch']) {
388
      if (!empty($this->entities[$row->{$this->field_alias}]->ds_switch)) {
389
        $view_mode = $this->entities[$row->{$this->field_alias}]->ds_switch;
390
      }
391
    }
392

    
393
    // Change the view mode per row.
394
    if ($this->options['alternating']) {
395
      // Check for paging to determine the view mode.
396
      if (isset($_GET['page']) && isset($this->options['alternating_fieldset']['allpages']) && !$this->options['alternating_fieldset']['allpages']) {
397
        $view_mode = $this->options['view_mode'];
398
      }
399
      else {
400
        $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'];
401
      }
402
    }
403

    
404
    // Give modules a chance to alter the $view_mode. Use $view_mode by ref.
405
    $context = array(
406
      'entity' => $this->entities[$row->{$this->field_alias}],
407
      'view_name' => $this->view->name,
408
      'display' => $this->view->current_display
409
    );
410
    drupal_alter('ds_views_view_mode', $view_mode, $context);
411
    // Call the row render function.
412
    $content = $this->ds_views_row_render_entity($view_mode, $row, $load_comments);
413

    
414
    // Keep a static grouping for this view.
415
    if ($this->options['grouping']) {
416

    
417
      $group_field = $this->options['grouping_fieldset']['group_field'];
418

    
419
      // New way of creating the alias.
420
      if (strpos($group_field, '|') !== FALSE) {
421
        list($ftable, $ffield) = explode('|', $group_field);
422
        $group_field = $this->view->sort[$ffield]->table_alias . '_' . $this->view->sort[$ffield]->real_field;
423
      }
424

    
425
      // Note, the keys in the $row object are cut of at 60 chars.
426
      // see views_plugin_query_default.inc.
427
      if (drupal_strlen($group_field) > 60) {
428
        $group_field = drupal_substr($group_field, 0, 60);
429
      }
430

    
431
      $raw_group_value = isset($row->{$group_field}) ? $row->{$group_field} : '';
432
      $group_value = $raw_group_value;
433
      // Special function to format the heading value.
434
      if (!empty($this->options['grouping_fieldset']['group_field_function'])) {
435
        $function = $this->options['grouping_fieldset']['group_field_function'];
436
        if (function_exists($function)) {
437
          $group_value = $function($raw_group_value, $this->entities[$row->{$this->field_alias}]);
438
        }
439
      }
440
      if (!isset($grouping[$view_name][$group_value])) {
441
        $group_value_content = '<h2 class="grouping-title">' . $group_value . '</h2>';
442
        $grouping[$view_name][$group_value] = $group_value;
443
      }
444
    }
445

    
446
    // Grouping.
447
    if (!empty($grouping[$view_name])) {
448
      if (!empty($group_value_content)) {
449
        $content = $group_value_content . $content;
450
      }
451
      $content = '<div class="grouping-content">' . $content . '</div>';
452
    }
453

    
454
    // Return the content.
455
    return $content;
456
  }
457

    
458
  /**
459
   * Render a discrete entity based with the selected view mode.
460
   *
461
   * @param $view_mode
462
   *   The view mode which is set in the Views' options.
463
   * @param $row
464
   *   The current active row object being rendered.
465
   *
466
   * @return $content
467
   *   An entity view rendered as HTML
468
   */
469
  function ds_views_row_render_entity($view_mode, $row, $load_comments) {
470

    
471
    // Add delta fields if necessary.
472
    if (!empty($this->delta_fields)) {
473
      $ds_delta = array();
474
      foreach ($this->delta_fields as $field_name => $delta_field) {
475
        $ds_delta[$field_name] = $row->{$delta_field};
476
      }
477
      $this->entities[$row->{$this->field_alias}]->ds_delta = $ds_delta;
478
    }
479

    
480
    $row_function = 'ds_views_row_render_' . $this->base_table;
481
    $content = $row_function($this->entities[$row->{$this->field_alias}], $view_mode, $load_comments);
482
    // Allow other modules to modify the entity render array in context.
483
    $context = array(
484
      'row' => $row,
485
      'view' => &$this->view,
486
      'view_mode' => $view_mode,
487
      'load_comments' => $load_comments,
488
    );
489
    drupal_alter('ds_views_row_render_entity', $content, $context);
490
    return drupal_render($content);
491
  }
492
}
493

    
494
/**
495
 * Render the node through the entity plugin.
496
 */
497
function ds_views_row_render_node($entity, $view_mode, $load_comments) {
498
  $node_display = node_view($entity, $view_mode);
499
  if ($load_comments && module_exists('comment')) {
500
    $node_display['comments'] = comment_node_page_additions($entity);
501
  }
502
  return $node_display;
503
}
504

    
505
/**
506
 * Render the comment through the entity plugin.
507
 */
508
function ds_views_row_render_comment($entity, $view_mode, $load_comments) {
509
  $node = node_load($entity->nid);
510
  $element = comment_view($entity, $node, $view_mode);
511
  return $element;
512
}
513

    
514
/**
515
 * Render the user through the entity plugin.
516
 */
517
function ds_views_row_render_users($entity, $view_mode, $load_comments) {
518
  $element = user_view($entity, $view_mode);
519
  return $element;
520
}
521

    
522
/**
523
 * Render the taxonomy term through the entity plugin.
524
 */
525
function ds_views_row_render_taxonomy_term_data($entity, $view_mode, $load_comments) {
526
  $element = taxonomy_term_view($entity, $view_mode);
527
  return $element;
528
}
529

    
530
/**
531
 * Render the file through the entity plugin.
532
 */
533
function ds_views_row_render_file_managed($entity, $view_mode, $load_comments) {
534
  $element = file_view($entity, $view_mode);
535
  return $element;
536
}
537

    
538
/**
539
 * Render the micro through the entity plugin.
540
 */
541
function ds_views_row_render_micro($entity, $view_mode, $load_comments) {
542
  $element = micro_view($entity, $view_mode);
543
  return $element;
544
}