Projet

Général

Profil

Paste
Télécharger (9,84 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / modules / mediafield / mediafield.module @ e4215af7

1
<?php
2

    
3
/**
4
 * @file
5
 * Provide a "Multimedia asset" field.
6
 */
7

    
8
/**
9
 * Implements hook_field_info().
10
 */
11
function mediafield_field_info() {
12
  return array(
13
    'media' => array(
14
      'label' => t('Multimedia asset'),
15
      'description' => t('This field stores a reference to a multimedia asset.'),
16
      'settings' => array(),
17
      'instance_settings' => array(
18
        'file_extensions' => variable_get('file_entity_default_allowed_extensions', 'jpg jpeg gif png txt doc docx xls xlsx pdf ppt pptx pps ppsx odt ods odp mp3 mov mp4 m4a m4v mpeg avi ogg oga ogv weba webp webm'),
19
      ),
20
      'default_widget' => 'media_generic',
21
      'default_formatter' => 'media',
22
      'property_type' => 'field_item_file',
23
      'property_callbacks' => array('entity_metadata_field_file_callback'),
24
    ),
25
  );
26
}
27

    
28
/**
29
 * Implements hook_field_widget_info_alter().
30
 *
31
 * Alter the media file selector so it is available for media fields.
32
 */
33
function mediafield_field_widget_info_alter(&$info) {
34
  $info['media_generic']['field types'][] = 'media';
35
}
36

    
37
/**
38
 * Implements hook_field_instance_settings_form().
39
 */
40
function mediafield_field_instance_settings_form($field, $instance) {
41
  $settings = $instance['settings'];
42

    
43
  // Make the extension list a little more human-friendly by comma-separation.
44
  $extensions = str_replace(' ', ', ', $settings['file_extensions']);
45
  $form['file_extensions'] = array(
46
    '#type' => 'textfield',
47
    '#title' => t('Allowed file extensions for uploaded files'),
48
    '#default_value' => $extensions,
49
    '#description' => t('Separate extensions with a space or comma and do not include the leading dot.'),
50
    '#element_validate' => array('_file_generic_settings_extensions'),
51
    // By making this field required, we prevent a potential security issue
52
    // that would allow files of any type to be uploaded.
53
    '#required' => TRUE,
54
    '#maxlength' => 255,
55
  );
56

    
57
  return $form;
58
}
59

    
60
/**
61
 * Implements hook_field_is_empty().
62
 */
63
function mediafield_field_is_empty($item, $field) {
64
  return empty($item['fid']);
65
}
66

    
67
/**
68
 * Implements hook_field_formatter_info().
69
 */
70
function mediafield_field_formatter_info() {
71
  $formatters = array(
72
    'media' => array(
73
      'label' => t('Media'),
74
      'field types' => array('media'),
75
      'settings' => array('file_view_mode' => 'default'),
76
    ),
77
  );
78

    
79
  return $formatters;
80
}
81

    
82
/**
83
 * Implements hook_field_formatter_settings_form().
84
 */
85
function mediafield_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
86
  $display = $instance['display'][$view_mode];
87
  $settings = $display['settings'];
88

    
89
  $element = array();
90

    
91
  if ($display['type'] == 'media') {
92
    $entity_info = entity_get_info('file');
93
    $options = array('default' => t('Default'));
94
    foreach ($entity_info['view modes'] as $file_view_mode => $file_view_mode_info) {
95
      $options[$file_view_mode] = $file_view_mode_info['label'];
96
    }
97
    $element['file_view_mode'] = array(
98
      '#title' => t('File view mode'),
99
      '#type' => 'select',
100
      '#default_value' => $settings['file_view_mode'],
101
      '#options' => $options,
102
    );
103
  }
104

    
105
  return $element;
106
}
107

    
108
/**
109
 * Implements hook_field_formatter_settings_summary().
110
 */
111
function mediafield_field_formatter_settings_summary($field, $instance, $view_mode) {
112
  $display = $instance['display'][$view_mode];
113
  $settings = $display['settings'];
114

    
115
  $summary = '';
116

    
117
  if ($display['type'] == 'media') {
118
    $entity_info = entity_get_info('file');
119
    $file_view_mode_label = isset($entity_info['view modes'][$settings['file_view_mode']]) ? $entity_info['view modes'][$settings['file_view_mode']]['label'] : t('Default');
120
    $summary = t('File view mode: @view_mode', array('@view_mode' => $file_view_mode_label));
121
  }
122

    
123
  return $summary;
124
}
125

    
126
/**
127
 * Implements hook_field_formatter_view().
128
 */
129
function mediafield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
130
  $element = array();
131

    
132
  $files = array();
133
  foreach ($items as $delta => $item) {
134
    if (!empty($item['file'])) {
135
      $files[$item['fid']] = $item['file'];
136
    }
137
  }
138

    
139
  if (!empty($files)) {
140
    $output = file_view_multiple($files, $display['settings']['file_view_mode'], 0, $langcode);
141
    // Remove the first level from the output array.
142
    $element = reset($output);
143
  }
144

    
145
  return $element;
146
}
147

    
148
/**
149
 * Implements hook_field_prepare_view().
150
 */
151
function mediafield_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
152
  // Collect all file IDs that need loading.
153
  $fids = array();
154
  foreach ($entities as $id => $entity) {
155
    // Load the files from the files table.
156
    foreach ($items[$id] as $delta => $item) {
157
      if (!empty($item['fid'])) {
158
        $fids[] = $item['fid'];
159
      }
160
    }
161
  }
162

    
163
  // Load the file entities.
