false, 'errors' => ['file' => 'Ошибка декодирования файла']]; } // Проверка расширения $allowed_ext = ['png', 'jpg', 'jpeg', 'zip', 'rar']; $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed_ext)) { return ['success' => false, 'errors' => ['file' => 'Разрешены только PNG, JPG, JPEG, ZIP, RAR']]; } // Проверка размера (10 МБ) $max_size = 10 * 1024 * 1024; if (strlen($file_data) > $max_size) { return ['success' => false, 'errors' => ['file' => 'Файл слишком большой. Максимум 10 МБ']]; } // Всё ок — возвращаем данные return [ 'task' => $task, 'file_data' => $file_data, 'is_archive' => in_array($ext, ['zip', 'rar']) ]; } // Генерация уникального имени файла protected static function getUniqueName($upload_dir, $file_name) { $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); $base_name = pathinfo($file_name, PATHINFO_FILENAME); $final_name = $file_name; $counter = 1; while (file_exists($upload_dir . '/' . $final_name)) { $final_name = $base_name . '_' . $counter . '.' . $ext; $counter++; } return $final_name; } // Загрузка изображения public static function upload($task_id, $file_base64, $file_name) { // Валидация $validation = self::validate($task_id, $file_base64, $file_name); if (isset($validation['success'])) return $validation; $task = $validation['task']; $file_data = $validation['file_data']; // Путь к папке $upload_dir = __DIR__ . '/../../../public/task/' . $task_id; if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); } // Уникальное имя $final_name = self::getUniqueName($upload_dir, $file_name); // Сохранение файла $file_path = $upload_dir . '/' . $final_name; if (!file_put_contents($file_path, $file_data)) { return ['success' => false, 'errors' => ['file' => 'Ошибка сохранения файла']]; } // Формируем URL $file_url = self::$upload_path . $task_id . '/' . $final_name; $file_size = strlen($file_data); // Обновляем file_img в базе $current_files = json_decode($task['file_img'], true) ?? []; $current_files[] = [ 'url' => $file_url, 'name' => $final_name, 'size' => $file_size ]; Database::update(self::$db_name, [ 'file_img' => json_encode($current_files, JSON_UNESCAPED_UNICODE) ], [ 'id' => $task_id ]); return [ 'success' => true, 'file' => [ 'url' => $file_url, 'name' => $final_name, 'size' => $file_size ] ]; } // Удаление изображений (принимает строку или массив имён файлов) public static function delete($task_id, $file_names) { // Проверка и получение задачи $task = Task::check_task($task_id); // Приводим к массиву если передана строка if (!is_array($file_names)) { $file_names = [$file_names]; } // Получаем текущие файлы $current_files = json_decode($task['file_img'], true) ?? []; $upload_dir = __DIR__ . '/../../../public/task/' . $task_id; $deleted = []; // Удаляем каждый файл foreach ($file_names as $file_name) { // Ищем файл в массиве foreach ($current_files as $index => $file) { if ($file['name'] === $file_name) { // Удаляем файл с диска $file_path = $upload_dir . '/' . $file_name; if (file_exists($file_path)) { unlink($file_path); } // Удаляем из массива array_splice($current_files, $index, 1); $deleted[] = $file_name; break; } } } // Обновляем в базе Database::update(self::$db_name, [ 'file_img' => json_encode($current_files, JSON_UNESCAPED_UNICODE) ], [ 'id' => $task_id ]); // Удаляем папку если она пустая if (is_dir($upload_dir) && count(scandir($upload_dir)) === 2) { rmdir($upload_dir); } return ['success' => true, 'deleted' => $deleted]; } } ?>