Search code examples
phpcodeigniter-3

working on hotel reservation system and I get stuck on check avaibility room


there is my db structure:

  1. Rooms: roomId-roomName-roomCapacity
  2. Reservation: rsId-rsroomId-date_in-date_out

I want to create a search function for searching available rooms. I can't get the ones which are available, which are not booked for those days. I have tried lots of things but till now can't solve this issue. There is my latest code:

function search ($name, $date_in, $date_out) {
    $this->db->select('*')->from('Rooms');
    $this->db->join('Reservation', 'rooms.roomid = reservation.rsroomId', 'LEFT');
    $this->db->like('date_in', $date_in);
    $this->db->like('date_out', $date_out);
    $this->db->like('roomName', $name);
    return $this->db->get()->result_array();
}

Thank You


Solution

  • I am not very familiar with the CodeIgniter way to build a query, but I understand what you want to achieve. The raw query would look something like this:

    SELECT  Rooms.*
    FROM    Rooms
            LEFT JOIN Reservation
                ON Rooms.roomId = Reservation.rsroomId
                    AND date_in < '$date_out' AND date_out > '$date_in'
    WHERE   rsId IS NULL;
    

    To select all overlapping reservations in the JOIN ON condition, you must compare the date_in of existing reservations with the $date_out of the desired reservation, and vice versa. If an existing reservation checks out before you want to check in, it does not overlap. If an existing reservation checks in after you want to check out, it does not overlap.

    After carefully crafting these JOIN ON conditions to get the overlapping reservations, the WHERE rsId IS NULL condition ensures that you get only rooms for which there is no such existing overlapping reservation.

    That last part is easy in CodeIgniter, but getting all the three JOIN ON conditions into $this->db->join() is going to be messy. The like() and where() functions automatically escape your values, but here you need to add this protection against SQL injection manually. Perhaps something like this:

    function search ($date_in, $date_out) {
        // Ensuring these values are safe in raw SQL:
        $date_in = $this->db->escape($date_in);
        $date_out = $this->db->escape($date_out);
        
        $joinCondition = 'rooms.roomid = reservation.rsroomId';
        $joinCondition .= " AND date_in < $date_out AND date_out > $date_in";
        
        $this->db->select('*')->from('Rooms');
        $this->db->join('Reservation', $joinCondition, 'LEFT');
        $this->db->where('rsId', NULL);
        return $this->db->get()->result_array();
    }
    

    An alternative is to put question marks in the raw query, so CodeIgniter can escape your values via query bindings:

    function search ($date_in, $date_out) {
        $sql = "SELECT  Rooms.*
                FROM    Rooms
                        LEFT JOIN Reservation
                            ON Rooms.roomId = Reservation.rsroomId
                                AND date_in < ? AND date_out > ?
                WHERE   rsId IS NULL";
        $binds = [$date_out, $date_in];
        return $this->db->query($sql, $binds)->result_array();
    }