Jump to content

how do i make file upload system efficient!?


ujjwalG

Recommended Posts

my wt1t1.php:
 

<?php
session_start();

// Check if the user is logged in
if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit();
}

// Include database connection
include_once('db/dbcon.php');

// Set the task_id for the specific task (e.g., WT1B1)
$task_id = 1; // Static value for testing

// Get the student_id from the session
$student_id = $_SESSION['user_id'];

// Fetch writing task details
try {
    // Updated SQL query to fetch tasks based on task_id, student_id, and status as 'checked'
    $sql = "SELECT id, studentResponse, submitted_at, task_feedback, feedback_given_at 
            FROM writing_tasks 
            WHERE task_type_id = :task_id 
            AND student_id = :student_id 
            AND status = 'checked'";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute(['task_id' => $task_id, 'student_id' => $student_id]);
    $tasks = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    echo 'Query failed: ' . $e->getMessage();
}

?>

<?php include_once('components/top.php'); ?>
<title>Landing Page</title>
<style type="text/css">
    .logout {
        text-align: right;
    }
</style>
</head>
<body>

<h1 class="text-center">Welcome, <?php echo htmlspecialchars($_SESSION['name'], ENT_QUOTES, 'UTF-8'); ?>!</h1>
<p class="text-center">This is your landing page.</p>
<p class="logout"> 
    <a href="logout.php" class="btn btn-danger">
        <i class="fa-solid fa-right-from-bracket"></i> Logout
    </a>
</p>

<div class="central container-fluid">
    <h1 class="text-center">IELTS Writing Tasks Menu</h1>
    <div class="row">
        <div class="col-sm-4">
            <header>
                <nav>
                    <ul>
                        <li><a href="wt1b1.php">Writing Task 1 - Bar Graph 1</a></li>
                        <li><a href="wt1b2.php">Writing Task 1 - Bar Graph 2</a></li>
                        <li><a href="wt1m1.php">Writing Task 1 - Map 1</a></li>
                        <li><a href="wt1m2.php">Writing Task 1 - Map 2</a></li>
                        <li><a href="wt1p1.php">Writing Task 1 - Process Diagram 1</a></li>
                        <li><a href="wt1p2.php">Writing Task 1 - Process Diagram 2</a></li>
                        <li><a href="wt2a1.php">Writing Task 2 - Argument Essay 1</a></li>
                        <li><a href="wt2a2.php">Writing Task 2 - Argument Essay 2</a></li>
                        <li><a href="wt2d1.php">Writing Task 2 - Discussion Essay 1</a></li>
                        <li><a href="wt2d2.php">Writing Task 2 - Discussion Essay 2</a></li>
                        <li><a href="wt2t1.php">Writing Task 2 - Two-Part Question Essay 1</a></li>
                        <li><a href="wt2t2.php">Writing Task 2 - Two-Part Question Essay 2</a></li>
                        <li><a href="wt2ad1.php">WT2Ad1 - Writing Task 2 - Advantage/Disadvantage Essay 1</a></li>
                        <li><a href="wt2ad2.php">WT2Ad2 - Writing Task 2 - Advantage/Disadvantage Essay 2</a></li>
                    </ul>
                </nav>
            </header>
        </div>

        <div class="col-sm-8">
            <div class="container mt-5">
                <h1 class="text-center">Bar Graph/ Pie Chart/ Line Graph-Work 1</h1>
                <form method="POST" action="sendfile.php" enctype="multipart/form-data">
                    <input type="file" name="wt1b1[]" multiple>
                    <br><br>
                    <textarea rows="10" cols="100" name="studentResponse"></textarea>
                    <br><br>
                    <input type="hidden" name="taskTypeId" value="1">
                    <input type="submit" name="subwt1b1">
                </form>

                <!-- Displaying student responses, feedback, and associated photos -->
                <?php if ($tasks): ?>
                    <?php foreach ($tasks as $task): ?>
                        <div class="stdFeedback">
                            <h2>Upload Time</h2>
                            <p><?php echo htmlspecialchars($task['submitted_at'], ENT_QUOTES, 'UTF-8'); ?></p>

                            <h2>Student Response</h2>
                            <p><?php echo htmlspecialchars($task['studentResponse'], ENT_QUOTES, 'UTF-8'); ?></p>

                            <h2>Feedback</h2>
                            <p><?php echo htmlspecialchars($task['task_feedback'], ENT_QUOTES, 'UTF-8'); ?></p>

                            <h2>Feedback Given At</h2>
                            <p><?php echo htmlspecialchars($task['feedback_given_at'], ENT_QUOTES, 'UTF-8'); ?></p>

                            <h2>Uploaded Photos</h2>
                            <?php
                            // Fetch photos related to this specific task (using task id)
                            $sql_photos = "SELECT filename FROM task_photos WHERE writing_tasks_id = :task_id";
                            $stmt_photos = $pdo->prepare($sql_photos);
                            $stmt_photos->execute(['task_id' => $task['id']]);
                            $photos = $stmt_photos->fetchAll(PDO::FETCH_ASSOC);

                            
                            ?>

                            <?php if ($photos): ?>
                                <div class="photo-gallery">
                                    <?php foreach ($photos as $photo): ?>
                                        <div class="photo">
                                            <img src="uploads/<?php echo htmlspecialchars($photo['filename'], ENT_QUOTES, 'UTF-8'); ?>" alt="Task Photo" style="max-width: 100%; height: auto;">
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            <?php else: ?>
                                <p>No photos uploaded for this task.</p>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                <?php else: ?>
                    <p>No tasks found for this instance.</p>
                <?php endif; ?>
            </div>
        </div>
    </div>
