In our previous conversation regarding my procedural PHP project, this is your last response:
Certainly! Let's address your requirements step by step.

---

Overview:

- PHP Code (update-profile.php): We'll write a procedural PHP script that handles image upload, saves the file in assets/images/users, and updates the profile_picture column in your user_profile table.

- JavaScript Code (uploadComplete function): We'll modify the JavaScript to handle server responses gracefully, displaying messages on the page instead of using alerts.

- Delete Profile Picture Functionality:
- PHP Code (delete-profile-picture.php): We'll create a script to handle deleting the profile picture from both the file system and the database.
- JavaScript Code: We'll add code to make an AJAX request to the delete script and update the UI accordingly.

---

### 1. PHP Code for Image Upload (update-profile.php):

Here's the PHP script adjusted to your specifications:


<?php
session_start();
include('../config.php'); // Adjust the path as needed

// Check if the user is logged in
if (!isset($_SESSION['user_id'])) {
    echo json_encode(array(
        'status' => 'error', 
        'message' => 'You must be logged in to upload a profile picture.'
    ));
    exit;
}

$user_id = $_SESSION['user_id'];

// Define the target directory
$target_dir = '../assets/images/users/'; // Adjust the path as needed

// Ensure the directory exists
if (!is_dir($target_dir)) {
    mkdir($target_dir, 0755, true);
}

if (isset($_FILES['profilePicture'])) {
    $file = $FILES['profilePicture'];

    // Check for upload errors
    if ($file['error'] === UPLOAD_ERR_OK) {
        // Get file info
        $filename = $file['name'];
        $fileTmpName = $file['tmp_name'];
        $fileSize = $file['size'];
        $fileType = $file['type'];

        // Allowed file extensions and MIME types
        $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
        $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp'];

        // Get the file extension
        $fileExt = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

        // Validate file extension and MIME type
        if (in_array($fileExt, $allowedExtensions) && in_array($fileType, $allowedMimeTypes)) {
            // Check file size (limit to 5MB)
            $maxFileSize = 5 * 1024 * 1024; // 5MB

            if ($fileSize <= $maxFileSize) {

                // Generate new filename
                $newFilename = 'user' . $user_id . '_profile.' . $fileExt;

                // Target file path
                $target_file = $target_dir . $newFilename;

                // Move uploaded file to target directory
                if (move_uploaded_file($fileTmpName, $target_file)) {

                    // Update the user's profile picture in the database
                    // Assuming 'user_profile' table and 'profile_picture' column
                    // Also assuming that the path stored is relative to the project root

                    $profile_picture_url = 'assets/images/users/' . $newFilename; // Adjust if needed

                    // Use prepared statements to prevent SQL injection
                    $query = "UPDATE user_profile SET profile_picture = ? WHERE user_id = ?";
                    $stmt = mysqli_prepare($conn, $query);
                    mysqli_stmt_bind_param($stmt, 'si', $profile_picture_url, $user_id);

                    if (mysqli_stmt_execute($stmt)) {
                        // Return success response with the new profile picture URL
                        echo json_encode(array(
                            'status' => 'success', 
                            'message' => 'Profile image uploaded successfully.', 
                            'profile_picture' => $profile_picture_url
                        ));
                    } else {
                        // Database update failed
                        echo json_encode(array(
                            'status' => 'error', 
                            'message' => 'Failed to update profile picture in database.'
                        ));
                    }

                } else {
                    // Failed to move uploaded file
                    echo json_encode(array(
                        'status' => 'error', 
                        'message' => 'Failed to move the uploaded file.'
                    ));
                }
            } else {
                echo json_encode(array(
                    'status' => 'error', 
                    'message' => 'File size exceeds the limit of 5MB.'
                ));
            }
        } else {
            echo json_encode(array(
                'status' => 'error', 
                'message' => 'Invalid file type. Only JPG, JPEG, PNG, GIF, BMP files are allowed.'
            ));
        }
    } else {
        // Handle upload errors
        $uploadError = $file['error'];
        $errorMessage = '';

        switch ($uploadError) {
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                $errorMessage = 'File size exceeds the allowed limit.';
                break;
            case UPLOAD_ERR_PARTIAL:
                $errorMessage = 'File upload was not completed.';
                break;
            case UPLOAD_ERR_NO_FILE:
                $errorMessage = 'No file was uploaded.';
                break;
            default:
                $errorMessage = 'An error occurred during file upload.';
                break;
        }
        echo json_encode(array(
            'status' => 'error', 
            'message' => $errorMessage
        ));
    }
} else {
    echo json_encode(array(
        'status' => 'error', 
        'message' => 'No file uploaded.'
    ));
}
?>


Explanation:

- Database Connection: Included via include('../config.php');. Adjust the path based on your folder structure.

- Session Check: Ensures the user is logged in by checking $_SESSION['user_id'].

