Projet

Général

Profil

Paste
Télécharger (13,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / file_entity / file_entity.field.inc @ 87dbc3bf

1
<?php
2

    
3
/**
4
 * @file
5
 * Field API integration for the file_entity module.
6
 */
7

    
8
/**
9
 * Implements hook_field_formatter_info().
10
 */
11
function file_entity_field_formatter_info() {
12
  $info['file_rendered'] = array(
13
    'label' => t('Rendered file'),
14
    'description' => t('Display the file in a specific view mode'),
15
    'field types' => array('file', 'image'),
16
    'settings' => array(
17
      'file_view_mode' => 'default',
18
    ),
19
    'file formatter' => array(
20
      'hidden' => TRUE,
21
    ),
22
  );
23
  $info['file_download_link'] = array(
24
    'label' => t('Download link'),
25
    'description' => t('Displays a link that will force the browser to download the file.'),
26
    'field types' => array('file', 'image'),
27
    'settings' => array(
28
      'text' => t('Download [file:name]'),
29
    ),
30
  );
31
  $info['file_audio'] = array(
32
    'label' => t('Audio'),
33
    'description' => t('Render the file using an HTML5 audio tag.'),
34
    'field types' => array('file'),
35
    'settings' => array(
36
      'controls' => TRUE,
37
      'autoplay' => FALSE,
38
      'loop' => FALSE,
39
      'multiple_file_behavior' => 'tags',
40
    ),
41
    'file formatter' => array(
42
      'mime types' => array('audio/*'),
43
    ),
44
  );
45
  $info['file_video'] = array(
46
    'label' => t('Video'),
47
    'description' => t('Render the file using an HTML5 video tag.'),
48
    'field types' => array('file'),
49
    'settings' => array(
50
      'controls' => TRUE,
51
      'autoplay' => FALSE,
52
      'loop' => FALSE,
53
      'muted' => FALSE,
54
      'width' => NULL,
55
      'height' => NULL,
56
      'multiple_file_behavior' => 'tags',
57
    ),
58
    'file formatter' => array(
59
      'mime types' => array('video/*'),
60
    ),
61
  );
62
  return $info;
63
}
64

    
65
/**
66
 * Implements hook_field_formatter_info_alter().
67
 */
68
function file_entity_field_formatter_info_alter(&$info) {
69
  // Add descriptions to core formatters.
70
  $descriptions = array(
71
    'file_default' => t('Create a simple link to the file. The link is prefixed by a file type icon and the name of the file is used as the link text'),
72
    'file_table' => t('Build a two-column table where the first column contains a generic link to the file and the second column displays the size of the file.'),
73
    'file_url_plain' => t('Display a plain text URL to the file.'),
74
    'image' => t('Format the file as an image. The image can be displayed using an image style and can optionally be linked to the image file itself or its parent content.'),
75
  );
76
  foreach ($descriptions as $key => $description) {
77
    if (isset($info[$key]) && empty($info[$key]['description'])) {
78
      $info[$key]['description'] = $description;
79
    }
80
  }
81

    
82
  // Formatters that can be used for images but not files, should have a
83
  // default mimetype restriction added to the image/* mime type for use with
84
  // file formatters.
85
  foreach ($info as &$formatter) {
86
    if (!isset($formatter['file formatter']) && in_array('image', $formatter['field types']) && !in_array('file', $formatter['field types'])) {
87
      $formatter['file formatter']['mime types'] = array('image/*');
88
    }
89
  }
90
}
91

    
92
/**
93
 * Implements hook_field_formatter_settings_form().
94
 */
95
function file_entity_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
96
  $display = $instance['display'][$view_mode];
97
  $settings = $display['settings'];
98
  $element = array();
99

    
100
  if ($display['type'] == 'file_rendered') {
101
    $element['file_view_mode'] = array(
102
      '#title'   => t('View mode'),
103
      '#type'    => 'select',
104
      '#options' => file_entity_view_mode_labels(),
105
      '#default_value' => $settings['file_view_mode'],
106
      // Never empty, so no #empty_option
107
    );
108
  }
109
  elseif ($display['type'] == 'file_download_link') {
110
    $element['text'] = array(
111
      '#type' => 'textfield',
112
      '#title' => t('Link text'),
113
      '#description' => t('This field support tokens.'),
114
      '#default_value' => $settings['text'],
115
      '#required' => TRUE,
116
    );
117
  }
118
  elseif ($display['type'] == 'file_audio') {
119
    $element['controls'] = array(
120
      '#title' => t('Show audio controls'),
121
      '#type' => 'checkbox',
122
      '#default_value' => $settings['controls'],
123
    );
124
    $element['autoplay'] = array(
125
      '#title' => t('Autoplay'),
126
      '#type' => 'checkbox',
127
      '#default_value' => $settings['autoplay'],
128
    );
129
    $element['loop'] = array(
130
      '#title' => t('Loop'),
131
      '#type' => 'checkbox',
132
      '#default_value' => $settings['loop'],
133
    );
134
    $element['multiple_file_behavior'] = array(
135
      '#title' => t('Display of multiple files'),
136
      '#type' => 'radios',
137
      '#options' => array(
138
        'tags' => t('Use multiple @tag tags, each with a single source', array('@tag' => '<audio>')),
139
        'sources' => t('Use multiple sources within a single @tag tag', array('@tag' => '<audio>')),
140
      ),
141
      '#default_value' => $settings['multiple_file_behavior'],
142
      // Hide this setting in the manage file display configuration.
143
      '#access' => !empty($field),
144
    );
145

    
146
  }
147
  elseif ($display['type'] == 'file_video') {
148
    $element['controls'] = array(
149
      '#title' => t('Show video controls'),
150
      '#type' => 'checkbox',
151
      '#default_value' => $settings['controls'],
152
    );
153
    $element['autoplay'] = array(
154
      '#title' => t('Autoplay'),
155
      '#type' => 'checkbox',
156
      '#default_value' => $settings['autoplay'],
157
    );
158
    $element['loop'] = array(
159
      '#title' => t('Loop'),
160
      '#type' => 'checkbox',
161
      '#default_value' => $settings['loop'],
162
    );
163
    $element['muted'] = array(
164
      '#title' => t('Muted'),
165
      '#type' => 'checkbox',
166
      '#default_value' => $settings['muted'],
167
    );
168
    $element['width'] = array(
169
      '#type' => 'textfield',
170
      '#title' => t('Width'),
171
      '#default_value' => $settings['width'],
172
      '#size' => 5,
173
      '#maxlength' => 5,
174
      '#field_suffix' => t('pixels'),
175
    );
176
    $element['height'] = array(
177
      '#type' => 'textfield',
178
      '#title' => t('Height'),
179
      '#default_value' => $settings['height'],
180
      '#size' => 5,
181
      '#maxlength' => 5,
182
      '#field_suffix' => t('pixels'),
183
    );
184
    $element['multiple_file_behavior'] = array(
185
      '#title' => t('Display of multiple files'),
186
      '#type' => 'radios',
187
      '#options' => array(
188
        'tags' => t('Use multiple @tag tags, each with a single source', array('@tag' => '<video>')),
189
        'sources' => t('Use multiple sources within a single @tag tag', array('@tag' => '<video>')),
190
      ),
191
      '#default_value' => $settings['multiple_file_behavior'],
192
      // Hide this setting in the manage file display configuration.
193
      '#access' => !empty($field),
194
    );
195
  }
196

    
197
  return $element;
198
}
199

    
200
/**
201
 * Implements hook_field_formatter_settings_summary().
202
 */
