1

I am hoping I am overlooking something simple, and that I have not written this in such a crazy and convoluted way that I cannot achieve what I am going after.

I apologize for the giant mess of PHP mixed in with HTML. My plan is to separate what I can after I can get things working. This is my third app to write, so I am still learning basics, probably writing spaghetti code. Here is the query I am using, which will change depending on what the results of another query are further up the code.

I want to see if dates that are chosen and sent to this page with $_POST are already in the user's shopping cart aka itinerary.

<?php foreach($unique as $ukey => $uval) : ?>
<?php
// regular query to search for all room bookings
  try {
    $sqlSlctAll = "SELECT * FROM dates_booked 
                   INNER JOIN rooms
                   WHERE rooms.id = dates_booked.room_num
                   AND rooms.name = '$uval'
                   GROUP BY rooms.id
                   ";
                   // using group by here will not return all booked days
    $slctStmtAll = $dsn->prepare($sqlSlctAll);
    $slctStmtAll->execute();
    $allResults = $slctStmtAll->fetchAll(PDO::FETCH_ASSOC);
    foreach ($allResults as $allrow) {
      $uValArray[] = [
        'id' => $allrow['id'],
        'name' => $allrow['name'],
        'price' => $allrow['price'],
        'dateStart' => $allrow['dateStart'],
        'dateEnd' => $allrow['dateEnd']
      ];
    }
    // header('Content-type: application/json');
  } catch (PDOException $e) {
    echo 'Error selecting dates: ' . $e->getMessage();
  }
?>

Here's where it starts getting confusing for me. What is happening is if there is only one item in my $_SESSION['shopping_cart'], the table I am trying to create is just fine. For every item after that I add to the cart, it first compares first to see if the date range is one already in the session array, then if the shopping cart 'id' matches the id of the room in the database. So for the first iteration, it may return true or false, then in the next iteration it is returning the opposite, and adding an extra <td> in my table.

  <table class="table table-bordered">
    <thead>
      <tr>
        <th>Room Name</th>
        <th>Price Per Night</th>
        <th>Room ID</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <?php foreach ($uValArray as $aRoom) : ?>
  <form action="cart.php?id=<?php echo $aRoom['id']; ?>" method="post">
      <tr>
      <td><?php echo $aRoom['name']; ?></td>
      <td>$<?php echo $aRoom['price']; ?></td>
      <td><?php echo $aRoom['id']; ?></td>
      <?php 
      if(isset($_SESSION['shopping_cart'])) {
        foreach ($_SESSION['shopping_cart'] as $cart) {
          if(
            $chooseStart < $cart['dateEnd'] && 
            $cart['dateStart'] < $chooseEnd && 
            $aRoom['id'] == $cart['id']
            ) {
            echo '<td><a href="cart.php">in your itinerary</a></td>';
          } else {
            echo '<td><input class="btn btn-success" type="submit" name="book_now" value="Book Now"></td>';
          }
        }
      } else {
        echo '<td><input class="btn btn-success" type="submit" name="book_now" value="Book Now"></td>';
      }
      ?>
      <input type="hidden" name="dateStart" value="<?php echo $chooseStart; ?>"> 
      <input type="hidden" name="dateEnd" value="<?php echo $chooseEnd; ?>"> 
      <input type="hidden" name="name" value="<?php echo $aRoom['name']; ?>"> 
      <input type="hidden" name="price" value="<?php echo $aRoom['price']; ?>">
      <input type="hidden" name="room_quantity" value="1">
  </form>
      <?php endforeach; ?>
    </tbody>
  </table>

<?php } ?>

If I have two items in my shopping cart, I get this for my 'availability-search page:

available rooms with 2 items in shopping cart

I am super stumped, because I want to compare the $aRoom['id'] items to the $cart['id'] but I can't figure out how to do it without looping through the cart. I'm not sure if that even makes any sense.

If I take out the echo '<td>' in the else statement after the comparison, it ultimately gives me the table structure I am going for, minus the actual 'book_now' input that I need.

  <table class="table table-bordered">
    <thead>
      <tr>
        <th>Room Name</th>
        <th>Price Per Night</th>
        <th>Room ID</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <?php foreach ($uValArray as $aRoom) : ?>
  <form action="cart.php?id=<?php echo $aRoom['id']; ?>" method="post">
      <tr>
      <td><?php echo $aRoom['name']; ?></td>
      <td>$<?php echo $aRoom['price']; ?></td>
      <td><?php echo $aRoom['id']; ?></td>
      <?php 
      if(isset($_SESSION['shopping_cart'])) {
        foreach ($_SESSION['shopping_cart'] as $cart) {
          if(
            $chooseStart < $cart['dateEnd'] && 
            $cart['dateStart'] < $chooseEnd && 
            $aRoom['id'] == $cart['id']
            ) {
            echo '<td><a href="cart.php">in your itinerary</a></td>';
          } else {
            echo '';
          }
        }
      } else {
        echo '<td><input class="btn btn-success" type="submit" name="book_now" value="Book Now"></td>';
      }
      ?>
      <input type="hidden" name="dateStart" value="<?php echo $chooseStart; ?>"> 
      <input type="hidden" name="dateEnd" value="<?php echo $chooseEnd; ?>"> 
      <input type="hidden" name="name" value="<?php echo $aRoom['name']; ?>"> 
      <input type="hidden" name="price" value="<?php echo $aRoom['price']; ?>">
      <input type="hidden" name="room_quantity" value="1">
  </form>
      <?php endforeach; ?>
    </tbody>
  </table>

