Projet

Général

Profil

Révision ca0757b9

Ajouté par Assos Assos il y a plus de 9 ans

Weekly update of contrib modules

Voir les différences:

drupal7/sites/all/modules/media/media.module
8 8
 * See http://drupal.org/project/media for more details.
9 9
 */
10 10

  
11
/* ***************************************** */
12
/* INCLUDES                                  */
13
/* ***************************************** */
14

  
15 11
// Code relating to using media as a field.
16 12
require_once dirname(__FILE__) . '/includes/media.fields.inc';
17 13

  
18
 // Functions for working with [[inline tags]] and wysiwyg editors.
19
require_once dirname(__FILE__) . '/includes/media.filter.inc';
20

  
21
/* ***************************************** */
22
/* Hook Implementations                      */
23
/* ***************************************** */
24

  
25 14
/**
26 15
 * Implements hook_hook_info().
27 16
 */
......
32 21
    'media_browser_plugin_info_alter',
33 22
    'media_browser_plugins_alter',
34 23
    'media_browser_params_alter',
35
    'media_wysiwyg_allowed_view_modes_alter',
36
    'media_format_form_prepare_alter',
37
    'media_token_to_markup_alter',
38 24
    'query_media_browser_alter',
39 25
  );
40 26

  
......
71 57
  // For sites that updated from Media 1.x, continue to provide these deprecated
72 58
  // view modes.
73 59
  // @see http://drupal.org/node/1051090
74
  if (variable_get('media__show_deprecated_view_modes', FALSE)) {
75
    $entity_info['file']['view modes'] += array(
76
      'media_link' => array(
77
        'label' => t('Link'),
78
        'custom settings' => TRUE,
79
      ),
80
      'media_original' => array(
81
        'label' => t('Original'),
82
        'custom settings' => TRUE,
83
      ),
60
  if (variable_get('media_show_deprecated_view_modes', FALSE)) {
61
    $entity_info['file']['view modes']['media_link'] = array(
62
      'label' => t('Link'),
63
      'custom settings' => TRUE,
64
    );
65
    $entity_info['file']['view modes']['media_original'] = array(
66
      'label' => t('Original'),
67
      'custom settings' => TRUE,
84 68
    );
85 69
  }
86 70

  
87 71
  if (module_exists('entity_translation')) {
88 72
    $entity_info['file']['translation']['entity_translation']['class'] = 'MediaEntityTranslationHandler';
89
    $entity_info['file']['translation']['entity_translation']['path schemes']['media'] = array('edit path' => 'media/%file/edit/%ctools_js');
90 73
  }
91 74
}
92 75

  
93
/**
94
 * Access callback for files. This function is deprecated.
95
 *
96
 * @todo Completely remove this function in favor of file_entity_access after
97
 * a few releases, to ensure rest of contib catches up.
98
 */
99
function media_access($op, $account = NULL) {
100
  return user_access('administer files', $account);
101
}
102

  
103 76
/**
104 77
 * Implements hook_menu().
105 78
 */
......
127 100
    'weight' => 10,
128 101
  );
129 102

  
130
  // Used to import files from a local filesystem into Drupal.
