This commit is contained in:
F4ilji
2026-03-23 15:45:49 +05:00
parent c350f712dc
commit 5cf85f08e4
2 changed files with 53 additions and 15 deletions
@@ -61,9 +61,12 @@ class DownloadAttachmentsTask
$savedPath = $this->saveAttachment($attachment, $disk); $savedPath = $this->saveAttachment($attachment, $disk);
if ($savedPath) { if ($savedPath) {
// Декодируем MIME-имя для корректного определения расширения
$decodedFilename = $this->decodeMimeFilename($attachment->getName());
$savedAttachments[] = EmailAttachmentData::fromFile( $savedAttachments[] = EmailAttachmentData::fromFile(
path: $savedPath, path: $savedPath,
originalFilename: $attachment->getName(), originalFilename: $decodedFilename,
mimeType: $attachment->getContentType(), mimeType: $attachment->getContentType(),
size: $attachment->getSize(), size: $attachment->getSize(),
contentId: $attachment->getContentId(), contentId: $attachment->getContentId(),
@@ -139,13 +142,7 @@ class DownloadAttachmentsTask
*/ */
private function generateUniqueFilename(string $originalName): string private function generateUniqueFilename(string $originalName): string
{ {
// Декодируем MIME-кодировку (=?UTF-8?B?...?=) $decodedName = $this->decodeMimeFilename($originalName);
$decodedName = mb_decode_mimeheader($originalName) ?: $originalName;
// Если не декодировалось, пробуем другой метод
if ($decodedName === $originalName && str_contains($originalName, '=?')) {
$decodedName = iconv_mime_decode($originalName, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8') ?: $originalName;
}
// Очищаем имя от специальных символов // Очищаем имя от специальных символов
$decodedName = preg_replace('/[^a-zA-Z0-9_\-\p{L}.]/u', '_', $decodedName); $decodedName = preg_replace('/[^a-zA-Z0-9_\-\p{L}.]/u', '_', $decodedName);
@@ -171,4 +168,23 @@ class DownloadAttachmentsTask
return $basename . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . ($extension ?: 'bin'); return $basename . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . ($extension ?: 'bin');
} }
/**
* Декодировать MIME-кодированное имя файла
*
* @param string $filename Имя файла в MIME-кодировке
* @return string Декодированное имя файла
*/
private function decodeMimeFilename(string $filename): string
{
// Декодируем MIME-кодировку (=?UTF-8?B?...?=)
$decodedName = mb_decode_mimeheader($filename) ?: $filename;
// Если не декодировалось, пробуем другой метод
if ($decodedName === $filename && str_contains($filename, '=?')) {
$decodedName = iconv_mime_decode($filename, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8') ?: $filename;
}
return $decodedName;
}
} }
@@ -36,7 +36,29 @@ class FindMainNewsFileTask
// Фильтруем DOC и DOCX файлы (поддерживаем оба формата) // Фильтруем DOC и DOCX файлы (поддерживаем оба формата)
$docFiles = $files->filter(function($file) { $docFiles = $files->filter(function($file) {
$ext = strtolower($file->getClientOriginalExtension()); $ext = strtolower($file->getClientOriginalExtension());
return in_array($ext, ['doc', 'docx']); $mimeType = $file->getMimeType();
// Проверяем по расширению
if (in_array($ext, ['doc', 'docx'])) {
return true;
}
// Проверяем по MIME-типу (для случаев, когда расширение не определено)
$documentMimes = [
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
];
if (in_array($mimeType, $documentMimes, true)) {
return true;
}
// Проверяем по содержимому имени файла (для MIME-кодированных имён)
$filename = $file->getClientOriginalName();
if (str_contains(strtolower($filename), '.docx') || str_contains(strtolower($filename), '.doc')) {
return true;
}
return false;
}); });
Log::info('[FindMainNewsFileTask] Найдено DOC/DOCX файлов', [ Log::info('[FindMainNewsFileTask] Найдено DOC/DOCX файлов', [