uri) === 'private')) { return MENU_ACCESS_DENIED; } drupal_set_title($file->filename); $uri = entity_uri('file', $file); // Set the file path as the canonical URL to prevent duplicate content. drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], $uri['options'])), TRUE); // Set the non-aliased path as a default shortlink. drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE); return file_view($file, 'full'); } /** * Form callback for adding media via an upload form. * @todo: should use the AJAX uploader */ function file_entity_add_upload($form, &$form_state, array $options = array()) { $form['upload'] = array( '#type' => 'managed_file', '#title' => t('Upload a new file'), '#upload_location' => file_entity_upload_destination_uri($options), '#upload_validators' => file_entity_get_upload_validators($options), '#progress_indicator' => 'bar', '#required' => TRUE, '#pre_render' => array('file_managed_file_pre_render', 'file_entity_upload_validators_pre_render'), ); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); form_load_include($form_state, 'inc', 'file_entity', 'file_entity.pages'); return $form; } /** * Page callback to show file usage information. */ function file_entity_usage_page($file) { $rows = array(); $occured_entities = array(); foreach (file_usage_list($file) as $module => $usage) { $info = system_get_info('module', $module); // There are cases, where actual entitiy doesen't exist. We have to handle this. foreach ($usage as $entity_type => $entity_ids) { $entity_info = entity_get_info($entity_type); $entities = empty($entity_info) ? NULL : entity_load($entity_type, array_keys($entity_ids)); foreach ($entity_ids as $entity_id => $count) { // If some other module already added this entity just sum all counts. if (isset($occured_entities[$entity_type][$entity_id])) { $rows[$occured_entities[$entity_type][$entity_id]][2] += $count; continue; } $label = empty($entities[$entity_id]) ? $module : entity_label($entity_type, $entities[$entity_id]); $entity_uri = empty($entities[$entity_id]) ? NULL : entity_uri($entity_type, $entities[$entity_id]); // Some entities do not have URL. if (empty($entity_uri)) { $rows[] = array($entity_type, check_plain($label), $count); } else { $uri = $entity_uri['path']; $rows[] = array($entity_type, l($label, $uri), $count); } $occured_entities[$entity_type][$entity_id] = count($rows) - 1; } } } $header[] = array( 'data' => t('Type'), ); $header[] = array( 'data' => t('Title'), ); $header[] = array( 'data' => t('Count'), ); $build['usage_table'] = array( '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#caption' => t('This table lists all of the places where @filename is used.', array('@filename' => $file->filename)), '#empty' => t('This file is not currently used.'), ); return $build; } /** * Upload a file. */ function file_entity_add_upload_submit($form, &$form_state) { $file = file_load($form_state['values']['upload']); if ($file) { // The media browser widget does not use the 'display' field. $file->display = TRUE; // Change the file from temporary to permanent. $file->status = FILE_STATUS_PERMANENT; file_save($file); $form_state['file'] = $file; drupal_set_message(t('The file @name was uploaded', array('@name' => $file->filename))); } else { drupal_set_message(t('An error occurred and no file was uploaded.'), 'error'); return; } // Figure out destination. if (isset($_GET['destination'])) { $destination = drupal_get_destination(); unset($_GET['destination']); } elseif (user_access('administer files')) { $destination = array('destination' => 'admin/content/file'); } else { $destination = array('destination' => 'file/' . $file->fid); } // Redirect to the file edit page after submission. if (file_entity_access('update', $file)) { $form_state['redirect'] = array('file/' . $file->fid . '/edit', array('query' => $destination)); } else { $form_state['redirect'] = $destination['destination']; } } /** * Determines the upload location for the file add upload form. * * @param array $params * An array of parameters from the media browser. * @param array $data * (optional) An array of token objects to pass to token_replace(). * * @return * A file directory URI with tokens replaced. * * @see token_replace() */ function file_entity_upload_destination_uri(array $params, array $data = array()) { $params += array( 'uri_scheme' => file_default_scheme(), 'file_directory' => '', ); $destination = trim($params['file_directory'], '/'); // Replace tokens. $destination = token_replace($destination, $data); return $params['uri_scheme'] . '://' . $destination; } function file_entity_add_upload_multiple($form, &$form_state, $params = array()) { $form = file_entity_add_upload($form, $form_state, $params); unset($form['upload']['#title']); // The validators will be set from plupload anyway. This isn't pretty, but don't // it to show up twice. unset($form['upload']['#description']); $form['upload']['#type'] = 'plupload'; $form['submit']['#value'] = t('Start upload'); return $form; } function file_entity_add_upload_multiple_submit($form, &$form_state) { $upload_location = !empty($form['upload']['#upload_location']) ? $form['upload']['#upload_location'] . '/' : variable_get('file_default_scheme', 'public') . '://'; // We can't use file_save_upload() because of http://www.jacobsingh.name/content/tight-coupling-no-not foreach ($form_state['values']['upload'] as $uploaded_file) { if ($uploaded_file['status'] == 'done') { $source = $uploaded_file['tmppath']; $destination = file_stream_wrapper_uri_normalize($upload_location . $uploaded_file['name']); // Rename it to its original name, and put it in its final home. // Note - not using file_move here because if we call file_get_mime // (in file_uri_to_object) while it has a .tmp extension, it horks. $destination = file_unmanaged_move($source, $destination, FILE_EXISTS_RENAME); $file = file_uri_to_object($destination); $file->status = FILE_STATUS_PERMANENT; file_save($file); $saved_files[] = $file; $form_state['files'][$file->fid] = $file; } else { // @todo: move this to element validate or something. form_set_error('pud', t('The specified file %name could not be uploaded.', array('%name' => $uploaded_file['name']))); } } // Redirect to the file edit page. if (file_entity_access('update', $file) && module_exists('multiform')) { $destination = array('destination' => 'admin/content/file'); if (isset($_GET['destination'])) { $destination = drupal_get_destination(); unset($_GET['destination']); } $form_state['redirect'] = array('admin/content/file/edit-multiple/' . implode(' ', array_keys($form_state['files'])), array('query' => $destination)); } else { $form_state['redirect'] = 'admin/content/file'; } } /** * Page callback: Form constructor for the file edit form. * * Path: file/%file/edit * * @param object $file * A file object from file_load(). * * @see file_entity_menu() * * @todo Rename this form to file_edit_form to ease into core. */ function file_entity_edit($form, &$form_state, $file) { drupal_set_title(t('Edit @type @title', array('@type' => $file->type, '@title' => $file->filename)), PASS_THROUGH); $form_state['file'] = $file; $form['#attributes']['class'][] = 'file-form'; if (!empty($file->type)) { $form['#attributes']['class'][] = 'file-' . $file->type . '-form'; } // Basic file information. // These elements are just values so they are not even sent to the client. foreach (array('fid', 'type', 'uid', 'timestamp') as $key) { $form[$key] = array( '#type' => 'value', '#value' => isset($file->$key) ? $file->$key : NULL, ); } $form['filename'] = array( '#type' => 'textfield', '#title' => t('Name'), '#default_value' => $file->filename, '#required' => TRUE, '#maxlength' => 255, '#weight' => -10, ); // Add a 'replace this file' upload field if the file is a local file only. if (file_entity_file_is_local($file)) { // Set up replacement file validation. $replacement_options = array(); // The replacement file must have the same extension as the original file. $replacement_options['file_extensions'] = pathinfo($file->uri, PATHINFO_EXTENSION); $form['replace_upload'] = array( '#type' => 'file', '#title' => t('Replace file'), '#description' => t('This file will replace the existing file. This action cannot be undone.'), '#upload_validators' => file_entity_get_upload_validators($replacement_options), '#pre_render' => array('file_entity_upload_validators_pre_render'), ); } $form['preview'] = file_view_file($file, 'preview'); // Add the buttons. $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('Save'), '#weight' => 5, '#submit' => array('file_entity_edit_submit'), ); $form['actions']['delete'] = array( '#type' => 'submit', '#value' => t('Delete'), '#weight' => 10, '#submit' => array('file_entity_edit_delete_submit'), ); $form['actions']['cancel'] = array( '#type' => 'link', '#title' => t('Cancel'), '#href' => isset($_GET['destination']) ? $_GET['destination'] : 'file/' . $file->fid, '#weight' => 15, ); $langcode = function_exists('entity_language') ? entity_language('file', $file) : NULL; field_attach_form('file', $file, $form, $form_state, $langcode); return $form; } /** * Form validation handler for file_entity_edit(). */ function file_entity_edit_validate($form, &$form_state) { // Handle the replacement file if uploaded. if (isset($form_state['values']['replace_upload'])) { // Save the file as a temporary file. $file = file_save_upload('replace_upload', $form['replace_upload']['#upload_validators']); if (!empty($file)) { // Put the temporary file in form_values so we can save it on submit. $form_state['values']['replace_upload'] = $file; } elseif ($file === FALSE) { // File uploaded failed. form_set_error('replace_upload', t('The replacement file could not be uploaded.')); } } // Run entity form validation. entity_form_field_validate('file', $form, $form_state); } /** * Form submission handler for the 'Save' button for file_entity_edit(). */ function file_entity_edit_submit($form, &$form_state) { $file = $form_state['file']; // Check if a replacement file has been uploaded. if (!empty($form_state['values']['replace_upload'])) { $replacement = $form_state['values']['replace_upload']; // Move file from temp to permanent home. file_unmanaged_copy($replacement->uri, $file->uri, FILE_EXISTS_REPLACE); } // Run entity form submit handling and save the file. entity_form_submit_build_entity('file', $file, $form, $form_state); file_save($file); $args = array( '@type' => file_entity_type_get_name($file), '%title' => entity_label('file', $file), ); watchdog('file', '@type: updated %title.', $args); drupal_set_message(t('@type %title has been updated.', $args)); $form_state['redirect'] = 'file/' . $file->fid; } /** * Form submission handler for the 'Delete' button for file_entity_edit(). */ function file_entity_edit_delete_submit($form, &$form_state) { $fid = $form_state['values']['fid']; $destination = array(); if (isset($_GET['destination'])) { $destination = drupal_get_destination(); unset($_GET['destination']); } $form_state['redirect'] = array('file/' . $fid . '/delete', array('query' => $destination)); } /** * Page callback: Form constructor for the file deletion confirmation form. * * Path: file/%file/delete * * @param object $file * A file object from file_load(). * * @see file_entity_menu() */ function file_entity_delete_form($form, &$form_state, $file) { $form_state['file'] = $file; $form['fid'] = array( '#type' => 'value', '#value' => $file->fid, ); $description = t('This action cannot be undone.'); if ($references = file_usage_list($file)) { $description .= ' ' . t('This file is currently in use and may cause problems if deleted.'); } return confirm_form($form, t('Are you sure you want to delete the file %title?', array( '%title' => entity_label('file', $file), )), 'file/' . $file->fid, $description, t('Delete') ); } /** * Form submission handler for file_entity_delete_form(). */ function file_entity_delete_form_submit($form, &$form_state) { if ($form_state['values']['confirm'] && $file = file_load($form_state['values']['fid'])) { // Use file_delete_multiple() rather than file_delete() since we want to // avoid unwanted validation and usage checking. file_delete_multiple(array($file->fid)); $args = array( '@type' => file_entity_type_get_name($file), '%title' => entity_label('file', $file), ); watchdog('file', '@type: deleted %title.', $args); drupal_set_message(t('@type %title has been deleted.', $args)); } $form_state['redirect'] = ''; } /** * Form constructor for file deletion confirmation form. * * @param array $files * An array of file objects. */ function file_entity_multiple_delete_form($form, &$form_state, array $files) { $form['files'] = array( '#prefix' => '', '#tree' => TRUE, ); $files_have_usage = FALSE; foreach ($files as $fid => $file) { $title = entity_label('file', $file); $usage = file_usage_list($file); if (!empty($usage)) { $files_have_usage = TRUE; $title = t('@title (in use)', array('@title' => $title)); } else { $title = check_plain($title); } $form['files'][$fid] = array( '#type' => 'hidden', '#value' => $fid, '#prefix' => '
  • ', '#suffix' => $title . "
  • \n", ); } $form['operation'] = array( '#type' => 'hidden', '#value' => 'delete', ); $description = t('This action cannot be undone.'); if ($files_have_usage) { $description .= ' ' . t('Some of the files are currently in use and may cause problems if deleted.'); } return confirm_form( $form, format_plural(count($files), 'Are you sure you want to delete this file?', 'Are you sure you want to delete these files?'), 'admin/content/file', $description, t('Delete') ); } /** * Form submission handler for file_entity_multiple_delete_form(). */ function file_entity_multiple_delete_form_submit($form, &$form_state) { if ($form_state['values']['confirm'] && $fids = array_keys($form_state['values']['files'])) { file_delete_multiple($fids); $count = count($fids); watchdog('file', 'Deleted @count files.', array('@count' => $count)); drupal_set_message(format_plural($count, 'Deleted one file.', 'Deleted @count files.')); } $form_state['redirect'] = 'admin/content/file'; } /** * Page callback for the file edit form. * * @deprecated * Use drupal_get_form('file_entity_edit') */ function file_entity_page_edit($file) { return drupal_get_form('file_entity_edit', $file); } /** * Page callback for the file deletion confirmation form. * * @deprecated * Use drupal_get_form('file_entity_delete_form') */ function file_entity_page_delete($file) { return drupal_get_form('file_entity_delete_form'); } /** * Retrieves the upload validators for a file. * * @param array $options * (optional) An array of options for file validation. * * @return array * An array suitable for passing to file_save_upload() or for a managed_file * or upload element's '#upload_validators' property. */ function file_entity_get_upload_validators(array $options = array()) { // Set up file upload validators. $validators = array(); // Validate file extensions. If there are no file extensions in $params and // there are no Media defaults, there is no file extension validation. if (!empty($options['file_extensions'])) { $validators['file_validate_extensions'] = array($options['file_extensions']); } else { $validators['file_validate_extensions'] = array(FILE_ENTITY_DEFAULT_ALLOWED_EXTENSIONS); } // Validate file size but do not allow anything higher than file_upload_max_size(). $max_filesize = file_upload_max_size(); if (!empty($options['max_filesize']) && $options['max_filesize'] < $max_filesize) { $validators['file_validate_size'] = array(parse_size($options['max_filesize'])); } else { $validators['file_validate_size'] = array($max_filesize); } // Add image validators. $options += array('min_resolution' => 0, 'max_resolution' => 0); if ($options['min_resolution'] || $options['max_resolution']) { $validators['file_validate_image_resolution'] = array($options['max_resolution'], $options['min_resolution']); } return $validators; }