131
  $items['admin/content/file/import'] = array(
132
    'title' => 'Import files',
133
    'description' => 'Import files into your media library.',
134
    'page callback' => 'drupal_get_form',
135
    'page arguments' => array('media_import'),
136
    'access arguments' => array('import media'),
137
    'type' => MENU_LOCAL_ACTION,
138
    'file' => 'includes/media.admin.inc',
139
    'weight' => 10,
103
  $items['media/ajax'] = array(
104
    'page callback' => 'media_ajax_upload',
105
    'delivery callback' => 'ajax_deliver',
106
    'access arguments' => array('access content'),
107
    'theme callback' => 'ajax_base_page_theme',
108
    'type' => MENU_CALLBACK,
140 109
  );
141
  $items['admin/content/file/thumbnails/import'] = $items['admin/content/file/import'];
142 110

  
143 111
  $items['media/browser'] = array(
144 112
    'title' => 'Media browser',
145 113
    'description' => 'Media Browser for picking media and uploading new media',
146 114
    'page callback' => 'media_browser',
147
    'access callback' => 'file_entity_access',
148
    'access arguments' => array('create'),
115
    'access arguments' => array('access media browser'),
149 116
    'type' => MENU_CALLBACK,
150 117
    'file' => 'includes/media.browser.inc',
151 118
    'theme callback' => 'media_dialog_get_theme_name',
......
162 129
    'file' => 'includes/media.browser.inc',
163 130
  );
164 131

  
165
  $items['media/%file/format-form'] = array(
166
    'title' => 'Style selector',
167
    'description' => 'Choose a format for a piece of media',
168
    'page callback' => 'drupal_get_form',
169
    'page arguments' => array('media_format_form', 1),
170
    'access callback' => 'file_entity_access',
171
    'access arguments' => array('view', 1),
172
    'file' => 'includes/media.filter.inc',
173
    'theme callback' => 'media_dialog_get_theme_name',
174
    'type' => MENU_CALLBACK,
175
  );
176

  
177
  if (module_exists('multiform')) {
178
    // @todo Investigate passing file IDs in query string rather than a menu
179
    // argument and then deprecate media_multi_load().
180
    $items['admin/content/file/edit-multiple/%media_multi'] = array(
181
      'title' => 'Edit multiple files',
182
      'page callback' => 'media_file_page_edit_multiple',
183
      'page arguments' => array(4),
184
      'access callback' =>  '_media_file_entity_access_recursive',
185
      'access arguments' => array(4, 'update'),
186
      'file' => 'includes/media.pages.inc',
187
    );
188
  }
189

  
190 132
  // We could re-use the file/%file/edit path for the modal callback, but
191 133
  // it is just easier to use our own namespace here.
192 134
  $items['media/%file/edit/%ctools_js'] = array(
......
195 137
    'page arguments' => array('media_file_edit_modal', 1, 3),
196 138
    'access callback' => 'file_entity_access',
197 139
    'access arguments' => array('update', 1),
198
    'file' => 'includes/media.pages.inc',
199
    'type' => MENU_CALLBACK,
200
  );
201

  
202
  // Upgrade interface for old file types.
203
  $items['admin/structure/file-types/upgrade'] = array(
204
    'title' => 'Upgrade types',
205
    'page callback' => 'drupal_get_form',
206
    'page arguments' => array('media_upgrade_file_types'),
207
    'access arguments' => array('administer file types'),
208
    'file' => 'includes/media.pages.inc',
209
    'type' => MENU_CALLBACK,
210
  );
211
  $items['admin/structure/file-types/upgrade/confirm'] = array(
212
    'title' => 'Upgrade types',
213
    'page callback' => 'drupal_get_form',
214
    'page arguments' => array('media_upgrade_file_types_confirm'),
215
    'access arguments' => array('administer file types'),
140
    'theme callback' => 'ajax_base_page_theme',
216 141
    'file' => 'includes/media.pages.inc',
217 142
    'type' => MENU_CALLBACK,
218 143
  );
......
242 167
 */
243 168
function media_admin_paths() {
244 169
  $paths['media/*/edit/*'] = TRUE;
170
  $paths['media/*/format-form'] = TRUE;
245 171

  
246 172
  // If the media browser theme is set to the admin theme, ensure it gets set
247 173
  // as an admin path as well.
248
  $dialog_theme = variable_get('media__dialog_theme', '');
174
  $dialog_theme = variable_get('media_dialog_theme', '');
249 175
  if (empty($dialog_theme) || $dialog_theme == variable_get('admin_theme')) {
250 176
    $paths['media/browser'] = TRUE;
251 177
    $paths['media/browser/*'] = TRUE;
......
263 189
      'title' => t('Administer media browser'),
264 190
      'description' => t('Access media browser settings.'),
265 191
    ),
266
    'import media' => array(
267
      'title' => t('Import media files from the local filesystem'),
268
      'description' => t('Simple file importer'),
192
    'access media browser' => array(
193
      'title' => t('Use the media browser'),
269 194
    ),
270 195
  );
271 196
}
......
275 200
 */
276 201
function media_theme() {
277 202
  return array(
278
    // The default media file list form element.
279
    'media_file_list' => array(
280
      'variables' => array('element' => NULL),
203
    // media.module.
204
    'media_element' => array(
205
      'render element' => 'element',
281 206
    ),
282 207

  
283
    // A preview of the uploaded file.
284
    'media_thumbnail' => array(
208
    // media.field.inc.
209
    'media_widget' => array(
285 210
      'render element' => 'element',
286
      'file' => 'includes/media.theme.inc',
287 211
    ),
288

  
289
    // Dialog page.
290
    'media_dialog_page' => array(
291
      'render element' => 'page',
292
      'template' => 'templates/media-dialog-page',
293
      'file' => 'includes/media.theme.inc',
212
    'media_widget_multiple' => array(
213
      'render element' => 'element',
214
    ),
215
    'media_upload_help' => array(
216
      'variables' => array('description' => NULL),
294 217
    ),
295 218

  
296
    // Media form API element type.
297
    'media_element' => array(
219
    // media.theme.inc.
220
    'media_thumbnail' => array(
298 221
      'render element' => 'element',
299 222
      'file' => 'includes/media.theme.inc',
300 223
    ),
301

  
302
    // Display a file as a large icon.
303 224
    'media_formatter_large_icon' => array(
304 225
      'variables' => array('file' => NULL, 'attributes' => array(), 'style_name' => 'media_thumbnail'),
305 226
      'file' => 'includes/media.theme.inc',
306 227
    ),
228
    'media_dialog_page' => array(
229
      'render element' => 'page',
230
      'template' => 'templates/media-dialog-page',
231
      'file' => 'includes/media.theme.inc',
232
    ),
307 233
  );
308 234
}
309 235

  
236
/**
237
 * Menu callback; Shared Ajax callback for media attachment and deletions.
238
 *
239
 * This rebuilds the form element for a particular field item. As long as the
240
 * form processing is properly encapsulated in the widget element the form
241
 * should rebuild correctly using FAPI without the need for additional callbacks
242
 * or processing.
243
 */
244
function media_ajax_upload() {
245
  $form_parents = func_get_args();
246
  $form_build_id = (string) array_pop($form_parents);
247

  
248
  if (empty($_POST['form_build_id']) || $form_build_id != $_POST['form_build_id']) {
249
    // Invalid request.
250
    drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
251
    $commands = array();
252
    $commands[] = ajax_command_replace(NULL, theme('status_messages'));
253
    return array('#type' => 'ajax', '#commands' => $commands);
254
  }
255

  
256
  list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
257

  
258
  if (!$form) {
259
    // Invalid form_build_id.
260
    drupal_set_message(t('An unrecoverable error occurred. Use of this form has expired. Try reloading the page and submitting again.'), 'error');
261
    $commands = array();
262
    $commands[] = ajax_command_replace(NULL, theme('status_messages'));
263
    return array('#type' => 'ajax', '#commands' => $commands);
264
  }
265

  
266
  // Get the current element and count the number of files.
267
  $current_element = $form;
268
  foreach ($form_parents as $parent) {
269
    $current_element = $current_element[$parent];
270
  }
271
  $current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
272

  
273
  // Process user input. $form and $form_state are modified in the process.
274
  drupal_process_form($form['#form_id'], $form, $form_state);
275

  
276
  // Retrieve the element to be rendered.
277
  foreach ($form_parents as $parent) {
278
    $form = $form[$parent];
279
  }
280

  
281
  // Add the special Ajax class if a new file was added.
282
  if (isset($form['#file_upload_delta']) && $current_file_count < $form['#file_upload_delta']) {
283
    $form[$current_file_count]['#attributes']['class'][] = 'ajax-new-content';
284
  }
285
  // Otherwise just add the new content class on a placeholder.
286
  else {
287
    $form['#suffix'] .= '<span class="ajax-new-content"></span>';
288
  }
289

  
290
  $output = theme('status_messages') . drupal_render($form);
291
  $js = drupal_add_js();
292
  $settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
293

  
294
  $commands[] = ajax_command_replace(NULL, $output, $settings);
295
  return array('#type' => 'ajax', '#commands' => $commands);
296
}
297

  
310 298
/**
311 299
 * Implements hook_image_default_styles().
312 300
 */
......
345 333
      }
346 334
    }
347 335
  }
348

  
349
  // Check if there are file types that need migration and display a message
350
  // to user if so.
351
  $menu = menu_get_item();
352
  if (variable_get('media__display_types_migration_mess', TRUE) && $menu['path'] == 'admin/structure/file-types') {
353
    if ($migratable_types = _media_get_migratable_file_types()) {
354
      drupal_set_message(t('There are disabled/deleted file types that can be migrated to their new alternatives. Visit <a href="!url">migration page</a> to get more information.', array('!url' => url('admin/structure/file-types/upgrade'))));
355
    }
356
  }
357
}
358

  
359
/**
360
 * Implements hook_element_info_alter().
361
 */
362
function media_element_info_alter(&$types) {
363
  $types['text_format']['#pre_render'][] = 'media_pre_render_text_format';
364
}
365

  
366
/**
367
 * Implements hook_file_operations().
368
 */
369
function media_file_operations() {
370
  $operations = array();
371

  
372
  // If the multiform module is not installed, do not show this option.
373
  if (module_exists('multiform')) {
374
    $operations['edit_multiple'] = array(
375
      'label' => t('Edit selected files'),
376
      'callback' => 'media_file_operation_edit_multiple',
377
    );
378
  }
379

  
380
  return $operations;
381
}
382

  
383
/**
384
 * Return a URL for editing an files.
385
 *
386
 * Works with an array of fids or a single fid.
387
 *
388
 * @param mixed $fids
389
 *   An array of file IDs or a single file ID.
390
 */
391
function media_file_edit_url($fids) {
392
  if (!is_array($fids)) {
393
    $fids = array($fids);
394
  }
395

  
396
  if (count($fids) > 1) {
397
    return 'admin/content/file/edit-multiple/' . implode(' ', $fids);
398
  }
399
  else {
400
    return 'file/' . reset($fids) . '/edit';
401
  }
402
}
403

  
404
/**
405
 * Callback for the edit operation.
406
 *
407
 * Redirects the user to the edit multiple files page.
408
 *
409
 * @param array $fids
410
 *   An array of file IDs.
411
 *
412
 * @see media_file_page_edit_multiple()
413
 */
414
function media_file_operation_edit_multiple($fids) {
415
  // The thumbnail browser returns TRUE/FALSE for each item, so use array keys.
416
  $fids = array_keys(array_filter($fids));
417
  drupal_goto(media_file_edit_url($fids), array('query' => drupal_get_destination()));
418
}
419

  
420
/**
421
 * Implements hook_forms().
422
 */
423
function media_forms($form_id, $args) {
424
  $forms = array();
425
  // To support the multiedit form, each form has to have a unique ID.
426
  // So we name all the forms media_edit_N where the first requested form is
427
  // media_edit_0, 2nd is media_edit_1, etc.
428
  module_load_include('inc', 'file_entity', 'file_entity.pages');
429
  if ($form_id != 'media_edit' && (strpos($form_id, 'media_edit') === 0)) {
430
    $forms[$form_id] = array(
431
      'callback' => 'file_entity_edit',
432
    );
433
  }
434
  return $forms;
435
}
436

  
437
/**
438
 * Implements hook_form_FIELD_UI_FIELD_SETTINGS_FORM_alter().
439
 *
440
 * @todo: Respect field settings in 7.x-2.x and handle them in the media widget
441
 * UI.
442
 */
443
function media_form_field_ui_field_settings_form_alter(&$form, &$form_state) {
444
  // On file fields that use the media widget we need remove specific fields.
445
  if ($form['field']['type']['#value'] == 'file') {
446
    $fields = field_info_instances($form['#entity_type'], $form['#bundle']);
447
    if ($fields[$form['field']['field_name']['#value']]['widget']['type'] == 'media_generic') {
448
      $form['field']['settings']['display_field']['#access'] = FALSE;
449
      $form['field']['settings']['display_default']['#access'] = FALSE;
450
    }
451
  }
452 336
}
453 337

  
454 338
/**
......
460 344
function media_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
461 345
  // On file fields that use the media widget we need remove specific fields.
462 346
  if ($form['#field']['type'] == 'file' && $form['instance']['widget']['type']['#value'] == 'media_generic') {
463
    $form['field']['settings']['display_field']['#access'] = FALSE;
464
    $form['field']['settings']['display_default']['#access'] = FALSE;
465
    $form['instance']['settings']['description_field']['#access'] = FALSE;
466 347
    $form['instance']['settings']['file_extensions']['#title'] = t('Allowed file extensions for uploaded files');
467 348
    $form['instance']['settings']['file_extensions']['#maxlength'] = 255;
468 349
  }
......
475 356
    // Do not increase maxlength of file extensions for image fields, since
476 357
    // presumably they will not need a long list of extensions.
477 358
  }
359

  
360
  // Add a validation function to any field instance which uses the media widget
361
  // to ensure that the upload destination scheme is one of the allowed schemes.
362
  if ($form['instance']['widget']['type']['#value'] == 'media_generic') {
363
    $form['#validate'][] = 'media_field_instance_validate';
364
  }
365

  
478 366
  if ($form['#instance']['entity_type'] == 'file') {
479 367
    $form['instance']['settings']['wysiwyg_override'] = array(
480 368
      '#type' => 'checkbox',
......
486 374
}
487 375

  
488 376
/**
489
 * Implements hook_form_FORM_ID_alter().
377
 * Validation handler; ensure that the upload destination scheme is one of the
378
 * allowed schemes.
490 379
 */
491
function media_form_file_entity_edit_alter(&$form, &$form_state) {
492
  // Make adjustments to the file edit form when used in a CTools modal.
493
  if (!empty($form_state['ajax'])) {
494
    // Remove the preview and the delete button.
495
    $form['preview']['#access'] = FALSE;
496
    $form['actions']['delete']['#access'] = FALSE;
380
function media_field_instance_validate($form, &$form_state) {
381
  $allowed_schemes = $form_state['values']['instance']['widget']['settings']['allowed_schemes'];
382
  $upload_destination = $form_state['values']['field']['settings']['uri_scheme'];
497 383

  
498
    // Convert the cancel link to a button which triggers a modal close.
499
    $form['actions']['cancel']['#attributes']['class'][] = 'button';
500
    $form['actions']['cancel']['#attributes']['class'][] = 'button-no';
501
    $form['actions']['cancel']['#attributes']['class'][] = 'ctools-close-modal';
384
  if (!in_array($upload_destination, array_filter($allowed_schemes))) {
385
    form_set_error('allowed_schemes', t('The upload destination must be one of the allowed schemes.'));
502 386
  }
503 387
}
504 388

  
......
534 418
    $parameters = array('query' => array('render' => 'media-popup', 'fid' => $file->fid));
535 419
  }
536 420

  
537
  // Multi upload.
538
  if (!empty($form_state['files'])) {
539
    $files = $form_state['files'];
540
    $url = 'media/browser';
541
    $parameters = array('query' => array('render' => 'media-popup', 'fid' => array_keys($files)));
542
  }
543

  
544 421
  // If $url is set, we had some sort of upload, so redirect the form.
545 422
  if (!empty($url)) {
546 423
    $form_state['redirect'] = array($url, $parameters);
547 424
  }
548 425
}
549 426

  
550
/**
551
 * Implements hook_form_FORM_ID_alter().
552
 */
553
function media_form_wysiwyg_profile_form_alter(&$form, &$form_state) {
554
  // Add warnings if the media filter is disabled for the WYSIWYG's text format.
555
  $form['buttons']['drupal']['media']['#element_validate'][] = 'media_wysiwyg_button_element_validate';
556
  $form['buttons']['drupal']['media']['#after_build'][] = 'media_wysiwyg_button_element_validate';
557
  form_load_include($form_state, 'inc', 'media', 'wysiwyg_plugins/media');
558
}
559

  
560
/**
561
 * Access callback for the media-multi form.
562
 *
563
 * @param $files
564
 *   An array of files being editing on the multiform.
565
 * @param $op
566
 *   A string containing the operation requested, such as 'update'.
567
 * @return
568
 *   TRUE if the current user has access to edit all of the files, otherwise FALSE.
569
 */
570
function _media_file_entity_access_recursive($files, $op) {
571
  // Check that the current user can access each file.
572
  if (!empty($files)) {
573
    foreach ($files as $file) {
574
      if (!file_entity_access($op, $file)) {
575
        return FALSE;
576
      }
577
    }
578
    return TRUE;
579
  }
580
  return FALSE;
581
}
582

  
583
/* ***************************************** */
584
/* API FUNCTIONS                             */
585
/* ***************************************** */
586

  
587
/**
588
 * Load callback for %media_multi placeholder in menu paths.
589
 *
590
 * @param string $fids
591
 *   Separated by space (e.g., "3 6 12 99"). This often appears as "+" within
592
 *   URLs (e.g., "3+6+12+99"), but Drupal automatically decodes paths when
593
 *   intializing $_GET['q'].
594
 *
595
 * @return array
596
 *   An array of corresponding file entities.
597
 */
598
function media_multi_load($fids) {
599
  return file_load_multiple(explode(' ', $fids));
600
}
601

  
602
/* ***************************************** */
603
/* Callbacks                                 */
604
/* ***************************************** */
605

  
606
/**
607
 * Process callback for the media_browser element.
608
 */
609
function media_file_list_element_process($element, $edit, $form_state, $form) {
610
  $element['list'] = array(
611
    '#type'     => 'select',
612
    '#options'  => $element['#options'],
613
    '#size'     => variable_get('media__file_list_size', 10),
614
  );
615
  return $element;
616
}
617

  
618 427
/**
619 428
 * Implements hook_library().
620 429
 */
......
682 491
 * will default to the administration theme, unless set otherwise.
683 492
 */
684 493
function media_dialog_get_theme_name() {
685
  return variable_get('media__dialog_theme', variable_get('admin_theme'));
494
  return variable_get('media_dialog_theme', variable_get('admin_theme'));
686 495
}
687 496

  
688 497
/**
......
808 617
 * Implements hook_element_info().
809 618
 */
810 619
function media_element_info() {
811
  $types = array();
812 620
  $types['media'] = array(
813 621
    '#input' => TRUE,
814 622
    '#process' => array('media_element_process'),
815
    // '#value_callback' => 'media_element_value',
623
    '#value_callback' => 'media_file_value',
816 624
    '#element_validate' => array('media_element_validate'),
817
    '#theme_wrappers' => array('container'),
818
    '#progress_indicator' => 'throbber',
625
    '#pre_render' => array('media_element_pre_render'),
626
    '#theme' => 'media_element',
627
    '#theme_wrappers' => array('form_element'),
628
    '#size' => 22,
819 629
    '#extended' => FALSE,
820
    '#required' => FALSE,
821 630
    '#media_options' => array(
822 631
      'global' => array(
823 632
        // Example: array('image', 'audio');
......
826 635
        'schemes' => array(),
827 636
      ),
828 637
    ),
829
    '#attributes' => array(
830
      'class' => array('media-widget', 'form-item'),
831
    ),
832 638
    '#attached' => array(
833 639
      'library' => array(
834 640
        array('media', 'media_browser'),
835 641
      ),
836 642
    ),
837 643
  );
644

  
645
  $setting = array();
646
  $setting['media']['global'] = $types['media']['#media_options'];
647

  
648
  $types['media']['#attached']['js'][] = array(
649
    'type' => 'setting',
650
    'data' => $setting,
651
  );
652

  
838 653
  return $types;
839 654
}
840 655

  
841 656
/**
842 657
 * Process callback for the media form element.
843 658
 */
844
function media_element_process(&$element, &$form_state, $form) {
845
  $fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
846
  $file = $fid ? file_load($fid) : FALSE;
847

  
848
  // Add the CTools modal JavaScript for the edit button if necessary.
659
function media_element_process($element, &$form_state, $form) {
849 660
  ctools_include('modal');
850 661
  ctools_include('ajax');
851 662
  ctools_modal_add_js();
663
  $fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
852 664

  
853 665
  // Set some default element properties.
854
  $element['#file'] = $file;
855

  
856
  $element['title'] = array(
857
    '#type' => 'item',
858
    '#title' => $element['#title'],
859
    '#description' => $element['#description'],
860
    '#required' => $element['#required'],
861
    '#weight' => -100,
666
  $element['#file'] = $fid ? file_load($fid) : FALSE;
667
  $element['#tree'] = TRUE;
668

  
669
  $ajax_settings = array(
670
    'path' => 'media/ajax/' . implode('/', $element['#array_parents']) . '/' . $form['form_build_id']['#value'],
671
    'wrapper' => $element['#id'] . '-ajax-wrapper',
672
    'effect' => 'fade',
673
  );
674

  
675
  // Set up the buttons first since we need to check if they were clicked.
676
  $element['attach_button'] = array(
677
    '#name' => implode('_', $element['#parents']) . '_attach_button',
678
    '#type' => 'submit',
679
    '#value' => t('Attach'),
680
    '#validate' => array(),
681
    '#submit' => array('media_file_submit'),
682
    '#limit_validation_errors' => array($element['#parents']),
683
    '#ajax' => $ajax_settings,
684
    '#attributes' => array('class' => array('attach')),
685
    '#weight' => -1,
862 686
  );
863
  if (isset($element['#title_display'])) {
864
    $element['title']['#title_display'] = $element['#title_display'];
865
  }
866 687

  
867
  // @todo This should load from the JS in case of a failed form submission.
868 688
  $element['preview'] = array(
869
    '#prefix' => '<div class="preview launcher">',
689
    'content' => array(),
690
    '#prefix' => '<div class="preview">',
870 691
    '#suffix' => '</div>',
871
    '#weight' => 0,
872
    'content' => $file ? media_get_thumbnail_preview($file) : array(),
692
    '#ajax' => $ajax_settings,
693
    '#weight' => -10,
873 694
  );
874 695

  
875
  // @todo: Perhaps this language logic should be handled by JS since the state
876
  // changes on client side after choosing an item.
877
  $element['select'] = array(
696
  // Substitute the JS preview for a true file thumbnail once the file is
697
  // attached.
698
  if ($fid && $element['#file']) {
699
    $element['preview']['content'] = media_get_thumbnail_preview($element['#file']);
700
  }
701

  
702
  // The file ID field itself.
703
  $element['upload'] = array(
704
    '#name' => 'media[' . implode('_', $element['#parents']) . ']',
705
    '#type' => 'textfield',
706
    '#title' => t('Enter the ID of an existing file'),
707
    '#title_display' => 'invisible',
708
    '#field_prefix' => t('File ID'),
709
    '#size' => $element['#size'],
710
    '#theme_wrappers' => array(),
711
    '#attributes' => array('class' => array('upload')),
712
    '#weight' => -9,
713
  );
714

  
715
  $element['browse_button'] = array(
878 716
    '#type' => 'link',
879 717
    '#href' => '',
880
    '#title' => t('Select'),
881
    '#attributes' => array('class' => array('button', 'launcher')),
718
    '#title' => t('Browse'),
719
    '#attributes' => array('class' => array('button', 'browse', 'element-hidden')),
882 720
    '#options' => array('fragment' => FALSE, 'external' => TRUE),
883
    '#weight' => 10,
721
    '#weight' => -8,
884 722
  );
885
  // @todo Figure out how to update the preview image after the Edit modal is
886
  // closed.
723

  
724
  // Force the progress indicator for the remove button to be either 'none' or
725
  // 'throbber', even if the upload button is using something else.
726
  $ajax_settings['progress']['type'] = 'throbber';
727
  $ajax_settings['progress']['message'] = NULL;
728
  $ajax_settings['effect'] = 'none';
887 729
  $element['edit'] = array(
888 730
    '#type' => 'link',
889 731
    '#href' => 'media/' . $fid . '/edit/nojs',
......
896 738
      ),
897 739
    ),
898 740
    '#weight' => 20,
899
    '#access' => $file ? file_entity_access('update', $file) : TRUE, // only do perm check for existing files
741
    '#access' => $element['#file'] ? file_entity_access('update', $element['#file']) : FALSE,
900 742
  );
901
  $element['remove'] = array(
902
    '#type' => 'link',
903
    '#href' => '',
904
    '#title' => t('Remove'),
905
    '#attributes' => array('class' => array('button', 'remove')),
906
    '#options' => array('fragment' => FALSE, 'external' => TRUE),
907
    '#weight' => 30,
743
  $element['remove_button'] = array(
744
    '#name' => implode('_', $element['#parents']) . '_remove_button',
745
    '#type' => 'submit',
746
    '#value' => t('Remove'),
747
    '#validate' => array(),
748
    '#submit' => array('media_file_submit'),
749
    '#limit_validation_errors' => array($element['#parents']),
750
    '#ajax' => $ajax_settings,
751
    '#attributes' => array('class' => array('remove')),
752
    '#weight' => 0,
908 753
  );
909 754

  
910 755
  $element['fid'] = array(
911 756
    '#type' => 'hidden',
912 757
    '#value' => $fid,
913 758
    '#attributes' => array('class' => array('fid')),
914
    '#weight' => 100,
915 759
  );
916 760

  
917 761
  // Media browser attach code.
918 762
  $element['#attached']['js'][] = drupal_get_path('module', 'media') . '/js/media.js';
919 763

  
920
  $setting = array();
921
  $setting['media']['elements'][$element['#id']] = $element['#media_options'];
922

  
923
  $element['#attached']['js'][] = array(
924
    'type' => 'setting',
925
    'data' => $setting,
764
  // Add the media options to the page as JavaScript settings.
765
  $element['browse_button']['#attached']['js'] = array(
766
    array(
767
      'type' => 'setting',
768
      'data' => array('media' => array('elements' => array('#' . $element['#id'] => $element['#media_options'])))
769
    )
926 770
  );
927 771

  
928
  // @todo: Might need to think about this. All settings would likely apply to
929
  // all media in a multi-value, but what about passing the existing fid?
930 772
  module_load_include('inc', 'media', 'includes/media.browser');
931 773
  media_attach_browser_js($element);
932 774

  
775
  // Prefix and suffix used for Ajax replacement.
776
  $element['#prefix'] = '<div id="' . $element['#id'] . '-ajax-wrapper">';
777
  $element['#suffix'] = '</div>';
778

  
933 779
  return $element;
934
  // @todo: make this work for file and image fields.
780
}
781

  
782
/**
783
 * Implements hook_form_FORM_ID_alter().
784
 */
785
function media_form_file_entity_edit_alter(&$form, &$form_state) {
786
  // Make adjustments to the file edit form when used in a CTools modal.
787
  if (!empty($form_state['ajax'])) {
788
    // Remove the preview and the delete button.
789
    $form['preview']['#access'] = FALSE;
790
    $form['actions']['delete']['#access'] = FALSE;
791

  
792
    // Convert the cancel link to a button which triggers a modal close.
793
    $form['actions']['cancel']['#attributes']['class'][] = 'button';
794
    $form['actions']['cancel']['#attributes']['class'][] = 'button-no';
795
    $form['actions']['cancel']['#attributes']['class'][] = 'ctools-close-modal';
796
  }
797
}
798

  
799
/**
800
 * The #value_callback for a media type element.
801
 */
802
function media_file_value(&$element, $input = FALSE, $form_state = NULL) {
803
  $fid = 0;
804

  
805
  // Find the current value of this field from the form state.
806
  $form_state_fid = $form_state['values'];
807
  foreach ($element['#parents'] as $parent) {
808
    $form_state_fid = isset($form_state_fid[$parent]) ? $form_state_fid[$parent] : 0;
809
  }
810

  
811
  if ($element['#extended'] && isset($form_state_fid['fid'])) {
812
    $fid = $form_state_fid['fid'];
813
  }
814
  elseif (is_numeric($form_state_fid)) {
815
    $fid = $form_state_fid;
816
  }
817

  
818
  // Process any input and attach files.
819
  if ($input !== FALSE) {
820
    $return = $input;
821

  
822
    // Attachments take priority over all other values.
823
    if ($file = media_attach_file($element)) {
824
      $fid = $file->fid;
825
    }
826
    else {
827
      // Check for #filefield_value_callback values.
828
      // Because FAPI does not allow multiple #value_callback values like it
829
      // does for #element_validate and #process, this fills the missing
830
      // functionality to allow File fields to be extended through FAPI.
831
      if (isset($element['#file_value_callbacks'])) {
832
        foreach ($element['#file_value_callbacks'] as $callback) {
833
          $callback($element, $input, $form_state);
834
        }
835
      }
836
      // Load file if the FID has changed to confirm it exists.
837
      if (isset($input['fid']) && $file = file_load($input['fid'])) {
838
        $fid = $file->fid;
839
      }
840
    }
841
  }
842

  
843
  // If there is no input, set the default value.
844
  else {
845
    if ($element['#extended']) {
846
      $default_fid = isset($element['#default_value']['fid']) ? $element['#default_value']['fid'] : 0;
847
      $return = isset($element['#default_value']) ? $element['#default_value'] : array('fid' => 0);
848
    }
849
    else {
850
      $default_fid = isset($element['#default_value']) ? $element['#default_value'] : 0;
851
      $return = array('fid' => 0);
852
    }
853

  
854
    // Confirm that the file exists when used as a default value.
855
    if ($default_fid && $file = file_load($default_fid)) {
856
      $fid = $file->fid;
857
    }
858
  }
859

  
860
  $return['fid'] = $fid;
861

  
862
  return $return;
935 863
}
936 864

  
937 865
/**
......
941 869
 * necessary in order to respect the #required property.
942 870
 */
943 871
function media_element_validate(&$element, &$form_state) {
944
  if ($element['#required']) {
945
    $has_value = FALSE;
946
    $widget_parents = $element['#array_parents'];
947
    array_pop($widget_parents);
948
    $items = drupal_array_get_nested_value($form_state['values'], $widget_parents);
949
    foreach ($items as $value) {
950
      if (is_array($value) && !empty($value['fid'])) {
951
        $has_value = TRUE;
952
      }
953
    }
954
    if (!$has_value) {
955
      form_error($element, t('%element_title is required.', array('%element_title' => $element['#title'])));
872
  $clicked_button = end($form_state['triggering_element']['#parents']);
873

  
874
  // Check required property based on the FID.
875
  if ($element['#required'] && empty($element['fid']['#value']) && !in_array($clicked_button, array('attach_button', 'remove_button'))) {
876
    form_error($element['browse_button'], t('!name field is required.', array('!name' => $element['#title'])));
877
  }
878

  
879
  // Consolidate the array value of this field to a single FID.
880
  if (!$element['#extended']) {
881
    form_set_value($element, $element['fid']['#value'], $form_state);
882
  }
883
}
884

  
885
/**
886
 * Form submission handler for attach / remove buttons of media elements.
887
 *
888
 * @see media_element_process()
889
 */
890
function media_file_submit($form, &$form_state) {
891
  // Determine whether it was the attach or remove button that was clicked, and
892
  // set $element to the managed_file element that contains that button.
893
  $parents = $form_state['triggering_element']['#array_parents'];
894
  $button_key = array_pop($parents);
895
  $element = drupal_array_get_nested_value($form, $parents);
896

  
897
  // No action is needed here for the attach button, because all media
898
  // attachments on the form are processed by media_file_value() regardless of
899
  // which button was clicked. Action is needed here for the remove button,
900
  // because we only remove a file in response to its remove button being
901
  // clicked.
902
  if ($button_key == 'remove_button') {
903
    // If it's a temporary file we can safely remove it immediately, otherwise
904
    // it's up to the implementing module to clean up files that are in use.
905
    if ($element['#file'] && $element['#file']->status == 0) {
906
      file_delete($element['#file']);
956 907
    }
908
    // Update both $form_state['values'] and $form_state['input'] to reflect
909
    // that the file has been removed, so that the form is rebuilt correctly.
910
    // $form_state['values'] must be updated in case additional submit handlers
911
    // run, and for form building functions that run during the rebuild, such as
912
    // when the media element is part of a field widget.
913
    // $form_state['input'] must be updated so that media_file_value() has
914
    // correct information during the rebuild.
915
    $values_element = $element['#extended'] ? $element['fid'] : $element;
916
    form_set_value($values_element, NULL, $form_state);
917
    drupal_array_set_nested_value($form_state['input'], $values_element['#parents'], NULL);
957 918
  }
919

  
920
  // Set the form to rebuild so that $form is correctly updated in response to
921
  // processing the file removal. Since this function did not change $form_state
922
  // if the upload button was clicked, a rebuild isn't necessary in that
923
  // situation and setting $form_state['redirect'] to FALSE would suffice.
924
  // However, we choose to always rebuild, to keep the form processing workflow
925
  // consistent between the two buttons.
926
  $form_state['rebuild'] = TRUE;
958 927
}
959 928

  
960 929
/**
961
 * Implements hook_filter_info().
930
 * Attaches any files that have been referenced by a media element.
931
 *
932
 * @param $element
933
 *   The FAPI element whose files are being attached.
934
 *
935
 * @return
936
 *   The file object representing the file that was attached, or FALSE if no
937
 *   file was attached.
962 938
 */
963
function media_filter_info() {
964
  $filters['media_filter'] = array(
965
    'title' => t('Convert Media tags to markup'),
966
    'description' => t('This filter will convert [[{type:media... ]] tags into markup.'),
967
    'process callback' => 'media_filter',
968
    'weight' => 2,
969
    // @TODO not implemented
970
    'tips callback' => 'media_filter_tips',
971
  );
939
function media_attach_file($element) {
940
  $upload_name = implode('_', $element['#parents']);
941
  if (empty($_POST['media'][$upload_name])) {
942
    return FALSE;
943
  }
972 944

  
973
  // If the WYSIWYG module is enabled, add additional help.
974
  if (module_exists('wysiwyg')) {
975
    $filters['media_filter']['description'] .= ' ' . t('This must be enabled for the Media WYSIWYG integration to work with this input format.');
945
  if (!$file = file_load($_POST['media'][$upload_name])) {
946
    watchdog('file', 'The file upload failed. %upload', array('%upload' => $upload_name));
947
    form_set_error($upload_name, t('The file in the !name field was unable to be uploaded.', array('!name' => $element['#title'])));
948
    return FALSE;
976 949
  }
977 950

  
978
  return $filters;
951
  return $file;
952
}
953

  
954
/**
955
 * Returns HTML for a managed file element.
956
 *
957
 * @param $variables
958
 *   An associative array containing:
959
 *   - element: A render element representing the file.
960
 *
961
 * @ingroup themeable
962
 */
963
function theme_media_element($variables) {
964
  $element = $variables['element'];
965

  
966
  $attributes = array();
967
  if (isset($element['#id'])) {
968
    $attributes['id'] = $element['#id'];
969
  }
970
  if (!empty($element['#attributes']['class'])) {
971
    $attributes['class'] = (array) $element['#attributes']['class'];
972
  }
973
  $attributes['class'][] = 'form-media';
974

  
975
  // This wrapper is required to apply JS behaviors and CSS styling.
976
  $output = '';
977
  $output .= '<div' . drupal_attributes($attributes) . '>';
978
  $output .= drupal_render_children($element);
979
  $output .= '</div>';
980
  return $output;
981
}
982

  
983
/**
984
 * #pre_render callback to hide display of the browse/attach or remove controls.
985
 *
986
 * Browse/attach controls are hidden when a file is already attached.
987
 * Remove controls are hidden when there is no file attached. Controls are
988
 * hidden here instead of in media_element_process(), because #access for these
989
 * buttons depends on the media element's #value. See the documentation of
990
 * form_builder() for more detailed information about the relationship between
991
 * #process, #value, and #access.
992
 *
993
 * Because #access is set here, it affects display only and does not prevent
994
 * JavaScript or other untrusted code from submitting the form as though access
995
 * were enabled. The form processing functions for these elements should not
996
 * assume that the buttons can't be "clicked" just because they are not
997
 * displayed.
998
 *
999
 * @see media_element_process()
1000
 * @see form_builder()
1001
 */
1002
function media_element_pre_render($element) {
1003
  // If we already have a file, we don't want to show the browse and attach
1004
  // controls.
1005
  if (!empty($element['#value']['fid'])) {
1006
    $element['upload']['#access'] = FALSE;
1007
    $element['browse_button']['#access'] = FALSE;
1008
    $element['attach_button']['#access'] = FALSE;
1009
  }
1010
  // If we don't already have a file, there is nothing to remove.
1011
  else {
1012
    $element['remove_button']['#access'] = FALSE;
1013
  }
1014
  return $element;
979 1015
}
980 1016

  
981 1017
/**
......
995 1031
  if (!file_type_is_enabled($file->type)) {
996 1032
    $file->type = file_get_type($file);
997 1033
  }
998
  // @todo should CSS be attached to the form element here?
999
  // $element['#attached']['css'][] = drupal_get_path('module', 'media') . '/css/media.css';
1000
  drupal_add_css(drupal_get_path('module', 'media') . '/css/media.css');
1034

  
1001 1035
  $preview = file_view_file($file, 'preview');
1002 1036
  $preview['#show_names'] = TRUE;
1003 1037
  $preview['#add_link'] = $link;
1004 1038
  $preview['#theme_wrappers'][] = 'media_thumbnail';
1039
  $preview['#attached']['css'][] = drupal_get_path('module', 'media') . '/css/media.css';
1005 1040
  return $preview;
1006 1041
}
1007 1042

  
......
1018 1053
 *
1019 1054
 * @see hook_file_validate()
1020 1055
 */
1021
function media_file_validate_types(stdClass $file, $types) {
1056
function media_file_validate_types($file, $types) {
1022 1057
  $errors = array();
1023 1058
  if (!in_array(file_get_type($file), $types)) {
1024 1059
    $errors[] = t('Only the following types of files are allowed to be uploaded: %types-allowed', array('%types-allowed' => implode(', ', $types)));
......
1050 1085
        $file->{$field_name} = $value;}
1051 1086
    }
1052 1087
  }
1088

  
1089
  // Alt and title are special.
1090
  // @see file_entity_file_load
1091
  $alt = variable_get('file_entity_alt', '[file:field_file_image_alt_text]');
1092
  $title = variable_get('file_entity_title', '[file:field_file_image_title_text]');
1093

  
1094
  $replace_options = array(
1095
    'clear' => TRUE,
1096
    'sanitize' => FALSE,
1097
  );
1098

  
1099
  // Load alt and title text from fields.
1100
  if (!empty($alt)) {
1101
    $file->alt = token_replace($alt, array('file' => $file), $replace_options);
1102
  }
1103
  if (!empty($title)) {
1104
    $file->title = token_replace($title, array('file' => $file), $replace_options);
1105
  }
1053 1106
}
1054 1107

  
1055 1108
/**
1056
 * Implements hook_file_default_displays_alter().
1109
 * For sanity in grammar.
1110
 *
1111
 * @see media_set_browser_params()
1057 1112
 */
1058
function media_file_default_displays_alter(&$file_displays) {
1059
  // Image previews should be displayed using the media image style.
1060
  if (isset($file_displays['image__preview__file_field_image'])) {
1061
    $file_displays['image__preview__file_field_image']->settings['image_style'] = 'media_thumbnail';
1062
  }
1113
function media_get_browser_params() {
1114
  return media_set_browser_params();
1115
}
1063 1116

  
1064
  // Video previews should be displayed using a large filetype icon.
1065
  if (isset($file_displays['video__preview__file_field_file_default'])) {
1066
    $file_displays['video__preview__file_field_file_default']->status = FALSE;
1067
  }
1117
/**
1118
 * Provides a singleton of the params passed to the media browser.
1119
 *
1120
 * This is useful in situations like form alters because callers can pass
1121
 * id="wysiywg_form" or whatever they want, and a form alter could pick this up.
1122
 * We may want to change the hook_media_browser_plugin_view() implementations to
1123
 * use this function instead of being passed params for consistency.
1124
 *
1125
 * It also offers a chance for some meddler to meddle with them.
1126
 *
1127
 * @see media_browser()
1128
 */
1129
function media_set_browser_params() {
1130
  $params = &drupal_static(__FUNCTION__, array());
1131

  
1132
  if (empty($params)) {
1133
    // Build out browser settings. Permissions- and security-related behaviors
1134
    // should not rely on these parameters, since they come from the HTTP query.
1135
    // @TODO make sure we treat parameters as user input.
1136
    $params = drupal_get_query_parameters() + array(
1137
        'types' => array(),
1138
        'multiselect' => FALSE,
1139
      );
1068 1140

  
1069
  $file_display = new stdClass();
1070
  $file_display->api_version = 1;
1071
  $file_display->name = 'video__preview__file_field_media_large_icon';
1072
  $file_display->weight = 50;
1073
  $file_display->status = TRUE;
1074
  $file_display->settings = '';
1075
  $file_displays['video__preview__file_field_media_large_icon'] = $file_display;
1076

  
1077
  // Audio previews should be displayed using a large filetype icon.
1078
  if (isset($file_displays['audio__preview__file_field_file_default'])) {
1079
    $file_displays['audio__preview__file_field_file_default']->status = FALSE;
1080
  }
1141
    // Transform text 'true' and 'false' to actual booleans.
1142
    foreach ($params as $k => $v) {
1143
      if ($v === 'true') {
1144
        $params[$k] = TRUE;
1145
      }
1146
      elseif ($v === 'false') {
1147
        $params[$k] = FALSE;
1148
      }
1149
    }
1081 1150

  
1082
  $file_display = new stdClass();
1083
  $file_display->api_version = 1;
1084
  $file_display->name = 'audio__preview__file_field_media_large_icon';
1085
  $file_display->weight = 50;
1086
  $file_display->status = TRUE;
1087
  $file_display->settings = '';
1088
  $file_displays['audio__preview__file_field_media_large_icon'] = $file_display;
1089

  
1090
  // Document previews should be displayed using a large filetype icon.
1091
  if (isset($file_displays['document__preview__file_field_file_default'])) {
1092
    $file_displays['document__preview__file_field_file_default']->status = FALSE;
1151
    array_walk_recursive($params, 'media_recursive_check_plain');
1152

  
1153
    // Allow modules to alter the parameters.
1154
    drupal_alter('media_browser_params', $params);
1093 1155
  }
1094 1156

  
1095
  $file_display = new stdClass();
1096
  $file_display->api_version = 1;
1097
  $file_display->name = 'document__preview__file_field_media_large_icon';
1098
  $file_display->weight = 50;
1099
  $file_display->status = TRUE;
1100
  $file_display->settings = '';
1101
  $file_displays['document__preview__file_field_media_large_icon'] = $file_display;
1157
  return $params;
1102 1158
}
1103 1159

  
1104 1160
/**
......
1132 1188
  // selected and they try to switch between the "Thumbnail" and "List" local
1133 1189
  // tasks.
1134 1190
  $path = drupal_get_path('module', 'media');
1135
  require_once $path . '/includes/media.browser.inc';
1136 1191
  $form['#attributes']['class'][] = 'file-entity-admin-file-form';
1137 1192
  $form['#attached']['js'][] = $path . '/js/media.admin.js';
1138 1193
  $form['#attached']['css'][] = $path . '/css/media.css';
1139
  media_attach_browser_js($form);
1140 1194

  
1141 1195
  // By default, this form contains a table select element called "files". For
1142 1196
  // the 'thumbnails' tab, Media generates a thumbnail for each file and
1143 1197
  // replaces the tableselect with a grid of thumbnails.
1144 1198
  if (arg(3) == 'thumbnails') {
1145
    if (empty($form['admin']['files'])) {
1199
    if (empty($form['admin']['files']['#options'])) {
1146 1200
      // Display empty text if there are no files.
1147 1201
      $form['admin']['files'] = array(
1148
        '#markup' => '<p>' . $form['files']['#empty'] . '</p>',
1202
        '#markup' => '<p>' . $form['admin']['files']['#empty'] . '</p>',
1149 1203
      );
1150 1204
    }
1151 1205
    else {
......
1245 1299
  return $info;
1246 1300
}
1247 1301

  
1302
/**
1303
 * Gets the MIME type mapped to a given extension.
1304
 *
1305
 * @param string $extension
1306
 *   A file extension.
1307
 *
1308
 * @return string
1309
 *   The MIME type associated with the extension or FALSE if the extension does
1310
 *   not have an associated MIME type.
1311
 *
1312
 * @see file_mimetype_mapping()
1313
 */
1314
function media_get_extension_mimetype($extension) {
1315
  include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
1316
  $mimetype_mappings = file_mimetype_mapping();
1317

  
1318
  if (isset($mimetype_mappings['extensions'][$extension])) {
1319
    $id = $mimetype_mappings['extensions'][$extension];
1320
    return $mimetype_mappings['mimetypes'][$id];
1321
  }
1322
  else {
1323
    return FALSE;
1324
  }
1325
}
1326

  
1248 1327
/**
1249 1328
 * Helper function to get a list of local stream wrappers.
1250 1329
 */
......
1261 1340
  $wrappers = array_diff_key($wrappers, file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL_HIDDEN));
1262 1341
  return $wrappers;
1263 1342
}
1264

  
1265

  
1266
/**
1267
 * Checks if there are any files that belong to disabled or deleted file
1268
 * types.
1269
 *
1270
 * @return Array of file types (machine names) that are candidates for
1271
 *   migration.
1272
 */
1273
function _media_get_migratable_file_types() {
1274
  $query = db_select('file_managed', 'f')
1275
    ->fields('f', array('type'))
1276
    ->distinct();
1277
  $types = $query->execute()->fetchCol();
1278
  $enabled_types = array();
1279
  foreach (file_type_get_enabled_types() as $type) {
1280
    $enabled_types[] = $type->type;
1281
  }
1282

  
1283
  return array_diff($types, $enabled_types);
1284
}

Formats disponibles : Unified diff