Skip to content
Snippets Groups Projects
Commit 2e831742 authored by Chris Gross's avatar Chris Gross
Browse files

7.x-1.49 Release

parent c1c42ab5
No related branches found
No related tags found
No related merge requests found
Pipeline #160700 failed
Showing
with 579 additions and 147 deletions
WCM Base 7.x-1.49, 2024-01-10
-----------------------------
- WCM Base: Updated File Entity contrib module to 2.38 per SA-CONTRIB-2024-001.
WCM Base 7.x-1.48, 2023-12-08 WCM Base 7.x-1.48, 2023-12-08
----------------------------- -----------------------------
- WCM Base: Updated Drupal core to 7.99. - WCM Base: Updated Drupal core to 7.99.
......
################
# DrupalCI GitLabCI template
#
# Gitlab-ci.yml to replicate DrupalCI testing for Contrib
#
# With thanks to:
# * The GitLab Acceleration Initiative participants
# * DrupalSpoons
################
################
# Guidelines
#
# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification. It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
#
# However, you can modify this template if you have additional needs for your project.
################
################
# Includes
#
# Additional configuration can be provided through includes.
# One advantage of include files is that if they are updated upstream, the changes affect all pipelines using that include.
#
# Includes can be overridden by re-declaring anything provided in an include, here in gitlab-ci.yml
# https://docs.gitlab.com/ee/ci/yaml/includes.html#override-included-configuration-values
################
include:
################
# DrupalCI includes:
# As long as you include this, any future includes added by the Drupal Association will be accessible to your pipelines automatically.
# View these include files at https://git.drupalcode.org/project/gitlab_templates/
################
- project: $_GITLAB_TEMPLATES_REPO
ref: $_GITLAB_TEMPLATES_REF
file:
# - '/includes/include.drupalci.main.yml'
# EXPERIMENTAL: For Drupal 7, remove the above line and uncomment the below.
- '/includes/include.drupalci.main-d7.yml'
- '/includes/include.drupalci.variables.yml'
- '/includes/include.drupalci.workflows.yml'
################
# Pipeline configuration variables
#
# These are the variables provided to the Run Pipeline form that a user may want to override.
#
# Docs at https://git.drupalcode.org/project/gitlab_templates/-/blob/1.0.x/includes/include.drupalci.variables.yml
################
#variables:
# SKIP_ESLINT: '1'
# _PHPUNIT_CONCURRENT: "1"
# _PHPUNIT_EXTRA: --suppress-deprecations
# OPT_IN_TEST_NEXT_MINOR: '1'
###################################################################################
#
# *
# /(
# ((((,
# /(((((((
# ((((((((((*
# ,(((((((((((((((
# ,(((((((((((((((((((
# ((((((((((((((((((((((((*
# *(((((((((((((((((((((((((((((
# ((((((((((((((((((((((((((((((((((*
# *(((((((((((((((((( .((((((((((((((((((
# ((((((((((((((((((. /(((((((((((((((((*
# /((((((((((((((((( .(((((((((((((((((,
# ,(((((((((((((((((( ((((((((((((((((((
# .(((((((((((((((((((( .(((((((((((((((((
# ((((((((((((((((((((((( ((((((((((((((((/
# (((((((((((((((((((((((((((/ ,(((((((((((((((*
# .((((((((((((((/ /(((((((((((((. ,(((((((((((((((
# *(((((((((((((( ,(((((((((((((/ *((((((((((((((.
# ((((((((((((((, /(((((((((((((. ((((((((((((((,
# (((((((((((((/ ,(((((((((((((* ,(((((((((((((,
# *((((((((((((( .((((((((((((((( ,(((((((((((((
# ((((((((((((/ /((((((((((((((((((. ,((((((((((((/
# ((((((((((((( *(((((((((((((((((((((((* *((((((((((((
# ((((((((((((( ,(((((((((((((..((((((((((((( *((((((((((((
# ((((((((((((, /((((((((((((* /((((((((((((/ ((((((((((((
# ((((((((((((( /((((((((((((/ (((((((((((((* ((((((((((((
# (((((((((((((/ /(((((((((((( ,((((((((((((, *((((((((((((
# (((((((((((((( *(((((((((((/ *((((((((((((. ((((((((((((/
# *((((((((((((((((((((((((((, /(((((((((((((((((((((((((
# ((((((((((((((((((((((((( ((((((((((((((((((((((((,
# .(((((((((((((((((((((((/ ,(((((((((((((((((((((((
# ((((((((((((((((((((((/ ,(((((((((((((((((((((/
# *((((((((((((((((((((( (((((((((((((((((((((,
# ,(((((((((((((((((((((, ((((((((((((((((((((/
# ,(((((((((((((((((((((* /((((((((((((((((((((
# ((((((((((((((((((((((, ,/((((((((((((((((((((,
# ,(((((((((((((((((((((((((((((((((((((((((((((((((((
# .(((((((((((((((((((((((((((((((((((((((((((((
# .((((((((((((((((((((((((((((((((((((,.
# .,(((((((((((((((((((((((((.
#
###################################################################################
The following patches have been applied to this project:
- http://drupal.org/files/issues/file_entity-file-size-limit-per-file-type-2530656-3.patch
- http://drupal.org/files/issues/file_entity-playsinline-attribute-video-files-2835631-4.patch
This file was automatically generated by Drush Make (http://drupal.org/project/drush).
...@@ -21,7 +21,8 @@ $handler->display->display_options['title'] = 'Files'; ...@@ -21,7 +21,8 @@ $handler->display->display_options['title'] = 'Files';
$handler->display->display_options['css_class'] = 'admin-views-view'; $handler->display->display_options['css_class'] = 'admin-views-view';
$handler->display->display_options['use_ajax'] = TRUE; $handler->display->display_options['use_ajax'] = TRUE;
$handler->display->display_options['use_more_always'] = FALSE; $handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'menu'; $handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['access']['perm'] = 'access administration pages';
$handler->display->display_options['cache']['type'] = 'none'; $handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query'; $handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic'; $handler->display->display_options['exposed_form']['type'] = 'basic';
......
...@@ -362,7 +362,7 @@ function file_entity_admin_files() { ...@@ -362,7 +362,7 @@ function file_entity_admin_files() {
$count_query = db_select('file_usage', 'fu') $count_query = db_select('file_usage', 'fu')
->fields('fu', array('fid', 'count')) ->fields('fu', array('fid', 'count'))
->condition('fu.fid', $file_result->fid, '='); ->condition('fu.fid', $file_result->fid, '=');
$count_query->addExpression('SUM(fu.count)', 'total_count'); $count_query->addExpression('fu.count', 'total_count');
$count_result = $count_query->execute()->fetchAll(); $count_result = $count_query->execute()->fetchAll();
if (!empty($count_result[0]->total_count)) { if (!empty($count_result[0]->total_count)) {
...@@ -1195,6 +1195,7 @@ function file_entity_settings_form($form, &$form_state) { ...@@ -1195,6 +1195,7 @@ function file_entity_settings_form($form, &$form_state) {
/** /**
* Element validate callback for the maximum upload size / file extension field. * Element validate callback for the maximum upload size / file extension field.
* Only validates non-empty values.
*/ */
function file_entity_max_filesize_extensions_validate($element, &$form_state) { function file_entity_max_filesize_extensions_validate($element, &$form_state) {
$list = explode("\n", $element['#value']); $list = explode("\n", $element['#value']);
...@@ -1203,17 +1204,20 @@ function file_entity_max_filesize_extensions_validate($element, &$form_state) { ...@@ -1203,17 +1204,20 @@ function file_entity_max_filesize_extensions_validate($element, &$form_state) {
$matches = array(); $matches = array();
preg_match('/(.*)\|(.*)/', $text, $matches); preg_match('/(.*)\|(.*)/', $text, $matches);
$extension = $matches[1]; if (isset($matches[1]) && isset($matches[2]) && !empty($matches[1]) && !empty($matches[2])) {
$filesize = $matches[2]; // Only validate non-empty values.
$extension = $matches[1];
$filesize = $matches[2];
//Validate filesize. //Validate filesize.
$element['#value'] = $filesize; $element['#value'] = $filesize;
_file_generic_settings_max_filesize($element, $form_state); _file_generic_settings_max_filesize($element, $form_state);
//Validate extension. //Validate extension.
$extensions = explode(' ', $form_state['input']['file_entity_default_allowed_extensions']); $extensions = explode(' ', $form_state['input']['file_entity_default_allowed_extensions']);
if (!in_array($extension, $extensions)) { if (!in_array($extension, $extensions)) {
form_error($element, t('"!extension" was not found in the list of allowed extensions.', array('!extension' => $extension))); form_error($element, t('"!extension" was not found in the list of allowed extensions.', array('!extension' => $extension)));
}
} }
} }
} }
...@@ -354,13 +354,17 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan ...@@ -354,13 +354,17 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan
switch ($display['type']) { switch ($display['type']) {
case 'file_rendered': case 'file_rendered':
// A file entity page view (/file/[fid]) may not have a value on the $field['field_name'] key
// @see https://www.drupal.org/project/file_entity/issues/3175010
$has_referencing_field = isset($field['field_name']) ? TRUE : FALSE;
foreach ($items as $delta => $item) { foreach ($items as $delta => $item) {
if (!empty($item)) { if (!empty($item)) {
// The repeat-rendering protection may be disabled if necessary. // The repeat-rendering protection may be disabled if necessary.
if (variable_get('file_entity_protect_repeated_render', TRUE)) { if (variable_get('file_entity_protect_repeated_render', TRUE) && $has_referencing_field) {
// Protect ourselves from repeated rendering. // Protect ourselves from repeated rendering.
static $repeated_render_depth = array(); static $repeated_render_depth = array();
$repeated_render_id = $entity_type . $field['field_name'] . $item['fid']; list($entity_id) = entity_extract_ids($entity_type, $entity);
$repeated_render_id = $entity_type . $entity_id . $field['field_name'] . $item['fid'];
if (isset($repeated_render_depth[$repeated_render_id])) { if (isset($repeated_render_depth[$repeated_render_id])) {
$repeated_render_depth[$repeated_render_id]++; $repeated_render_depth[$repeated_render_id]++;
} }
...@@ -395,8 +399,18 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan ...@@ -395,8 +399,18 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan
// @see https://www.drupal.org/node/2333107 // @see https://www.drupal.org/node/2333107
$file->referencing_entity = $entity; $file->referencing_entity = $entity;
$file->referencing_entity_type = $entity_type; $file->referencing_entity_type = $entity_type;
$file->referencing_field = $field['field_name']; $file->referencing_field = $has_referencing_field ? $field['field_name'] : '';
// Prevent recursion by checking if the referencing entity is itself
// do not display it again (return an empty array).
// This senario is created a few lines below when file_view is called
// it returns an array containing a referncing entity that is itself.
// This is likely treating the symptom and not the root cause which is
// probably buried in some hook_file_view() setting the referencing
// entity.
if (!empty($entity->fid) && $entity->fid === $item['fid']) {
return $element;
}
// Untranslatable fields are rendered with no language code, fall back // Untranslatable fields are rendered with no language code, fall back
// to the content language in that case. // to the content language in that case.
$element[$delta] = file_view($file, $settings['file_view_mode'], $langcode !== LANGUAGE_NONE ? $langcode : NULL); $element[$delta] = file_view($file, $settings['file_view_mode'], $langcode !== LANGUAGE_NONE ? $langcode : NULL);
...@@ -413,6 +427,7 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan ...@@ -413,6 +427,7 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan
); );
} }
} }
break; break;
case 'file_download_link': case 'file_download_link':
...@@ -426,10 +441,17 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan ...@@ -426,10 +441,17 @@ function file_entity_field_formatter_view($entity_type, $entity, $field, $instan
if (isset($item['description'])) { if (isset($item['description'])) {
$file->description = $item['description']; $file->description = $item['description'];
} }
$text = $settings['text'];
if (module_exists('i18n_string')) {
$key = 'file_entity:file_download_link:' . $entity_type . ':' . $instance['bundle'] . ':link_text:' . $text;
$text = i18n_string($key, $text);
}
$element[$delta] = array( $element[$delta] = array(
'#theme' => 'file_entity_download_link', '#theme' => 'file_entity_download_link',
'#file' => $file, '#file' => $file,
'#text' => $settings['text'], '#text' => $text,
); );
} }
} }
......
...@@ -130,7 +130,7 @@ function file_entity_file_update($file) { ...@@ -130,7 +130,7 @@ function file_entity_file_update($file) {
* Returns whether the file has changed * Returns whether the file has changed
*/ */
function file_entity_has_file_changed($file) { function file_entity_has_file_changed($file) {
return empty($file->is_new) || empty($file->original) || $file->filesize != $file->original->filesize || $file->uri != $file->original->uri; return empty($file->is_new) ? empty($file->original) || $file->filesize != $file->original->filesize || $file->uri != $file->original->uri : FALSE;
} }
...@@ -275,10 +275,6 @@ function file_entity_set_title_alt_properties($files, $language = NULL) { ...@@ -275,10 +275,6 @@ function file_entity_set_title_alt_properties($files, $language = NULL) {
if (!isset($language)) { if (!isset($language)) {
$language = $GLOBALS['language']; $language = $GLOBALS['language'];
} }
$alt = variable_get('file_entity_alt', '[file:field_file_image_alt_text]');
$title = variable_get('file_entity_title', '[file:field_file_image_title_text]');
$replace_options = array( $replace_options = array(
'clear' => TRUE, 'clear' => TRUE,
'sanitize' => FALSE, 'sanitize' => FALSE,
...@@ -286,26 +282,11 @@ function file_entity_set_title_alt_properties($files, $language = NULL) { ...@@ -286,26 +282,11 @@ function file_entity_set_title_alt_properties($files, $language = NULL) {
); );
foreach ($files as $file) { foreach ($files as $file) {
// Load alt and title text from fields. if (empty($file->title)) {
if (!empty($alt)) { $file->title = file_entity_replace_title($file, $replace_options, NULL, $language->language);
$output = token_replace($alt, array('file' => $file), $replace_options);
if (!empty($output)) {
// @todo Remove once https://www.drupal.org/node/1713164 is fixed.
// There is currently no way to get the raw alt text returned from the
// token so we revert the encoding done during tokenization.
$file->alt = decode_entities($output);
}
} }
if (!empty($title)) { if (empty($file->alt)) {
$output = token_replace($title, array('file' => $file), $replace_options); $file->alt = file_entity_replace_alt($file, $replace_options, NULL, $language->language);
if (!empty($output)) {
// @todo Remove once https://www.drupal.org/node/1713164 is fixed.
// There is currently no way to get the raw title text returned from the
// token so we revert the encoding done during tokenization.
$file->title = decode_entities($output);
}
} }
} }
} }
......
...@@ -77,6 +77,10 @@ function file_info_cache_clear() { ...@@ -77,6 +77,10 @@ function file_info_cache_clear() {
function file_view_multiple($files, $view_mode = 'full', $weight = 0, $langcode = NULL) { function file_view_multiple($files, $view_mode = 'full', $weight = 0, $langcode = NULL) {
$build = array(); $build = array();
if (empty($files)) {
return $build;
}
$entities_by_view_mode = entity_view_mode_prepare('file', $files, $view_mode, $langcode); $entities_by_view_mode = entity_view_mode_prepare('file', $files, $view_mode, $langcode);
foreach ($entities_by_view_mode as $entity_view_mode => $entities) { foreach ($entities_by_view_mode as $entity_view_mode => $entities) {
field_attach_prepare_view('file', $entities, $entity_view_mode, $langcode); field_attach_prepare_view('file', $entities, $entity_view_mode, $langcode);
......
<?php
/**
* Implements hook_i18n_string_info().
*/
function file_entity_i18n_string_info() {
$groups['file_entity'] = array(
'title' => t('File Entity'),
'format' => FALSE,
);
return $groups;
}
/**
* Implements hook_i18n_string_list().
*/
function file_entity_i18n_string_list($group) {
if ($group == 'file_entity') {
$fields = field_info_instances();
$strings = array();
foreach ($fields as $entity_type => $bundles) {
foreach ($bundles as $bundle => $fields) {
foreach ($fields as $field_key => $field_settings) {
foreach ($field_settings['display'] as $view_mode => $view_mode_settings) {
if (!empty($view_mode_settings['type']) && $view_mode_settings['type'] == 'file_download_link') {
$text = $view_mode_settings['settings']['text'];
$key = $entity_type . ':' . $bundle . ':' . 'link_text';
$strings['file_entity']['file_download_link'][$key][$text] = $text;
}
}
}
}
}
return $strings;
}
}
...@@ -32,8 +32,8 @@ configure = admin/config/media/file-settings ...@@ -32,8 +32,8 @@ configure = admin/config/media/file-settings
; We have to add a fake version so Git checkouts do not fail Media dependencies ; We have to add a fake version so Git checkouts do not fail Media dependencies
version = 7.x-2.x-dev version = 7.x-2.x-dev
; Information added by Drupal.org packaging script on 2018-11-09 ; Information added by Drupal.org packaging script on 2024-01-10
version = "7.x-2.25" version = "7.x-2.38"
core = "7.x" core = "7.x"
project = "file_entity" project = "file_entity"
datestamp = "1541794687" datestamp = "1704852768"
...@@ -1095,3 +1095,26 @@ function file_entity_update_7216() { ...@@ -1095,3 +1095,26 @@ function file_entity_update_7216() {
// database. It has been removed due to reported problems and is better // database. It has been removed due to reported problems and is better
// addressed by adding support for ctools default content to features. // addressed by adding support for ctools default content to features.
} }
/**
* Remove deprecated views_plugin_access_menu plugin.
*/
function file_entity_update_7227() {
$result = db_query("SELECT vid, id, display_options FROM {views_display}");
foreach ($result as $record) {
$options = unserialize($record->display_options);
if (isset($options['access']) && is_array($options['access']) && isset($options['access']['type']) && $options['access']['type'] === 'menu') {
$options['access'] = array(
'type' => 'perm',
'perm' => 'access administration pages',
);
db_query("UPDATE {views_display} SET display_options = :options WHERE vid = :vid AND id = :id", array(
'vid' => $record->vid,
'id' => $record->id,
'options' => serialize($options),
));
}
}
}
...@@ -1233,23 +1233,111 @@ function file_entity_file_formatter_file_field_settings($form, &$form_state, $se ...@@ -1233,23 +1233,111 @@ function file_entity_file_formatter_file_field_settings($form, &$form_state, $se
// formatter functions, but we are not working with a Field API field, so // formatter functions, but we are not working with a Field API field, so
// set $field accordingly. Unfortunately, the API is for $settings to be // set $field accordingly. Unfortunately, the API is for $settings to be
// transferred via the $instance parameter, so we must mock it. // transferred 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)) { if (isset($field_formatter_info['module'])) {
$field = NULL; $function = $field_formatter_info['module'] . '_field_formatter_settings_form';
$mock_instance = array( if (function_exists($function)) {
'display' => array( // The formatter's first argument is expected to be a field definition
$view_mode => array( // with at least "type" and "bundles" elements.
'type' => $field_formatter_type, $mock_field = array(
'settings' => $settings, 'type' => NULL,
'bundles' => array(),
);
$mock_instance = array(
'display' => array(
$view_mode => array(
'type' => $field_formatter_type,
'settings' => $settings,
),
), ),
), 'entity_type' => 'file',
'entity_type' => 'file', 'bundle' => $file_type,
'bundle' => $file_type, );
); return $function($mock_field, $mock_instance, $view_mode, $form, $form_state);
return $function($field, $mock_instance, $view_mode, $form, $form_state); }
} }
} }
} }
/**
* Replace file entity title text.
*
* @param $file
* The file entity.
* @param $replace_options
* (Optional) Options to pass to token_replace().
* @param $title
* (Optional) The title text to use.
* @param string $langcode
* (Optional) Language code
*
* @return string
* Returns the replaced title text.
*/
function file_entity_replace_title($file, $replace_options = array(), $title = NULL, $langcode = NULL) {
$replace_options += array(
'clear' => TRUE,
'sanitize' => FALSE,
);
$title_default = '[file:field_file_image_title_text]';
if (!isset($title)) {
$title = variable_get('file_entity_title', $title_default);
}
// If the defaults are not changed then inlining replacement is much faster
// than dealing with the token system.
if ($title === $title_default) {
$title_items = field_get_items('file', $file, 'field_file_image_title_text', $langcode);
return $title_items ? $title_items[0]['value'] : '';
}
elseif (!empty($title)) {
$token_replaced = token_replace($title, array('file' => $file), $replace_options);
return decode_entities($token_replaced); // Filter out possible XSS.
}
return '';
}
/**
* Replace file entity alt.
*
* @param $file
* The file entity.
* @param array $replace_options
* (Optional) Options to pass to token_replace().
* @param $alt
* (Optional) The alt text to use.
* @param string $langcode
* (Optional) Language code
*
* @return string
* Returns the replaced alt text.
*/
function file_entity_replace_alt($file, $replace_options = array(), $alt = NULL, $langcode = NULL) {
$replace_options += array(
'clear' => TRUE,
'sanitize' => FALSE,
);
$alt_default = '[file:field_file_image_alt_text]';
if (!isset($alt)) {
$alt = variable_get('file_entity_alt', $alt_default);
}
// If the defaults are not changed then inlining replacement is much faster
// than dealing with the token system.
if ($alt === $alt_default) {
$alt_items = field_get_items('file', $file, 'field_file_image_alt_text', $langcode);
return $alt_items ? $alt_items[0]['value'] : '';
}
elseif (!empty($alt)) {
$token_replaced = token_replace($alt, array('file' => $file), $replace_options);
return decode_entities($token_replaced); // Filter out possible XSS.
}
return '';
}
/** /**
* Implements hook_file_formatter_FORMATTER_view(). * Implements hook_file_formatter_FORMATTER_view().
* *
...@@ -1290,8 +1378,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode) ...@@ -1290,8 +1378,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode)
'#path' => $file->uri, '#path' => $file->uri,
'#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'], '#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'],
'#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'], '#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'],
'#alt' => token_replace($display['settings']['alt'], array('file' => $file), $replace_options), '#alt' => file_entity_replace_alt($file, $replace_options, $display['settings']['alt'], $langcode),
'#title' => token_replace($display['settings']['title'], array('file' => $file), $replace_options), '#title' => file_entity_replace_title($file, $replace_options, $display['settings']['title'], $langcode),
); );
} }
else { else {
...@@ -1300,8 +1388,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode) ...@@ -1300,8 +1388,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode)
'#path' => $file->uri, '#path' => $file->uri,
'#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'], '#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'],
'#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'], '#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'],
'#alt' => token_replace($display['settings']['alt'], array('file' => $file), $replace_options), '#alt' => file_entity_replace_alt($file, $replace_options, $display['settings']['alt'], $langcode),
'#title' => token_replace($display['settings']['title'], array('file' => $file), $replace_options), '#title' => file_entity_replace_title($file, $replace_options, $display['settings']['title'], $langcode),
); );
} }
return $element; return $element;
......
...@@ -36,9 +36,22 @@ function file_entity_download_page($file) { ...@@ -36,9 +36,22 @@ function file_entity_download_page($file) {
return MENU_NOT_FOUND; return MENU_NOT_FOUND;
} }
// @todo Why basename? Why not drupal_basename which was working up until recently. // @todo Why basename? Why not drupal_basename which was working up until recently.
$content_type = '';
if (isset($file->filemime)) {
$content_type = mime_header_encode($file->filemime);
// Strip new lines for php 8.0 compatibility with headers.
$content_type = str_replace(array("\n\r", "\n", "\r"), '', $content_type);
}
$disposition = '';
if (isset($file->uri)) {
$disposition = mime_header_encode(basename($file->uri));
// Strip new lines for php 8.0 compatibility with headers.
$disposition = str_replace(array("\n\r", "\n", "\r"), '', $disposition);
}
$headers = array( $headers = array(
'Content-Type' => mime_header_encode($file->filemime), 'Content-Type' => $content_type,
'Content-Disposition' => 'attachment; filename="' . mime_header_encode(basename($file->uri)) . '"', 'Content-Disposition' => 'attachment; filename="' . $disposition . '"',
'Content-Length' => $file->filesize, 'Content-Length' => $file->filesize,
'Content-Transfer-Encoding' => 'binary', 'Content-Transfer-Encoding' => 'binary',
'Pragma' => 'no-cache', 'Pragma' => 'no-cache',
...@@ -56,9 +69,19 @@ function file_entity_download_page($file) { ...@@ -56,9 +69,19 @@ function file_entity_download_page($file) {
// For local files, transfer the file and do not reveal the actual URL. // For local files, transfer the file and do not reveal the actual URL.
file_transfer($file->uri, $headers); file_transfer($file->uri, $headers);
} }
else if (file_uri_scheme($file->uri) == 's3') {
$url = file_create_url($file->uri);
drupal_goto($url);
}
else { else {
// For remote files, just redirect the user to that file's actual URL. // For remote files, just redirect the user to that file's actual URL.
$headers['Location'] = file_create_url($file->uri); $headers['Location'] = file_create_url($file->uri);
// If using S3 as a replacement for the file system, default headers
// for downloading will cause the server to not respond. Remove them.
if (module_exists('s3fs')) {
unset($headers['Content-Length']);
unset($headers['Content-Transfer-Encoding']);
}
foreach ($headers as $name => $value) { foreach ($headers as $name => $value) {
drupal_add_http_header($name, $value); drupal_add_http_header($name, $value);
} }
...@@ -112,11 +135,12 @@ function file_entity_add_upload($form, &$form_state, $options = array()) { ...@@ -112,11 +135,12 @@ function file_entity_add_upload($form, &$form_state, $options = array()) {
* Generate form fields for the first step in the add file wizard. * Generate form fields for the first step in the add file wizard.
*/ */
function file_entity_add_upload_step_upload($form, &$form_state, array $options = array()) { function file_entity_add_upload_step_upload($form, &$form_state, array $options = array()) {
$upload_validators = file_entity_get_upload_validators($options);
$form['upload'] = array( $form['upload'] = array(
'#type' => 'managed_file', '#type' => 'managed_file',
'#title' => t('Upload a new file'), '#title' => t('Upload a new file'),
'#upload_location' => file_entity_upload_destination_uri($options), '#upload_location' => file_entity_upload_destination_uri($options),
'#upload_validators' => file_entity_get_upload_validators($options), '#upload_validators' => $upload_validators,
'#progress_indicator' => 'bar', '#progress_indicator' => 'bar',
'#required' => TRUE, '#required' => TRUE,
'#pre_render' => array('file_managed_file_pre_render', 'file_entity_upload_validators_pre_render'), '#pre_render' => array('file_managed_file_pre_render', 'file_entity_upload_validators_pre_render'),
...@@ -125,12 +149,28 @@ function file_entity_add_upload_step_upload($form, &$form_state, array $options ...@@ -125,12 +149,28 @@ function file_entity_add_upload_step_upload($form, &$form_state, array $options
$form['upload']['#description'] = t('Files must be less than !size.', array('!size' => '<strong>' . format_size($form['upload']['#upload_validators']['file_entity_validate_size_extensions'][0]) . '</strong>')); $form['upload']['#description'] = t('Files must be less than !size.', array('!size' => '<strong>' . format_size($form['upload']['#upload_validators']['file_entity_validate_size_extensions'][0]) . '</strong>'));
$file_entity_max_filesize = variable_get('file_entity_max_filesize_extensions');
if (is_null($file_entity_max_filesize)) {
// PHP 8.1 does not accept NULL for a second param in explode().
$file_entity_max_filesize = '';
}
// Get list of extensions. // Get list of extensions.
$extensions = explode("\n", variable_get('file_entity_max_filesize_extensions')); $extensions = explode("\n", $file_entity_max_filesize);
if (!empty($extensions)) { if (!empty($extensions)) {
$limits = array();
$limits = ''; // Limit extensions displayed to those in upload validator.
$valid_extensions = array();
if (!empty($upload_validators)) {
foreach ($upload_validators['file_validate_extensions'] as $key => $values) {
$valid_extensions[$key] = explode(' ', strtolower($values));
}
}
// If there are valid extensions, merge sub-arrays into a single array.
if (!empty($valid_extensions)) {
$valid_extensions = call_user_func_array('array_merge', $valid_extensions);
}
foreach ($extensions as $position => $text) { foreach ($extensions as $position => $text) {
$matches = array(); $matches = array();
...@@ -140,14 +180,37 @@ function file_entity_add_upload_step_upload($form, &$form_state, array $options ...@@ -140,14 +180,37 @@ function file_entity_add_upload_step_upload($form, &$form_state, array $options
$extension = $matches[1]; $extension = $matches[1];
$filesize = $matches[2]; $filesize = $matches[2];
$limits .= $extension . ': ' . $filesize . ','; if (empty($valid_extensions) || in_array(strtolower($extension), $valid_extensions)) {
$limits[] = trim($extension) . ': <strong>' . trim($filesize) . '</strong>';
}
} }
} }
$limits = rtrim($limits, ','); if (!empty($limits)) {
// If less than or equal to 15 items to display, show as unordered list.
$form['upload']['#description'] = t('Files must be less than !size (!limits).', array('!size' => '<strong>' . format_size($form['upload']['#upload_validators']['file_entity_validate_size_extensions'][0]) . '</strong>', '!limits' => $limits)); // Otherwise, implode into a single list item.
$list = array(
'#theme' => 'item_list',
'#list_type' => 'ul',
'#items' => (count($limits) <= 15) ? $limits : array(implode(', ', $limits)),
);
if (!empty($valid_extensions) && count($limits) == count($valid_extensions)) {
$form['upload']['#description'] = t('Files must be less than these sizes: !list',
array(
'!list' => render($list),
)
);
}
else {
$form['upload']['#description'] = t('Files must be less than these sizes: !list The default maximum size is !size.',
array(
'!list' => render($list),
'!size' => '<strong>' . format_size($form['upload']['#upload_validators']['file_entity_validate_size_extensions'][0]) . '</strong>'
)
);
}
}
} }
$form['actions'] = array('#type' => 'actions'); $form['actions'] = array('#type' => 'actions');
...@@ -169,7 +232,12 @@ function file_entity_validate_size_extensions(stdClass $file, $file_limit = 0, $ ...@@ -169,7 +232,12 @@ function file_entity_validate_size_extensions(stdClass $file, $file_limit = 0, $
$current_extension = pathinfo($file->filename, PATHINFO_EXTENSION); $current_extension = pathinfo($file->filename, PATHINFO_EXTENSION);
// Get list of extensions. // Get list of extensions.
$extensions = explode("\n", variable_get('file_entity_max_filesize_extensions')); $file_entity_max_filesize = variable_get('file_entity_max_filesize_extensions');
if (is_null($file_entity_max_filesize)) {
// PHP 8.1 does not accept NULL for a second param in explode().
$file_entity_max_filesize = '';
}
$extensions = explode("\n", $file_entity_max_filesize);
if ($extensions) { if ($extensions) {
foreach ($extensions as $position => $text) { foreach ($extensions as $position => $text) {
...@@ -338,23 +406,60 @@ function file_entity_usage_page($file) { ...@@ -338,23 +406,60 @@ function file_entity_usage_page($file) {
// additional usage to the total count column in the table row and // additional usage to the total count column in the table row and
// continue on to the next iteration of the loop. // continue on to the next iteration of the loop.
if (isset($occured_entities[$entity_type][$entity_id])) { if (isset($occured_entities[$entity_type][$entity_id])) {
$rows[$occured_entities[$entity_type][$entity_id]][2] += $count; $rows[$occured_entities[$entity_type][$entity_id]][3] += $count;
continue; continue;
} }
// Retrieve the label and the URI of the entity. // Retrieve the label and the URI of the entity.
$label = empty($entities[$entity_id]) ? $module : entity_label($entity_type, $entities[$entity_id]); $label = empty($entities[$entity_id]) ? t('(entity not loaded)') : entity_label($entity_type, $entities[$entity_id]);
if (empty($label)) {
$label = t('(entity label not loaded)');
}
$entity_label = $label;
$entity_uri = empty($entities[$entity_id]) ? NULL : entity_uri($entity_type, $entities[$entity_id]); $entity_uri = empty($entities[$entity_id]) ? NULL : entity_uri($entity_type, $entities[$entity_id]);
// Link the label to the URI when possible. // Link the label to the URI when possible.
if (!empty($entity_uri['path'])) { if (!empty($entity_uri['path']) && $entity_type != 'paragraphs_item') {
$entity_label = l($label, $entity_uri['path']); if (empty($entity_uri['options'])) {
$entity_label = l($label, $entity_uri['path']);
}
else {
$entity_label = l($label, $entity_uri['path'], $entity_uri['options']);
}
}
// For paragraphs items, we are searching for usages in nodes.
elseif ($entity_type == 'paragraphs_item') {
$paragraph_fields = field_read_fields(array('type' => 'paragraphs'));
foreach ($paragraph_fields as $paragraph_field) {
$field_name = $paragraph_field['field_name'];
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->fieldCondition($field_name, 'value', $entity_id, '=');
$nid = $query->execute();
if (!empty($nid)) {
$nid = implode(array_keys($nid['node']));
if ($nid) {
$node = node_load($nid);
$entity_label = l($node->title, 'node/' . $nid);
}
}
}
}
// For file_lock module, display relevant usage information.
elseif ($module == 'file_lock') {
$entity_label = t('File lock');
$entity_id = '--';
} }
else { else {
$entity_label = check_plain($label); $entity_label = check_plain($label);
} }
$rows[] = array($entity_label, $entity_type, $count); $rows[] = array(
$entity_label,
$entity_id,
$entity_type,
$count,
);
// Record the occurrence of the entity to ensure that it isn't listed in // Record the occurrence of the entity to ensure that it isn't listed in
// the table again. // the table again.
...@@ -363,7 +468,12 @@ function file_entity_usage_page($file) { ...@@ -363,7 +468,12 @@ function file_entity_usage_page($file) {
} }
} }
$header = array(t('Entity'), t('Entity type'), t('Use count')); $header = array(
t('Entity label'),
t('Entity ID'),
t('Entity type'),
t('Times this file used by this entity'),
);
$build['usage_table'] = array( $build['usage_table'] = array(
'#theme' => 'table', '#theme' => 'table',
'#header' => $header, '#header' => $header,
...@@ -587,7 +697,7 @@ function file_entity_upload_destination_uri(array $params, array $data = array() ...@@ -587,7 +697,7 @@ function file_entity_upload_destination_uri(array $params, array $data = array()
$destination = trim($params['file_directory'], '/'); $destination = trim($params['file_directory'], '/');
// Replace tokens. // Replace tokens.
$destination = token_replace($destination, $data); $destination = decode_entities(token_replace($destination, $data));
return $params['uri_scheme'] . '://' . $destination; return $params['uri_scheme'] . '://' . $destination;
} }
...@@ -719,38 +829,36 @@ function file_entity_edit($form, &$form_state, $file) { ...@@ -719,38 +829,36 @@ function file_entity_edit($form, &$form_state, $file) {
// Add a 'replace this file' upload field if the file is writeable. // Add a 'replace this file' upload field if the file is writeable.
if (file_entity_file_is_writeable($file)) { if (file_entity_file_is_writeable($file)) {
// Set up replacement file validation. // Set up replacement file validation.
$replacement_options = array(); $replacement_options = !empty($form_state['#upload_options']) ? $form_state['#upload_options'] : array();
// The replacement file must have an extension valid for the original type. // Replacement file must have the same extension as the original file.
$file_extensions = array(); $replacement_options['file_extensions'] = pathinfo($file->uri, PATHINFO_EXTENSION);
$file_type_name = isset($file->type) ? $file->type : file_get_type($file);
if ($file_type_name && ($file_type = file_type_load($file_type_name))) { // Replacement file must also be one of the allowed filetypes.
$file_extensions = file_type_get_valid_extensions($file_type); $allowed_filetypes = explode(' ', variable_get('file_entity_default_allowed_extensions', 'jpg jpeg gif png txt doc docx xls xlsx pdf ppt pptx pps ppsx odt ods odp mp3 mov mp4 m4a m4v mpeg avi ogg oga ogv weba webp webm'));
}
if (!empty($replacement_options['file_extensions']) && in_array($replacement_options['file_extensions'], $allowed_filetypes)) {
// Set allowed file extensions. $form['replace_upload'] = array(
if (!empty($file_extensions)) { '#type' => 'file',
// Set to type based file extensions. '#title' => t('Replace file'),
$replacement_options['file_extensions'] = implode(' ', $file_extensions); '#description' => t('This file will replace the existing file. This action cannot be undone.'),
'#upload_validators' => file_entity_get_upload_validators($replacement_options),
'#pre_render' => array('file_entity_upload_validators_pre_render'),
);
$form['replace_keep_original_filename'] = array(
'#type' => 'checkbox',
'#title' => t('Keep original filename'),
'#default_value' => variable_get('file_entity_file_replace_options_keep_original_filename', FALSE),
'#description' => t('Rename the newly uploaded file to the name of the original file. This action cannot be undone.'),
);
} }
else { else {
// Fallback to the extension of the current file. $form['replace_upload'] = array(
$replacement_options['file_extensions'] = pathinfo($file->uri, PATHINFO_EXTENSION); '#type' => 'item',
'#title' => t('Replace file'),
'#description' => t('This file cannot be replaced.'),
);
} }
$form['replace_upload'] = array(
'#type' => 'file',
'#title' => t('Replace file'),
'#description' => t('This file will replace the existing file. This action cannot be undone.'),
'#upload_validators' => file_entity_get_upload_validators($replacement_options),
'#pre_render' => array('file_entity_upload_validators_pre_render'),
);
$form['replace_keep_original_filename'] = array(
'#type' => 'checkbox',
'#title' => t('Keep original filename'),
'#default_value' => variable_get('file_entity_file_replace_options_keep_original_filename', FALSE),
'#description' => t('Rename the newly uploaded file to the name of the original file. This action cannot be undone.'),
);
} }
$form['preview'] = file_view_file($file, 'preview'); $form['preview'] = file_view_file($file, 'preview');
...@@ -1184,7 +1292,7 @@ function file_entity_get_upload_validators(array $options = array()) { ...@@ -1184,7 +1292,7 @@ function file_entity_get_upload_validators(array $options = array()) {
$max_filesize = min($max_filesize, $file_entity_max_filesize); $max_filesize = min($max_filesize, $file_entity_max_filesize);
} }
if (!empty($options['max_filesize']) && $options['max_filesize'] < $max_filesize) { if (!empty($options['max_filesize']) && parse_size($options['max_filesize']) < $max_filesize) {
$max_filesize = parse_size($options['max_filesize']); $max_filesize = parse_size($options['max_filesize']);
} }
...@@ -1248,23 +1356,66 @@ function file_entity_upload_archive_form_submit($form, &$form_state) { ...@@ -1248,23 +1356,66 @@ function file_entity_upload_archive_form_submit($form, &$form_state) {
if ($archive = file_load($form_state['values']['upload'])) { if ($archive = file_load($form_state['values']['upload'])) {
if ($archiver = archiver_get_archiver($archive->uri)) { if ($archiver = archiver_get_archiver($archive->uri)) {
$files = $archiver->listContents(); $files = $archiver->listContents();
$destination = pathinfo($archive->filename, PATHINFO_FILENAME);
// Prepare a temporary directory to extract the archive to before saving
// it is content.
$extract_location = 'temporary://' . $destination;
$extract_location = file_destination($extract_location, FILE_EXISTS_RENAME);
if (!file_prepare_directory($extract_location, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) {
throw new Exception(t('Unable to prepare, a temporary directory %dir for extraction.', array('%dir' => $extract_location)));
}
$extract_dir = file_default_scheme() . '://' . pathinfo($archive->filename, PATHINFO_FILENAME); // Prepare target directory where files are going to be saved.
$extract_dir = file_destination($extract_dir, FILE_EXISTS_RENAME); $target_dir = file_default_scheme() . '://' . $destination;
if (!file_prepare_directory($extract_dir, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) { $target_dir = file_destination($target_dir, FILE_EXISTS_RENAME);
throw new Exception(t('Unable to prepar, e directory %dir for extraction.', array('%dir' => $extract_dir))); if (!file_prepare_directory($target_dir, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) {
throw new Exception(t('Unable to prepare, a directory %dir for extraction.', array('%dir' => $target_dir)));
} }
$archiver->extract($extract_dir); $archiver->extract($extract_location);
$pattern = '/' . $form_state['values']['pattern'] . '/'; $pattern = '/' . $form_state['values']['pattern'] . '/';
if ($files = file_scan_directory($extract_dir, $pattern)) { if ($extracted_files = file_scan_directory($extract_location, $pattern)) {
foreach ($files as $file) { foreach ($extracted_files as $extracted_file) {
$file = new stdClass();
$file->fid = NULL;
$file->uid = $archive->uid;
$file->filename = $extracted_file->filename;
$file->origname = $extracted_file->filename;
$file->status = FILE_STATUS_PERMANENT; $file->status = FILE_STATUS_PERMANENT;
$file->uid = $archive->uid; $file->filemime = file_get_mimetype($extracted_file->filename);
// destination uri should match the current file directory hierarchy.
$file->uri = $target_dir . str_replace($extract_location, '', $extracted_file->uri);
// Rename potentially executable files, to help prevent exploits (i.e. will
// rename filename.php.foo and filename.php to filename.php.foo.txt and
// filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads'
// evaluates to TRUE.
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
$file->filemime = 'text/plain';
$file->uri .= '.txt';
$file->filename .= '.txt';
}
// prepare destination path for the extracted file while keeping the
// directory hierarchy of the file.
$destination = pathinfo($file->uri, PATHINFO_DIRNAME);
if (!file_prepare_directory($destination, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) {
throw new Exception(t('Unable to prepare, a directory %dir for extraction.', array('%dir' => $destination)));
}
if (!file_unmanaged_move($extracted_file->uri, $file->uri)) {
throw new Exception(t('Could not move uploaded file %file to destination %destination.', array('%file' => $extracted_file->filename, '%destination' => $file->uri)));
return FALSE;
}
file_save($file); file_save($file);
$form_state['files'][$file->fid] = $file; $form_state['files'][$file->fid] = $file;
} }
} }
// Delete extract location
file_unmanaged_delete_recursive($extract_location);
drupal_set_message(t('Extracted %file and added @count new files.', array('%file' => $archive->filename, '@count' => count($files)))); drupal_set_message(t('Extracted %file and added @count new files.', array('%file' => $archive->filename, '@count' => count($files))));
} }
else { else {
......
...@@ -56,7 +56,7 @@ class FileEntityTestHelper extends DrupalWebTestCase { ...@@ -56,7 +56,7 @@ class FileEntityTestHelper extends DrupalWebTestCase {
protected function createFileEntity($settings = array()) { protected function createFileEntity($settings = array()) {
// Populate defaults array. // Populate defaults array.
$settings += array( $settings += array(
'filepath' => 'Файл для тестирования ' . $this->randomName(), // Prefix with non-latin characters to ensure that all file-related tests work with international filenames. 'filepath' => 'Файл для тестирования ' . $this->randomName() . '.txt', // Prefix with non-latin characters to ensure that all file-related tests work with international filenames.
'filemime' => 'text/plain', 'filemime' => 'text/plain',
'uid' => 1, 'uid' => 1,
'timestamp' => REQUEST_TIME, 'timestamp' => REQUEST_TIME,
...@@ -136,7 +136,7 @@ class FileEntityFileTypeClassificationTestCase extends DrupalWebTestCase { ...@@ -136,7 +136,7 @@ class FileEntityFileTypeClassificationTestCase extends DrupalWebTestCase {
return array( return array(
'name' => 'File entity classification', 'name' => 'File entity classification',
'description' => 'Test existing file entity classification functionality.', 'description' => 'Test existing file entity classification functionality.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -206,7 +206,7 @@ class FileEntityUnitTestCase extends FileEntityTestHelper { ...@@ -206,7 +206,7 @@ class FileEntityUnitTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity unit tests', 'name' => 'File entity unit tests',
'description' => 'Test basic file entity functionality.', 'description' => 'Test basic file entity functionality.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -311,7 +311,7 @@ class FileEntityEditTestCase extends FileEntityTestHelper { ...@@ -311,7 +311,7 @@ class FileEntityEditTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity edit', 'name' => 'File entity edit',
'description' => 'Create a file and test file edit functionality.', 'description' => 'Create a file and test file edit functionality.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -421,7 +421,7 @@ class FileEntityUploadWizardTestCase extends FileEntityTestHelper { ...@@ -421,7 +421,7 @@ class FileEntityUploadWizardTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity upload wizard', 'name' => 'File entity upload wizard',
'description' => 'Upload a file using the multi-step wizard.', 'description' => 'Upload a file using the multi-step wizard.',
'group' => 'File entity', 'group' => 'file_entity',
'dependencies' => array('token'), 'dependencies' => array('token'),
); );
} }
...@@ -642,11 +642,17 @@ class FileEntityUploadWizardTestCase extends FileEntityTestHelper { ...@@ -642,11 +642,17 @@ class FileEntityUploadWizardTestCase extends FileEntityTestHelper {
* Test file administration page functionality. * Test file administration page functionality.
*/ */
class FileEntityAdminTestCase extends FileEntityTestHelper { class FileEntityAdminTestCase extends FileEntityTestHelper {
protected $admin_user = NULL;
protected $base_user_1 = NULL;
protected $base_user_2 = NULL;
protected $base_user_3 = NULL;
protected $base_user_4 = NULL;
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => 'File administration', 'name' => 'File administration',
'description' => 'Test file administration page functionality.', 'description' => 'Test file administration page functionality.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -809,7 +815,7 @@ class FileEntityUsageTestCase extends FileEntityTestHelper { ...@@ -809,7 +815,7 @@ class FileEntityUsageTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity usage', 'name' => 'File entity usage',
'description' => 'Create a file and verify its usage.', 'description' => 'Create a file and verify its usage.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -875,7 +881,7 @@ class FileEntityUsageTestCase extends FileEntityTestHelper { ...@@ -875,7 +881,7 @@ class FileEntityUsageTestCase extends FileEntityTestHelper {
// Verify that the module name is used in place of a link to the entity. // Verify that the module name is used in place of a link to the entity.
$this->assertNoLink('test_module'); $this->assertNoLink('test_module');
$this->assertRaw('test_module', 'Module name used in place of link to the entity.'); $this->assertRaw('(entity not loaded)', '"(entity not loaded)" notice used in place of link to the entity.');
// Verify that the entity type and use count information is also present. // Verify that the entity type and use count information is also present.
$expected_values = array( $expected_values = array(
...@@ -896,7 +902,7 @@ class FileEntityAltTitleTestCase extends FileEntityTestHelper { ...@@ -896,7 +902,7 @@ class FileEntityAltTitleTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity alt and title text', 'name' => 'File entity alt and title text',
'description' => 'Create an image file with alt and title text.', 'description' => 'Create an image file with alt and title text.',
'group' => 'File entity', 'group' => 'file_entity',
'dependencies' => array('token'), 'dependencies' => array('token'),
); );
} }
...@@ -987,7 +993,7 @@ class FileEntityChangeSchemeTestCase extends FileEntityTestHelper { ...@@ -987,7 +993,7 @@ class FileEntityChangeSchemeTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'Changing file scheme', 'name' => 'Changing file scheme',
'description' => 'Test changing the scheme of a file.', 'description' => 'Test changing the scheme of a file.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -1025,7 +1031,7 @@ class FileEntityReplaceTestCase extends FileEntityTestHelper { ...@@ -1025,7 +1031,7 @@ class FileEntityReplaceTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File replacement', 'name' => 'File replacement',
'description' => 'Test file replace functionality.', 'description' => 'Test file replace functionality.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -1081,6 +1087,16 @@ class FileEntityReplaceTestCase extends FileEntityTestHelper { ...@@ -1081,6 +1087,16 @@ class FileEntityReplaceTestCase extends FileEntityTestHelper {
$this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save')); $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
$this->assertRaw(t('The specified file %file could not be uploaded. Only files with the following extensions are allowed:', array('%file' => $image->filename)), 'File validation works, upload failed correctly.'); $this->assertRaw(t('The specified file %file could not be uploaded. Only files with the following extensions are allowed:', array('%file' => $image->filename)), 'File validation works, upload failed correctly.');
// Restrict allowed document filetypes to exclude plain text files.
variable_set('file_entity_default_allowed_extensions', 'doc docx pdf');
// Test that the file can't be replaced if there's a problem with the original file's extension.
$this->drupalGet('file/' . $file->fid . '/edit');
$this->assertRaw(t('This file cannot be replaced.'), 'File extension filter works, upload prevented correctly.');
// Clean up variable.
variable_del('file_entity_default_allowed_extensions');
// Create a non-local file record. // Create a non-local file record.
$file2 = new stdClass(); $file2 = new stdClass();
$file2->uri = 'oembed://' . $this->randomName(); $file2->uri = 'oembed://' . $this->randomName();
...@@ -1109,7 +1125,7 @@ class FileEntityTokenTestCase extends FileEntityTestHelper { ...@@ -1109,7 +1125,7 @@ class FileEntityTokenTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity tokens', 'name' => 'File entity tokens',
'description' => 'Test the file entity tokens.', 'description' => 'Test the file entity tokens.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -1167,7 +1183,7 @@ class FileEntityTypeTestCase extends FileEntityTestHelper { ...@@ -1167,7 +1183,7 @@ class FileEntityTypeTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity types', 'name' => 'File entity types',
'description' => 'Test the file entity types.', 'description' => 'Test the file entity types.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -1296,7 +1312,7 @@ class FileEntityAccessTestCase extends FileEntityTestHelper { ...@@ -1296,7 +1312,7 @@ class FileEntityAccessTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity access', 'name' => 'File entity access',
'description' => 'Test the access aspects of file entity.', 'description' => 'Test the access aspects of file entity.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
...@@ -1639,7 +1655,7 @@ class FileEntityAttributeOverrideTestCase extends FileEntityTestHelper { ...@@ -1639,7 +1655,7 @@ class FileEntityAttributeOverrideTestCase extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity attribute override', 'name' => 'File entity attribute override',
'description' => 'Test overriding file entity attributes.', 'description' => 'Test overriding file entity attributes.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
......
...@@ -114,8 +114,8 @@ function file_entity_token_info() { ...@@ -114,8 +114,8 @@ function file_entity_token_info() {
$entity_type = 'term'; $entity_type = 'term';
} }
$info['tokens'][$entity_type][$field_name] = array( $info['tokens'][$entity_type][$field_name] = array(
'name' => $field_info['label'], 'name' => ($field_info) ? $field_info['label'] : '',
'description' => $field_info['description'], 'description' => ($field_info) ? $field_info['description'] : '',
'type' => 'file_field', 'type' => 'file_field',
'module' => 'file_entity', 'module' => 'file_entity',
); );
...@@ -169,7 +169,7 @@ function file_entity_tokens($type, $tokens, array $data = array(), array $option ...@@ -169,7 +169,7 @@ function file_entity_tokens($type, $tokens, array $data = array(), array $option
unset($entity->_field_view_prepared); unset($entity->_field_view_prepared);
$field_output = field_view_field($entity_type, $entity, $field_name, 'token', $langcode); $field_output = field_view_field($entity_type, $entity, $field_name, 'token', $langcode);
$field_output['#token_options'] = $options; $field_output['#token_options'] = $options;
$field_output['#prerender'][] = 'token_pre_render_field_token'; $field_output['#pre_render'][] = 'token_pre_render_field_token';
$replacements[$original] = drupal_render($field_output); $replacements[$original] = drupal_render($field_output);
} }
else { else {
...@@ -185,7 +185,9 @@ function file_entity_tokens($type, $tokens, array $data = array(), array $option ...@@ -185,7 +185,9 @@ function file_entity_tokens($type, $tokens, array $data = array(), array $option
} }
} }
else { else {
$replacements[$original] = $return; if (!is_null($return)) {
$replacements[$original] = $return;
}
} }
} }
...@@ -317,8 +319,8 @@ function _file_entity_tokens_get_property($files, $property, $array_handler = 'f ...@@ -317,8 +319,8 @@ function _file_entity_tokens_get_property($files, $property, $array_handler = 'f
} }
// If file type is video // If file type is video
elseif ($file['type'] == 'video') { elseif ($file['type'] == 'video' && strpos($file['uri'], '://v')) {
list($provider, $filename) = explode('://v/', $file['uri']); list($provider, $filename) = preg_split('!://v.*/!', $file['uri']);
$imageuri = "public://file_entity-$provider/$filename.jpg"; $imageuri = "public://file_entity-$provider/$filename.jpg";
} }
......
...@@ -5,8 +5,8 @@ core = 7.x ...@@ -5,8 +5,8 @@ core = 7.x
dependencies[] = file_entity dependencies[] = file_entity
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2018-11-09 ; Information added by Drupal.org packaging script on 2024-01-10
version = "7.x-2.25" version = "7.x-2.38"
core = "7.x" core = "7.x"
project = "file_entity" project = "file_entity"
datestamp = "1541794687" datestamp = "1704852768"
...@@ -24,7 +24,7 @@ class FileEntityViewsFieldLinkUsageHandlerTest extends FileEntityTestHelper { ...@@ -24,7 +24,7 @@ class FileEntityViewsFieldLinkUsageHandlerTest extends FileEntityTestHelper {
return array( return array(
'name' => 'File entity views integration: file link usage', 'name' => 'File entity views integration: file link usage',
'description' => 'Test file usage Views field.', 'description' => 'Test file usage Views field.',
'group' => 'File entity', 'group' => 'file_entity',
); );
} }
......
...@@ -59,10 +59,8 @@ projects[features_extra][subdir] = contrib ...@@ -59,10 +59,8 @@ projects[features_extra][subdir] = contrib
projects[field_group][version] = 1.6 projects[field_group][version] = 1.6
projects[field_group][subdir] = contrib projects[field_group][subdir] = contrib
projects[file_entity][version] = 2.25 projects[file_entity][version] = 2.38
projects[file_entity][subdir] = contrib projects[file_entity][subdir] = contrib
projects[file_entity][patch][2530656] = http://drupal.org/files/issues/file_entity-file-size-limit-per-file-type-2530656-3.patch
projects[file_entity][patch][2835631] = http://drupal.org/files/issues/file_entity-playsinline-attribute-video-files-2835631-4.patch
projects[file_entity_swf][version] = 1.0-rc2 projects[file_entity_swf][version] = 1.0-rc2
projects[file_entity_swf][subdir] = contrib projects[file_entity_swf][subdir] = contrib
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment