281 lines
7.5 KiB
PHP
281 lines
7.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Core\Auth;
|
|
use App\Core\DB;
|
|
|
|
class TaskFileController
|
|
{
|
|
public function upload(): void
|
|
{
|
|
if (!Auth::check()) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Unauthorized'], 403);
|
|
}
|
|
|
|
header('Location: /login');
|
|
exit;
|
|
}
|
|
|
|
$taskId = (int)($_POST['task_id'] ?? 0);
|
|
|
|
if ($taskId <= 0 || empty($_FILES['file'])) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Файл не выбран'], 400);
|
|
}
|
|
|
|
$_SESSION['error'] = 'Файл не выбран';
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
$file = $_FILES['file'];
|
|
|
|
if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Ошибка загрузки файла'], 400);
|
|
}
|
|
|
|
$_SESSION['error'] = 'Ошибка загрузки файла';
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
$uploadDir = __DIR__ . '/../../storage/uploads/tasks/' . $taskId;
|
|
|
|
if (!is_dir($uploadDir)) {
|
|
mkdir($uploadDir, 0775, true);
|
|
}
|
|
|
|
$originalName = (string)$file['name'];
|
|
$tmpName = (string)$file['tmp_name'];
|
|
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
|
|
$storedName = uniqid('task_', true) . ($extension ? '.' . $extension : '');
|
|
$targetPath = $uploadDir . '/' . $storedName;
|
|
|
|
if (!move_uploaded_file($tmpName, $targetPath)) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Не удалось сохранить файл'], 500);
|
|
}
|
|
|
|
$_SESSION['error'] = 'Не удалось сохранить файл';
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
$relativePath = 'storage/uploads/tasks/' . $taskId . '/' . $storedName;
|
|
$fileSize = (int)filesize($targetPath);
|
|
$mimeType = mime_content_type($targetPath) ?: null;
|
|
|
|
$pdo = DB::connection();
|
|
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO task_files (
|
|
task_id,
|
|
uploaded_by,
|
|
original_name,
|
|
stored_name,
|
|
file_path,
|
|
file_size,
|
|
mime_type,
|
|
created_at
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())
|
|
");
|
|
$stmt->execute([
|
|
$taskId,
|
|
Auth::user()['id'],
|
|
$originalName,
|
|
$storedName,
|
|
$relativePath,
|
|
$fileSize,
|
|
$mimeType,
|
|
]);
|
|
|
|
if ($this->isAjax()) {
|
|
$this->json([
|
|
'success' => true,
|
|
'task_id' => $taskId,
|
|
]);
|
|
}
|
|
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
public function download(): void
|
|
{
|
|
if (!Auth::check()) {
|
|
header('Location: /login');
|
|
exit;
|
|
}
|
|
|
|
$fileId = (int)($_GET['id'] ?? 0);
|
|
|
|
if ($fileId <= 0) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден';
|
|
return;
|
|
}
|
|
|
|
$pdo = DB::connection();
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT *
|
|
FROM task_files
|
|
WHERE id = ?
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute([$fileId]);
|
|
$file = $stmt->fetch();
|
|
|
|
if (!$file) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден';
|
|
return;
|
|
}
|
|
|
|
$absolutePath = __DIR__ . '/../../' . $file['file_path'];
|
|
|
|
if (!is_file($absolutePath)) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден на диске';
|
|
return;
|
|
}
|
|
|
|
header('Content-Description: File Transfer');
|
|
header('Content-Type: ' . ($file['mime_type'] ?: 'application/octet-stream'));
|
|
header('Content-Disposition: attachment; filename="' . basename((string)$file['original_name']) . '"');
|
|
header('Content-Length: ' . filesize($absolutePath));
|
|
header('Pragma: public');
|
|
|
|
readfile($absolutePath);
|
|
exit;
|
|
}
|
|
public function view(): void
|
|
{
|
|
if (!Auth::check()) {
|
|
header('Location: /login');
|
|
exit;
|
|
}
|
|
|
|
$fileId = (int)($_GET['id'] ?? 0);
|
|
|
|
if ($fileId <= 0) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден';
|
|
return;
|
|
}
|
|
|
|
$pdo = DB::connection();
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT *
|
|
FROM task_files
|
|
WHERE id = ?
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute([$fileId]);
|
|
$file = $stmt->fetch();
|
|
|
|
if (!$file) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден';
|
|
return;
|
|
}
|
|
|
|
$absolutePath = __DIR__ . '/../../' . $file['file_path'];
|
|
|
|
if (!is_file($absolutePath)) {
|
|
http_response_code(404);
|
|
echo 'Файл не найден на диске';
|
|
return;
|
|
}
|
|
|
|
$mimeType = $file['mime_type'] ?: mime_content_type($absolutePath) ?: 'application/octet-stream';
|
|
|
|
header('Content-Type: ' . $mimeType);
|
|
header('Content-Length: ' . filesize($absolutePath));
|
|
header('Content-Disposition: inline; filename="' . basename((string)$file['original_name']) . '"');
|
|
|
|
readfile($absolutePath);
|
|
exit;
|
|
}
|
|
public function delete(): void
|
|
{
|
|
if (!Auth::check()) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Unauthorized'], 403);
|
|
}
|
|
|
|
header('Location: /login');
|
|
exit;
|
|
}
|
|
|
|
$fileId = (int)($_POST['id'] ?? 0);
|
|
|
|
if ($fileId <= 0) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Файл не найден'], 404);
|
|
}
|
|
|
|
$_SESSION['error'] = 'Файл не найден';
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
$pdo = DB::connection();
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT *
|
|
FROM task_files
|
|
WHERE id = ?
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute([$fileId]);
|
|
$file = $stmt->fetch();
|
|
|
|
if (!$file) {
|
|
if ($this->isAjax()) {
|
|
$this->json(['success' => false, 'message' => 'Файл не найден'], 404);
|
|
}
|
|
|
|
$_SESSION['error'] = 'Файл не найден';
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
|
|
$absolutePath = __DIR__ . '/../../' . $file['file_path'];
|
|
|
|
$stmt = $pdo->prepare("DELETE FROM task_files WHERE id = ?");
|
|
$stmt->execute([$fileId]);
|
|
|
|
if (is_file($absolutePath)) {
|
|
@unlink($absolutePath);
|
|
}
|
|
|
|
if ($this->isAjax()) {
|
|
$this->json([
|
|
'success' => true,
|
|
'file_id' => $fileId,
|
|
]);
|
|
}
|
|
|
|
header('Location: /tasks');
|
|
exit;
|
|
}
|
|
private function isAjax(): bool
|
|
{
|
|
return strtolower((string)($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '')) === 'xmlhttprequest';
|
|
}
|
|
|
|
private function json(array $data, int $statusCode = 200): void
|
|
{
|
|
http_response_code($statusCode);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
} |