Projet

Général

Profil

Paste
Télécharger (15,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / file_entity / file_entity.field.inc @ 9e88ab34

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

    
67
/**
68
 * Implements hook_field_formatter_info_alter().
69
 */
70
function file_entity_field_formatter_info_alter(&$info) {
71
  // Add descriptions to core formatters.
72
  $descriptions = array(
73
    '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'),
74
    '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.'),
75
    'file_url_plain' => t('Display a plain text URL to the file.'),
76
    '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.'),
77
  );
78
  foreach ($descriptions as $key => $description) {
79
    if (isset($info[$key]) && empty($info[$key]['description'])) {
80
      $info[$key]['description'] = $description;
81
    }
82
  }
83

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

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

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

    
155
  }
156
  elseif ($display['type'] == 'file_video') {
157
    $element['controls'] = array(
158
      '#title' => t('Show video controls'),
159
      '#type' => 'checkbox',
160
      '#default_value' => $settings['controls'],
161
    );
162
    $element['autoplay'] = array(
163
      '#title' => t('Autoplay'),
164
      '#type' => 'checkbox',
165
      '#default_value' => $settings['autoplay'],
166
    );
167
    $element['loop'] = array(
168
      '#title' => t('Loop'),
169
      '#type' => 'checkbox',
170
      '#default_value' => $settings['loop'],
171
    );
172
    $element['muted'] = array(
173
      '#title' => t('Muted'),
174
      '#type' => 'checkbox',
175
      '#default_value' => $settings['muted'],
176
    );
177
    $element['width'] = array(
178
      '#type' => 'textfield',
179
      '#title' => t('Width'),
180
      '#default_value' => $settings['width'],
181
      '#size' => 5,
182
      '#maxlength' => 5,
183
      '#field_suffix' => t('pixels'),
184
    );
185
    $element['height'] = array(
186
      '#type' => 'textfield',
187
      '#title' => t('Height'),
188
      '#default_value' => $settings['height'],
189
      '#size' => 5,
190
      '#maxlength' => 5,
191
      '#field_suffix' => t('pixels'),
192
    );
193
    $element['preload'] = array(
194
      '#title' => t('Preload'),
195
      '#type' => 'select',
196
      '#default_value' => $settings['preload'],
197
      '#options' => drupal_map_assoc(array('none', 'auto', 'metadata')),
198
      '#empty_option' => 'unspecified',
199
    );
200
    $element['multiple_file_behavior'] = array(
201
      '#title' => t('Display of multiple files'),
202
      '#type' => 'radios',
203
      '#options' => array(
204
        'tags' => t('Use multiple @tag tags, each with a single source', array('@tag' => '<video>')),
205
        'sources' => t('Use multiple sources within a single @tag tag', array('@tag' => '<video>')),
206
      ),
207
      '#default_value' => $settings['multiple_file_behavior'],
208
      // Hide this setting in the manage file display configuration.
209
      '#access' => !empty($field),
210
    );
211
  }
212

    
213
  return $element;
214
}
215

    
216
/**
217
 * Implements hook_field_formatter_settings_summary().
218
 */
