Projet

Général

Profil

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

root / drupal7 / sites / all / modules / file_entity / file_entity.field.inc @ 66c11afc

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
      'controls_list' => array(
38
        'download' => 'download',
39
        'remote_playback' => 'remote_playback',
40
      ),
41
      'autoplay' => FALSE,
42
      'loop' => FALSE,
43
      'preload' => '',
44
      'multiple_file_behavior' => 'tags',
45
    ),
46
    'file formatter' => array(
47
      'mime types' => array('audio/*'),
48
    ),
49
  );
50
  $info['file_video'] = array(
51
    'label' => t('Video'),
52
    'description' => t('Render the file using an HTML5 video tag.'),
53
    'field types' => array('file'),
54
    'settings' => array(
55
      'controls' => TRUE,
56
      'controls_list' => array(
57
        'fullscreen' => 'fullscreen',
58
        'download' => 'download',
59
        'remote_playback' => 'remote_playback',
60
      ),
61
      'autoplay' => FALSE,
62
      'loop' => FALSE,
63
      'muted' => FALSE,
64
      'width' => NULL,
65
      'height' => NULL,
66
      'preload' => '',
67
      'multiple_file_behavior' => 'tags',
68
    ),
69
    'file formatter' => array(
70
      'mime types' => array('video/*'),
71
    ),
72
  );
73
  return $info;
74
}
75

    
76
/**
77
 * Implements hook_field_formatter_info_alter().
78
 */
79
function file_entity_field_formatter_info_alter(&$info) {
80
  // Add descriptions to core formatters.
81
  $descriptions = array(
82
    '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'),
83
    '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.'),
84
    'file_url_plain' => t('Display a plain text URL to the file.'),
85
    '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.'),
86
  );
87
  foreach ($descriptions as $key => $description) {
88
    if (isset($info[$key]) && empty($info[$key]['description'])) {
89
      $info[$key]['description'] = $description;
90
    }
91
  }
92

    
93
  // Formatters that can be used for images but not files, should have a
94
  // default mimetype restriction added to the image/* mime type for use with
95
  // file formatters.
96
  foreach ($info as &$formatter) {
97
    if (!isset($formatter['file formatter']) && in_array('image', $formatter['field types']) && !in_array('file', $formatter['field types'])) {
98
      $formatter['file formatter']['mime types'] = array('image/*');
99
    }
100
  }
101
}
102

    
103
/**
104
 * Implements hook_field_formatter_settings_form().
105
 */
106
function file_entity_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
107
  $display = $instance['display'][$view_mode];
108
  $settings = $display['settings'];
109
  $element = array();
110

    
111
  if ($display['type'] == 'file_rendered') {
112
    $element['file_view_mode'] = array(
113
      '#title'   => t('View mode'),
114
      '#type'    => 'select',
115
      '#options' => file_entity_view_mode_labels(),
116
      '#default_value' => $settings['file_view_mode'],
117
      // Never empty, so no #empty_option
118
    );
119
  }
120
  elseif ($display['type'] == 'file_download_link') {
121
    $element['text'] = array(
122
      '#type' => 'textfield',
123
      '#title' => t('Link text'),
124
      '#description' => t('This field support tokens.'),
125
      '#default_value' => $settings['text'],
126
      '#required' => TRUE,
127
    );
128
  }
129
  elseif ($display['type'] == 'file_audio') {
130
    $element['controls'] = array(
131
      '#title' => t('Show audio controls'),
132
      '#type' => 'checkbox',
133
      '#default_value' => $settings['controls'],
134
    );
135
    $element['controls_list'] = array(
136
      '#title' => t('Controls list'),
137
      '#type' => 'checkboxes',
138
      '#options' => array(
139
        'download' => t('Download'),
140
        'remote_playback' => t('Remote playback'),
141
      ),
142
      '#default_value' => $settings['controls_list'],
143
      '#description' => t("Customize native media controls such as the download and remoteplayback buttons. Valid only if above \"Show audio controls\" setting is enabled.<br>Please note that not all browsers support this feature. Only Chrome 58+ and Opera 45+ supports it."),
144
    );
145
    $element['autoplay'] = array(
146
      '#title' => t('Autoplay'),
147
      '#type' => 'checkbox',
148
      '#default_value' => $settings['autoplay'],
149
    );
150
    $element['loop'] = array(
151
      '#title' => t('Loop'),
152
      '#type' => 'checkbox',
153
      '#default_value' => $settings['loop'],
154
    );
155
    $element['preload'] = array(
156
      '#title' => t('Preload'),
157
      '#type' => 'select',
158
      '#default_value' => $settings['preload'],
159
      '#options' => drupal_map_assoc(array('none', 'auto', 'metadata')),
160
      '#empty_option' => 'unspecified',
161
    );
162
    $element['multiple_file_behavior'] = array(
163
      '#title' => t('Display of multiple files'),
164
      '#type' => 'radios',
165
      '#options' => array(
166
        'tags' => t('Use multiple @tag tags, each with a single source', array('@tag' => '<audio>')),
167
        'sources' => t('Use multiple sources within a single @tag tag', array('@tag' => '<audio>')),
168
      ),
169
      '#default_value' => $settings['multiple_file_behavior'],
170
      // Hide this setting in the manage file display configuration.
171
      '#access' => !empty($field),
172
    );
173

    
174
  }