- File Handling:
- Validates the uploaded file for errors, type, and size.
- Moves the uploaded file to assets/images/users/ directory.
- Generates a unique filename based on user ID.

- Database Update:
- Updates the profile_picture column in the user_profile table with the new file path.
- Uses prepared statements to prevent SQL injection.

- Response:
- Returns a JSON response with status, message, and profile_picture (on success).

---

### 2. JavaScript Code (uploadComplete Function):

We'll modify your JavaScript code to handle the server's JSON response and display messages on the page.

Add a Message Display Element in HTML:

In your HTML, add a &lt;div&gt; to display messages:

<div id="profileMessage" class="alert d-none mt-2"></div>


Updated JavaScript Code:

function uploadComplete(evt) {
    var response = JSON.parse(evt.target.responseText);

    var messageDiv = document.getElementById('profileMessage');
    messageDiv.classList.remove('d-none');
    if (response.status === 'success') {
        // Update the profile image src
        document.getElementById('profileImage').src = response.profile_picture;

        // Display success message
        messageDiv.classList.remove('alert-danger');
        messageDiv.classList.add('alert-success');
        messageDiv.innerHTML = response.message;
    } else {
        // Display error message
        messageDiv.classList.remove('alert-success');
        messageDiv.classList.add('alert-danger');
        messageDiv.innerHTML = response.message;
    }

    // Hide the progress bar
    document.getElementById("profileProgress").classList.add("d-none");
}

function uploadFailed(evt) {
    var messageDiv = document.getElementById('profileMessage');
    messageDiv.classList.remove('d-none');
    messageDiv.classList.remove('alert-success');
    messageDiv.classList.add('alert-danger');
    messageDiv.innerHTML = "There was an error attempting to upload the file.";
    document.getElementById("profileProgress").classList.add("d-none");
}

function uploadCanceled(evt) {
    var messageDiv = document.getElementById('profileMessage');
    messageDiv.classList.remove('d-none');
    messageDiv.classList.remove('alert-success');
    messageDiv.classList.add('alert-danger');
    messageDiv.innerHTML = "The upload has been canceled by the user or the browser dropped the connection.";
    document.getElementById("profileProgress").classList.add("d-none");
}


Modify fileSelected Function to Call updateProfile:

At the end of your fileSelected function, call updateProfile() to initiate the upload after previewing the image.

function fileSelected() {
    var file = document.getElementById('profilePicture').files[0];
    var messageDiv = document.getElementById('profileMessage');

    if (file) {
        var filename = file.name;
        var fileType = /(.jpg|.jpeg|.bmp|.gif|.png)$/i;
        if (!fileType.exec(filename)) {
            // Display error message
            messageDiv.classList.remove('d-none');
            messageDiv.classList.remove('alert-success');
            messageDiv.classList.add('alert-danger');
            messageDiv.innerHTML = "Please select a valid image file!";
            document.getElementById('profilePicture').value = '';
            return false;
        } else {
            // Clear previous messages
            messageDiv.classList.add('d-none');
            messageDiv.innerHTML = '';

            // Display file details
            var fileSize;
            if (file.size > 1024 * 1024) {
                fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
            } else {
                fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
            }
            document.getElementById('fileName').innerHTML = '<b>Name:</b> ' + filename;
            document.getElementById('fileSize').innerHTML = '<b>Size:</b> ' + fileSize;
            document.getElementById('fileType').innerHTML = '<b>Type:</b> ' + file.type;

            var reader = new FileReader();
            reader.onload = function(e) {
                document.getElementById('profileImage').src = e.target.result;
            };

            reader.readAsDataURL(file);

            // After preview, upload the file
            updateProfile();
        }
    }
}


Explanation:

- Message Display: Instead of alert, we display the messages inside the profileMessage div.
- Error Handling: Provides feedback for invalid file types directly on the page.
- Auto Upload: Calls updateProfile() to upload the image after it's selected and previewed.

---

### 3. Delete Profile Picture Functionality:

#### PHP Code (delete-profile-picture.php):

<?php
session_start();
include('../config.php'); // Adjust the path as needed

// Check if the user is logged in
if (!isset($_SESSION['user_id'])) {
    echo json_encode(array(
        'status' => 'error', 
        'message' => 'You must be logged in to delete your profile picture.'
    ));
    exit;
}

$user_id = $_SESSION['user_id'];

// Get the current profile picture file path from the database
$query = "SELECT profile_picture FROM user_profile WHERE user_id = ?";
$stmt = mysqli_prepare($conn, $query);
mysqli_stmt_bind_param($stmt, 'i', $user_id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $profile_picture);
mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt);