219
function file_entity_field_formatter_settings_summary($field, $instance, $view_mode) {
220
  $display = $instance['display'][$view_mode];
221
  $settings = $display['settings'];
222
  $summary = array();
223

    
224
  if ($display['type'] === 'file_rendered') {
225
    $view_mode_label = file_entity_view_mode_label($settings['file_view_mode'], t('Unknown'));
226
    $summary[] = t('View mode: %mode', array('%mode' => $view_mode_label));
227
  }
228
  elseif ($display['type'] == 'file_download_link') {
229
    $summary[] = t('Link text: %text', array('%text' => $settings['text']));
230
  }
231
  elseif ($display['type'] === 'file_audio') {
232
    if (isset($settings['controls'])) {
233
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
234
    }
235
    if (isset($settings['autoplay'])) {
236
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
237
    }
238
    if (isset($settings['loop'])) {
239
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
240
    }
241
    if (!empty($settings['preload'])) {
242
      $summary[] = t('Preload: %preload', array('%preload' => $settings['preload']));
243
    }
244
    if (isset($settings['multiple_file_behavior'])) {
245
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
246
    }
247
  }
248
  elseif ($display['type'] === 'file_video') {
249
    if (isset($settings['controls'])) {
250
      $summary[] = t('Controls: %controls', array('%controls' => $settings['controls'] ? 'visible' : 'hidden'));
251
    }
252
    if (isset($settings['autoplay'])) {
253
      $summary[] = t('Autoplay: %autoplay', array('%autoplay' => $settings['autoplay'] ? t('yes') : t('no')));
254
    }
255
    if (isset($settings['loop'])) {
256
      $summary[] = t('Loop: %loop', array('%loop' => $settings['loop'] ? t('yes') : t('no')));
257
    }
258
    if (isset($settings['muted'])) {
259
      $summary[] = t('Muted: %muted', array('%muted' => $settings['muted'] ? t('yes') : t('no')));
260
    }
261
    if ($settings['width'] && $settings['height']) {
262
      $summary[] = t('Size: %width x %height', array('%width' => $settings['width'], '%height' => $settings['height']));
263
    }
264
    if (!empty($settings['preload'])) {
265
      $summary[] = t('Preload: %preload', array('%preload' => $settings['preload']));
266
    }
267
    if (isset($settings['multiple_file_behavior'])) {
268
      $summary[] = t('Multiple files: %multiple', array('%multiple' => $settings['multiple_file_behavior']));
269
    }
270
  }
271

    
272
  return implode('<br />', $summary);
273
}
274

    
275
/**
276
 * Implements hook_field_formatter_prepare_view().
277
 */
278
function file_entity_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
279
  // File and image fields set item values to NULL if a file cannot be loaded.
280
  // Remove those empty items so we can simply iterate through $items normally
281
  // in file_entity_field_formatter_view().
282
  foreach (array_keys($entities) as $id) {
283
    $items[$id] = array_filter($items[$id]);
284
  }
285
}
286

    
287
/**
288
 * Implements hook_field_formatter_view().
289
 */
290
function file_entity_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
291
  $element = array();
292
  $settings = $display['settings'];
