View file test.4imas.ru/public/upload.php

File size: 11.24Kb
<?php

require_once __DIR__ . '/../config/bootstrap.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/functions.php';

if (!is_logged_in()) {
    header('Location: ' . BASE_URL . 'login.php');
    exit;
}

$errors = [];
$success = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $csrf_token = $_POST['csrf'] ?? $_POST['csrf_token'] ?? '';
    
    if (empty($csrf_token)) {
        $errors[] = 'Отсутствует CSRF токен';
        error_log('CSRF token missing in POST data: ' . print_r($_POST, true));
    } elseif (!check_csrf($csrf_token)) {
        $errors[] = 'Ошибка безопасности. Попробуйте снова.';
        error_log('CSRF check failed. Token from POST: ' . $csrf_token . ', Token in session: ' . ($_SESSION['csrf_token'] ?? 'none'));
    } elseif (!isset($_FILES['photo']) || $_FILES['photo']['error'] !== UPLOAD_ERR_OK) {
        $errors[] = 'Ошибка загрузки файла. Код ошибки: ' . ($_FILES['photo']['error'] ?? 'No file');
        error_log('File upload error: ' . ($_FILES['photo']['error'] ?? 'No file uploaded'));
    } else {
        $allowed_types = ['image/jpeg', 'image/png', 'image/jpg'];
        $tmp_name = $_FILES['photo']['tmp_name'];

        if (!file_exists($tmp_name)) {
            $errors[] = 'Временный файл не существует.';
            error_log('Temporary file does not exist: ' . $tmp_name);
        } else {

            if ($_FILES['photo']['size'] > 10 * 1024 * 1024) {
                $errors[] = 'Файл слишком большой. Максимальный размер: 10 МБ.';
            } else {
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $file_type = finfo_file($finfo, $tmp_name);
                finfo_close($finfo);
                
                error_log('Detected file type: ' . $file_type);

                if ($file_type === 'image/jpg') {
                    $file_type = 'image/jpeg';
                }
                
                if (!in_array($file_type, $allowed_types)) {
                    $errors[] = 'Разрешены только JPG и PNG файлы. Загружен тип: ' . $file_type;
                } else {
                    $original_name = $_FILES['photo']['name'];
                    $extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));

                    if ($extension === 'jpg') {
                        $extension = 'jpeg';
                    }
                    
                    $filename = bin2hex(random_bytes(8)) . '.' . $extension;
                    $upload_dir = __DIR__ . '/../uploads/photos/';

                    if (!is_dir($upload_dir)) {
                        if (!mkdir($upload_dir, 0755, true)) {
                            $errors[] = 'Не удалось создать директорию для загрузки.';
                            error_log('Failed to create upload directory: ' . $upload_dir);
                        }
                    }
                    
                    if (empty($errors)) {
                        $destination = $upload_dir . $filename;
                        
                        if (move_uploaded_file($tmp_name, $destination)) {
                            error_log('File moved successfully to: ' . $destination);
                            
                            try {
                                $stmt = $pdo->prepare("INSERT INTO photos (user_id, filename, uploaded_at, status) VALUES (:user_id, :filename, NOW(), 'Новый')");
                                $stmt->execute([
                                    'user_id' => $_SESSION['user_id'],
                                    'filename' => $filename
                                ]);
                                
                                $success = true;
                                $last_id = $pdo->lastInsertId();
                                error_log('Photo saved to database with ID: ' . $last_id);

                                $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
                                
                            } catch (PDOException $e) {
                                $errors[] = 'Ошибка базы данных: ' . $e->getMessage();
                                error_log('Database error: ' . $e->getMessage());

                                if (file_exists($destination)) {
                                    unlink($destination);
                                }
                            }
                        } else {
                            $errors[] = 'Не удалось сохранить файл.';
                            error_log('Failed to move uploaded file. Error: ' . error_get_last()['message'] ?? 'unknown');
                        }
                    }
                }
            }
        }
    }
}

include __DIR__ . '/../includes/header.php';
?>

