Platform: Gentoo Linux (locale: UTF-8) + Apache2 + PHP5 + MySQL
Drupal version: 5.1
Столкнулся с такой проблемой. При добавлении файлов с русскоязычными именами в названии файла отрезается первое слово до первого пробела или символа подчеркивания. В результате IE не может открывать прикрепленные к нодам файлы. В FF все работает.
С англоязычными именами файлов все ок.
На Drupal.org ничего не нашел по этому поводу. Сталкивался ли кто-нибудь с подобной проблемой?
Комментарии
попробкуйте транслитерировать файлы,при сохранении на сервер.
А вообще национальные алфавиты в коммандной строке броузера(без преобразования),а хотят и доменные имена-бред полнейший(imho).
Попробуй найти и отличить mama,мaмa и mамa
======================================================
[url=http://wiki.drupal.ru]Документация[/url],[url=http://wiki.drupal.ru/doc/poleznye_ssylki_dlya_dizainerov]Дизайн[/url],[url=http://wiki.drupal.ru/doc/gotovye_perevody]Переводы[/url]
я тоже думал над этой проблемой.
надо бы как то патч написать, чтобы имена файлов в транслите хранились, только ума не хватает и времени разобраться с этим.
1 php функция :)======================================================
[url=http://wiki.drupal.ru]Документация[/url],[url=http://wiki.drupal.ru/doc/poleznye_ssylki_dlya_dizainerov]Дизайн[/url],[url=http://wiki.drupal.ru/doc/gotovye_perevody]Переводы[/url]
у меня ощущение, что транслитерация должна производиться еще на стороне клиента (если загрузка производится с помощью AJAX'овского интерфейса). Если же транслитерацию делать на стороне сервера, то тогда подскажите, какую функцию использовать - я в стандартной библиотеке PHP такого не помню (только в PECL что-то было, по-моему)..
А вообще, процесс решения проблемы я бы разбил на следующие шаги:
Кто поможет?
up
Это модуль upload?
Да, видимо, он.
Ничего предосудительного в национальных алфавитах в URLе не вижу (с доменными именами, действительно, перебор). Патчить модуль надо на предмет urlencode() и urldecode(), чтоб это работало везде. Ну и разобраться кто первое слово отрезает.
Что-то не нашёл на drupal.org issue по этому поводу. Действительно нет, или плохо искал? Проблема-то, похоже, давняя.
а русские буквы и на диске в некоторых файловых системах плохо сохраняются
поэтому надо взять функцию транслита из pathauto и вставить в upload или еще лучше дописать ее в ядро потому что iconv не всегда правильно работает и не у всех есть
уважаемый kiev1
не могли бы назвать имя функции транслита из pathauto?
значит надо использовать нормальные файловые системы, где проблем с алфавитами нет
а транслитерировать всё - это идиотизм
представьте себе бизнес-портал, на котором собираются люди, не разбирающиеся в компьютерах
и дела им нет ни до каких файловых систем и кодировок
а тут имена файлов (например, msword - сплошь и рядом) преобразуются в транслит
неудобно и неимиджево
ps: поглядел upload.module.. там все строковые ф-ии восьмибитные.. не ожидал, что такое будет в ядре, тем более для некоторых есть врапперы (drupal_strlen, drupal_strtolower и drupal_strtoupper)
function pathauto_cleanstring($string) {
что будем делать?
я запостил репорт на drupal.org, пока тишина..
боюсь, придётся самостоятельно патч писать - им-то что, им юникод не нужен
плохи дела
слово отрезает php функция basename, которая криво работает с unicode
см. file.inc ф-ию file_check_upload
хм, продолжаем изыскания
basename нормально отрабатывает и ничего не отрезает в случае, если запускать с локалью ru_RU.UTF-8
короче, quick & dirty hack прилагаю
Спасибо. Потестирую сегодня и сообщу о результатах.
Походу, не помогло. Кэш браузера и в базе почистил - нифига.
Локаль на сервере была выставлена в POSIX. Поправил на ru_RU.UTF-8 в соответствие с этим мануалом: http://ru.gentoo-wiki.com/HOWTO_ru_RU.utf8_Gentoo_way
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
Проблема осталась. какие еще могут быть варианты?
общесистемную локаль нет смысла выставлять, если патч не помог - то и от этого мало толку
в системе, вообще, присутствует локаль ru_RU.UTF-8? команда date чего показывает?
возможно, надо пересобрать php - не знаю точно, где он локали берёт.. или просто положить их ему
попробуй ещё print_r вставить в file.inc в эту ф-ию после basename - может это не он обрезает, хотя вряд ли..
Локаль присутствует:
ru_RU
ru_RU.koi8r
ru_RU.utf8
ru_UA
ru_UA.utf8
$
$ date
Mon Apr 23 14:25:23 MSD 2007
Как посмотреть локаль, используемую php? в phpinfo нашел только:
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Content-Type: text/html; charset=cp-1251
Не в этом ли проблема кроется?
в phpinfo есть ещё вот что
LANG => ru_RU.UTF-8
_SERVER["LANG"] => ru_RU.UTF-8
_ENV["LANG"] => ru_RU.UTF-8
пример, демонстрирующий, что я хочу сказать:
user@host:~$ cat test.php
#!/usr/bin/php5
<?php
$var = "раз два три\n";
setlocale(LC_CTYPE, 'C');
print basename($var);
setlocale(LC_CTYPE, 'ru_RU.UTF-8');
print basename($var);
user@host:~$ ./test.php
два три
раз два три
user@host:~$
хм-м-м... у меня нет LANG в переменных окружения.. и приведенный пример выдает:
два три
Похоже это баг php: http://bugs.php.net/bug.php?id=37945
Обновляю до 5.2.1-r3
обновление помогло?
Пока не знаю. Завтра посмотрю - там много зависимостией тянулось, поэтой я в screen'е запустил. О результате сообщу.
хмм.. странно
у меня 5.2.0
user@host:~$ dpkg -l | grep php
ii libapache2-mod-php5 5.2.0-8+etch1 server-side, HTML-embedded scripting language
ii php5 5.2.0-8+etch1 server-side, HTML-embedded scripting language
ii php5-cli 5.2.0-8+etch1 command-line interpreter for the php5 script
ii php5-common 5.2.0-8+etch1 Common files for packages built from the php
ii php5-gd 5.2.0-8+etch1 GD module for php5
ii php5-mcrypt 5.2.0-8+etch1 MCrypt module for php5
ii php5-mysql 5.2.0-8+etch1 MySQL module for php5
Проблема решилась обновлением. Теперь все ок!
Всем огромное спасибо!
уважаемый USTAS не могли бы вы дать описание своих действий а также конфигурации php и OS в которой у вас функционирует сохранение файлов с символами кирилицы???
P.S. большое спасибо.
Сервер работает под управлением Gentoo Linux.
Linux bodhidharma 2.6.14-gentoo-r2 #1 SMP PREEMPT Wed Nov 23 10:23:02 Local time zone must be set-- i686 Intel(R) Xeon(TM) CPU 3.06GHz GenuineIntel GNU/Linux
Локаль: ru_RU.UTF-8 (настроена по этому мануалу: http://ru.gentoo-wiki.com/HOWTO_ru_RU.utf8_Gentoo_way - он подходит только для Gentoo)
Apache 2.0.58-r2
PHP 5.2.1-pl3-gentoo (cli) (built: May 2 2007 14:28:54)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
Все собирал из стандартных портежей Gentoo. USE-Флаги:
dev-lang/php -* cli apache2 ctype expat fastbuild ftp gd hash iconv memlimit mysql nls pcre pic pdo reflection session simplexml sockets spl ssl tokenizer truetype unicode xml xsl zlib
все равно надо как-то в друпале сделать транслитезацию при аплоаде файлов, потому что очень большая вероятность их потери при неудачном переносе или бекапе (некоторые фтп клиенты, или архиваторы).
У меня тоже самое. Как решить эту проблему? ASAP
Версии:
Apache 1.3.37 (Unix)
PHP 5.2.3
Проблема и на этом сервере существует:
имя файла было:
а тут как_эта проблема работает.txt
стало:
тут как_эта проблема работает.txt
ну да, там где локаль utf-8 оно работает вроде нормально, но если юзер начнет копировать кривыми ftp клиентами - то они могут подменить имя файла - а в базе он останется под другим именем - и тогда он не будет находиться.
Так что же тогда делать?
Надо как то решать. так жить нельзя на друпале.
В drupal 6.0beta2 проблема остается...
так и нету нормального решения проблемы?
Кто успел попробовать http://drupal.org/project/transliteration ?
после установки модуля http://drupal.org/project/transliteration все заработало как надо
По поводу модуля transliteration - добавил обработку прикрепленных файлов в комментариях и некоторую косметику (это для пятой версии, авторам тоже отправил); но если локаль неправильно работает - я не уверен в результате, т.к. тут тоже используется функция basename.
* Helper function; retroactive transliteration of existing filenames.
*/
function transliteration_install_retroactive() {
require_once(drupal_get_path('module', 'transliteration') .'/transliteration.inc');
// Regexp operators differ between database manufacturers.
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$op = 'RLIKE';
break;
case 'pgsql':
$op = '~*';
break;
}
// Get all of the files that need to be converted, that is those that
// contain characters other than alphanumerics, underscores, dots, or
// hyphens.
// aka: added routines for 'filename' field
$result = db_query("SELECT fid, filename, filepath FROM {files} WHERE SUBSTRING_INDEX(filepath, '/', -1) $op '[^0-9A-Za-z_.-]'");
$errors = array();
while ($file = db_fetch_object($result)) {
// Transliterate the file's name.
$filepath = $file->filepath;
// aka: new code
$filename_new = transliteration_clean_filename(basename($filepath));
$filepath_new = dirname($filepath) .'/'. $filename_new;
// aka: old version
//$filepath_new = dirname($filepath) .'/'. transliteration_clean_filename(basename($filepath));
// Move the file to a new location but do a shortcut check first to avoid
// unneccessary error messages. It's probably better to not mess with
// records for missing files.
$realpath = realpath($filepath);
if ($realpath && file_exists($realpath) && file_move($filepath, $filepath_new, FILE_EXISTS_RENAME)) {
// Get the file's new path; it may have changed.
$filepath_new = $filepath;
// Update the files table with the new path.
db_query("UPDATE {files} SET filename = '%s', filepath = '%s' WHERE fid = %d", $filename_new, $filepath_new, $file->fid);
}
else {
$errors[] = 'table files: ' . $file->filepath;
}
}
// aka: repeat routines for comment_upload_files
$result = db_query("SELECT fid, filename, filepath, description FROM {comment_upload_files} WHERE SUBSTRING_INDEX(filepath, '/', -1) $op '[^0-9A-Za-z_.-]'");
$errors = array();
while ($file = db_fetch_object($result)) {
// Transliterate the file's name.
$filepath = $file->filepath;
// aka: new code
$filename_new = transliteration_clean_filename(basename($filepath));
$filepath_new = dirname($filepath) .'/'. $filename_new;
// aka: translate description
$description_new = ($file->filename == $file->description) ? $filename_new : $file->description;
// aka: old version
//$filepath_new = dirname($filepath) .'/'. transliteration_clean_filename(basename($filepath));
// Move the file to a new location but do a shortcut check first to avoid
// unneccessary error messages. It's probably better to not mess with
// records for missing files.
$realpath = realpath($filepath);
if ($realpath && file_exists($realpath) && file_move($filepath, $filepath_new, FILE_EXISTS_RENAME)) {
// Get the file's new path; it may have changed.
$filepath_new = $filepath;
// Update the files table with the new path.
db_query("UPDATE {comment_upload_files} SET filename = '%s', filepath = '%s', description = '%s' WHERE fid = %d", $filename_new, $filepath_new, $description_new, $file->fid);
}
else {
$errors[] = 'table comment_upload_files: ' . $file->filepath;
}
}
return $errors;
}
После добавления отсутсвующей локали ru_RU.UTF-8 на ubuntu у меня basename не заработал. Точнее, он работал на тестах, а в друпале отказывался. Собака порылась в unique.inc > _unicode_check(). Там выставляется setlocale(LC_CTYPE, 'C');
Т.е. вот этот костыль в bootstrap.inc меня вылечил:
...
case DRUPAL_BOOTSTRAP_FULL:
require_once './includes/common.inc';
_drupal_bootstrap_full();
setlocale(LC_CTYPE, 'ru_RU.UTF-8');
break;
...
Та же проблема. Решилась выставлением LC_ALL=ru_RU.UTF-8 для апача и комментированием setlocale в unicode.inc
Не понимаю, для чего там сбрасывается локаль на C?
Просто написали это:
вместо
В unicode.inc.
За транслитерацию получил от начальника по мозгам