if ($profile_picture && file_exists('../' . $profile_picture)) {
    // Delete the file
    if (unlink('../' . $profile_picture)) {
        // Update the database, set profile_picture to NULL or empty string
        $updateQuery = "UPDATE user_profile SET profile_picture = '' WHERE user_id = ?";
        $updateStmt = mysqli_prepare($conn, $updateQuery);
        mysqli_stmt_bind_param($updateStmt, 'i', $user_id);

        if (mysqli_stmt_execute($updateStmt)) {
            // Return success response
            echo json_encode(array(
                'status' => 'success', 
                'message' => 'Profile picture deleted successfully.', 
                'default_picture' => 'assets/images/users/default.jpg'
            ));
        } else {
            // Database update failed
            echo json_encode(array(
                'status' => 'error', 
                'message' => 'Failed to update profile picture in database.'
            ));
        }
        mysqli_stmt_close($updateStmt);
    } else {
        echo json_encode(array(
            'status' => 'error', 
            'message' => 'Failed to delete profile picture file.'
        ));
    }
} else {
    // File does not exist or profile_picture is empty
    // Update the database, set profile_picture to NULL or empty string
    $updateQuery = "UPDATE user_profile SET profile_picture = '' WHERE user_id = ?";
    $updateStmt = mysqli_prepare($conn, $updateQuery);
    mysqli_stmt_bind_param($updateStmt, 'i', $user_id);

    if (mysqli_stmt_execute($updateStmt)) {
        // Return success response
        echo json_encode(array(
            'status' => 'success', 
            'message' => 'Profile picture deleted successfully.', 
            'default_picture' => 'assets/images/users/default.jpg'
        ));
    } else {
        // Database update failed
        echo json_encode(array(
            'status' => 'error', 
            'message' => 'Failed to update profile picture in database.'
        ));
    }
    mysqli_stmt_close($updateStmt);
}
?>


Explanation:

- File Deletion:
- Checks if the profile picture exists.
- Deletes the file from the server.
- Database Update:
- Sets the profile_picture column to an empty string in the database.
- Response:
- Returns a JSON response with status, message, and default_picture (the path to the default image).

#### JavaScript Code for Deleting Profile Picture:

Add this code to handle the delete button click event:

var deleteProfilePictureBtn = document.getElementById('deleteProfilePicture');
deleteProfilePictureBtn.addEventListener("click", function() {
    // Send AJAX request to delete-profile-picture.php
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "ajax/delete-profile-picture.php", true); // Adjust the path as needed
    xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            var response = JSON.parse(xhr.responseText);

            var messageDiv = document.getElementById('profileMessage');
            messageDiv.classList.remove('d-none');
            if (response.status === 'success') {
                // Reset the profile image to default picture
                document.getElementById('profileImage').src = response.default_picture;

                // Clear file input and other fields
                document.getElementById('profilePicture').value = "";
                document.getElementById('fileName').innerHTML = "";
                document.getElementById('fileSize').innerHTML = "";
                document.getElementById('fileType').innerHTML = "";

                // Display success message
                messageDiv.classList.remove('alert-danger');
                messageDiv.classList.add('alert-success');
                messageDiv.innerHTML = response.message;
            } else {
                // Display error message
                messageDiv.classList.remove('alert-success');
                messageDiv.classList.add('alert-danger');
                messageDiv.innerHTML = response.message;
            }
        }
    };

    xhr.send(); // No data to send
});


Explanation:

- AJAX Request: Sends a POST request to delete-profile-picture.php.
- Response Handling:
- Parses the JSON response.
- Updates the profile image to the default picture.
- Displays a success or error message on the page.

---

### Adjustments to Your HTML:

Display Correct Profile Picture on Page Load:

Ensure your HTML displays the correct profile picture based on whether a user has set one or not.

<?php
// Assume $conn is your database connection from config.php
session_start();
include('config.php');

$user_id = $_SESSION['user_id'];

// Fetch the user's profile picture from the database
$query = "SELECT profile_picture FROM user_profile WHERE user_id = ?";
$stmt = mysqli_prepare($conn, $query);
mysqli_stmt_bind_param($stmt, 'i', $user_id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $profile_picture);
mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt);

// Set the profile image path
if ($profile_picture && file_exists($profile_picture)) {
    $profile_image_src = $profile_picture;
} else {
    $profile_image_src = 'assets/images/users/default.jpg';
}
?>
<!-- Your HTML -->
<img id="profileImage" src="<?php echo $profile_image_src; ?>" class="flex-shrink-0 avatar-lg img-thumbnail" alt="Profile">


Explanation:

- Fetches the current profile picture from the database.
- Sets the image source to either the user's profile picture or the default image.

---

### Final Notes:

- File Paths: Ensure that all file paths are correctly set based on your directory structure. Adjust ../ in the PHP scripts if necessary.

- Security Considerations:
- Validate and sanitize all user inputs.
- Protect your scripts from unauthorized access.
- Ensure that the delete operation only affects files uploaded by the user.

- Feedback to User: By displaying messages on the page, users have a better experience and can see the result of their actions without disruptive alerts.

---

I hope this helps you implement the desired functionality in your project. Let me know if you have any questions or need further assistance!