skip to Main Content

I have a simple PHP app for expense records approval.
When a user submits a record this record should be approved by different roles coming from table 'users' for example, the record should be approved by ‘Manager’, ‘Finance’, ‘ccOapprover’ and ‘observer’, all those are roles for different users in a column.
What I want is to have some users with more than one role for example JohnDoe to be ‘ccapprover’ and ‘observer’.
My idea was to separate those via commas for the specific user like 'ccapprover, observer' and to use explode in PHP but something is wrong with my code.

Here is my process_approval.php

include 'session.php';
include 'config.php';


if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $reportId = $_POST['report_id'];
    $approval = $_POST['approval'];
    $allowedRoles = ['manager', 'finance', 'ccapprover', 'observer'];
    if (in_array($user_type, $allowedRoles)) {
        
        $approvedRoles = explode(', ', $user_type);

        $approverColumn = '';
        $statusColumn = '';
        $dateColumn = '';

        foreach ($approvedRoles as $approvedRole) {
            switch ($approvedRole) {
                case 'manager':
                    $approverColumn = 'mng_approver';
                    $statusColumn = 'mng_approver_status';
                    $dateColumn = 'mng_approval_date';
                    break;
                case 'finance':
                    $approverColumn = 'finance_approval';
                    $statusColumn = 'finance_approval_status';
                    $dateColumn = 'finance_approval_date';
                    break;
                case 'ccapprover':
                    $approverColumn = 'cc_approver';
                    $statusColumn = 'cc_approver_status';
                    $dateColumn = 'cc_approval_date';
                    break;
                case 'observer':
                    $approverColumn = 'observer';
                    $statusColumn = 'observer_status';
                    $dateColumn = 'observer_approval_date';
                    break;
            }

            if (!empty($approverColumn)) {
                
                $updateQuery = "UPDATE expenses SET $approverColumn = :email, $statusColumn = :status, $dateColumn = NOW() WHERE id = :report_id";

                try {
                    $stmt = $pdo->prepare($updateQuery);
                    $stmt->bindParam(':email', $email);
                    $stmt->bindParam(':status', $approval);
                    $stmt->bindParam(':report_id', $reportId);
                    $stmt->execute();
                    echo "Approval/Rejection recorded successfully for role: $approvedRole<br>";
                } catch (PDOException $e) {
                    echo "Error recording approval/rejection: " . $e->getMessage();
                }
            } else {
                echo "Invalid approver role: $approvedRole<br>";
            }
        }
    } else {
        
        echo "Unauthorized access.";
    }
} else {
    echo "No POST data received.";
}

When I set it to some user 'ccapprover, observer' he is not able to approve both and always getting Unauthorized access

Where is my mistake?

Edit: In session.php I am sorting variable
$user_type = $_SESSION['type']; which is getting type from db

2

Answers


  1. It is hard to tell what is wrong, because we do not know where $user_type is coming from. Nevertheless I can still already answer that those three lines of code seem to be wrong:

       $allowedRoles = ['manager', 'finance', 'ccapprover', 'observer'];
       if (in_array($user_type, $allowedRoles)) {
            
            $approvedRoles = explode(', ', $user_type);
    

    If you use explode like this on $user_type, it has to be a string, potentially containing , like your example 'ccapprover, observer'. If $user_type looks like this, your if clause will always evaluate to false, since that string is not in the array $allowedRoles. Therefor you always land in the else branch giving you the described error.

    You would have to explode the string before the if clause and change your logic starting from there.

    Login or Signup to reply.
  2. I agree with the comments about database design mentioned above. However, to fix your immediate problem you could change the following code:

    $allowedRoles = ['manager', 'finance', 'ccapprover', 'observer'];
    if (in_array($user_type, $allowedRoles)) {
        
        $approvedRoles = explode(', ', $user_type);
    
        // ...
    

    to:

    $allowedRoles = ['manager', 'finance', 'ccapprover', 'observer'];
    $userRoles = explode(', ', $user_type);
    $approvedRoles = array_interesect($allowedRoles, $userRoles);
    if (!empty($approvedRoles)) {
        
        // ...
    

    This should answer your question. But I echo the concerns others have raised – this approach is going to cause you more problems in the long term.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search