1

I have 2 SQL query's,

  1. The first query fetches the device details
  2. The second query uses the device name from the first query to fetch the status of that device (To see if that device is booked or not).

The output of the 2nd query is supposed to be displayed on the 'fullcalendar' plugin.

fetch_data.php

<?php

//fetch_data.php

include('database.php');



function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);      
    return $data;
}



if(isset($_POST["btnValue"]))
{    
    $btnValue = test_input($_POST["btnValue"]);

    if ($btnValue == "UE") {

        $query = "
            SELECT * FROM UE WHERE Device_Type = '$btnValue'
        ";
        }
    if ($btnValue == "Server"){

            $query = "
                SELECT * FROM Servers WHERE Device_Type = '$btnValue'
            ";

    }
    if ($btnValue == "Test-Tool"){

       $query = "
           SELECT * FROM TestTools WHERE Device_Type = '$btnValue'
       ";
    }               

    $statement = $db_conn->prepare($query);
    $statement->execute();
    $result = $statement->fetchAll();
    $total_row = $statement->rowCount();    
    $output = '';
    $i = 0;
    if($total_row > 0)
    {
        
        foreach($result as $row)
        {
            $deviceName = $row['Device_Name'];
            $output .= '
            <div class="row">
                <div style="border:1px solid #ccc; border-radius:5px; padding:16px; margin-bottom:16px; float: left; width: 50%; height:200px;background-color:#FFFFFF;">
                    <img src="images/'. $row['Device_Image'] .'" alt="" class="img-responsive" style="height: 50px;" >
                    <p align="left"><strong><a href="#">'. $row['Device_Name'] .'</a></strong></p>                  
                    <p style="color:#000000">Capablity : '. $row['Device_Capability'].' <br />
                    Brand : '. $row['Device_Brand'] .' <br />
                    Model : '. $row['Device_Model'] .'<br />
                    Device Type : '. $row['Device_Type'] .' </p>
                    
                </div>
                <div id="calendar" style="border:1px solid #ccc; border-radius:5px; padding:16px; margin-bottom:16px; float: left; width: 50%; height:200px;background-color:#FFFFFF;"> 
                echo "Helo";             
            
                 '.$deviceName .' 
                 
                
            
                </div>

                
            </div>
            '           
            ;   
            
            
        }   

        if(!empty($_GET['type']) && $_GET['type'] == 'list'){
            // Prepare and execute query
                $sql = "SELECT * FROM Booking WHERE Equipment= '.$deviceName .' Status = 'Approved' ";//Loading events for the calendar
        
                $statement = $db_conn->prepare($sql);
                $statement->execute();
                $result = $statement->fetchAll();
                $total_row = $statement->rowCount();            
                if($total_row > 0)
                {
                    
                    foreach($result as $row)
                    {
                        $eventArray[] = $row;
        
                    }
                }
                echo json_encode($eventArray);   
            }
        
    }else
        {
            $output = '<h3>No Data Found</h3>';
        }
        
        echo $output;

index.php

<!DOCTYPE html>
<html>
<head>

<title> FullCalendar</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"/>
<script src='js/index.global.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>  
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

<meta charset='utf-8' />


<style>

  body {
    margin: 40px 10px;
    padding: 0;
    font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
    font-size: 14px;
  }

#calendar {
    width: 350px;
    height: 250px;
    margin: 0 auto;
    font-size: 10px;
}
.fc-header-title h2 {
    font-size: .9em;
    white-space: normal !important;
}
.fc-view-month .fc-event, .fc-view-agendaWeek .fc-event {
    font-size: 0;
    overflow: hidden;
    height: 2px;
}
.fc-view-agendaWeek .fc-event-vert {
    font-size: 0;
    overflow: hidden;
    width: 2px !important;
}
.fc-agenda-axis {
    width: 20px !important;
    font-size: .7em;
}

.fc-button-content {
    padding: 0;
}
</style>
</head>
<body>
<div class="col-md-9">
                <br />
                <div class="row filter_data">

                  <div id="calendar" style="border:1px solid #ccc; border-radius:5px; padding:16px; margin-bottom:16px; float: left; width: 50%; height:200px;background-color:#FFFFFF;">                
                
            
                  </div>

                

                </div>
                
            </div> 
</body>
</html>