203
function file_entity_field_formatter_settings_summary($field, $instance, $view_mode) {
204
  $display = $instance['display'][$view_mode];
205
  $settings = $display['settings'];
206
  $summary = array();
207

    
208
  if ($display['type'] === 'file_rendered') {
209
    $view_mode_label = file_entity_view_mode_label($settings['file_view_mode'], t('Unknown'));
210
    $summary[] = t('View mode: %mode', array('%mode' => $view_mode_label));
211
  }
212
  elseif ($display['type'] == 'file_download_link') {
213
    $summary[] = t('Link text: %text', array('%text' => $settings['text']));
214
  }
215
  elseif ($display['type'] === 'file_audio') {
216
    if (isset($settings['controls'])) {
217
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
218
    }
219
    if (isset($settings['autoplay'])) {
220
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
221
    }
222
    if (isset($settings['loop'])) {
223
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
224
    }
225
    if (isset($settings['multiple_file_behavior'])) {
226
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
227
    }
228
  }
229
  elseif ($display['type'] === 'file_video') {
230
    if (isset($settings['controls'])) {
231
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
232
    }
233
    if (isset($settings['autoplay'])) {
234
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
235
    }
236
    if (isset($settings['loop'])) {
237
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
238
    }
239
    if (isset($settings['muted'])) {
240
      $summary[] = t('Muted: %muted', array('%muted' => $settings['muted'] ? t('yes') : t('no')));
241
    }
242
    if ($settings['width'] && $settings['height']) {
243
      $summary[] = t('Size: %width x %height', array('%width' => $settings['width'], '%height' => $settings['height']));
244
    }
245
    if (isset($settings['multiple_file_behavior'])) {
246
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
247
    }
248
  }
249

    
250
  return implode('<br />', $summary);
251
}
252

    
253
/**
254
 * Implements hook_field_formatter_view().
255
 */
256
function file_entity_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
257
  $settings = $display['settings'];
258
  $element = array();
