You are here

file_entity.module in File Entity (fieldable files) 7

Same filename and directory in other branches
  1. 8.2 file_entity.module
  2. 7.3 file_entity.module
  3. 7.2 file_entity.module

Extends Drupal file entities to be fieldable and viewable.

File

file_entity.module
View source
<?php

/**
 * @file
 * Extends Drupal file entities to be fieldable and viewable.
 */

/**
 * As part of extending Drupal core's file entity API, this module adds some
 * functions to the 'file' namespace. For organization, those are kept in the
 * 'file_entity.file_api.inc' file.
 */
require_once dirname(__FILE__) . '/file_entity.file_api.inc';

// @todo Remove when http://drupal.org/node/977052 is fixed.
require_once dirname(__FILE__) . '/file_entity.field.inc';

/**
 * Implements hook_help().
 */
function file_entity_help($path, $arg) {
  switch ($path) {
    case 'admin/config/media/file-types':
      $output = '<p>' . t('When a file is uploaded to this website, it is assigned one of the following types, based on what kind of file it is.') . '</p>';
      return $output;
  }
}

/**
 * Access callback for files.
 */
function file_entity_access($op) {
  return user_access('administer files') || user_access($op . ' file');
}

/**
 * Implements hook_menu().
 */
function file_entity_menu() {

  // File Configuration
  $items['admin/config/media/file-types'] = array(
    'title' => 'File types',
    'description' => 'Manage settings for the type of files used on your site.',
    'page callback' => 'file_entity_list_types_page',
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'file_entity.admin.inc',
  );
  $items['admin/config/media/file-types/manage/%'] = array(
    'title' => 'Manage file types',
    'description' => 'Manage settings for the type of files used on your site.',
  );
  $items['admin/content/file'] = array(
    'title' => 'Files',
    'description' => 'Manage files used on your site.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'file_entity_admin_files',
    ),
    'access arguments' => array(
      'administer files',
    ),
    'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM,
    'file' => 'file_entity.admin.inc',
  );
  $items['admin/content/file/list'] = array(
    'title' => 'List',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

  // general view, edit, delete for files
  $items['file/%file'] = array(
    'page callback' => 'file_entity_view_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'file_entity_access',
    'access arguments' => array(
      'view',
    ),
    'file' => 'file_entity.pages.inc',
  );
  $items['file/%file/view'] = array(
    'title' => 'View',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['file/%file/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'file_entity_page_edit',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'file_entity_access',
    'access arguments' => array(
      'edit',
    ),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'file_entity.pages.inc',
  );
  $items['file/%file/delete'] = array(
    'title' => 'Delete',
    'page callback' => 'file_entity_page_delete',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'file_entity_access',
    'access arguments' => array(
      'edit',
    ),
    'weight' => 1,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'file_entity.pages.inc',
  );

  // Attach a "Manage file display" tab to each file type in the same way that
  // Field UI attaches "Manage fields" and "Manage display" tabs. Note that
  // Field UI does not have to be enabled; we're just using the same IA pattern
  // here for attaching the "Manage file display" page.
  $entity_info = entity_get_info('file');
  foreach ($entity_info['bundles'] as $file_type => $bundle_info) {
    if (isset($bundle_info['admin'])) {

      // Get the base path and access.
      $path = $bundle_info['admin']['path'];
      $access = array_intersect_key($bundle_info['admin'], drupal_map_assoc(array(
        'access callback',
        'access arguments',
      )));
      $access += array(
        'access callback' => 'user_access',
        'access arguments' => array(
          'administer site configuration',
        ),
      );

      // The file type must be passed to the page callbacks. It might be
      // configured as a wildcard (multiple file types sharing the same menu
      // router path).
      $file_type_argument = isset($bundle_info['admin']['bundle argument']) ? $bundle_info['admin']['bundle argument'] : $file_type;

      // Add the 'Manage file display' tab.
      $items["{$path}/file-display"] = array(
        'title' => 'Manage file display',
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
          'file_entity_file_display_form',
          $file_type_argument,
          'default',
        ),
        'type' => MENU_LOCAL_TASK,
        'weight' => 3,
        'file' => 'file_entity.admin.inc',
      ) + $access;

      // Add a secondary tab for each view mode.
      $weight = 0;
      $view_modes = array(
        'default' => array(
          'label' => t('Default'),
        ),
      ) + $entity_info['view modes'];
      foreach ($view_modes as $view_mode => $view_mode_info) {
        $items["{$path}/file-display/{$view_mode}"] = array(
          'title' => $view_mode_info['label'],
          'page arguments' => array(
            'file_entity_file_display_form',
            $file_type_argument,
            $view_mode,
          ),
          'type' => $view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
          'weight' => $view_mode == 'default' ? -10 : $weight++,
          'file' => 'file_entity.admin.inc',
          // View modes for which the 'custom settings' flag isn't TRUE are
          // disabled via this access callback. This needs to extend, rather
          // than override normal $access rules.
          'access callback' => '_file_entity_view_mode_menu_access',
          'access arguments' => array_merge(array(
            $file_type_argument,
            $view_mode,
            $access['access callback'],
          ), $access['access arguments']),
        );
      }
    }
  }
  return $items;
}