175
  elseif ($display['type'] == 'file_video') {
176
    $element['controls'] = array(
177
      '#title' => t('Show video controls'),
178
      '#type' => 'checkbox',
179
      '#default_value' => $settings['controls'],
180
    );
181
    $element['controls_list'] = array(
182
      '#title' => t('Controls list'),
183
      '#type' => 'checkboxes',
184
      '#options' => array(
185
        'fullscreen' => t('Fullscreen'),
186
        'download' => t('Download'),
187
        'remote_playback' => t('Remote playback'),
188
      ),
189
      '#default_value' => $settings['controls_list'],
190
      '#description' => t("Customize native media controls such as the download, fullscreen and remoteplayback buttons. Valid only if above \"Show video controls\" setting is enabled.<br>Please note that not all browsers support this feature. Only Chrome 58+ and Opera 45+ supports it."),
191
    );
192
    $element['autoplay'] = array(
193
      '#title' => t('Autoplay'),
194
      '#type' => 'checkbox',
195
      '#default_value' => $settings['autoplay'],
196
    );
197
    $element['loop'] = array(
198
      '#title' => t('Loop'),
199
      '#type' => 'checkbox',
200
      '#default_value' => $settings['loop'],
201
    );
202
    $element['muted'] = array(
203
      '#title' => t('Muted'),
204
      '#type' => 'checkbox',
205
      '#default_value' => $settings['muted'],
206
    );
207
    $element['width'] = array(
208
      '#type' => 'textfield',
209
      '#title' => t('Width'),
210
      '#default_value' => $settings['width'],
211
      '#size' => 5,
212
      '#maxlength' => 5,
213
      '#field_suffix' => t('pixels'),
214
    );
215
    $element['height'] = array(
216
      '#type' => 'textfield',
217
      '#title' => t('Height'),
218
      '#default_value' => $settings['height'],
219
      '#size' => 5,
220
      '#maxlength' => 5,
221
      '#field_suffix' => t('pixels'),
222
    );
223
    $element['preload'] = array(
224
      '#title' => t('Preload'),
225
      '#type' => 'select',
226
      '#default_value' => $settings['preload'],
227
      '#options' => drupal_map_assoc(array('none', 'auto', 'metadata')),
228
      '#empty_option' => 'unspecified',
229
    );
230
    $element['multiple_file_behavior'] = array(
231
      '#title' => t('Display of multiple files'),
232
      '#type' => 'radios',
233
      '#options' => array(
234
        'tags' => t('Use multiple @tag tags, each with a single source', array('@tag' => '<video>')),
235
        'sources' => t('Use multiple sources within a single @tag tag', array('@tag' => '<video>')),
236
      ),
237
      '#default_value' => $settings['multiple_file_behavior'],
238
      // Hide this setting in the manage file display configuration.
239
      '#access' => !empty($field),
240
    );
241
  }
242

    
243
  return $element;
244
}
245

    
246
/**
247
 * Implements hook_field_formatter_settings_summary().
248
 */
