Транслитерация имен файлов и папок

Added by Андрей Халявин over 1 year ago

Посоветуйте в чем может быть дело: в функции _checkName() добавил код для транслитерации русских имен файлов и папок, при создании папок и файлов все работает отлично, но при попытке загрузки файла с русским именем выдается ошибка "Unable to parse server responce!" - в каком направлении копать?


Replies (24)

RE: Транслитерация имен файлов и папок - Added by Troex Nevelin over 1 year ago

Клиентская часть (JavaScript) ожидает в ответ JSON, если вы выводите какие-либо echo то клиенская часть не сможет их обработать, notice и прочие ошибки относяться сюда же. Вам нужно посмотреть какой ответ присылает коннектор после загрузки файлов, проще всего это сделать через FireBug.

RE: Транслитерация имен файлов и папок - Added by Андрей Халявин over 1 year ago

ага, так стало гораздо проще. хотя причина пока и непонятна - ответ идет такой:

1 {
2    "select": [],
3    "errorData": {
4       null: "Invalid name" 
5    },
6    "error": "Unable to upload files"}

но теперь проще рыть, спасибо =)

RE: Транслитерация имен файлов и папок - Added by Troex Nevelin over 1 year ago

null - явно настараживает, скорее всего ваш метод _checkName возвращает null. В любом случаи я бы не рекомендовал трогать _checkName, а просто после загрузки файлов в _upload() тихо переименовать фаылы пепред вызовом $this->_content($dir);

RE: Транслитерация имен файлов и папок - Added by Андрей Халявин over 1 year ago

Ну по-моему для таких целей как раз логичнее использовать эту функцию.

Все дело по-видимому в кодировке, хотя я никак не пойму в каком именно месте: исходное имя файла приходит в функцию в кодировке UTF-8, после некоторого количества танцев с бубном файл стал сохраняться, но его имя сохраняется в исходном виде, русскими буквами, но в кодировке ISO-8859-5. КАК это получается, я пока ума не приложу =)

RE: Транслитерация имен файлов и папок - Added by Андрей Халявин over 1 year ago

приложил =)

В функции _upload() все организовано очень странно: переменная $name для файла формируется через _checkName() как обычно, но при сохранении итоговое имя файла с директорией собирается вот так:

$file = $dir.DIRECTORY_SEPARATOR.$_FILES['upload']['name'][$i];

хотя правильно и логично было бы это делать так:

$file = $dir.DIRECTORY_SEPARATOR.$name;

в таком виде все работает отлично и без ошибок =)

RE: Транслитерация имен файлов и папок - Added by Troex Nevelin over 1 year ago

Соглашусь, в остальных методах где используется _checkName используется именно return от этой функции, примём к сведению #194

RE: Транслитерация имен файлов и папок - Added by Александр Михневич over 1 year ago

Для транслитерации внёс правки в файл elFinder.class.php - может несколько на скорую руку, но работает.
Транслитерация тут при создании файла/папки на русском, загрузке файла с русским названием и везде, где фигурирует русский. :)
Прилагаю исправленный файл.

elFinder.class.php - elFinder.class.php с транслитерацией (56.5 kB)

RE: Транслитерация имен файлов и папок - Added by Troex Nevelin over 1 year ago

Сделал патч с ваших изменений, так понятнее что вы изменили и можно будет применить патч к дальнейшим версиям. elFinder.class.php у вас был с cp1251 кодировке с CRLF, перебил его в UTF-8 и unix line-endings.

Не совсем понял зачем почему при _rename, _mkfile, _mkdir используется _rusutf2translit, а при _upload _rus2translit? это получается ты elFinder используете на странице с кодировкой cp1251? А почему тогда файлы в UTF-8 загружаются?

RE: Транслитерация имен файлов и папок - Added by Георгий Шляхов about 1 year ago

обнаружил некую странность
перестала работать перекодировка

как были сделаны правильные замечания насчет функций _rusutf2translit и _rus2translit - передал так:

private function _rus2translit($str) {
return $this->_rusutf2translit($str);
}

перекодировка после сделанных исправлений заработала корректно

P.S. функцию я оставил потому на всякий поскольку необходима проверка этого решения на исключения, что требует время к-роо у меня просто нету - потому такое вот решение

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Здравствуйте, хотел бы вернуться к данному вопросу, также требуется реализовать транслитерацию имен файлов и папок, но уже для версии 2.0 (описанное выше для этой версии уже не работает) может в версии 2.0 появилась какая-либо возможность получить доступ к имени файла (и изменить его) перед тем как файл будет сохранён?

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

Так и есть, в 2.0 вы можете подписаться на события коннектора и менять файлы. В connector.php есть пример логгера - он работает по такому же принципу

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Можно немного поподробнее?
Как я понял, что бы изменить название загружаемого файла пользователем, я должен указать в параметрах коннектора следующее:

#Отслеживаем команду загрузки файла пользователем
'bind' => array('upload' => 'my_rename_function'),

А также написать функцию:

function my_rename_function($cmd, $voumes, $result) {
#Переименовываем файл
$result['added'][0]['name']='Rename.txt';
return $result;
}

Но это почему-то не работает (при загрузке любого файла в Elfinder появляется файл с именем Rename.txt, но на самом деле на хостинг заливается файл с исходным именем(с тем с которым заливает его пользователь) и если обновить список файлов в менеджере то и там файл имеет исходное название), (или я что-то не так делаю), как правильно?

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

