Обновление бека+фронт
MVP версия - которая уже готова к работе
This commit is contained in:
163
backend/app/class/enity/class_taskImage.php
Normal file
163
backend/app/class/enity/class_taskImage.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
class TaskImage {
|
||||
|
||||
protected static $db_name = 'cards_task';
|
||||
protected static $upload_path = '/public/img/task/';
|
||||
|
||||
// Валидация всех данных для загрузки
|
||||
protected static function validate($task_id, $file_base64, $file_name) {
|
||||
// Проверка и получение задачи
|
||||
$task = Task::check_task($task_id);
|
||||
|
||||
// Декодируем base64
|
||||
$file_data = base64_decode(preg_replace('/^data:image\/\w+;base64,/', '', $file_base64));
|
||||
if (!$file_data) {
|
||||
return ['success' => false, 'errors' => ['file' => 'Ошибка декодирования файла']];
|
||||
}
|
||||
|
||||
// Проверка расширения
|
||||
$allowed_ext = ['png', 'jpg', 'jpeg'];
|
||||
$ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
|
||||
if (!in_array($ext, $allowed_ext)) {
|
||||
return ['success' => false, 'errors' => ['file' => 'Разрешены только PNG, JPG, JPEG']];
|
||||
}
|
||||
|
||||
// Проверка размера (10 МБ)
|
||||
$max_size = 10 * 1024 * 1024;
|
||||
if (strlen($file_data) > $max_size) {
|
||||
return ['success' => false, 'errors' => ['file' => 'Файл слишком большой. Максимум 10 МБ']];
|
||||
}
|
||||
|
||||
// Проверка MIME типа
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->buffer($file_data);
|
||||
$allowed_mime = ['image/png', 'image/jpeg'];
|
||||
if (!in_array($mime, $allowed_mime)) {
|
||||
return ['success' => false, 'errors' => ['file' => 'Недопустимый тип файла']];
|
||||
}
|
||||
|
||||
// Всё ок — возвращаем данные
|
||||
return [
|
||||
'task' => $task,
|
||||
'file_data' => $file_data
|
||||
];
|
||||
}
|
||||
|
||||
// Генерация уникального имени файла
|
||||
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/img/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/img/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];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user