end up looking like this, which is what I want, but with the input buttons:

table without the 'book_now' input

If I need to clarify on anything, please let me know, and I will try my best. One of my problems is that it's hard for me to really even know what my problem is, since I am still a beginner. I am hoping someone has ran into a similar problem, and knows what I am trying to ask.

I have tried using different GROUP BYs on the MySQL query, to no avail. But I am pretty sure that has nothing to do with my problem. I am fairly sure my problem is that $aRoom is being compared to every item in the shopping cart, which I only want compared once, though I can't figure out how to do the comparison without using a foreach loop on $_SESSION['shopping_cart'].

EDIT

I am trying to use Barmar's suggestion in the linked post, where he mentions that "The simple modification is to use a variable that tracks whether you found something, and then check this variable at the end of the loop" I am currently trying to set the variable to either 1 or 0 depending on how the if statement evaluates.

Here's what I have done:

if(isset($_SESSION['shopping_cart'])) {;
  foreach ($_SESSION['shopping_cart'] as $cart) {
    if(
      $chooseStart < $cart['dateEnd'] && 
      $cart['dateStart'] < $chooseEnd && 
      $aRoom['id'] == $cart['id']
      ) {
      $info = 1;
    } else {
      $info = 0;
    }

  }
} else {
  $info = 0;
}

if($info == 1) {
  echo "<td><a href='cart.php'>in your itinerary</a></td>";
} else {
  echo "<td><input class='btn btn-success' type='submit' name='book_now' value='Book Now'></td>";
}

I have tried placing the if ($info == 1) logic at different places in the foreach($_SESSION['shopping_cart'] loop--after the loop is finished, and right before it finishes. After the loop, it is not returning each value, since it is not filtering through each iteration of the loop. Therefore only the first item in the array is being evaluated. I am wanting to loop through the session array again. I tried that, and at that point it is not being evaluated against the other foreach loop with the $aRoom variable.

I don't want anyone to tell me what to do as much as give me a hint or something. I want to understand it, and do not want to copy-paste someone's code.

Can anyone offer me a hint, like a built-in PHP function that would be of help? There are many array functions with PHP. I have tried array_diff, I have tried getting the array_column and using that, tried to merge the arrays and get unique values out of it. I am currently researching array_map.

halfer
  • 19,824
  • 17
  • 99
  • 186
Collin512
  • 23
  • 5
  • Could date formats be different? Perhaps try this if not unix times: strtotime($chooseStart) < strtotime($cart['dateEnd']) && strtotime($cart['dateStart']) < strtotime($chooseEnd) -----> i.e., your script may be comparing apples to oranges – The One and Only ChemistryBlob Aug 15 '17 at 20:42
  • Also how are you setting $_SESSION['shopping_cart']? – The One and Only ChemistryBlob Aug 15 '17 at 20:48
  • Thank you for the reply. Unfortunately it did not work for me, and the comparisons are all returning false, and I am getting two of 'book now' buttons. – Collin512 Aug 15 '17 at 20:51
  • I am setting the shopping cart via $_POST. – Collin512 Aug 15 '17 at 20:55
  • Excuse me--minus the room id, which I am setting the session with using $_GET. – Collin512 Aug 15 '17 at 21:16
  • I think I can see the problem. I don't think it is correct when you say that only the first array entry is being evaluated. What is happening is that if your first entry is a match (1), the flag is being overwritten (0) by a non-match in a subsequent iteration. So your current algorithm would only work if your last array entry is the match! [Try this instead](https://pastebin.com/qkuKbQvu). – halfer Aug 16 '17 at 08:30
  • That suggestion can be further improved with a `break` after the `$info = 1`, but you'll be working with such short arrays it is not too important. – halfer Aug 16 '17 at 08:31
  • I have voted to open in order to add this as an answer proper - ping me at `@halfer` if the question opens successfully. – halfer Aug 16 '17 at 08:31
  • @halfer, you just saved me. I don't know how I can thank you. Sometimes, we need a little help from someone experienced. I really appreciate you not just blowing me off. I can finally move forward. If there's any way I can help you, please let me know. – Collin512 Aug 16 '17 at 13:07
  • @Collin512: not a problem. I am myself a keen question closer, since a substantial wedge of questions on Stack Overflow really are duplicates or unanswerable. There is also probably more help required than available here, and that's a difficult problem to solve. Nevertheless, we try to help where we can - pleased you got it to work! – halfer Aug 16 '17 at 13:35

0 Answers0