Files
crm.clientright.ru/crm_extensions/file_storage/TransliterationService.php

129 lines
5.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Сервис транслитерации имен файлов
* Преобразует кириллические имена в латиницу и сокращает их
*/
class TransliterationService {
/**
* Таблица транслитерации кириллицы в латиницу
*/
private static $transliterationTable = [
'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo',
'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm',
'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u',
'ф' => 'f', 'х' => 'h', 'ц' => 'ts', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch',
'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo',
'Ж' => 'Zh', 'З' => 'Z', 'И' => 'I', 'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M',
'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U',
'Ф' => 'F', 'Х' => 'H', 'Ц' => 'Ts', 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sch',
'Ъ' => '', 'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu', 'Я' => 'Ya',
' ' => '_', '-' => '_', '(' => '', ')' => '', '[' => '', ']' => '',
'{' => '', '}' => '', '.' => '.', ',' => '', ':' => '', ';' => '',
'!' => '', '?' => '', '"' => '', "'" => '', '№' => 'N', '№' => 'N'
];
/**
* Транслитерация имени файла
*
* @param string $filename Оригинальное имя файла
* @param int $maxLength Максимальная длина имени (по умолчанию 50)
* @return string Транслитерированное имя файла
*/
public static function transliterate($filename, $maxLength = 50) {
// Получаем расширение файла
$pathInfo = pathinfo($filename);
$extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
$nameWithoutExt = $pathInfo['filename'];
// Транслитерация
$transliterated = strtr($nameWithoutExt, self::$transliterationTable);
// Удаляем множественные подчеркивания и заменяем на одинарные
$transliterated = preg_replace('/_+/', '_', $transliterated);
// Удаляем подчеркивания в начале и конце
$transliterated = trim($transliterated, '_');
// Сокращаем до максимальной длины
if (strlen($transliterated) > $maxLength) {
$transliterated = substr($transliterated, 0, $maxLength);
$transliterated = rtrim($transliterated, '_');
}
// Если имя стало пустым, используем хеш
if (empty($transliterated)) {
$transliterated = 'file_' . substr(md5($filename), 0, 8);
}
return $transliterated . $extension;
}
/**
* Создает короткое имя файла с хешем
*
* @param string $originalFilename Оригинальное имя файла
* @param int $notesid ID записи
* @param int $maxLength Максимальная длина (по умолчанию 30)
* @return string Короткое имя файла
*/
public static function createShortName($originalFilename, $notesid, $maxLength = 30) {
$pathInfo = pathinfo($originalFilename);
$extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
// Создаем короткое имя: doc_[ID]_[hash].ext
$hash = substr(md5($originalFilename), 0, 8);
$shortName = "doc_{$notesid}_{$hash}{$extension}";
return $shortName;
}
/**
* Создает имя файла с транслитерацией и сокращением
*
* @param string $originalFilename Оригинальное имя файла
* @param int $notesid ID записи
* @param int $maxLength Максимальная длина (по умолчанию 40)
* @return string Оптимизированное имя файла
*/
public static function createOptimizedName($originalFilename, $notesid, $maxLength = 40) {
// Сначала пробуем транслитерацию
$transliterated = self::transliterate($originalFilename, $maxLength);
// Если транслитерация дала слишком длинное имя, используем короткое
if (strlen($transliterated) > $maxLength) {
return self::createShortName($originalFilename, $notesid, $maxLength);
}
return $transliterated;
}
/**
* Проверяет, нужно ли переименовывать файл
*
* @param string $filename Имя файла
* @param int $maxLength Максимальная длина
* @return bool True если нужно переименовать
*/
public static function needsRenaming($filename, $maxLength = 50) {
// Проверяем длину
if (strlen($filename) > $maxLength) {
return true;
}
// Проверяем наличие кириллицы
if (preg_match('/[а-яё]/iu', $filename)) {
return true;
}
// Проверяем наличие проблемных символов
if (preg_match('/[^a-zA-Z0-9._-]/', $filename)) {
return true;
}
return false;
}
}
?>