293

    
294
  switch ($display['type']) {
295
    case 'file_rendered':
296
      foreach ($items as $delta => $item) {
297
        // Protect ourselves from recursive rendering.
298
        static $recursive_render_depth = array();
299
        if (!empty($item)) {
300
          $recursive_render_id = $entity_type . $field['field_name'] . $item['fid'];
301
          if (isset($recursive_render_depth[$recursive_render_id])) {
302
            $recursive_render_depth[$recursive_render_id]++;
303
          }
304
          else {
305
            $recursive_render_depth[$recursive_render_id] = 1;
306
          }
307

    
308
          if ($recursive_render_depth[$recursive_render_id] > 20) {
309
            watchdog(
310
              'file_entity',
311
              'Recursive rendering detected when rendering entity %entity_type: %entity_id, using the %field_name field. Aborting rendering.',
312
              array(
313
                '%entity_type' => 'file',
314
                '%entity_id' => $item['fid'],
315
                '%field_name' => $field['field_name'],
316
              ),
317
              WATCHDOG_ERROR
318
            );
319
            return $element;
320
          }
321

    
322
          $file = file_load($item['fid']);
323
          if (isset($item['display'])) {
324
            $file->display = $item['display'];
325
          }
326
          if (isset($item['description'])) {
327
            $file->description = $item['description'];
328
          }
329

    
330
          // Add some references to the referencing entity.
331
          // @see https://www.drupal.org/node/2333107
332
          $file->referencing_entity = $entity;
333
          $file->referencing_entity_type = $entity_type;
334
          $file->referencing_field = $field['field_name'];
335

    
336
          // Untranslatable fields are rendered with no language code, fall back
337
          // to the content language in that case.
338
          $element[$delta] = file_view($file, $settings['file_view_mode'], $langcode !== LANGUAGE_NONE ? $langcode : NULL);
339
        } else {
340
          watchdog(
341
            'file_entity',
342
            'In the %referencing_entity_type, the %field_name field refers to a %entity_type which does not exist. Aborting the render for it.',
343
            array(
344
              '%referencing_entity_type' => $entity_type,
345
              '%field_name' => $field['field_name'],
346
              '%entity_type' => 'file',
347
            ),
348
            WATCHDOG_ERROR
349
          );
350
        }
351
      }
352
      break;
353

    
354
    case 'file_download_link':
355
      // Prevent 'empty' fields from causing a WSOD.
356
      $items = array_filter($items);
357
      foreach ($items as $delta => $item) {
358
        if (!empty($item['fid']) && ($file = file_load($item['fid'])) && file_entity_access('download', $file)) {
359
          if (isset($item['display'])) {
360
            $file->display = $item['display'];
361
          }
362
          if (isset($item['description'])) {
363
            $file->description = $item['description'];
364
          }
365
          $element[$delta] = array(
366
            '#theme' => 'file_entity_download_link',
367
            '#file' => $file,
368
            '#text' => $settings['text'],
369
          );
370
        }
371
      }
372
      break;
373

    
374
    case 'file_audio':
375
      $multiple_file_behavior = $settings['multiple_file_behavior'];
376

    
377
      // Build an array of sources for each <audio> element.
378
      $source_lists = array();
379
      if ($multiple_file_behavior == 'tags') {
380
        foreach ($items as $delta => $item) {
381
          if (file_entity_file_get_mimetype_type($item) == 'audio') {
382
            $source_lists[$delta] = array($item);
383
          }
384
        }
385
      }
386
      else {
387
        foreach ($items as $delta => $item) {
388
          if (file_entity_file_get_mimetype_type($item) == 'audio') {
389
            $source_lists[0][$delta] = $item;
390
          }
391
        }
392
      }
393

    
394
      // Render each source list as an <audio> element.
395
      foreach ($source_lists as $delta => $sources) {
396
        $element[$delta] = array(
397
          '#theme' => 'file_entity_file_audio',
398
          '#files' => $sources,
399
          '#controls' => $settings['controls'],
400
          '#autoplay' => $settings['autoplay'],
401
          '#loop' => $settings['loop'],
402
          '#preload' => $settings['preload'],
403
        );
404
      }
405
      break;
406

    
407
    case 'file_video':
408
      $multiple_file_behavior = $settings['multiple_file_behavior'];
409

    
410
      // Build an array of sources for each <video> element.
411
      $source_lists = array();
412
      if ($multiple_file_behavior == 'tags') {
413
        foreach ($items as $delta => $item) {
414
          if (file_entity_file_get_mimetype_type($item) == 'video') {
415
            $source_lists[$delta] = array($item);
416
          }
417
        }
418
      }
419
      else {
420
        foreach ($items as $delta => $item) {
421
          if (file_entity_file_get_mimetype_type($item) == 'video') {
422
            $source_lists[0][$delta] = $item;
423
          }
424
        }
425
      }
426

    
427
      // Render each source list as an <video> element.
428
      foreach ($source_lists as $delta => $sources) {
429
        $element[$delta] = array(
430
          '#theme' => 'file_entity_file_video',
431
          '#files' => $sources,
432
          '#controls' => $settings['controls'],
433
          '#autoplay' => $settings['autoplay'],
434
          '#loop' => $settings['loop'],
435
          '#muted' => $settings['muted'],
436
          '#width' => $settings['width'],
437
          '#height' => $settings['height'],
438
          '#preload' => $settings['preload'],
439
        );
440
      }
441
      break;
442
  }
443

    
444
  return $element;
445
}