<script>
$(document).ready(function(){

    filter_data();

    function filter_data()
    {
        $('.filter_data').html('<div id="loading" style="" ></div>');
        var action = 'fetch_data';                
        var brand = get_filter('brand');
        var ram = get_filter('ram');
        var storage = get_filter('storage');       
        $.ajax({
            url:"fetch_data.php",
            method:"POST",
            data:{action:action, brand:brand, ram:ram, storage:storage},
            success:function(data){
                $('.filter_data').html(data);
            }
        });
    }

    function get_filter(class_name)
    {
        var filter = [];
        $('.'+class_name+':checked').each(function(){
            filter.push($(this).val());
        });       

        return filter;
    }  

    $('.common_selector').click(function(){
        filter_data();
    });   
   
    
    let btn = document.getElementById("btn");
    
     // Adding event listener to button
    btn.addEventListener("click", () => {
 
    // Fetching Button value
    let btnValue = btn.value;
 
    // jQuery Ajax Post Request
    $.post('fetch_data.php', {
        btnValue: btnValue
    }, function(response) {
        // response from PHP back-end
       // console.log(response);
        //alert(response) 
        $('.filter_data').html(response);     
        
    });
    
});  

let btn1 = document.getElementById("btn1");
    
     // Adding event listener to button
    btn1.addEventListener("click", () => {
 
    // Fetching Button value
    let btnValue = btn1.value;
 
    // jQuery Ajax Post Request
    $.post('fetch_data.php', {
        btnValue: btnValue
    }, function(response) {
        // response from PHP back-end
       // console.log(response);
        //alert(response) 
        $('.filter_data').html(response);     
        
    });
    
});

let btn2 = document.getElementById("btn2");
    
     // Adding event listener to button
    btn2.addEventListener("click", () => {
 
    // Fetching Button value
    let btnValue = btn2.value;
 
    // jQuery Ajax Post Request
    $.post('fetch_data.php', {
        btnValue: btnValue
    }, function(response) {
        // response from PHP back-end
       // console.log(response);
        //alert(response) 
        $('.filter_data').html(response);     
        
    });
    
});

let btn3 = document.getElementById("btn3");
    
     // Adding event listener to button
    btn3.addEventListener("click", () => {
 
    // Fetching Button value
    let btnValue = btn3.value;
 
    // jQuery Ajax Post Request
    $.post('fetch_data.php', {
        btnValue: btnValue
    }, function(response) {
        // response from PHP back-end
       // console.log(response);
        //alert(response) 
        $('.filter_data').html(response);     
        
    });
    
});

let btn4 = document.getElementById("btn4");
    
     // Adding event listener to button
    btn4.addEventListener("click", () => {
 
    // Fetching Button value
    let btnValue = btn4.value;
 
    // jQuery Ajax Post Request
    $.post('fetch_data.php', {
        btnValue: btnValue
    }, function(response) {
        // response from PHP back-end
       // console.log(response);
        //alert(response) 
        $('.filter_data').html(response);     
        
    });
    
});


$('#submit').click(function(){  
           $('#submit').prop('disabled', true);            
           var email = $('#email').val();
           var psw = $('#psw').val();           
            
           if(email == '' || psw == '' )  
           {  
                $('#response').html('<span class="text-danger">All Fields are required</span>')  
                $('#submit').prop('disabled', false);  
           }  
           else  
           {  
                $.post(  
                     'adminLogin.php',  
                     $('#bookingForm').serialize(),  
                     function(data)
                     {  
                          //alert(data);
                          $('form').trigger("reset");                                                                            
                          //$(".modal-body").html(data);                                                                            
                          $('#submit').prop("disabled", false); 
                          //$('#empModal').modal('show');  
                          window.location.href = 'AdminPanel.php';                                               
                           
                     }
                ); 
                
           }  
      }); 

      function getEvent(){
      var events = new Array();
        $.ajax({
          type : "POST",
          url : "fetch-test.php?type=list",
          dataType : "json",
          success : function(data) {
              var result = data;

              $.each(result, function(i, item){
                events.push({
                  event_id : result[i].id,
                  title : result[i].Equipment,
                  start : result[i].StartDate,
                  end : result[i].EndDate                   

                })

              })
              var calendarEl = document.getElementById('calendar');

              var calendar = new FullCalendar.Calendar(calendarEl, {
              headerToolbar: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
              },
              initialDate: new Date(),
              navLinks: true, // can click day/week names to navigate views
              businessHours: true, // display business hours
              editable: true,
              selectable: true,
              weekNumbers: true,
              fixedWeekCount: false,
              aspectRatio: "3",
              events: events
           });

               calendar.render();

          }
        })
    }

    getEvent()

      
      

  
});

