Révision ca0757b9
Ajouté par Assos Assos il y a plus de 9 ans
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
Weekly update of contrib modules