259

    
260
  if ($display['type'] == 'file_rendered') {
261
    $view_mode = $settings['file_view_mode'];
262

    
263
    // To prevent infinite recursion caused by reference cycles, we store
264
    // diplayed nodes in a recursion queue.
265
    $recursion_queue = &drupal_static(__FUNCTION__, array());
266

    
267
    // If no 'referencing entity' is set, we are starting a new 'reference
268
    // thread' and need to reset the queue.
269
    // @todo Bug: $entity->referencing_entity on files referenced in a different
270
    // thread on the page.
271
    // E.g: 1 references 1+2 / 2 references 1+2 / visit homepage.
272
    // We'd need a more accurate way...
273
    if (!isset($entity->referencing_entity)) {
274
      $recursion_queue = array();
275
    }
276

    
277
    // The recursion queue only needs to track files.
278
    if ($entity_type == 'file') {
279
      list($id) = entity_extract_ids($entity_type, $entity);
280
      $recursion_queue[$id] = $id;
281
    }
282

    
283
    // Prevent 'empty' fields from causing a WSOD.
284
    $items = array_filter($items);
285

    
286
    // Check the recursion queue to determine which nodes should be fully
287
    // displayed, and which nodes will only be displayed as a title.
288
    $files_display = array();
289
    foreach ($items as $delta => $item) {
290
      if (!isset($recursion_queue[$item['fid']])) {
291
        $files_display[$item['fid']] = file_load($item['fid']);
292
        if (!empty($item['description'])) {
293
          $files_display[$item['fid']]->description = $item['description'];
294
        }
295
      }
296
    }
297

    
298
    // Load and build the fully displayed nodes.
299
    if ($files_display) {
300
      foreach ($files_display as $fid => $file) {
301
        $files_display[$fid]->referencing_entity = $entity;
302
        $files_display[$fid]->referencing_entity_type = $entity_type;
303
        $files_display[$fid]->referencing_field = $field['field_name'];
304
      }
305
      $output = file_view_multiple($files_display, $view_mode);
306
      // Remove the first level from the output array.
307
      $files_built = reset($output);
308
    }
309

    
310
    // Assemble the render array.
311
    foreach ($items as $delta => $item) {
312
      if (isset($files_built[$item['fid']])) {
313
        $element[$delta] = $files_built[$item['fid']];
314
      }
315
    }
316
  }
317
  elseif ($display['type'] == 'file_download_link') {
318
    foreach ($items as $delta => $item) {
319
      $file = (object) $item;
320
      if (file_entity_access('download', $file)) {
321
        $element[$delta] = array(
322
          '#theme' => 'file_entity_download_link',
323
          '#file' => $file,
324
          '#text' => $settings['text'],
325
        );
326
      }
327
    }
328
  }
329
  elseif ($display['type'] == 'file_audio') {
330
    $multiple_file_behavior = $settings['multiple_file_behavior'];
331

    
332
    // Prevent 'empty' fields from causing a WSOD.
333
    $items = array_filter($items);
334

    
335
    // Build an array of sources for each <audio> element.
336
    $source_lists = array();
337
    if ($multiple_file_behavior == 'tags') {
338
      foreach ($items as $delta => $item) {
339
        if ($item['type'] == 'audio') {
340
          $source_lists[$delta] = array($item);
341
        }
342
      }
343
    }
344
    else {
345
      foreach ($items as $delta => $item) {
346
        if ($item['type'] == 'audio') {
347
          $source_lists[0][$delta] = $item;
348
        }
349
      }
350
    }
351

    
352
    // Render each source list as an <audio> element.
353
    foreach ($source_lists as $delta => $sources) {
354
      $element[$delta] = array(
355
        '#theme' => 'file_entity_file_audio',
356
        '#files' => $sources,
357
        '#controls' => $settings['controls'],
358
        '#autoplay' => $settings['autoplay'],
359
        '#loop' => $settings['loop'],
360
      );
361
    }
362
  }
363
  elseif ($display['type'] == 'file_video') {
364
    $multiple_file_behavior = $settings['multiple_file_behavior'];
365

    
366
    // Prevent 'empty' fields from causing a WSOD.
367
    $items = array_filter($items);
368

    
369
    // Build an array of sources for each <video> element.
370
    $source_lists = array();
371
    if ($multiple_file_behavior == 'tags') {
372
      foreach ($items as $delta => $item) {
373
        if ($item['type'] == 'video') {
374
          $source_lists[$delta] = array($item);
375
        }
376
      }
377
    }
378
    else {
379
      foreach ($items as $delta => $item) {
380
        if ($item['type'] == 'video') {
381
          $source_lists[0][$delta] = $item;
382
        }
383
      }
384
    }
385

    
386
    // Render each source list as an <video> element.
387
    foreach ($source_lists as $delta => $sources) {
388
      $element[$delta] = array(
389
        '#theme' => 'file_entity_file_video',
390
        '#files' => $sources,
391
        '#controls' => $settings['controls'],
392
        '#autoplay' => $settings['autoplay'],
393
        '#loop' => $settings['loop'],
394
        '#muted' => $settings['muted'],
395
        '#width' => $settings['width'],
396
        '#height' => $settings['height'],
397
      );
398
    }
399
  }
400

    
401
  return $element;
402
}