/**
 * Implement hook_permission().
 */
function file_entity_permission() {
  return array(
    'administer files' => array(
      'title' => t('Administer files'),
      'description' => t('Add, edit or delete files and administer settings.'),
    ),
    'view file' => array(
      'title' => t('View file'),
      'description' => t('View all files.'),
    ),
    'edit file' => array(
      'title' => t('Edit file'),
      'description' => t('Edit all files.'),
    ),
  );
}

/**
 * Implements hook_admin_paths().
 */
function file_entity_admin_paths() {
  $paths = array(
    'file/*/edit' => TRUE,
    'file/*/delete' => TRUE,
  );
  return $paths;
}

/**
 * Implements hook_theme().
 */
function file_entity_theme() {
  return array(
    'file_entity' => array(
      'render element' => 'elements',
      'template' => 'file_entity',
    ),
    'file_entity_file_type_overview' => array(
      'variables' => array(
        'label' => NULL,
        'description' => NULL,
      ),
      'file' => 'file_entity.admin.inc',
    ),
    'file_entity_file_display_order' => array(
      'render element' => 'element',
      'file' => 'file_entity.admin.inc',
    ),
    'file_entity_file_link' => array(
      'variables' => array(
        'file' => NULL,
        'icon_directory' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook_entity_info_alter().
 *
 * Extends the core file entity to be fieldable. Modules can define file types
 * via hook_file_type_info(). For each defined type, create a bundle, so that
 * fields can be configured per file type.
 */
function file_entity_entity_info_alter(&$entity_info) {
  $entity_info['file']['fieldable'] = TRUE;
  $entity_info['file']['entity keys']['bundle'] = 'type';
  $entity_info['file']['bundles'] = array();
  $entity_info['file']['view modes']['full'] = array(
    'label' => t('Full'),
    'custom settings' => FALSE,
  );
  foreach (file_info_file_types() as $type => $info) {
    $info += array(
      // Provide a default administration path for Field UI, but not if 'admin'
      // has been explicitly set to NULL.
      'admin' => array(
        'path' => 'admin/config/media/file-types/manage/%',
        'real path' => 'admin/config/media/file-types/manage/' . $type,
        'bundle argument' => 5,
      ),
    );
    $entity_info['file']['bundles'][$type] = array_intersect_key($info, drupal_map_assoc(array(
      'label',
      'admin',
    )));
    $entity_info['file']['view callback'] = 'file_view_multiple';
  }
}

/**
 * Implements hook_field_extra_fields().
 *
 * Adds 'file' as an extra field, so that its display and form component can be
 * weighted relative to the fields that are added to file entity bundles.
 */
function file_entity_field_extra_fields() {
  $return = array();
  $info = entity_get_info('file');
  foreach (array_keys($info['bundles']) as $bundle) {
    $return['file'][$bundle] = array(
      'form' => array(
        'file' => array(
          'label' => t('File'),
          'description' => t('File preview'),
          'weight' => 0,
        ),
      ),
      'display' => array(
        'file' => array(
          'label' => t('File'),
          'description' => t('File display'),
          'weight' => 0,
        ),
      ),
    );
  }
  return $return;
}

/**
 * Implements hook_file_presave().
 */
function file_entity_file_presave($file) {

  // Always ensure the filemime property is current.
  if (!empty($file->original) || empty($file->filemime)) {
    $file->filemime = file_get_mimetype($file->uri);
  }

  // Always update file type based on filemime.
  $file->type = file_get_type($file);
  field_attach_presave('file', $file);
}

/**
 * Implements hook_file_insert().
 */
function file_entity_file_insert($file) {
  field_attach_insert('file', $file);
}

/**
 * Implement hook_file_update().
 */
function file_entity_file_update($file) {
  field_attach_update('file', $file);
}

/**
 * Implements hook_file_delete().
 */
function file_entity_file_delete($file) {
  field_attach_delete('file', $file);
}

/**
 * Implements hook_file_formatter_info().
 */
function file_entity_file_formatter_info() {
  $formatters = array();

  // Allow file field formatters to be reused for displaying the file entity's
  // file pseudo-field.
  if (module_exists('file')) {
    foreach (field_info_formatter_types() as $field_formatter_type => $field_formatter_info) {
      if (in_array('file', $field_formatter_info['field types'])) {
        $formatters['file_field_' . $field_formatter_type] = array(
          'label' => $field_formatter_info['label'],
          'view callback' => 'file_entity_file_formatter_file_field_view',
        );
        if (isset($field_formatter_info['settings'])) {
          $formatters['file_field_' . $field_formatter_type] += array(
            'default settings' => $field_formatter_info['settings'],
            'settings callback' => 'file_entity_file_formatter_file_field_settings',
          );
        }
      }
    }
  }

  // Add a simple file formatter for displaying an image in a chosen style.
  if (module_exists('image')) {
    $formatters['file_image'] = array(
      'label' => t('Image'),
      'default settings' => array(
        'image_style' => '',
      ),
      'view callback' => 'file_entity_file_formatter_file_image_view',
      'settings callback' => 'file_entity_file_formatter_file_image_settings',
    );
  }
  return $formatters;
}

/**
 * Implements hook_file_formatter_FORMATTER_view().
 *
 * This function provides a bridge to the field formatter API, so that file
 * field formatters can be reused for displaying the file entity's file
 * pseudo-field.
 */
function file_entity_file_formatter_file_field_view($file, $display, $langcode) {
  if (strpos($display['type'], 'file_field_') === 0) {
    $field_formatter_type = substr($display['type'], strlen('file_field_'));
    $field_formatter_info = field_info_formatter_types($field_formatter_type);
    if (isset($field_formatter_info['module'])) {

      // Set $display['type'] to what hook_field_formatter_*() expects.
      $display['type'] = $field_formatter_type;

      // Set $items to what file field formatters expect. See file_field_load(),
      // and note that, here, $file is already a fully loaded entity.
      $items = array(
        (array) $file,
      );

      // Invoke hook_field_formatter_prepare_view() and
      // hook_field_formatter_view(). Note that we are reusing field formatter
      // functions, but we are not displaying a Field API field, so we set
      // $field and $instance accordingly, and do not invoke
      // hook_field_prepare_view(). This assumes that the formatter functions do
      // not rely on $field or $instance. A module that implements formatter
      // functions that rely on $field or $instance (and therefore, can only be
      // used for real fields) can prevent this formatter from being used on the
      // pseudo-field by removing it within hook_file_formatter_info_alter().
      $field = $instance = NULL;
      if (($function = $field_formatter_info['module'] . '_field_formatter_prepare_view') && function_exists($function)) {
        $fid = $file->fid;

        // hook_field_formatter_prepare_view() alters $items by reference.
        $grouped_items = array(
          $fid => &$items,
        );
        $function('file', array(
          $fid => $file,
        ), $field, array(
          $fid => $instance,
        ), $langcode, $grouped_items, array(
          $fid => $display,
        ));
      }
      if (($function = $field_formatter_info['module'] . '_field_formatter_view') && function_exists($function)) {
        $element = $function('file', $file, $field, $instance, $langcode, $items, $display);

        // We passed the file as $items[0], so return the corresponding element.
        if (isset($element[0])) {
          return $element[0];
        }
      }
    }
  }
}

/**
 * Implements hook_file_formatter_FORMATTER_settings().
 *
 * This function provides a bridge to the field formatter API, so that file
 * field formatters can be reused for displaying the file entity's file
 * pseudo-field.
 */
function file_entity_file_formatter_file_field_settings($form, &$form_state, $settings, $formatter_type, $file_type, $view_mode) {
  if (strpos($formatter_type, 'file_field_') === 0) {
    $field_formatter_type = substr($formatter_type, strlen('file_field_'));
    $field_formatter_info = field_info_formatter_types($field_formatter_type);

    // Invoke hook_field_formatter_settings_form(). We are reusing field
    // formatter functions, but we are not working with a Field API field, so
    // set $field accordingly. Unfortunately, the API is for $settings to be
    // transfered via the $instance parameter, so we must mock it.
    if (isset($field_formatter_info['module']) && ($function = $field_formatter_info['module'] . '_field_formatter_settings_form') && function_exists($function)) {
      $field = NULL;
      $mock_instance['display'][$view_mode] = array(
        'type' => $field_formatter_type,
        'settings' => $settings,
      );
      return $function($field, $mock_instance, $view_mode, $form, $form_state);
    }
  }
}

/**
 * Implements hook_file_formatter_FORMATTER_view().
 *
 * Returns a drupal_render() array to display an image of the chosen style.
 *
 * This formatter is only capable of displaying local images. If the passed in
 * file is either not local or not an image, nothing is returned, so that
 * file_view_file() can try another formatter.
 */
function file_entity_file_formatter_file_image_view($file, $display, $langcode) {
  $scheme = file_uri_scheme($file->uri);
  $local_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
  if (isset($local_wrappers[$scheme]) && strpos($file->filemime, 'image/') === 0) {
    if (!empty($display['settings']['image_style'])) {
      $element = array(
        '#theme' => 'image_style',
        '#style_name' => $display['settings']['image_style'],
        '#path' => $file->uri,
      );
    }
    else {
      $element = array(
        '#theme' => 'image',
        '#path' => $file->uri,
      );
    }
    return $element;
  }
}

/**
 * Implements hook_file_formatter_FORMATTER_settings().
 *
 * Returns form elements for configuring the 'file_image' formatter.
 */
function file_entity_file_formatter_file_image_settings($form, &$form_state, $settings) {
  $element = array();
  $element['image_style'] = array(
    '#title' => t('Image style'),
    '#type' => 'select',
    '#options' => image_style_options(FALSE),
    '#default_value' => $settings['image_style'],
    '#empty_option' => t('None (original image)'),
  );
  return $element;
}

/**
 * Menu access callback for the 'view mode file display settings' pages.
 *
 * Based on _field_ui_view_mode_menu_access(), but the Field UI module might not
 * be enabled.
 */
function _file_entity_view_mode_menu_access($file_type, $view_mode, $access_callback) {

  // Deny access if the view mode isn't configured to use custom display
  // settings.
  $view_mode_settings = field_view_mode_settings('file', $file_type);
  $visibility = $view_mode == 'default' || !empty($view_mode_settings[$view_mode]['custom_settings']);
  if (!$visibility) {
    return FALSE;
  }

  // Otherwise, continue to an $access_callback check.
  $args = array_slice(func_get_args(), 3);
  $callback = empty($access_callback) ? 0 : trim($access_callback);
  if (is_numeric($callback)) {
    return (bool) $callback;
  }
  elseif (function_exists($access_callback)) {
    return call_user_func_array($access_callback, $args);
  }
}

/**
 * Implements hook_modules_enabled().
 */
function file_entity_modules_enabled($modules) {
  file_info_cache_clear();
}

/**
 * Implements hook_modules_disabled().
 */
function file_entity_modules_disabled($modules) {
  file_info_cache_clear();
}

/**
 * Implements hook_views_api().
 */
function file_entity_views_api() {
  return array(
    'api' => 3,
  );
}

/**
 * Returns whether the current page is the full page view of the passed-in file.
 *
 * @param $file
 *   A file object.
 */
function file_is_page($file) {
  $page_file = menu_get_object('file', 1);
  return !empty($page_file) ? $page_file->fid == $file->fid : FALSE;
}

/**
 * Process variables for file_entity.tpl.php
 *
 * The $variables array contains the following arguments:
 * - $file
 * - $view_mode
 *
 * @see file_entity.tpl.php
 */
function template_preprocess_file_entity(&$variables) {
  $view_mode = $variables['view_mode'] = $variables['elements']['#view_mode'];
  $variables['file'] = $variables['elements']['#file'];
  $file = $variables['file'];
  $variables['date'] = format_date($file->timestamp);
  $account = user_load($file->uid);
  $variables['name'] = theme('username', array(
    'account' => $account,
  ));

  // @todo Use entity_uri once http://drupal.org/node/1057242 is fixed.

  //$uri = entity_uri('file', $file);

  //$variables['file_url']  = url($uri['path'], $uri['options']);
  $variables['file_url'] = file_create_url($file->uri);
  $label = entity_label('file', $file);
  $variables['label'] = check_plain($label);
  $variables['page'] = $view_mode == 'full' && file_is_page($file);

  // Disable the file name from being displayed as the title until we can
  // figure out a better way to control this.
  // @see http://drupal.org/node/1245266
  $variables['page'] = TRUE;

  // Flatten the file object's member fields.
  $variables = array_merge((array) $file, $variables);

  // Helpful $content variable for templates.
  $variables += array(
    'content' => array(),
  );
  foreach (element_children($variables['elements']) as $key) {
    $variables['content'][$key] = $variables['elements'][$key];
  }

  // Make the field variables available with the appropriate language.
  field_attach_preprocess('file', $file, $variables['content'], $variables);

  // Display post information only on certain file types.
  if (variable_get('file_submitted_' . $file->type, FALSE)) {
    $variables['display_submitted'] = TRUE;
    $variables['submitted'] = t('Uploaded by !username on !datetime', array(
      '!username' => $variables['name'],
      '!datetime' => $variables['date'],
    ));
    $variables['user_picture'] = theme_get_setting('toggle_file_user_picture') ? theme('user_picture', array(
      'account' => $account,
    )) : '';
  }
  else {
    $variables['display_submitted'] = FALSE;
    $variables['submitted'] = '';
    $variables['user_picture'] = '';
  }

  // Gather file classes.
  $variables['classes_array'][] = drupal_html_class('file-' . $file->type);
  $variables['classes_array'][] = drupal_html_class('file-' . $file->filemime);
  if ($file->status != FILE_STATUS_PERMANENT) {
    $variables['classes_array'][] = 'file-temporary';
  }

  // Change the 'file-entity' class into 'file'
  if ($variables['classes_array'][0] == 'file-entity') {
    $variables['classes_array'][0] = 'file';
  }

  // Clean up name so there are no underscores.
  $variables['theme_hook_suggestions'][] = 'file__' . $file->type;
  $variables['theme_hook_suggestions'][] = 'file__' . $file->type . '__' . $view_mode;
  $variables['theme_hook_suggestions'][] = 'file__' . str_replace(array(
    '/',
    '-',
  ), array(
    '__',
    '_',
  ), $file->filemime);
  $variables['theme_hook_suggestions'][] = 'file__' . str_replace(array(
    '/',
    '-',
  ), array(
    '__',
    '_',
  ), $file->filemime) . '__' . $view_mode;
  $variables['theme_hook_suggestions'][] = 'file__' . $file->fid;
  $variables['theme_hook_suggestions'][] = 'file__' . $file->fid . '__' . $view_mode;
}

/**
 * Returns the file type name of the passed file or file type string.
 *
 * @param $file
 *   A file object or string that indicates the file type to return.
 *
 * @return
 *   The file type name or FALSE if the file type is not found.
 */
function file_type_get_name($file) {
  $type = is_object($file) ? $file->type : $file;
  $info = entity_get_info('file');
  return isset($info['bundles'][$type]['label']) ? $info['bundles'][$type]['label'] : FALSE;
}

/**
 * Returns a list of available file type names.
 *
 * @return
 *   An array of file type names, keyed by the type.
 */
function file_type_get_names() {
  $names =& drupal_static(__FUNCTION__);
  if (!isset($names)) {
    $info = entity_get_info('file');
    foreach ($info['bundles'] as $bundle => $bundle_info) {
      $names[$bundle] = $bundle_info['label'];
    }
  }
  return $names;
}

/**
 * Implements hook_file_mimetype_mapping_alter().
 */
function file_entity_file_mimetype_mapping_alter(&$mapping) {

  // Fix the mime type mapping for ogg.
  // @todo Remove when http://drupal.org/node/1239376 is fixed in core.
  $new_mappings['ogg'] = 'audio/ogg';

  // Add support for m4v.
  // @todo Remove when http://drupal.org/node/1290486 is fixed in core.
  $new_mappings['m4v'] = 'video/x-m4v';

  // Add support for mka and mkv.
  // @todo Remove when http://drupal.org/node/1293140 is fixed in core.
  $new_mappings['mka'] = 'audio/x-matroska';
  $new_mappings['mkv'] = 'video/x-matroska';
  foreach ($new_mappings as $extension => $mime_type) {
    if (!in_array($mime_type, $mapping['mimetypes'])) {

      // If the mime type does not already exist, add it.
      $mapping['mimetypes'][] = $mime_type;
    }

    // Get the index of the mime type and assign the extension to that key.
    $index = array_search($mime_type, $mapping['mimetypes']);
    $mapping['extensions'][$extension] = $index;
  }
}

/**
 * Return an array of available view modes for file entities.
 */
function file_entity_view_mode_labels() {
  $labels =& drupal_static(__FUNCTION__);
  if (!isset($options)) {
    $entity_info = entity_get_info('file');
    $labels = array(
      'default' => t('Default'),
    );
    foreach ($entity_info['view modes'] as $machine_name => $mode) {
      $labels[$machine_name] = $mode['label'];
    }
  }
  return $labels;
}

/**
 * Return the label for a specific file entity view mode.
 */
function file_entity_view_mode_label($view_mode, $default = FALSE) {
  $labels = file_entity_view_mode_labels();
  return isset($labels[$view_mode]) ? $labels[$view_mode] : $default;
}

/**
 * Implements hook_file_operations_info().
 */
function file_entity_file_operations_info() {
  $operations = array(
    'delete' => array(
      'label' => t('Delete selected files'),
      'callback' => 'file_entity_multiple_delete_confirm_operation',
      'confirm' => TRUE,
    ),
  );
  return $operations;
}

/**
 * File operation to show a confirm form for file deletion.
 *
 * @param array $files
 *   An array of file_ids to delete.
 * @return type
 */
function file_entity_multiple_delete_confirm_operation($files) {

  // This function is a form generation function.
  $form = array();
  $form_state = array();

  // Set the submit handler explicitly because this form is being built
  // under a different form_id.
  $form['#submit'] = array();
  $form['#submit'][] = 'file_entity_multiple_delete_confirm_submit';
  return file_entity_multiple_delete_confirm($form, $form_state, $files);
}

/**
 * Helper function to get a list of hidden stream wrappers.
 *
 * This is used in several places to filter queries for media so that files in
 * temporary:// don't show up.
 */
function file_entity_get_hidden_stream_wrappers() {
  return array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_VISIBLE));
}

/**
 * A copy of theme_file_file_link() that makes the link point to file/[fid].
 *
 * @see theme_file_file_link()
 * @return type
 */
function theme_file_entity_file_link($variables) {
  $file = $variables['file'];
  $icon_directory = $variables['icon_directory'];
  $url = 'file/' . $file->fid;
  $icon = theme('file_icon', array(
    'file' => $file,
    'icon_directory' => $icon_directory,
  ));

  // Set options as per anchor format described at
  // http://microformats.org/wiki/file-format-examples
  $options = array(
    'attributes' => array(
      'type' => $file->filemime . '; length=' . $file->filesize,
    ),
  );

  // Use the description as the link text if available.
  if (empty($file->description)) {
    $link_text = $file->filename;
  }
  else {
    $link_text = $file->description;
    $options['attributes']['title'] = check_plain($file->filename);
  }
  return '<span class="file">' . $icon . ' ' . l($link_text, $url, $options) . '</span>';
}

Functions

Namesort descending Description
file_entity_access Access callback for files.
file_entity_admin_paths Implements hook_admin_paths().
file_entity_entity_info_alter Implements hook_entity_info_alter().
file_entity_field_extra_fields Implements hook_field_extra_fields().
file_entity_file_delete Implements hook_file_delete().
file_entity_file_formatter_file_field_settings Implements hook_file_formatter_FORMATTER_settings().
file_entity_file_formatter_file_field_view Implements hook_file_formatter_FORMATTER_view().
file_entity_file_formatter_file_image_settings Implements hook_file_formatter_FORMATTER_settings().
file_entity_file_formatter_file_image_view Implements hook_file_formatter_FORMATTER_view().
file_entity_file_formatter_info Implements hook_file_formatter_info().
file_entity_file_insert Implements hook_file_insert().
file_entity_file_mimetype_mapping_alter Implements hook_file_mimetype_mapping_alter().
file_entity_file_operations_info Implements hook_file_operations_info().
file_entity_file_presave Implements hook_file_presave().
file_entity_file_update Implement hook_file_update().
file_entity_get_hidden_stream_wrappers Helper function to get a list of hidden stream wrappers.
file_entity_help Implements hook_help().
file_entity_menu Implements hook_menu().
file_entity_modules_disabled Implements hook_modules_disabled().
file_entity_modules_enabled Implements hook_modules_enabled().
file_entity_multiple_delete_confirm_operation File operation to show a confirm form for file deletion.
file_entity_permission Implement hook_permission().
file_entity_theme Implements hook_theme().
file_entity_views_api Implements hook_views_api().
file_entity_view_mode_label Return the label for a specific file entity view mode.
file_entity_view_mode_labels Return an array of available view modes for file entities.
file_is_page Returns whether the current page is the full page view of the passed-in file.
file_type_get_name Returns the file type name of the passed file or file type string.
file_type_get_names Returns a list of available file type names.
template_preprocess_file_entity Process variables for file_entity.tpl.php
theme_file_entity_file_link A copy of theme_file_file_link() that makes the link point to file/[fid].
_file_entity_view_mode_menu_access Menu access callback for the 'view mode file display settings' pages.