<div class="container py-5">
    <div class="row justify-content-center">
        <div class="col-md-6 col-lg-5">
            <div class="card shadow-sm border-0 animate__animated animate__fadeInDown">
                <div class="card-body p-4">
                    <h3 class="card-title mb-4 text-center fw-bold">
                        <i class="bi bi-cloud-upload-fill"></i> Загрузка фотографии
                    </h3>

                    <?php if ($success): ?>
                        <div class="alert alert-success mb-3">
                            <div class="d-flex align-items-center">
                                <i class="bi bi-check-circle-fill fs-4 me-3"></i>
                                <div>
                                    <h5 class="alert-heading mb-1">Успешно!</h5>
                                    <p class="mb-0">Фотография успешно загружена и отправлена на печать.</p>
                                </div>
                            </div>
                        </div>
                    <?php endif; ?>

                    <?php if ($errors): ?>
                        <div class="alert alert-danger mb-3">
                            <div class="d-flex align-items-center">
                                <i class="bi bi-exclamation-circle-fill fs-4 me-3"></i>
                                <div>
                                    <h5 class="alert-heading mb-1">Ошибка загрузки</h5>
                                    <?php foreach ($errors as $error): ?>
                                        <p class="mb-1">• <?= e($error) ?></p>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        </div>
                    <?php endif; ?>

                    <form method="POST" enctype="multipart/form-data" class="needs-validation" novalidate>
                        <?= csrf_input(); ?>

                        <div class="mb-4">
                            <label for="photo" class="form-label fw-bold">
                                <i class="bi bi-image"></i> Выберите фотографию
                            </label>
                            <input type="file" 
                                   class="form-control" 
                                   id="photo" 
                                   name="photo" 
                                   accept=".jpg,.jpeg,.png" 
                                   required>
                            <div class="form-text">
                                <i class="bi bi-info-circle"></i> Поддерживаемые форматы: JPG, PNG. Максимальный размер: 10 МБ.
                            </div>
                            <div class="invalid-feedback">
                                Пожалуйста, выберите файл изображения.
                            </div>
                        </div>

                        <div class="d-grid gap-2">
                            <button type="submit" class="btn btn-primary btn-lg">
                                <i class="bi bi-cloud-upload"></i> Загрузить фотографию
                            </button>
                            <a href="<?= BASE_URL ?>" class="btn btn-outline-secondary">
                                <i class="bi bi-arrow-left"></i> На главную
                            </a>
                        </div>
                    </form>
                </div>
                <div class="card-footer bg-white border-0 text-center">
                    <small class="text-muted">
                        <i class="bi bi-shield-check"></i> Ваши фотографии защищены и не передаются третьим лицам
                    </small>
                </div>
            </div>
            
            <div class="alert alert-info mt-4">
                <div class="d-flex align-items-center">
                    <i class="bi bi-lightbulb fs-4 me-3"></i>
                    <div>
                        <h6 class="alert-heading mb-1">Советы по загрузке</h6>
                        <ul class="mb-0 ps-3">
                            <li>Используйте фотографии в хорошем качестве</li>
                            <li>Оптимальное разрешение: от 300 DPI</li>
                            <li>Рекомендуемый формат: JPG</li>
                            <li>Фотографии автоматически проверяются на качество</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const form = document.querySelector('form');
    const fileInput = document.getElementById('photo');

    fileInput.addEventListener('change', function() {
        const file = this.files[0];
        const maxSize = 10 * 1024 * 1024; // 10 МБ
        
        if (file && file.size > maxSize) {
            alert('Файл слишком большой. Максимальный размер: 10 МБ.');
            this.value = '';
        }

        if (file) {
            const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
            if (!allowedTypes.includes(file.type)) {
                alert('Разрешены только JPG и PNG файлы.');
                this.value = '';
            }
        }
    });

    (function() {
        'use strict';
        const forms = document.querySelectorAll('.needs-validation');
        Array.from(forms).forEach(form => {
            form.addEventListener('submit', event => {
                if (!form.checkValidity()) {
                    event.preventDefault();
                    event.stopPropagation();
                }
                form.classList.add('was-validated');
            }, false);
        });
    })();
});
</script>

<?php
include __DIR__ . '/../includes/footer.php';
?>