first import
This commit is contained in:
185
sites/all/modules/media/file_entity/file_entity.admin.inc
Normal file
185
sites/all/modules/media/file_entity/file_entity.admin.inc
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Administrative interface for file type configuration.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Displays the file type admin overview page.
|
||||
*/
|
||||
function file_entity_list_types_page() {
|
||||
$types = file_info_file_types();
|
||||
$entity_info = entity_get_info('file');
|
||||
$field_ui = module_exists('field_ui');
|
||||
$header = array(
|
||||
array('data' => t('Name')),
|
||||
array('data' => t('Operations'), 'colspan' => $field_ui ? '3' : '1'),
|
||||
);
|
||||
$rows = array();
|
||||
|
||||
foreach ($types as $type => $info) {
|
||||
$row = array(array('data' => theme('file_entity_file_type_overview', $info)));
|
||||
$path = isset($entity_info['bundles'][$type]['admin']['real path']) ? $entity_info['bundles'][$type]['admin']['real path'] : NULL;
|
||||
if ($field_ui) {
|
||||
$row[] = array('data' => isset($path) ? l(t('manage fields'), $path . '/fields') : '');
|
||||
$row[] = array('data' => isset($path) ? l(t('manage display'), $path . '/display') : '');
|
||||
}
|
||||
$row[] = array('data' => isset($path) ? l(t('manage file display'), $path . '/file-display') : '');
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$build['file_type_table'] = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
'#empty' => t('No file types available.'),
|
||||
);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form callback; presents file display settings for a given view mode.
|
||||
*/
|
||||
function file_entity_file_display_form($form, &$form_state, $bundle, $view_mode) {
|
||||
$file_type = field_extract_bundle('file', $bundle);
|
||||
$form['#file_type'] = $file_type;
|
||||
$form['#view_mode'] = $view_mode;
|
||||
$form['#tree'] = TRUE;
|
||||
$form['#attached']['js'][] = drupal_get_path('module', 'file_entity') . '/file_entity.admin.js';
|
||||
|
||||
// Retrieve available formatters for this file type and load all configured
|
||||
// filters for existing text formats.
|
||||
$formatters = file_info_formatter_types();
|
||||
foreach ($formatters as $name => $formatter) {
|
||||
if (isset($formatter['file types']) && !in_array($file_type, $formatter['file types'])) {
|
||||
unset ($formatters[$name]);
|
||||
}
|
||||
}
|
||||
$current_displays = file_displays_load($file_type, $view_mode, TRUE);
|
||||
foreach ($current_displays as $name => $display) {
|
||||
$current_displays[$name] = (array) $display;
|
||||
}
|
||||
|
||||
// Formatter status.
|
||||
$form['displays']['status'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Enabled displays'),
|
||||
'#prefix' => '<div id="file-displays-status-wrapper">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
$i=0;
|
||||
foreach ($formatters as $name => $formatter) {
|
||||
$form['displays']['status'][$name] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $formatter['label'],
|
||||
'#default_value' => !empty($current_displays[$name]['status']),
|
||||
'#description' => isset($formatter['description']) ? $formatter['description'] : NULL,
|
||||
'#parents' => array('displays', $name, 'status'),
|
||||
'#weight' => $formatter['weight'] + $i/1000,
|
||||
);
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Formatter order (tabledrag).
|
||||
$form['displays']['order'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Display precedence order'),
|
||||
'#theme' => 'file_entity_file_display_order',
|
||||
);
|
||||
foreach ($formatters as $name => $formatter) {
|
||||
$form['displays']['order'][$name]['label'] = array(
|
||||
'#markup' => check_plain($formatter['label']),
|
||||
);
|
||||
$form['displays']['order'][$name]['weight'] = array(
|
||||
'#type' => 'weight',
|
||||
'#title' => t('Weight for @title', array('@title' => $formatter['label'])),
|
||||
'#title_display' => 'invisible',
|
||||
'#delta' => 50,
|
||||
'#default_value' => isset($current_displays[$name]['weight']) ? $current_displays[$name]['weight'] : 0,
|
||||
'#parents' => array('displays', $name, 'weight'),
|
||||
);
|
||||
$form['displays']['order'][$name]['#weight'] = $form['displays']['order'][$name]['weight']['#default_value'];
|
||||
}
|
||||
|
||||
// Formatter settings.
|
||||
$form['display_settings_title'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Display settings'),
|
||||
);
|
||||
$form['display_settings'] = array(
|
||||
'#type' => 'vertical_tabs',
|
||||
);
|
||||
$i=0;
|
||||
foreach ($formatters as $name => $formatter) {
|
||||
if (isset($formatter['settings callback']) && ($function = $formatter['settings callback']) && function_exists($function)) {
|
||||
$defaults = !empty($formatter['default settings']) ? $formatter['default settings'] : array();
|
||||
$settings = !empty($current_displays[$name]['settings']) ? $current_displays[$name]['settings'] : array();
|
||||
$settings += $defaults;
|
||||
$settings_form = $function($form, $form_state, $settings, $name, $file_type, $view_mode);
|
||||
if (!empty($settings_form)) {
|
||||
$form['displays']['settings'][$name] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => $formatter['label'],
|
||||
'#parents' => array('displays', $name, 'settings'),
|
||||
'#group' => 'display_settings',
|
||||
'#weight' => $formatter['weight'] + $i/1000,
|
||||
) + $settings_form;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process file display settings form submissions.
|
||||
*/
|
||||
function file_entity_file_display_form_submit($form, &$form_state) {
|
||||
$file_type = $form['#file_type'];
|
||||
$view_mode = $form['#view_mode'];
|
||||
$displays = isset($form_state['values']['displays']) ? $form_state['values']['displays'] : array();
|
||||
$displays_original = file_displays_load($file_type, $view_mode, TRUE);
|
||||
foreach ($displays as $formatter_name => $display) {
|
||||
$display_original = isset($displays_original[$formatter_name]) ? $displays_original[$formatter_name] : file_display_new($file_type, $view_mode, $formatter_name);
|
||||
$display += (array) $display_original;
|
||||
file_display_save((object) $display);
|
||||
}
|
||||
drupal_set_message(t('Your settings have been saved.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for a file type label and description for the file type admin overview page.
|
||||
*/
|
||||
function theme_file_entity_file_type_overview($variables) {
|
||||
return check_plain($variables['label']) . '<div class="description">' . $variables['description'] . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for a file display's display order table.
|
||||
*/
|
||||
function theme_file_entity_file_display_order($variables) {
|
||||
$element = $variables['element'];
|
||||
|
||||
$rows = array();
|
||||
foreach (element_children($element, TRUE) as $name) {
|
||||
$element[$name]['weight']['#attributes']['class'][] = 'file-display-order-weight';
|
||||
$rows[] = array(
|
||||
'data' => array(
|
||||
drupal_render($element[$name]['label']),
|
||||
drupal_render($element[$name]['weight']),
|
||||
),
|
||||
'class' => array('draggable'),
|
||||
);
|
||||
}
|
||||
$output = drupal_render_children($element);
|
||||
$output .= theme('table', array('rows' => $rows, 'attributes' => array('id' => 'file-displays-order')));
|
||||
drupal_add_tabledrag('file-displays-order', 'order', 'sibling', 'file-display-order-weight', NULL, NULL, TRUE);
|
||||
|
||||
return $output;
|
||||
}
|
45
sites/all/modules/media/file_entity/file_entity.admin.js
Normal file
45
sites/all/modules/media/file_entity/file_entity.admin.js
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.fileDisplayStatus = {
|
||||
attach: function (context, settings) {
|
||||
$('#file-displays-status-wrapper input.form-checkbox', context).once('display-status', function () {
|
||||
var $checkbox = $(this);
|
||||
// Retrieve the tabledrag row belonging to this display.
|
||||
var $row = $('#' + $checkbox.attr('id').replace(/-status$/, '-weight'), context).closest('tr');
|
||||
// Retrieve the vertical tab belonging to this display.
|
||||
var tab = $('#' + $checkbox.attr('id').replace(/-status$/, '-settings'), context).data('verticalTab');
|
||||
|
||||
// Bind click handler to this checkbox to conditionally show and hide the
|
||||
// display's tableDrag row and vertical tab pane.
|
||||
$checkbox.bind('click.displayStatusUpdate', function () {
|
||||
if ($checkbox.is(':checked')) {
|
||||
$row.show();
|
||||
if (tab) {
|
||||
tab.tabShow().updateSummary();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$row.hide();
|
||||
if (tab) {
|
||||
tab.tabHide().updateSummary();
|
||||
}
|
||||
}
|
||||
// Restripe table after toggling visibility of table row.
|
||||
Drupal.tableDrag['file-displays-order'].restripeTable();
|
||||
});
|
||||
|
||||
// Attach summary for configurable displays (only for screen-readers).
|
||||
if (tab) {
|
||||
tab.fieldset.drupalSetSummary(function (tabContext) {
|
||||
return $checkbox.is(':checked') ? Drupal.t('Enabled') : Drupal.t('Disabled');
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger our bound click handler to update elements to initial state.
|
||||
$checkbox.triggerHandler('click.displayStatusUpdate');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
140
sites/all/modules/media/file_entity/file_entity.api.php
Normal file
140
sites/all/modules/media/file_entity/file_entity.api.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Hooks provided by the File Entity module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define file types.
|
||||
*
|
||||
* @return
|
||||
* An array whose keys are file type names and whose values are arrays
|
||||
* describing the file type, with the following key/value pairs:
|
||||
* - label: The human-readable name of the file type.
|
||||
* - claim callback: The name of the function that returns if a given file is
|
||||
* of this type. See hook_file_type_TYPE_claim() for details.
|
||||
* - default view callback: (optional) The name of the function that returns a
|
||||
* drupal_render() array for displaying the file. Used when there are no
|
||||
* administrator configured file formatters, or none of the configured ones
|
||||
* return a display. See hook_file_type_TYPE_default_view() for details.
|
||||
* - description: (optional) A short description of the file type.
|
||||
* - weight: (optional) A number defining the order in which the 'claim
|
||||
* callback' function for this type is called relative to the claim
|
||||
* callbacks of other defined types, when the type of a file needs to be
|
||||
* determined. The type with the lowest weighted claim callback to return
|
||||
* TRUE is assigned to the file. Also, on administrative pages listing file
|
||||
* types, the types are ordered by weight.
|
||||
* - admin: (optional) An array of information, to be added to the
|
||||
* ['bundles'][TYPE]['admin'] entry for the 'file' entity type, thereby
|
||||
* controlling the path at which Field UI pages are attached for this file
|
||||
* type, and which users may access them. Defaults to attaching the Field UI
|
||||
* pages to the admin/config/media/file-types/manage/TYPE path and requiring
|
||||
* 'administer site configuration' permission. See hook_entity_info() for
|
||||
* details about this array. This value can also be set to NULL to suppress
|
||||
* Field UI pages from attaching at all for this file type.
|
||||
*
|
||||
* @see hook_file_type_info_alter()
|
||||
*/
|
||||
function hook_file_type_info() {
|
||||
return array(
|
||||
'image' => array(
|
||||
'label' => t('Image'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform alterations on file types.
|
||||
*
|
||||
* @param $info
|
||||
* Array of information on file types exposed by hook_file_type_info()
|
||||
* implementations.
|
||||
*/
|
||||
function hook_file_type_info_alter(&$info) {
|
||||
// @todo Add example.
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*
|
||||
* Note: This is not really a hook. The function name is manually specified via
|
||||
* 'claim callback' in hook_file_type_info(), with this recommended
|
||||
* callback name pattern.
|
||||
*/
|
||||
function hook_file_type_TYPE_claim($file, $type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*
|
||||
* Note: This is not really a hook. The function name is manually specified via
|
||||
* 'default view callback' in hook_file_type_info(), with this recommended
|
||||
* callback name pattern.
|
||||
*/
|
||||
function hook_file_type_TYPE_default_view($file, $view_mode, $langcode) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Define file formatters.
|
||||
*
|
||||
* @return
|
||||
* An array whose keys are file formatter names and whose values are arrays
|
||||
* describing the formatter.
|
||||
*
|
||||
* @todo Document key/value pairs that comprise a formatter.
|
||||
*
|
||||
* @see hook_file_formatter_info_alter()
|
||||
*/
|
||||
function hook_file_formatter_info() {
|
||||
// @todo Add example.
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform alterations on file formatters.
|
||||
*
|
||||
* @param $info
|
||||
* Array of information on file formatters exposed by
|
||||
* hook_file_formatter_info() implementations.
|
||||
*/
|
||||
function hook_file_formatter_info_alter(&$info) {
|
||||
// @todo Add example.
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*
|
||||
* Note: This is not really a hook. The function name is manually specified via
|
||||
* 'view callback' in hook_file_formatter_info(), with this recommended callback
|
||||
* name pattern.
|
||||
*/
|
||||
function hook_file_formatter_FORMATTER_view($file, $display, $langcode) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*
|
||||
* Note: This is not really a hook. The function name is manually specified via
|
||||
* 'settings callback' in hook_file_formatter_info(), with this recommended
|
||||
* callback name pattern.
|
||||
*/
|
||||
function hook_file_formatter_FORMATTER_settings($form, &$form_state, $settings) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*/
|
||||
function hook_file_displays_alter($displays, $file, $view_mode) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*/
|
||||
function hook_file_view($file, $view_mode, $langcode) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add documentation.
|
||||
*/
|
||||
function hook_file_view_alter($build, $type) {
|
||||
}
|
391
sites/all/modules/media/file_entity/file_entity.file_api.inc
Normal file
391
sites/all/modules/media/file_entity/file_entity.file_api.inc
Normal file
@@ -0,0 +1,391 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API extensions of Drupal core's file.inc.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The {file_managed}.type value when the file type has not yet been determined.
|
||||
*/
|
||||
define('FILE_TYPE_NONE', 'undefined');
|
||||
|
||||
/**
|
||||
* Returns information about file types from hook_file_type_info().
|
||||
*
|
||||
* @param $file_type
|
||||
* (optional) A file type name. If ommitted, all file types will be returned.
|
||||
*
|
||||
* @return
|
||||
* Either a file type description, as provided by hook_file_type_info(), or an
|
||||
* array of all existing file types, keyed by file type name.
|
||||
*/
|
||||
function file_info_file_types($file_type = NULL) {
|
||||
$info = &drupal_static(__FUNCTION__);
|
||||
if (!isset($info)) {
|
||||
$info = module_invoke_all('file_type_info');
|
||||
drupal_alter('file_type_info', $info);
|
||||
_file_sort_array_by_weight($info);
|
||||
}
|
||||
if (isset($file_type)) {
|
||||
if (isset($info[$file_type])) {
|
||||
return $info[$file_type];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with file type information, so that %file_type can be used in hook_menu() paths.
|
||||
*
|
||||
* In addition to the information returned by file_info_file_types(), the 'type'
|
||||
* property is set for use by field_extract_bundle().
|
||||
*/
|
||||
function file_type_load($type) {
|
||||
$info = file_info_file_types($type);
|
||||
if (isset($info)) {
|
||||
$info = (object) $info;
|
||||
$info->type = $type;
|
||||
return $info;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the file type of a passed in file object.
|
||||
*/
|
||||
function file_get_type($file) {
|
||||
foreach (file_info_file_types() as $type => $info) {
|
||||
if (isset($info['claim callback']) && ($function = $info['claim callback']) && function_exists($function) && $function($file, $type)) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about file formatters from hook_file_formatter_info().
|
||||
*
|
||||
* @param $formatter_type
|
||||
* (optional) A file formatter type name. If ommitted, all file formatter
|
||||
* will be returned.
|
||||
*
|
||||
* @return
|
||||
* Either a file formatter description, as provided by
|
||||
* hook_file_formatter_info(), or an array of all existing file formatters,
|
||||
* keyed by formatter type name.
|
||||
*/
|
||||
function file_info_formatter_types($formatter_type = NULL) {
|
||||
$info = &drupal_static(__FUNCTION__);
|
||||
if (!isset($info)) {
|
||||
$info = module_invoke_all('file_formatter_info');
|
||||
drupal_alter('file_formatter_info', $info);
|
||||
_file_sort_array_by_weight($info);
|
||||
}
|
||||
if ($formatter_type) {
|
||||
if (isset($info[$formatter_type])) {
|
||||
return $info[$formatter_type];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the file info cache.
|
||||
*/
|
||||
function file_info_cache_clear() {
|
||||
drupal_static_reset('file_info_file_types');
|
||||
drupal_static_reset('file_info_formatter_types');
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a drupal_render() style array from an array of loaded files.
|
||||
*
|
||||
* @param $files
|
||||
* An array of files as returned by file_load_multiple().
|
||||
* @param $view_mode
|
||||
* View mode.
|
||||
* @param $weight
|
||||
* An integer representing the weight of the first file in the list.
|
||||
* @param $langcode
|
||||
* A string indicating the language field values are to be shown in. If no
|
||||
* language is provided the current content language is used.
|
||||
*
|
||||
* @return
|
||||
* An array in the format expected by drupal_render().
|
||||
*/
|
||||
function file_view_multiple($files, $view_mode = 'default', $weight = 0, $langcode = NULL) {
|
||||
if (empty($files)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
field_attach_prepare_view('file', $files, $view_mode);
|
||||
entity_prepare_view('file', $files);
|
||||
|
||||
$build = array();
|
||||
foreach ($files as $file) {
|
||||
$build[$file->fid] = file_view($file, $view_mode, $langcode);
|
||||
$build[$file->fid]['#weight'] = $weight;
|
||||
$weight++;
|
||||
}
|
||||
$build['#sorted'] = TRUE;
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array for rendering the given file.
|
||||
*
|
||||
* @param $file
|
||||
* A file object.
|
||||
* @param $view_mode
|
||||
* View mode.
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function file_view($file, $view_mode = 'default', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = $GLOBALS['language_content']->language;
|
||||
}
|
||||
|
||||
// Prepare the file object for viewing, in case file_view() was called by
|
||||
// something other than file_view_multiple(). These functions exit quickly if
|
||||
// they've already run, so it's okay to call them even if they've already been
|
||||
// called by file_view_multiple().
|
||||
field_attach_prepare_view('file', array($file->fid => $file), $view_mode);
|
||||
entity_prepare_view('file', array($file->fid => $file));
|
||||
|
||||
// Create the render array with the file itself and with fields.
|
||||
$build = array(
|
||||
'#file' => $file,
|
||||
'#view_mode' => $view_mode,
|
||||
'#language' => $langcode,
|
||||
);
|
||||
$build += field_attach_view('file', $file, $view_mode, $langcode);
|
||||
$build['file'] = file_view_file($file, $view_mode, $langcode);
|
||||
|
||||
// Allow modules to add and alter.
|
||||
module_invoke_all('file_view', $file, $view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $file, 'file', $view_mode, $langcode);
|
||||
$type = 'file';
|
||||
drupal_alter(array('file_view', 'entity_view'), $build, $type);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array for rendering just the file portion of a file entity.
|
||||
*
|
||||
* @param $file
|
||||
* A file object.
|
||||
* @param $displays
|
||||
* Can be either:
|
||||
* - the name of a view mode;
|
||||
* - or an array of custom display settings, as returned by file_displays().
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function file_view_file($file, $displays = 'default', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = $GLOBALS['language_content']->language;
|
||||
}
|
||||
|
||||
// Prepare incoming display specifications.
|
||||
if (is_string($displays)) {
|
||||
$view_mode = $displays;
|
||||
$displays = file_displays($file->type, $view_mode);
|
||||
}
|
||||
else {
|
||||
$view_mode = '_custom_display';
|
||||
}
|
||||
drupal_alter('file_displays', $displays, $file, $view_mode);
|
||||
_file_sort_array_by_weight($displays);
|
||||
|
||||
// Attempt to display the file with each of the possible displays. Stop after
|
||||
// the first successful one. See file_displays() for details.
|
||||
$element = NULL;
|
||||
foreach ($displays as $formatter_type => $display) {
|
||||
if (!empty($display['status'])) {
|
||||
$formatter_info = file_info_formatter_types($formatter_type);
|
||||
// Under normal circumstances, the UI prevents enabling formatters for
|
||||
// incompatible file types. In case this was somehow circumvented (for
|
||||
// example, a module updated its formatter definition without updating
|
||||
// existing display settings), perform an extra check here.
|
||||
if (isset($formatter_info['file types']) && !in_array($file->type, $formatter_info['file types'])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($formatter_info['view callback']) && ($function = $formatter_info['view callback']) && function_exists($function)) {
|
||||
$display['type'] = $formatter_type;
|
||||
if (!empty($formatter_info['default settings'])) {
|
||||
if (empty($display['settings'])) {
|
||||
$display['settings'] = array();
|
||||
}
|
||||
$display['settings'] += $formatter_info['default settings'];
|
||||
}
|
||||
$element = $function($file, $display, $langcode);
|
||||
if (isset($element)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If none of the configured formatters were able to display the file, attempt
|
||||
// to display the file using the file type's default view callback.
|
||||
if (!isset($element)) {
|
||||
$file_type_info = file_info_file_types($file->type);
|
||||
if (isset($file_type_info['default view callback']) && ($function = $file_type_info['default view callback']) && function_exists($function)) {
|
||||
$element = $function($file, $view_mode, $langcode);
|
||||
}
|
||||
}
|
||||
|
||||
// If a render element was returned by a formatter or the file type's default
|
||||
// view callback, add some defaults to it and return it.
|
||||
if (isset($element)) {
|
||||
$element += array(
|
||||
'#file' => $file,
|
||||
'#view_mode' => $view_mode,
|
||||
'#language' => $langcode,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of possible displays to use for a file type in a given view mode.
|
||||
*
|
||||
* It is common for a site to be configured with broadly defined file types
|
||||
* (e.g., 'video'), and to have different files of this type require different
|
||||
* displays (for example, the code required to display a YouTube video is
|
||||
* different than the code required to display a local QuickTime video).
|
||||
* Therefore, the site administrator can configure multiple displays for a given
|
||||
* file type. This function returns all of the displays that the administrator
|
||||
* enabled for the given file type in the given view mode. file_view_file() then
|
||||
* invokes each of these, and passes the specific file to display. Each display
|
||||
* implementation can inspect the file, and either return a render array (if it
|
||||
* is capable of displaying the file), or return nothing (if it is incapable of
|
||||
* displaying the file). The first render array returned is the one used.
|
||||
*
|
||||
* @param $file_type
|
||||
* The type of file.
|
||||
* @param $view_mode
|
||||
* The view mode.
|
||||
*
|
||||
* @return
|
||||
* An array keyed by the formatter type name. Each item in the array contains
|
||||
* the following key/value pairs:
|
||||
* - status: Whether this display is enabled. If not TRUE, file_view_file()
|
||||
* skips over it.
|
||||
* - weight: An integer that determines the order of precedence within the
|
||||
* returned array. The lowest weight display capable of displaying the file
|
||||
* is used.
|
||||
* - settings: An array of key/value pairs specific to the formatter type. See
|
||||
* hook_file_formatter_info() for details.
|
||||
*
|
||||
* @see hook_file_formatter_info()
|
||||
* @see file_view_file()
|
||||
*/
|
||||
function file_displays($file_type, $view_mode = 'default') {
|
||||
$cache = &drupal_static(__FUNCTION__, array());
|
||||
|
||||
// If the requested view mode isn't configured to use a custom display for its
|
||||
// fields, then don't use a custom display for its file either.
|
||||
if ($view_mode != 'default') {
|
||||
$view_mode_settings = field_view_mode_settings('file', $file_type);
|
||||
$view_mode = !empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default';
|
||||
}
|
||||
|
||||
if (!isset($cache[$file_type][$view_mode])) {
|
||||
// Load the display configurations for the file type and view mode. If none
|
||||
// exist for the view mode, use the default view mode.
|
||||
$displays = file_displays_load($file_type, $view_mode, TRUE);
|
||||
if (empty($displays) && $view_mode != 'default') {
|
||||
$cache[$file_type][$view_mode] = file_displays($file_type, 'default');
|
||||
}
|
||||
else {
|
||||
// Convert the display objects to arrays and remove unnecessary keys.
|
||||
foreach ($displays as $formatter_name => $display) {
|
||||
$displays[$formatter_name] = array_intersect_key((array) $display, drupal_map_assoc(array('status', 'weight', 'settings')));
|
||||
}
|
||||
$cache[$file_type][$view_mode] = $displays;
|
||||
}
|
||||
}
|
||||
|
||||
return $cache[$file_type][$view_mode];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {file_display} objects for the file type and view mode.
|
||||
*/
|
||||
function file_displays_load($file_type, $view_mode, $key_by_formatter_name = FALSE) {
|
||||
ctools_include('export');
|
||||
|
||||
$display_names = array();
|
||||
$prefix = $file_type . '__' . $view_mode . '__';
|
||||
foreach (array_keys(file_info_formatter_types()) as $formatter_name) {
|
||||
$display_names[] = $prefix . $formatter_name;
|
||||
}
|
||||
$displays = ctools_export_load_object('file_display', 'names', $display_names);
|
||||
|
||||
if ($key_by_formatter_name) {
|
||||
$prefix_length = strlen($prefix);
|
||||
$rekeyed_displays = array();
|
||||
foreach ($displays as $name => $display) {
|
||||
$rekeyed_displays[substr($name, $prefix_length)] = $display;
|
||||
}
|
||||
$displays = $rekeyed_displays;
|
||||
}
|
||||
|
||||
return $displays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a {file_display} object to the database.
|
||||
*/
|
||||
function file_display_save($display) {
|
||||
ctools_include('export');
|
||||
ctools_export_crud_save('file_display', $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {file_display} object.
|
||||
*/
|
||||
function file_display_new($file_type, $view_mode, $formatter_name) {
|
||||
ctools_include('export');
|
||||
$display = ctools_export_crud_new('file_display');
|
||||
$display->name = implode('__', array($file_type, $view_mode, $formatter_name));
|
||||
return $display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to sort an array by the value of each item's 'weight' key, while preserving relative order of items that have equal weight.
|
||||
*/
|
||||
function _file_sort_array_by_weight(&$a) {
|
||||
$i=0;
|
||||
foreach ($a as $key => $item) {
|
||||
if (!isset($a[$key]['weight'])) {
|
||||
$a[$key]['weight'] = 0;
|
||||
}
|
||||
$original_weight[$key] = $a[$key]['weight'];
|
||||
$a[$key]['weight'] += $i/1000;
|
||||
$i++;
|
||||
}
|
||||
uasort($a, 'drupal_sort_weight');
|
||||
foreach ($a as $key => $item) {
|
||||
$a[$key]['weight'] = $original_weight[$key];
|
||||
}
|
||||
}
|
13
sites/all/modules/media/file_entity/file_entity.info
Normal file
13
sites/all/modules/media/file_entity/file_entity.info
Normal file
@@ -0,0 +1,13 @@
|
||||
name = File entity
|
||||
description = "Extends Drupal file entities to be fieldable and viewable."
|
||||
package = Media
|
||||
core = 7.x
|
||||
dependencies[] = field
|
||||
dependencies[] = ctools
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-03-23
|
||||
version = "7.x-1.0"
|
||||
core = "7.x"
|
||||
project = "media"
|
||||
datestamp = "1332537952"
|
||||
|
207
sites/all/modules/media/file_entity/file_entity.install
Normal file
207
sites/all/modules/media/file_entity/file_entity.install
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the file_entity module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function file_entity_schema() {
|
||||
$schema['file_display'] = array(
|
||||
'description' => 'Stores configuration options for file displays.',
|
||||
'fields' => array(
|
||||
// @todo Can be refactored as a compond primary key after
|
||||
// http://drupal.org/node/924236 is implemented.
|
||||
'name' => array(
|
||||
'description' => 'A combined string (FILE_TYPE__VIEW_MODE__FILE_FORMATTER) identifying a file display configuration. For integration with CTools Exportables, stored as a single string rather than as a compound primary key.',
|
||||
'type' => 'varchar',
|
||||
'length' => '255',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'weight' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Weight of formatter within the display chain for the associated file type and view mode. A file is rendered using the lowest weighted enabled display configuration that matches the file type and view mode and that is capable of displaying the file.',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The status of the display. (1 = enabled, 0 = disabled)',
|
||||
),
|
||||
'settings' => array(
|
||||
'type' => 'blob',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
'description' => 'A serialized array of name value pairs that store the formatter settings for the display.',
|
||||
),
|
||||
),
|
||||
'primary key' => array('name'),
|
||||
// Exportable support via CTools.
|
||||
'export' => array(
|
||||
'key' => 'name',
|
||||
'key name' => 'Name',
|
||||
'primary key' => 'name',
|
||||
// The {file_display}.status field is used to control whether the display
|
||||
// is active in the display chain. CTools-level disabling is something
|
||||
// different, and it's not yet clear how to interpret it for file displays.
|
||||
// Until that's figured out, prevent CTools-level disabling.
|
||||
'can disable' => FALSE,
|
||||
'default hook' => 'file_default_displays',
|
||||
'identifier' => 'file_display',
|
||||
'api' => array(
|
||||
'owner' => 'file_entity',
|
||||
'api' => 'file_default_displays',
|
||||
'minimum_version' => 1,
|
||||
'current_version' => 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_schema_alter().
|
||||
*/
|
||||
function file_entity_schema_alter(&$schema) {
|
||||
$schema['file_managed']['fields']['type'] = array(
|
||||
'description' => 'The type of this file.',
|
||||
'type' => 'varchar',
|
||||
'length' => 50,
|
||||
'not null' => TRUE,
|
||||
// If the FILE_TYPE_NONE constant ever changes, then change the value here
|
||||
// too, and add an update function to deal with existing records. The
|
||||
// constant isn't used here, because there may be cases where this function
|
||||
// runs without the module file loaded.
|
||||
'default' => 'undefined',
|
||||
);
|
||||
$schema['file_managed']['indexes']['file_type'] = array('type');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function file_entity_install() {
|
||||
$schema = array();
|
||||
file_entity_schema_alter($schema);
|
||||
$spec = $schema['file_managed']['fields']['type'];
|
||||
$indexes_new = array('indexes' => $schema['file_managed']['indexes']);
|
||||
|
||||
// If another module (e.g., Media) had added a {file_managed}.type field,
|
||||
// then change it to the expected specification. Otherwise, add the field.
|
||||
if (db_field_exists('file_managed', 'type')) {
|
||||
// db_change_field() will fail if any records have type=NULL, so update
|
||||
// them to the new default value.
|
||||
db_update('file_managed')->fields(array('type' => $spec['default']))->isNull('type')->execute();
|
||||
|
||||
// Indexes using a field being changed must be dropped prior to calling
|
||||
// db_change_field(). However, the database API doesn't provide a way to do
|
||||
// this without knowing what the old indexes are. Therefore, it is the
|
||||
// responsibility of the module that added them to drop them prior to
|
||||
// allowing this module to be installed.
|
||||
db_change_field('file_managed', 'type', 'type', $spec, $indexes_new);
|
||||
}
|
||||
else {
|
||||
db_add_field('file_managed', 'type', $spec, $indexes_new);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function file_entity_uninstall() {
|
||||
db_drop_field('file_managed', 'type');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the {file_display} database table.
|
||||
*/
|
||||
function file_entity_update_7000() {
|
||||
$schema['file_display'] = array(
|
||||
'description' => 'Stores configuration options for file displays.',
|
||||
'fields' => array(
|
||||
'name' => array(
|
||||
'description' => 'A combined string (FILE_TYPE__VIEW_MODE__FILE_FORMATTER) identifying a file display configuration. For integration with CTools Exportables, stored as a single string rather than as a compound primary key.',
|
||||
'type' => 'varchar',
|
||||
'length' => '255',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'weight' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Weight of formatter within the display chain for the associated file type and view mode. A file is rendered using the lowest weighted enabled display configuration that matches the file type and view mode and that is capable of displaying the file.',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The status of the display. (1 = enabled, 0 = disabled)',
|
||||
),
|
||||
'settings' => array(
|
||||
'type' => 'blob',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
'description' => 'A serialized array of name value pairs that store the formatter settings for the display.',
|
||||
),
|
||||
),
|
||||
'primary key' => array('name'),
|
||||
);
|
||||
db_create_table('file_display', $schema['file_display']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move file display configurations from the 'file_displays' variable to the
|
||||
* {file_display} database table.
|
||||
*/
|
||||
function file_entity_update_7001() {
|
||||
$file_displays = variable_get('file_displays');
|
||||
if (!empty($file_displays)) {
|
||||
foreach ($file_displays as $file_type => $file_type_displays) {
|
||||
if (!empty($file_type_displays)) {
|
||||
foreach ($file_type_displays as $view_mode => $view_mode_displays) {
|
||||
if (!empty($view_mode_displays)) {
|
||||
foreach ($view_mode_displays as $formatter_name => $display) {
|
||||
if (!empty($display)) {
|
||||
db_merge('file_display')
|
||||
->key(array(
|
||||
'name' => implode('__', array($file_type, $view_mode, $formatter_name)),
|
||||
))
|
||||
->fields(array(
|
||||
'status' => isset($display['status']) ? $display['status'] : 0,
|
||||
'weight' => isset($display['weight']) ? $display['weight'] : 0,
|
||||
'settings' => isset($display['settings']) ? serialize($display['settings']) : NULL,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
variable_del('file_displays');
|
||||
}
|
||||
|
||||
/**
|
||||
* Drupal 7.8 disallows empty string as the value for a bundle key, so update
|
||||
* empty {file_managed}.type records to 'undefined' instead.
|
||||
*/
|
||||
function file_entity_update_7002() {
|
||||
db_update('file_managed')
|
||||
// Using 'undefined' instead of FILE_TYPE_NONE, because update functions can
|
||||
// run for disabled modules.
|
||||
->fields(array('type' => 'undefined'))
|
||||
->condition('type', '')
|
||||
->execute();
|
||||
}
|
467
sites/all/modules/media/file_entity/file_entity.module
Normal file
467
sites/all/modules/media/file_entity/file_entity.module
Normal file
@@ -0,0 +1,467 @@
|
||||
<?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';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function file_entity_menu() {
|
||||
$items['admin/config/media/file-types'] = array(
|
||||
'title' => 'File types',
|
||||
'description' => 'Manage 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 files used on your site.',
|
||||
);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function file_entity_theme() {
|
||||
return array(
|
||||
'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',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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']['bundle keys']['bundle'] = 'type';
|
||||
$entity_info['file']['bundles'] = array();
|
||||
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/%file_type',
|
||||
'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')));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
// The file type is a bundle key, so can't be NULL. file_entity_schema_alter()
|
||||
// ensures that it isn't NULL after a file_load(). However, file_save() can be
|
||||
// called on a new file object, so we apply the default here as well.
|
||||
if (!isset($file->type)) {
|
||||
$file->type = FILE_TYPE_NONE;
|
||||
}
|
||||
|
||||
// If the file doesn't already have a real type, attempt to assign it one.
|
||||
if ($file->type == FILE_TYPE_NONE && ($type = file_get_type($file))) {
|
||||
$file->type = $type;
|
||||
}
|
||||
|
||||
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) {
|
||||
// Prevent PHP notices when trying to read empty files.
|
||||
// @see http://drupal.org/node/681042
|
||||
if (!filesize($file->uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not bother proceeding if this file does not have an image mime type.
|
||||
if (strpos($file->filemime, 'image/') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_entity_file_is_local($file) && $image = image_load($file->uri)) {
|
||||
if (!empty($display['settings']['image_style'])) {
|
||||
$element = array(
|
||||
'#theme' => 'image_style',
|
||||
'#style_name' => $display['settings']['image_style'],
|
||||
'#path' => $file->uri,
|
||||
'#width' => $image->info['width'],
|
||||
'#height' => $image->info['height'],
|
||||
);
|
||||
}
|
||||
else {
|
||||
$element = array(
|
||||
'#theme' => 'image',
|
||||
'#path' => $file->uri,
|
||||
'#width' => $image->info['width'],
|
||||
'#height' => $image->info['height'],
|
||||
);
|
||||
}
|
||||
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($bundle, $view_mode, $access_callback) {
|
||||
// Deny access if the view mode isn't configured to use custom display
|
||||
// settings.
|
||||
$file_type = field_extract_bundle('file', $bundle);
|
||||
$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_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';
|
||||
|
||||
// Add support for weba, webm, and webp.
|
||||
// @todo Remove when http://drupal.org/node/1347624 is fixed in core.
|
||||
$new_mappings['weba'] = 'audio/webm';
|
||||
$new_mappings['webm'] = 'video/webm';
|
||||
$new_mappings['webp'] = 'image/webp';
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file entity is considered local or not.
|
||||
*
|
||||
* @param object $file
|
||||
* A file entity object from file_load().
|
||||
*
|
||||
* @return
|
||||
* TRUE if the file is using a local stream wrapper, or FALSE otherwise.
|
||||
*/
|
||||
function file_entity_file_is_local($file) {
|
||||
$scheme = file_uri_scheme($file->uri);
|
||||
$wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
|
||||
return !empty($wrappers[$scheme]) && empty($wrappers[$scheme]['remote']);
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
name = "File Entity Test"
|
||||
description = "Support module for File Entity tests."
|
||||
package = Testing
|
||||
core = 7.x
|
||||
dependencies[] = file_entity
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-03-23
|
||||
version = "7.x-1.0"
|
||||
core = "7.x"
|
||||
project = "media"
|
||||
datestamp = "1332537952"
|
||||
|
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* File Entity Test
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function file_entity_test_menu() {
|
||||
$items = array();
|
||||
|
||||
$items['file-entity-test/file/add'] = array(
|
||||
'title' => 'Add file',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('file_entity_test_add_form'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'file_entity_test.pages.inc',
|
||||
);
|
||||
$items['file-entity-test/file/%file'] = array(
|
||||
'title' => 'View file',
|
||||
'page callback' => 'file_entity_test_view_page',
|
||||
'page arguments' => array(2),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'file_entity_test.pages.inc',
|
||||
);
|
||||
$items['file-entity-test/file/%file/view'] = array(
|
||||
'title' => 'View',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
$items['file-entity-test/file/%file/preview'] = array(
|
||||
'title' => 'Preview',
|
||||
'page callback' => 'file_entity_test_preview_page',
|
||||
'page arguments' => array(2),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'weight' => 0,
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'file' => 'file_entity_test.pages.inc',
|
||||
);
|
||||
$items['file-entity-test/file/%file/edit'] = array(
|
||||
'title' => 'Edit',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('file_entity_test_edit_form', 2),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'weight' => 1,
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'file' => 'file_entity_test.pages.inc',
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_file_type_info().
|
||||
*/
|
||||
function file_entity_test_file_type_info() {
|
||||
return array(
|
||||
'file_entity_test' => array(
|
||||
'label' => t('Test'),
|
||||
'description' => t('A file type defined by the File Entity Test module. Used for testing only.'),
|
||||
'claim callback' => 'file_entity_test_file_type_file_entity_test_claim',
|
||||
'default view callback' => 'file_entity_test_file_type_file_entity_test_default_view',
|
||||
'weight' => 100,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_file_type_TYPE_claim().
|
||||
*
|
||||
* Returns TRUE if the passed in file should be assigned the 'file_entity_test'
|
||||
* file type.
|
||||
*/
|
||||
function file_entity_test_file_type_file_entity_test_claim($file) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_file_type_TYPE_default_view().
|
||||
*/
|
||||
function file_entity_test_file_type_file_entity_test_default_view($file, $view_mode, $langcode) {
|
||||
return array(
|
||||
'#type' => 'link',
|
||||
'#title' => $file->filename,
|
||||
'#href' => file_create_url($file->uri),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info_alter().
|
||||
*/
|
||||
function file_entity_test_entity_info_alter(&$entity_info) {
|
||||
$entity_info['file']['view modes']['file_entity_test_preview'] = array(
|
||||
'label' => t('Test Preview'),
|
||||
'custom settings' => TRUE,
|
||||
);
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test pages for the File Entity Test module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Form callback; upload a file.
|
||||
*/
|
||||
function file_entity_test_add_form($form, &$form_state) {
|
||||
$form['file'] = array(
|
||||
'#type' => 'managed_file',
|
||||
'#required' => TRUE,
|
||||
'#title' => 'File',
|
||||
'#upload_location' => 'public://',
|
||||
);
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submit callback; save the uploaded file.
|
||||
*/
|
||||
function file_entity_test_add_form_submit($form, &$form_state) {
|
||||
$file = file_load($form_state['values']['file']);
|
||||
if (!$file->status) {
|
||||
$file->status = FILE_STATUS_PERMANENT;
|
||||
file_save($file);
|
||||
}
|
||||
drupal_set_message(t('Your file has been saved.'));
|
||||
$form_state['redirect'] = 'file-entity-test/file/' . $file->fid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback; view a file.
|
||||
*/
|
||||
function file_entity_test_view_page($file) {
|
||||
return file_view($file, 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback; preview a file.
|
||||
*/
|
||||
function file_entity_test_preview_page($file) {
|
||||
return file_view($file, 'file_entity_test_preview');
|
||||
}
|
||||
|
||||
/**
|
||||
* Form callback; edit a file.
|
||||
*/
|
||||
function file_entity_test_edit_form($form, &$form_state, $file) {
|
||||
$form_state['file'] = $file;
|
||||
field_attach_form('file', $file, $form, $form_state);
|
||||
$form['file'] = file_view($file, 'file_entity_test_preview');
|
||||
|
||||
// Add internal file properties needed by
|
||||
// file_entity_test_edit_form_validate().
|
||||
foreach (array('fid', 'type') as $key) {
|
||||
$form[$key] = array('#type' => 'value', '#value' => $file->$key);
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation handler for the file edit form.
|
||||
*/
|
||||
function file_entity_test_edit_form_validate($form, &$form_state) {
|
||||
entity_form_field_validate('file', $form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submit handler for the file edit form
|
||||
*/
|
||||
function file_entity_test_edit_form_submit($form, &$form_state) {
|
||||
$file = $form_state['file'];
|
||||
entity_form_submit_build_entity('file', $file, $form, $form_state);
|
||||
file_save($file);
|
||||
drupal_set_message(t('Your changes to the file have been saved.'));
|
||||
$form_state['redirect'] = 'file-entity-test/file/' . $file->fid;
|
||||
}
|
Reference in New Issue
Block a user