Пробую прикрепить файл с кириллицей в наименовании (напр. "график.xls") к материалу, используя стандартный модуль upload.
Сообщает об ошибке:
Ваш файл был переименован в xls. из соображений безопасности.
Указанный файл xls. не может быть загружен. Прикреплять можно только файлы с расширениями: xcf svg jpg jpeg gif tiff png mng txt doc xls sxw sxc tex ps pdf rtf djvu ppt pps odt ods odp tgz tar.gz bz2 tar.bz2 tbz2 zip rar psd po pot module info xml xpi diff install patch ogg spx.
Анализ кода (file.inc функция file_save_upload в строке ~528) показал что некорректно обрабатывает функция basename имя файла с кириллицей (на входе "график.xls" на выходе ".xls")
$file = new stdClass();
$file->filename = file_munge_filename(trim(basename($_FILES['files']['name'][$source]), '.'), $extensions);
Попробовал на drupal.ru - ситуация аналогичная
Помогло использование модуля transliteration.
upd: пока писал, нашел решение с basename здесь
Комментарии
Как вариант, чтобы корректно работали национальные названия файлов (т.е. избежать проблем с различными алфавитами и с слишком длинными именами файлов), можно заменить исходное имя файла MD5-хэшем. Например, файл abc.rar -> 51632a04d6af9010a834c2c46012ca84.rar
И таким образом обойтись без использования дополнительного модуля transliteration.
Внимание: хак ядра! Данное описание проверено и работает для Drupal 6.15.
1. Для начала добавим в административном разделе в Управление/Настройка сайта/Загрузки файлов — настройку в виде галочки, для использования MD5.
В файле: /modules/upload/upload.admin.inc после строки:
<?php
$form['#validate'] = array('upload_admin_settings_validate');
?>
Добавим:
<?php
$form['node_files_md5name'] = array(
'#type' => 'checkbox',
'#title'=> t('MD5 filenames'),
'#description' => t('Override uploaded filenames with the MD5 hash of the file.'),
'#default_value' => variable_get('node_files_md5name', FALSE),
);
?>
2. Добавим функцию для замены исходного имени файла в файл: modules/upload/upload.module в самом конце добавляем:
<?php
/**
* Validate, apply md5 and normalize filename.
*
* param $file
* A Drupal file object.
* return
* An array. If the file name is not valid, it will contain an error message.
*/
function _node_file_validate_name(&$file) {
$errors = array();
if (
variable_get('node_files_md5name', FALSE)) {$parts = pathinfo($file->destination);
$file->destination = $parts['dirname'].'/'.substr(md5($dest.'/'.$file->filepath), 0, 16).'.'.$parts['extension'];
}
$file->filepath = preg_replace(array('/[ \']+/', '/["]+/'), array('_', ''), $file->filepath);
if (
strlen($file->filename) > 255) {$errors[] = t('Its name exceeds the 255 characters limit. Please rename the file and try again.');
}
return $errors;
}
?>
3. В том же файле: modules/upload/upload.module после строк:
<?php
'file_validate_extensions' => array($limits['extensions']),
'file_validate_image_resolution' => array($limits['resolution']),
'file_validate_size' => array($limits['file_size'], $limits['user_size']),
?>
запустим обращение к этой функции, добавляем строку:
<?php
'_node_file_validate_name' => array(),
?>
4. Ну и я ещё немного подправил внешний вид адреса добавляемого файла в форме добавления.
В том же файле: modules/upload/upload.module заменил строку:
<?php
$description = "<small>". check_plain($description) ."</small>";
?>
На это:
<?php
$description = '<small><a href="'. $description .'">' . check_plain($file->filepath) .'</small>';
?>
Патч для Drupal 6 — прилагается.