249
function file_entity_field_formatter_settings_summary($field, $instance, $view_mode) {
250
  $display = $instance['display'][$view_mode];
251
  $settings = $display['settings'];
252
  $summary = array();
253

    
254
  if ($display['type'] === 'file_rendered') {
255
    $view_mode_label = file_entity_view_mode_label($settings['file_view_mode'], t('Unknown'));
256
    $summary[] = t('View mode: %mode', array('%mode' => $view_mode_label));
257
  }
258
  elseif ($display['type'] == 'file_download_link') {
259
    $summary[] = t('Link text: %text', array('%text' => $settings['text']));
260
  }
261
  elseif ($display['type'] === 'file_audio') {
262
    if (isset($settings['controls'])) {
263
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
264
      if (!empty($settings['controls_list'])) {
265
        $controls_list = array();
266
        foreach ($settings['controls_list'] as $key => $value) {
267
          if ($value) {
268
            $controls_list[] = ucfirst(str_replace('_', ' ', $key));
269
          }
270
        }
271
        if (!empty($controls_list)) {
272
          $summary[] = t('Controls list: %controls_list', array('%controls_list' => implode(', ', $controls_list)));
273
        }
274
      }
275
    }
276
    if (isset($settings['autoplay'])) {
277
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
278
    }
279
    if (isset($settings['loop'])) {
280
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
281
    }
282
    if (!empty($settings['preload'])) {
283
      $summary[] = t('Preload: %preload', array('%preload' => $settings['preload']));
284
    }
285
    if (isset($settings['multiple_file_behavior'])) {
286
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
287
    }
288
  }
289
  elseif ($display['type'] === 'file_video') {
290
    if (isset($settings['controls'])) {
291
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
292
      if (!empty($settings['controls_list'])) {
293
        $controls_list = array();
294
        foreach ($settings['controls_list'] as $key => $value) {
295
          if ($value) {
296
            $controls_list[] = ucfirst(str_replace('_', ' ', $key));
297
          }
298
        }
299
        if (!empty($controls_list)) {
300
          $summary[] = t('Controls list: %controls_list', array('%controls_list' => implode(', ', $controls_list)));
301
        }
302
      }
303
    }
304
    if (isset($settings['autoplay'])) {
305
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
306
    }
307
    if (isset($settings['loop'])) {
308
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
309
    }
310
    if (isset($settings['muted'])) {
311
      $summary[] = t('Muted: %muted', array('%muted' => $settings['muted'] ? t('yes') : t('no')));
312
    }
313
    if ($settings['width'] && $settings['height']) {
314
      $summary[] = t('Size: %width x %height', array('%width' => $settings['width'], '%height' => $settings['height']));
315
    }
316
    if (!empty($settings['preload'])) {
317
      $summary[] = t('Preload: %preload', array('%preload' => $settings['preload']));
318
    }
319
    if (isset($settings['multiple_file_behavior'])) {
320
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
321
    }
322
  }
323

    
324
  return implode('<br />', $summary);
325
}
326

    
327
/**
328
 * Implements hook_field_formatter_prepare_view().
329
 */
330
function file_entity_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
331
  // File and image fields set item values to NULL if a file cannot be loaded.
332
  // Remove those empty items so we can simply iterate through $items normally
333
  // in file_entity_field_formatter_view().
334
  foreach (array_keys($entities) as $id) {
335
    $items[$id] = array_filter($items[$id]);
336
  }
337
}
338

    
339
/**
340
 * Implements hook_field_formatter_view().
341
 */
342
function file_entity_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
343
  $element = array();
344
  $settings = $display['settings'];