</script>

enter image description here

I expected the fullcalendar to display in the right div beside the device information on the left. Each device would have its own unique status displayed within the fullcalendar.

Shadow
  • 33,525
  • 10
  • 51
  • 64
CMorrin
  • 21
  • 2
  • Do you have any console errors? I don't see where you actually import the fullCalendar JS file into your page? Also you are creating multiple elements with the ID "calendar" and then trying to put a calendar into each of them. But how do you expect JS can tell them apart when they all have the same ID? An ID must, by definition, be unique! – ADyson Jun 23 '23 at 10:58
  • 1
    **Warning:** Your code is vulnerable to SQL Injection attacks. You should use prepared statements **with parameters** to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / PDO. **Never** insert unparameterised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. – ADyson Jun 23 '23 at 10:59
  • 1
    https://phpdelusions.net/pdo also contains good examples of writing safe SQL using PDO. See also: [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) . Parameterising your queries will also greatly reduce the risk of accidental syntax errors as a result of un-escaped or incorrectly quoted input values. If you learnt your current technique from a tutorial or book, please don't use that resource again. – ADyson Jun 23 '23 at 10:59
  • `initialDate: new Date()` is redundant, this is the default value (as per the docs) – ADyson Jun 23 '23 at 11:00
  • 1
    Why do you fetch the events and then initialise the calendar with a static event array? That's backwards. FullCalendar supports fully dynamic event feeds so you can download only what you need for the current display. Take a look at your options in https://fullcalendar.io/docs/event-source – ADyson Jun 23 '23 at 11:01
  • 1
    `function test_input`...needs to be deleted entirely. Not sure where you got this junk from but it doesn't test anything, all it does is add the potential for the code to unnecessarily mangle and corrupt your data without doing anything actually useful. What do you think it's supposed to be for? I would be interested to know why you used it. It certainly doesn't help to prevent SQL injection, if that's what you were thinking (see earlier comments also). – ADyson Jun 23 '23 at 11:02
  • @ADyson I don't have any errors form the console. I can see the response from the fetch_data.php which contains the details of the unique device. But we do not see the response from the Json to display in the fullcalendar. The import for the fullcalendar is at the top of the index.php page. – CMorrin Jun 23 '23 at 14:34
  • @ADyson I will take your SQL Advice too! Thanks. – CMorrin Jun 23 '23 at 14:36
  • @ADyson This test_input has functions that sanitize the inputs. $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); – CMorrin Jun 23 '23 at 14:39
  • 1
    As ADyson has already said, remove that `test_input` function completely. The only thing it does is give you a false sense of security. You are already using prepared statements but you are not parameterising them. When looping over the results you have `
    – user1191247 Jun 23 '23 at 15:30
  • 1
    `sanitize the inputs`...sanitise against what?? What do you think it's protecting against, precisely? You can't "sanitise" something unless you know what you're defending against, which it seems you don't. The only thing you use the variable returned from it for after you've "sanitised" it is to put it into a SQL query, and as already mentioned, it does nothing to protect against SQL injection. In some cases, the function could actively change the input data by removing or altering some of the characters, which is not a good or useful thing. It's complete nonsense, please delete it. – ADyson Jun 23 '23 at 15:51
  • @user1191247 I tried to remove one of the div id but, it still does not show. – CMorrin Jun 23 '23 at 16:03
  • 1
    You need to do more than just remove the IDs, as was mentioned in user1191247's comment. Use a different selector instead, to find all the calendar elements and loop through them. But your entire code seems to be based on the premise that there's only going to be one row of data. You seem to fetch the same event list for the calendar every time, too, there is no variation in the front-end based on what the product is. In fact the SQL will fail because your AJAX request doesn't send the device name in the request, only the type. The whole logic of your PHP backend code needs a rewrite – ADyson Jun 23 '23 at 16:09

0 Answers0