Суть проблемы в следующем. Установил модуль filebrowser. Есть некий Directory Listing, в нем - некие файлы. Модуль filebrowser предлагает возможность скачать эти файлы из директории одним архивом. Нажимаем - скачивает. Имя архива формирует нормально. Но вот содержимое... См. скриншот.
Имена файлов в директории кодированы в UTF-8. Причем проблема, естественно, наблюдается только с русскими названиями файлов. Идеи, предложения?
Вживую на это безобразие можно поглядеть, например, тут:
http://itblog.ath.cx/library?path=/%D0%98/%D0%98%D0%B1%D1%81%D0%B5%D0%BD... ,
нажав на ссылку внизу листинга Download files as an Archive
Комментарии
Думаю из под Linux никаких проблем наблюдаться не будет
А вообще чего вы собственно хотите? Если сайт в кодировке UTF-8 (а Drupal именно в UTF-8 и работает), то соответственно и имена файлов в означеной кодировке. Вы скажете, что вам нужно в cp1251? А я вот в Linux'е работаю, для меня ваша cp1251 будет такой же крокозяброй, как то, что на скриншоте. А на Mac'ах люди работают с кодировкой iso8859-5 и им тоже cp1251 не подойдёт.
Так что способ решения вижу один - допиливать модуль, чтобы он делал трансляцию имён из кодировки сервера в кодировку браузера например, или предлагал выбрать кодировку при генерации архива.
Ну в таком случае дам дополнительную информацию.
Сайт использует кодировку UTF-8. И крутится на Ubuntu 9.04. Все файлы лежат на разделе с ФС ext3.
З.ы. Сопсна, хотелось бы узнать - каким образом етот модуль допилить, чтобы транчлировал в cp1251, наверняка уже кто-то сталкивался...
З.з.ы. Как и предполагалось, проблем под линуксом не наблюдается. Шо же делать, как же быть?)
Вот код, который, судя по всему, формирует архив. Вытащено из filebrowser.module:
<?php/**
* Callback for filebrowser_download/%node menu.
*/
function _filebrowser_download_callback($node) {
if (!node_access('view', $node)) {
drupal_access_denied();
exit ();
}
$match= array ();
if (!_filebrowser_ends_with($node->download_file_name, '.zip')) {
foreach ($node->file_listing as $file_name => $file_data) {
if ($node->download_file_name == $file_data['name']) {
$match= $file_data;
break;
}
}
if (empty ($match)) {
drupal_not_found();
exit ();
}
} else {
if (!function_exists("zip_open")) {
return t("No ZIP support found in PHP installation, please contact your administrator");
}
$zip= new ZipArchive();
$match['name']= $node->download_file_name;
$match['mime-type']= 'application/zip';
$match['path']= file_directory_temp().'/'.$match['name'];
if (file_exists($match['path'])) {
unlink($match['path']);
}
if ($zip->open($match['path'], ZIPARCHIVE :: CREATE) === TRUE) {
foreach ($node->file_listing as $file_name => $file_data) {
if ($file_data['kind'] == 0) {
$zip->addFile($file_data['path'], $file_name);
}
}
$zip->close();
} else {
return t("Unable to create temporary zip file 'file'", array (
file => $match['name']
));
}
$match['size']= filesize($match['path']);
}
header('Content-Description: File Transfer');
header("Cache-Control: public, must-revalidate, max-age=0"); // HTTP/1.1
header("Pragma: public");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: ".$match['mime-type']);
header('Content-Disposition: attachment; filename="'.$match['name'].'";');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$match['size']);
$content= file_get_contents($match['path']);
print $content;
exit ();
}
function _filebrowser_is_filtered($node, $file) {
return trim($node->filtered_files) == '' || filebrowser_match_path($file, $node->filtered_files);
}
function _filebrowser_is_hidden($node, $file) {
return trim($node->hidden_files) != '' && filebrowser_match_path($file, $node->hidden_files);
}
?>
поробуйте заменить строчку
$zip->addFile($file_data['path'], $file_name);
на
$zip->addFile($file_data['path'], iconv('utf-8', 'Windows-1251', $file_name));
Заменил. К сожалению, не помогло(
Хотя, конечно, названия стали несколько более вменяемые.
В смысле? А что не работает?
Ну как вам сказать. Кодировка по прежнему битая, но выглядеть стала немного по другому - значит, скрипт отрабатывает. Может, стоит попробовать какую-нибудь другую? Только вот какую?)
Это потомучто она теперь однобайтовая. Тут дальше тупым методом перебора (или умным методом отладки - смотрите что есть и что надо
Вместо iconv('utf-8', 'Windows-1251', $file_name) напишите в разных кодировках 'проверка'. Выясните что на входе, вдруг $file_name не в utf8. Ну и т.д. - задача-то не такая сложная, тем более понятно где рыть.
Спасибо за совет, буду пробовать!
Я решил проблему так:
заменил строку в файле filebowser.pages.inc:
$zip->addFile($fs_filename, $file_name)
на такую:
$zip->addFile($fs_filename, iconv('utf-8', 'cp866', $file_name));
Русские символы в архиве норм.отображены.