Question

I am having a query problem. (I go into much more detail at the bottom of the post) I have a table of checkboxes. I send the checked boxes to a PHP file on POST to update the db. The only way I could figure out if there was a previously checked box that got unchecked before the POST was to query what should've been checked in the table and if it wasn't sent via POST then it had been unchecked. I decided to handle all this in one query. For some reason, though, it isn't handling the unchecked. If I check one Not previosuly checked then it will stay checked (It will mark it as checked in the db) However, if I uncheck one that was previously checked it will stay checked (I want it to uncheck it).

Here is my code for creating the checkboxes:

echo "<table class='tables' border='1'>";   //start an HTML table

    $fields =array();

    $result = mysqli_query($con, "SELECT u.unit_nickname AS unit, r.id AS reservation,
                                CONCAT(g.fname,' ',g.lname) AS guest, r.arrival, r.departure,
                                r.total_price - COALESCE(p.payment_amt, 0) AS balance,
                                r.checked_in 
                                FROM reservations r
                                JOIN units u ON r.unit = u.id 
                                JOIN guests g ON r.guest = g.id LEFT JOIN
                                (SELECT reservation, SUM(payment_amt) payment_amt
                                FROM payments
                                GROUP BY reservation) AS p
                                ON r.id = p.reservation
                                WHERE r.checked_out = 0");  

    echo '<th></th><th>Unit</th><th>Reservation</th><th>Guest</th><th>Arrival</th>
        <th>Depart</th><th>Balance</th><th>Status</th>';

    while ($row = mysqli_fetch_array($result))
    {       
        $fields[] = $row['unit']; $fields[] = $row['reservation']; $fields[] = $row['guest'];
        $fields[] = $row['arrival']; $fields[] = $row['departure']; $fields[] = $row['balance'];
        $fields[] = $row['checked_in'];

        //rowid == id of table (the row corresponds to the row in the table)
        $rowid = $row['reservation'];

        $count = count($fields);

        echo "<tr class='edit_tr' id='".$rowid."'>";
        echo "<td><input type='checkbox' value='".$fields[1]."' name='checkins[]'"; 
        if ($row['checked_in'] == 1)
            echo "checked='yes'";
        echo "/></td>"; 

        for ($j = 0; $j < $count; $j++)
        {
            echo "<td><span id='".$fields[1]."'>", ($j+1 == $count ? ($fields[$j] == 0 ? "Not Checked In" : "Checked In") : "".$fields[$j]."");
            echo "</span></td>"; 
        }

        echo "</tr>";

        //empty array
        $fields = "";
    }

    echo "</table>";    //close the HTML table

Here is part of my PHP file that it's submitting to:

if(isset($_POST['checkins']))
{
    //open connection
    $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);

    //set POST to array
    $checkins = array();

    //get all checkins that are not checked out
    $query = "SELECT id FROM reservations WHERE checked_in = 1 AND checked_out = 0";
    $result = mysqli_query($con, $query);
    while ($row = mysqli_fetch_assoc($result)) $checkedins[] = $row;

    //create WHERE clause for new checkins
    $where = " WHERE id =";
     foreach ($_POST['checkins'] as $id) {
        $where .= " $id OR id =";
        array_push($checkins, $id);
    }

    //loop through $checkedins[]
    foreach ($checkedins as $id) {
        //if they were checked in before and are now not checked in, add to list
        if (!in_array($id["id"], $checkins))
            $where .= " ".$id['id']." OR id =";
    }

    //remove last 8 characters from WHERE clause
    $where = substr($where, 0, -8);

    echo $query = "UPDATE reservations
                SET checked_in = CASE 
                WHEN checked_in = 0 THEN 1
                WHEN checked_in = 1 THEN 0 END 
                $where";
    mysqli_query($con, $query);
    mysqli_close($con);
}

I have tried to comment well enough to explain what's going on.

The only thing I am seeing as an issue is my query

$query = "UPDATE reservations
                SET checked_in = CASE 
                WHEN checked_in = 0 THEN 1
                WHEN checked_in = 1 THEN 0 END 
                $where";

I am sure it has to do with my CASE statement but I can't seem to pinpoint it no matter how much I tinker it.

What is supposed to be happening is this: I get a list of the new checkins into an array called $checkins and I also get a list of check*ed*ins which is all of those that were checked before the POST into an array called $checkedins. If they are not in the list of $checkins then I add it to $checkins array. So $checkins now contains all the rows to be checked and unchecked. What my query should do is change everything in the array to a 1 that is a 0 and everything that is a 0 to a 1. It is doing the latter. I am asking help for the other half.

Was it helpful?

Solution 2

What I decided to do was split up the queries. I made a $checkin_where string and a $uncheck_where string. I placed the appropriate $ids in each and used two different UPDATE queries:

//create WHERE clause for new checkins
    $checkin_where = " WHERE id =";
    $uncheck_where = " WHERE id =";
     foreach ($_POST['checkins'] as $id) {
        $checkin_where .= " $id OR id =";
        array_push($checkins, $id);
    }

    //loop through $checkedins[]
    foreach ($checkedins as $id) {
        //if they were checked in before and are now not checked in, add to list
        if (!in_array($id["id"], $checkins))
            $uncheck_where .= " ".$id['id']." OR id =";
    }

    //remove last 8 characters from WHERE clause
    $uncheck_where = substr($uncheck_where, 0, -8);
    $checkin_where = substr($checkin_where, 0, -8);

    if (strlen($checkin_where) > 5)
    {
        echo $query = "UPDATE reservations
                    SET checked_in = 1
                    $checkin_where";
        mysqli_query($con, $query);
    }

    if (strlen($uncheck_where) > 5)
    {
        echo $query = "UPDATE reservations
                    SET checked_in = 0
                    $uncheck_where";
        mysqli_query($con, $query);
    }

    mysqli_close($con);

OTHER TIPS

If checked_in is guaranteed to be zero or one, you can use this little trick to avoid the `CASE altogether:

SET checked_in = 1 - checked_in
WHERE ...

Expression 1-x evaluates to 1 when x is 0, and to 0 when x is 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top