</div>

<footer class="text-center">
    <p>&copy; 2024 IELTS Writing Feedback System</p>
</footer>
</body>
</html>

 

and my sendfile.php:
 

<?php 
session_start();

if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit();
}

include('db/dbcon.php'); // Include your database connection

date_default_timezone_set('Asia/Kathmandu'); // Set timezone to Asia/Kathmandu

if (isset($_POST["subwt1b1"])) {
    $taskTypeId = $_POST["taskTypeId"];  // Ensure this is correctly set as an ID
    $sid = $_SESSION['user_id'];
    $Timestamp = date('Y-m-d H:i:s'); // Current timestamp in Asia/Kathmandu timezone
    $student_response = $_POST['studentResponse'];
    $status = "unchecked";

    try {
        // Query to get the highest instance number for this task type and user
        $stmt = $pdo->prepare("SELECT MAX(instance_number) AS max_instance FROM writing_tasks WHERE student_id = :sid AND task_type_id = :task_type");
        $stmt->bindParam(':sid', $sid, PDO::PARAM_INT);
        $stmt->bindParam(':task_type', $taskTypeId, PDO::PARAM_INT);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        // Set the instance number for the new entry
        $instanceNumber = $result['max_instance'] ? $result['max_instance'] + 1 : 1;

        // Insert data into writing_tasks table
        $stmt = $pdo->prepare("INSERT INTO writing_tasks (student_id, task_type_id, studentResponse, status, instance_number, submitted_at) 
                                VALUES (:user_id, :task_type, :student_response, :status, :instance_number, :submitted_at)");
        $stmt->bindParam(':user_id', $sid, PDO::PARAM_INT);
        $stmt->bindParam(':task_type', $taskTypeId, PDO::PARAM_INT);
        $stmt->bindParam(':student_response', $student_response, PDO::PARAM_STR);
        $stmt->bindParam(':status', $status, PDO::PARAM_STR);
        $stmt->bindParam(':instance_number', $instanceNumber, PDO::PARAM_INT);
        $stmt->bindParam(':submitted_at', $Timestamp, PDO::PARAM_STR);
        $stmt->execute();

        // Get the task ID of the inserted row
        $writing_tasks_Id = $pdo->lastInsertId();

        // Handling file uploads
        $allFilesUploaded = true;
        if (isset($_FILES['wt1b1']) && count($_FILES['wt1b1']['name']) > 0) {
            $uploadDirectory = 'uploads/';  // Ensure this directory exists and is writable
            $errors = [];

            // Loop through each file
            foreach ($_FILES['wt1b1']['tmp_name'] as $key => $tmp_name) {
                $fileName = $instanceNumber . '_' . basename($_FILES['wt1b1']['name'][$key]);
                $targetFilePath = $uploadDirectory . $fileName;

                // Check if the file was uploaded without errors
                if (is_uploaded_file($tmp_name)) {
                    // Move the file to the desired directory with the new name
                    if (move_uploaded_file($tmp_name, $targetFilePath)) {
                        // Insert the filename into the database
                        $stmt = $pdo->prepare("INSERT INTO task_photos (writing_tasks_Id, filename, instance_number, task_type_id) 
                                                VALUES (:writing_tasks_Id, :filename, :instance_number, :task_type_id)");
                        $stmt->bindParam(':writing_tasks_Id', $writing_tasks_Id, PDO::PARAM_INT);
                        $stmt->bindParam(':filename', $fileName, PDO::PARAM_STR);
                        $stmt->bindParam(':instance_number', $instanceNumber, PDO::PARAM_INT);
                        $stmt->bindParam(':task_type_id', $taskTypeId, PDO::PARAM_INT);
                        $stmt->execute();
                    } else {
                        $allFilesUploaded = false;
                        $errors[] = "Error uploading $fileName.<br>";
                    }
                } else {
                    $allFilesUploaded = false;
                    $errors[] = "$fileName was not uploaded correctly.<br>";
                }
            }

            // If there were any errors, display them
            if (!empty($errors)) {
                foreach ($errors as $error) {
                    echo $error;
                }
            }

            // If all files are uploaded and both tables updated, show the alert and redirect
            if ($allFilesUploaded && empty($errors)) {
                echo "<script>
                    function showAlertAndRedirect(message, redirectUrl, delay) {
                        alert(message);
                        setTimeout(function() {
                            window.location.href = redirectUrl;
                        }, delay);
                    }
                </script>";
                echo "<script>
                        showAlertAndRedirect('Files uploaded and data updated successfully!', 'landing.php', 2000);
                      </script>";
            }
        } else {
            echo "No files were uploaded.";
        }
    } catch (PDOException $e) {
        echo "Error: " . $e->getMessage();
    }
}
?>




I made this code out of chat gpt, and sometime my students are able to send their files sometimes they are not able to send!, but from my laptop, i am always able to send file. Where should i work and what should i work?
My database:
 

show create TABLE users;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `reset_token` varchar(255) DEFAULT NULL,
  `token_expiry` datetime DEFAULT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

CREATE TABLE `task_photos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `writing_tasks_id` int(11) NOT NULL,
  `filename` varchar(255) NOT NULL,
  `instance_number` int(11) NOT NULL,
  `task_type_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=130 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

CREATE TABLE `writing_tasks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `task_type_id` int(11) NOT NULL,
  `instance_number` int(11) NOT NULL DEFAULT 0,
  `task_feedback` text DEFAULT NULL,
  `submitted_at` timestamp NULL DEFAULT NULL,
  `feedback_given_at` timestamp NULL DEFAULT NULL,
  `studentResponse` text NOT NULL,
  `status` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

 

Link to comment
Share on other sites

if the total size of the form data exceeds the post_max_size setting both the $_POST and $_FILES arrays will be empty. what will your existing code do when there is no $_POST and $_FILES data? the post_max_size setting should be set to a reasonable value that your application expects to deal with for form data.  resist the urge to set it to an extremely large value, since no matter how large you make it, someone can submit data that's larger. the total size of the form data is out of your control. the post method form processing code must first detect if a post method from was submitted, then test for this condition before trying to reference any of the form data. if there is no form data, you should setup and display an error message for the user that the form data was too large and was not processed.

you also need to test the ['error'] element of the uploaded files before referencing any of the file information. there are upload errors where the ['name'] element exists (what the current code is counting), but the file was not successfully uploaded. for upload errors that are under control of the user, you must setup and display a message letting the user know what they did and how to correct the problem. for upload errors that are out of the control of the user, you need to setup and display a general message letting them know that the uploaded file was not processed, and log the actual reason for the failure, so that you (the site owner/developer) will know what is occurring. 

don't query to get the current MAX() value from a database table and increment yourself. when there are concurrent instances of your script running they will all get the same starting value, increment it an use it, resulting in duplicate values. you should instead have and use an autoincrement primary index in the table.

don't run SELECT queries inside of loops (the task_photos query.) use a single appropriate type of JOIN query.

the form processing code and form should be on the same page. this simplifies the code, allows you to display any user/validation errors when you (re)display the form, and lets you repopulate appropriate form field values (type='field' fields cannot be set) with existing data so that the user doesn't need to keep reentering data over and over. the code for any single page should be laid out in this general order -

  1. initialization
  2. post method form processing
  3. get method business logic - get/produce data needed to display the page
  4. html document

the redirect you perform upon successful completion of post method form processing should be to the exact same URL of the current page to cause a get request for that page. this will prevent the browser from trying to resubmit the form data should that page get browsed back to or reloaded.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.