Сколько бы я не предупреждал контент менеджеров, что нельзя закачивать в MODx файлы с именами, написанными символами, отличными от латиницы, всё-равно периодически кто-нибудь обязательно закачает такой файл и в результате перестаёт работать окно закачки файлов в документах – оно просто не показывает ни одного файла.
Кстати я вообще сторонник того, что названия файлов вообще надо писать латиницей, тогда ни в одной системе не возникнет проблем и файл всегда будет виден и доступен.
Вобщем приходится изредка подчищать такие “неправильные” файлы. И так продолжается до тех пор, пока наконец лень не победит чувство долга
Сегодня как раз такой день – лень победила, чувство долга забилось в угол и освободило пространство для творчества.
Сегодня будем учить MODx транслитерировать файлы при загрузке на сервер. По правде говоря, так делать не очень хорошо – всё-таки должна быть свобода называть файлы так, как хочет контент менеджер. Но это, если контент менеджер знает, что делает. На практике же – это обычно девочка, секретать/офис менеджер/младший сотрудник отдела маркетинга, которая вовсе не обязана знать все эти тонкости.
Начнём с того самого окна загрузки файлов из документа. Выглядит оно примерно вот так:
Заходим на сервер в папку с установленным MODx и дальше переходим в папку manager/media/browser/mcpuk/connectors/php/Commands. Здесь открываем на редактирование файл FileUpload.php
Все дальнейшие операции должны проводиться с файлами в кодировке UTF-8. Это ВАЖНО! Я пользуюсь связкой WinSCP и Notepad++, который может перекодировать уже открытый файл в UTF-8. Делается это так:
Итак, файл перекодирован в UTF-8, можно продолжать.
В начало файла вставим следующий код:
function niceFilename($filename) { $changes = array( "Є"=>"EH", "І"=>"I", "і"=>"i", "№"=>"#", "є"=>"eh", "А"=>"A", "Б"=>"B", "В"=>"V", "Г"=>"G", "Д"=>"D", "Е"=>"E", "Ё"=>"E", "Ж"=>"ZH", "З"=>"Z", "И"=>"I", "Й"=>"J", "К"=>"K", "Л"=>"L", "М"=>"M", "Н"=>"N", "О"=>"O", "П"=>"P", "Р"=>"R", "С"=>"S", "Т"=>"T", "У"=>"U", "Ф"=>"F", "Х"=>"H", "Ц"=>"C", "Ч"=>"CH", "Ш"=>"SH", "Щ"=>"SCH", "Ъ"=>"", "Ы"=>"Y", "Ь"=>"", "Э"=>"E", "Ю"=>"YU", "Я"=>"YA", "Ē"=>"E", "Ū"=>"U", "Ī"=>"I", "Ā"=>"A", "Š"=>"S", "Ģ"=>"G", "Ķ"=>"K", "Ļ"=>"L", "Ž"=>"Z", "Č"=>"C", "Ņ"=>"N", "ē"=>"e", "ū"=>"u", "ī"=>"i", "ā"=>"a", "š"=>"s", "ģ"=>"g", "ķ"=>"k", "ļ"=>"l", "ž"=>"z", "č"=>"c", "ņ"=>"n", "а"=>"a", "б"=>"b", "в"=>"v", "г"=>"g", "д"=>"d", "е"=>"e", "ё"=>"e", "ж"=>"zh", "з"=>"z", "и"=>"i", "й"=>"j", "к"=>"k", "л"=>"l", "м"=>"m", "н"=>"n", "о"=>"o", "п"=>"p", "р"=>"r", "с"=>"s", "т"=>"t", "у"=>"u", "ф"=>"f", "х"=>"h", "ц"=>"c", "ч"=>"ch", "ш"=>"sh", "щ"=>"sch", "ъ"=>"", "ы"=>"y", "ь"=>"", "э"=>"e", "ю"=>"yu", "я"=>"ya", "Ą"=>"A", "Ę"=>"E", "Ė"=>"E", "Į"=>"I", "Ų"=>"U", "ą"=>"a", "ę"=>"e", "ė"=>"e", "į"=>"i", "ų"=>"u", "ö"=>"o", "Ö"=>"O", "ü"=>"u", "Ü"=>"U", "ä"=>"a", "Ä"=>"A", "õ"=>"o", "Õ"=>"O"); $alias=strtr($filename, $changes); $alias = strtolower( $alias ); $alias = preg_replace('/&.+?;/', '', $alias); // kill entities $alias = str_replace( '_', '-', $alias ); $alias = preg_replace('/[^a-z0-9\s-.]/', '', $alias); $alias = preg_replace('/\s+/', '-', $alias); $alias = preg_replace('|-+|', '-', $alias); $alias = trim($alias, '-'); return $alias; }
Далее находим строку:
$filename=basename(str_replace("\\","/",$_FILES['NewFile']['name']));
И меняем её на такую:
$filename=basename(str_replace("\\","/",$this->niceFilename($_FILES['NewFile']['name'])));
Сохраняем и проверяем закачкой файла, названного по-русски, по-латышски, по-литовски или по-эстонски. Если имя файла транслитерировалось, все спец-символы исчезли, все буквы стали строчными, а пробелы заменились на дефис, то всё работает как надо. Если нет – ищите ошибку.
Теперь займёмся менеджером файлов, который находится в MODx здесь:
Ресурсы->Управление файлами
Переходим в папку manager/actions и открываем, находящийся в ней файл files.dynamic.php
Точно также вставляем в него нашу функцию niceFilename(). Далее находим строку:
$userfiles[$i]['name'] = $_FILES['userfile']['name'][$i];
и заменяем её на:
$userfiles[$i]['name'] = niceFilename($_FILES['userfile']['name'][$i]);
Сохраняем файл.
Опять проверяем работу закачкой файла, но теперь уже через файл-менеджер. Если всё в порядке, сообщаем контент менеджерам, что и на их улицу пришёл праздник
А чувство долга зашевелилось у себя в углу и, похоже, непрочь набраться наглости, чтобы прогнать лень. Ну что же. Не будем ему мешать…
Толково, а главное просто
единственное что хотелось бы дополнить:
1. стоит добавить символы:
"є"=>"e",
"Є"=>"e",
"ї"=>"yi",
"Ї"=>"yi",
"і"=>"i",
"І"=>"i",
"ґ"=>"g",
"Ґ"=>"g"
из Украинского алфавита
2. есть смысл немного упростить regex’ы вот так:
$alias = strtr(trim($filename), $changes);
$alias = strtolower( $alias );
$alias = ereg_replace("[^a-zA-Z0-9]","-",$alias);
$alias = ereg_replace("[-]+","-",$alias);
$alias = trim($alias, '-');
тоесть мы просто заменяем любые символы кроме букв и цыфр на дефисы, а затем тримаем результат по этому делу да и все.
Спасибо за regexp-ы и отдельно за замены для украинского языка – как раз скоро пригодится!
Спасибо!
Только вот у меня заработало когда строку изменил на:
$filename=basename(str_replace(»\\»,»/»,niceFilename($_FILES['NewFile']['name'])));
MODx 1.0.4
спасибо! Недавно столкнулся с аналогичной проблемой – решение пришлось как нельзя кстати.
Полагаю следует уточнить, что в файле FileUpload.php функцию niceFilename следует вставить не в начало файла, а после описания переменных класса т.к. она используется как метод класса.
Вот так
class FileUpload {
var $fckphp_config;
var $type;
var $cwd;
var $actual_cwd;
var $newfolder;
function niceFilename($filename) {
$changes = array(
Вот вопрос возник, а как ту же самую процедуру сделать в MODx Revolution? Буду очень признателен если мне помогут
Ajpro, спасибо за уточнение! Конечно же niceFilename надо вставлять после описания переменных класса.