Все не так просто как вам хочется :)
От того, что вы поменяли имя в данных для клиента ничего не изменится.
Надо сказать драйверу тома ($volumes0) чтобы он переименовал файл
Надо сделать что-то вроде следующего

$target = $result['added'][0]['hash'];

if (($file = $volumes[0]->rename($target, "new name")) == false) {
    return $result;
}

$result['added'][0] = $file;

Подробней см elFinder::rename()

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Да, спасибо, получилось:

$hash=$result['added'][0]['hash'];
if (($file = $voumes[0]->rename($hash,'new_name')) != false) $result['added'][0] = $file;

Хотелось бы еще спросить можно ли получить уникальное имя файла с учетом того существует ли файл new_name на сервере или нет,
т.е если файл new_name существует, то переименовываем его в new_name-1, если и он существует то в new_name-2 и т.д

Как я понял за это отвечает: elFinder::uniqueName():

protected function uniqueName($dir, $name, $suffix = ' copy', $checkNum=true)

Пытался сделать так:

$hash = $result['added'][0]['hash'];
$new_name = $voumes[0]->uniqueName(dirname($voumes[0]->aroot),'new_name','-');
if (($file = $voumes[0]->rename($hash,$new_name)) != false) $result['added'][0] = $file;

Но из этого ничего не выходит

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

смените доступ на public
Если получится - я сделаю ее public

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Да, ещё раз спасибо, после смены на public всё работает, вот может кому пригодится:

# Новое имя файла в транслите
 $new_name='new_name.txt';
# Получаем директорию в которую загружаем текущий файл
 $path=$voumes[0]->parent($result['added'][0]['hash']);
# Проверяем есть ли такой файл, если есть генерируем для него уникальное имя
 if (is_file($path.DIRECTORY_SEPARATOR.$new_name)) $new_name=$voumes[0]->uniqueName($path,$new_name,'-',false);
# Переименовываем файл
 if (($file = $voumes[0]->rename($result['added'][0]['hash'],$new_name)) != false) $result['added'][0] = $file;

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

сделаю public
Как впечатления от API? удобно?

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Да, очень удобно)

Но хотелось бы ещё иметь возможность отправлять/считывать пользовательские параметры (может такое уже есть?), т.е, для примера:

допустим, мне нужно преобразовывать имена файлов в транслит только в определенной корневой категории, тогда я в коннекторе пишу так:

$opts = array(
'roots' => array(
array(
'driver'        => 'LocalFileSystem',
'path'          => '../files/',
'URL'           => dirname($_SERVER['PHP_SELF']) . '/../files/',
'accessControl' => 'access',

#Допустим пользовательские параметры у нас будут хранится в этом массиве
'users_data'=>array (

'user_param_1'=>'Параметр-1',
'status'=>true,
'my_param'=>array(1,2,8)

)
###

)
)
);

А затем уже в функции считывать эти параметры:

if ($voumes[0]->usersData['user_param_1']==1) ....

Кстати, аналогично у вас это реализовано в JS ( js/elFinder.options.js ) : customData : {token : '42', test : 'test'}

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

То есть, вы хотите объеденить customData с клиента и коннектора?

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

То есть, вы хотите объеденить customData с клиента и коннектора?

Нет, просто хотелось бы увидить customData в коннекторе (как я понял на данный момент такого нет или просто я не нашел)

Прикрепил получившийся коннектор с возможностью переименования файлов в транслит при их загрузке, может кому сгодится...

connector.php - Транслитерация имен файлов при загрузке (3.9 kB)

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

Они там есть в $_GET/$_POST, но устанавливаются на клиенте

RE: Транслитерация имен файлов и папок - Added by Сергей Сергеевич 10 months ago

Так уж получилось, что у меня нет возможности динамически менять параметры на клиенте, к тому же требуется передача большого массивова, для себя данный вопрос решил следующим образом:

в файле php/elFinderVolumeDriver.class.php сменил доступ к $options:

c

1 protected $options = array(

на

1 public $options = array(

в настройки коннектора добавил customData:

 1 $opts = array(
 2 'roots' => array(
 3 array(
 4 'driver'        => 'LocalFileSystem',
 5 ...
 6 ###
 7 'customData'=>array (
 8 'user_param_1'=>$parameter,
 9 'status'=>true,
10 'my_param'=>array(1,2,3)
11 )
12 ###
13 ...
14 )
15 )
16 );

Теперь в функции которую мы подписали на события коннектора, все пользовательские параметры находятся в массиве: $voumes[0]->options['customData']

RE: Транслитерация имен файлов и папок - Added by Dmitry Levashov 10 months ago

Можно проще - просто передайте их в конструктор

RE: Транслитерация имен файлов и папок - Added by Эдуард Лысенко 6 months ago

Для тех кто использует файл
connector.php - Транслитерация имен файлов при загрузке (3,88 КБ)

добавленный Сергей Сергеевичем.

При повторной загрузке файла на сервер возникает сообщение об ошибке.

Это происходит потому что в коде файла connector.php используется функция uniqueNamе.

Необходимо в файле elFinderVolumeDriver.class.php поменять доступ для функции uniqueNamе с protected на public (строка 1694).

Чтобы первый повторно загружаемый файл заканчивался не на "-" (foto-.jpg) а сразу на цифру (foto-1.jpg)
надо в строке 1708 файла elFinderVolumeDriver.class.php поменять $i=0 на $i=1;

(1-24/24)