345

    
346
  switch ($display['type']) {
347
    case 'file_rendered':
348
      foreach ($items as $delta => $item) {
349
        // Protect ourselves from recursive rendering.
350
        static $recursive_render_depth = array();
351
        if (!empty($item)) {
352
          $recursive_render_id = $entity_type . $field['field_name'] . $item['fid'];
353
          if (isset($recursive_render_depth[$recursive_render_id])) {
354
            $recursive_render_depth[$recursive_render_id]++;
355
          }
356
          else {
357
            $recursive_render_depth[$recursive_render_id] = 1;
358
          }
359

    
360
          if ($recursive_render_depth[$recursive_render_id] > 20) {
361
            watchdog(
362
              'file_entity',
363
              'Recursive rendering detected when rendering entity %entity_type: %entity_id, using the %field_name field. Aborting rendering.',
364
              array(
365
                '%entity_type' => 'file',
366
                '%entity_id' => $item['fid'],
367
                '%field_name' => $field['field_name'],
368
              ),
369
              WATCHDOG_ERROR
370
            );
371
            return $element;
372
          }
373

    
374
          $file = file_load($item['fid']);
375
          if (isset($item['display'])) {
376
            $file->display = $item['display'];
377
          }
378
          if (isset($item['description'])) {
379
            $file->description = $item['description'];
380
          }
381

    
382
          // Add some references to the referencing entity.
383
          // @see https://www.drupal.org/node/2333107
384
          $file->referencing_entity = $entity;
385
          $file->referencing_entity_type = $entity_type;
386
          $file->referencing_field = $field['field_name'];
387

    
388
          // Untranslatable fields are rendered with no language code, fall back
389
          // to the content language in that case.
390
          $element[$delta] = file_view($file, $settings['file_view_mode'], $langcode !== LANGUAGE_NONE ? $langcode : NULL);
391
        } else {
392
          watchdog(
393
            'file_entity',
394
            'In the %referencing_entity_type, the %field_name field refers to a %entity_type which does not exist. Aborting the render for it.',
395
            array(
396
              '%referencing_entity_type' => $entity_type,
397
              '%field_name' => $field['field_name'],
398
              '%entity_type' => 'file',
399
            ),
400
            WATCHDOG_ERROR
401
          );
402
        }
403
      }
404
      break;
405

    
406
    case 'file_download_link':
407
      // Prevent 'empty' fields from causing a WSOD.
408
      $items = array_filter($items);
409
      foreach ($items as $delta => $item) {
410
        if (!empty($item['fid']) && ($file = file_load($item['fid'])) && file_entity_access('download', $file)) {
411
          if (isset($item['display'])) {
412
            $file->display = $item['display'];
413
          }
414
          if (isset($item['description'])) {
415
            $file->description = $item['description'];
416
          }
417
          $element[$delta] = array(
418
            '#theme' => 'file_entity_download_link',
419
            '#file' => $file,
420
            '#text' => $settings['text'],
421
          );
422
        }
423
      }
424
      break;
425

    
426
    case 'file_audio':
427
      $multiple_file_behavior = $settings['multiple_file_behavior'];
428

    
429
      // Build an array of sources for each <audio> element.
430
      $source_lists = array();
431
      if ($multiple_file_behavior == 'tags') {
432
        foreach ($items as $delta => $item) {
433
          if (file_entity_file_get_mimetype_type($item) == 'audio') {
434
            $source_lists[$delta] = array($item);
435
          }
436
        }
437
      }
438
      else {
439
        foreach ($items as $delta => $item) {
440
          if (file_entity_file_get_mimetype_type($item) == 'audio') {
441
            $source_lists[0][$delta] = $item;
442
          }
443
        }
444
      }
445

    
446
      // Render each source list as an <audio> element.
447
      foreach ($source_lists as $delta => $sources) {
448
        $element[$delta] = array(
449
          '#theme' => 'file_entity_file_audio',
450
          '#files' => $sources,
451
          '#controls' => $settings['controls'],
452
          '#controls_list' => $settings['controls_list'],
453
          '#autoplay' => $settings['autoplay'],
454
          '#loop' => $settings['loop'],
455
          '#preload' => $settings['preload'],
456
        );
457
      }
458
      break;
459

    
460
    case 'file_video':
461
      $multiple_file_behavior = $settings['multiple_file_behavior'];
462

    
463
      // Build an array of sources for each <video> element.
464
      $source_lists = array();
465
      if ($multiple_file_behavior == 'tags') {
466
        foreach ($items as $delta => $item) {
467
          if (file_entity_file_get_mimetype_type($item) == 'video') {
468
            $source_lists[$delta] = array($item);
469
          }
470
        }
471
      }
472
      else {
473
        foreach ($items as $delta => $item) {
474
          if (file_entity_file_get_mimetype_type($item) == 'video') {
475
            $source_lists[0][$delta] = $item;
476
          }
477
        }
478
      }
479

    
480
      // Render each source list as an <video> element.
481
      foreach ($source_lists as $delta => $sources) {
482
        $element[$delta] = array(
483
          '#theme' => 'file_entity_file_video',
484
          '#files' => $sources,
485
          '#controls' => $settings['controls'],
486
          '#controls_list' => $settings['controls_list'],
487
          '#autoplay' => $settings['autoplay'],
488
          '#loop' => $settings['loop'],
489
          '#muted' => $settings['muted'],
490
          '#width' => $settings['width'],
491
          '#height' => $settings['height'],
492
          '#preload' => $settings['preload'],
493
        );
494
      }
495
      break;
496
  }
497

    
498
  return $element;
499
}