164
  $files = file_load_multiple($fids);
165

    
166
  // Add the loaded file entities to the field item array.
167
  foreach ($entities as $id => $entity) {
168
    foreach ($items[$id] as $delta => $item) {
169
      // If the file does not exist, mark the entire item as empty.
170
      if (empty($files[$item['fid']])) {
171
        unset($items[$id][$delta]);
172
      }
173
      else {
174
        $items[$id][$delta]['file'] = $files[$item['fid']];
175
      }
176
    }
177
  }
178
}
179

    
180
/**
181
 * Implements hook_field_validate().
182
 *
183
 * Possible error codes:
184
 * - 'media_remote_file_type_not_allowed': The remote file is not an allowed
185
 *   file type.
186
 */
187
function mediafield_field_validate($obj_type, $object, $field, $instance, $langcode, $items, &$errors) {
188
  $allowed_types = array_keys(array_filter($instance['widget']['settings']['allowed_types']));
189

    
190
    // @TODO: merge in stuff from media_uri_value
191
  foreach ($items as $delta => $item) {
192
    if (empty($item['fid'])) {
193
      return TRUE;
194
      //@TODO: make support for submiting with just a URI here?
195
    }
196

    
197
    $file = file_load($item['fid']);
198

    
199
    // Only validate allowed types if the file is remote and not local.
200
    if (!file_entity_file_is_local($file)) {
201
      if (!in_array($file->type, $allowed_types)) {
202
        $errors[$field['field_name']][$langcode][$delta][] = array(
203
          'error' => 'media_remote_file_type_not_allowed',
204
          'message' => t('%name: Only remote files with the following types are allowed: %types-allowed.', array('%name' => t($instance['label']), '%types-allowed' => !empty($allowed_types) ? implode(', ', $allowed_types) : t('no file types selected'))),
205
        );
206
      }
207
    }
208
  }
209
}
210

    
211
/**
212
 * Implements_hook_field_widget_error().
213
 */
214
function mediafield_field_widget_error($element, $error, $form, &$form_state) {
215
  form_error($element['fid'], $error['message']);
216
}
217

    
218
/**
219
 * @todo The following hook_field_(insert|update|delete|delete_revision)
220
 *   implementations are nearly identical to the File module implementations of
221
 *   the same field hooks. The only differences are:
222
 *   - We pass 'media' rather than 'file' as the module argument to the
223
 *     file_usage_(add|delete)() functions.
224
 *   - We do not delete the file / media entity when its usage count goes to 0.
225
 *   We should submit a core patch to File module to make it flexible with
226
 *   respect to the above, so that we can reuse its implementation rather than
227
 *   duplicating it.
228
 */
229

    
230
/**
231
 * Implements hook_field_insert().
232
 */
233
function mediafield_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
234
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
235

    
236
  // Add a new usage of each uploaded file.
237
  foreach ($items as $item) {
238
    $file = (object) $item;
239
    file_usage_add($file, 'mediafield', $entity_type, $id);
240
  }
241
}
242

    
243
/**
244
 * Implements hook_field_update().
245
 *
246
 * Checks for files that have been removed from the object.
247
 */
248
function mediafield_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
249
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
250

    
251
  // On new revisions, all files are considered to be a new usage and no
252
  // deletion of previous file usages are necessary.
253
  if (!empty($entity->revision)) {
254
    foreach ($items as $item) {
255
      $file = (object) $item;
256
      file_usage_add($file, 'mediafield', $entity_type, $id);
257
    }
258
    return;
259
  }
260

    
261
  // Build a display of the current FIDs.
262
  $current_fids = array();
263
  foreach ($items as $item) {
264
    $current_fids[] = $item['fid'];
265
  }
266

    
267
  // Compare the original field values with the ones that are being saved.
268
  $original_fids = array();
269
  if (!empty($entity->original->{$field['field_name']}[$langcode])) {
270
    foreach ($entity->original->{$field['field_name']}[$langcode] as $original_item) {
271
      $original_fids[] = $original_item['fid'];
272
      if (isset($original_item['fid']) && !in_array($original_item['fid'], $current_fids)) {
273
        // Decrement the file usage count by 1.
274
        $file = (object) $original_item;
275
        file_usage_delete($file, 'mediafield', $entity_type, $id, 1);
276
      }
277
    }
278
  }
279

    
280
  // Add new usage entries for newly added files.
281
  foreach ($items as $item) {
282
    if (!in_array($item['fid'], $original_fids)) {
283
      $file = (object) $item;
284
      file_usage_add($file, 'mediafield', $entity_type, $id);
285
    }
286
  }
287
}
288

    
289
/**
290
 * Implements hook_field_delete().
291
 */
292
function mediafield_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
293
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
294

    
295
  // Delete all file usages within this entity.
296
  foreach ($items as $delta => $item) {
297
    $file = (object) $item;
298
    file_usage_delete($file, 'mediafield', $entity_type, $id, 0);
299
  }
300
}
301

    
302
/**
303
 * Implements hook_field_delete_revision().
304
 */
305
function mediafield_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
306
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
307
  foreach ($items as $delta => $item) {
308
    // @TODO: Not sure if this is correct
309
    $file = (object)$item;
310
    if (file_usage_delete($file, 'mediafield', $entity_type, $id, 1)) {
311
      $items[$delta] = NULL;
312
    }
313
  }
314
}
315

    
316
/**
317
 * Implements hook_views_api().
318
 */
319
function mediafield_views_api() {
320
  return array(
321
    'api' => 3,
322
  );
323
}