Jump to content

Recommended Posts

I'm Trying to create a booking/availability calendar that shows a full 12 months bookings/availability.

I have come up with the following so far

 


        $publicHolidays = array(date('j-n-Y', strtotime('1st January 2025')),
                                date('j-n-Y', strtotime('18th April 2025')),
                                date('j-n-Y', strtotime('21st April 2025')),
                                date('j-n-Y', strtotime('5th May 2025')),
                                date('j-n-Y', strtotime('26th May 2025')),
                                date('j-n-Y', strtotime('25th August 2025')),
                                date('j-n-Y', strtotime('25th December 2025')),
                                date('j-n-Y', strtotime('26th December 2025')));
          
        $bookings = array(array('Check-In'    => '1-1-2025',
                                'Check-Out'   => '7-1-2025'),
                          array('Check-In'    => '3-2-2025',
                                'Check-Out'   => '13-2-2025'),
                          array('Check-In'    => '2-3-2025',
                                'Check-Out'   => '25-3-2025'),
                          array('Check-In'    => '2-4-2025',
                                'Check-Out'   => '21-4-2025'),
                          array('Check-In'    => '6-6-2025',
                                'Check-Out'   => '9-6-2025'),
                          array('Check-In'    => '2-9-2025',
                                'Check-Out'   => '5-9-2025'),
                          array('Check-In'    => '3-11-2025',
                                'Check-Out'   => '30-11-2025'));
        foreach($bookings as $row) {
          $res[] = Cal::bookedArray($row['Check-In'],$row['Check-Out']);
        }
        
        $booked = Cal::bookedArray('1-4-2025','7-4-2025');
          
        $month = '1';
        $year = date('Y');
        for($m=$month;$m<13;$m++) {
        $timestamp = mktime(0, 0, 0, $m, 1, $year);
        $daysInMonth = date("t", $timestamp);
        $firstDay = date("N", $timestamp);
        
        if($m == date('m')) { $featured =' featured'; } else { $featured=''; }
        
        ?>
        <div class="col-xl-4 col-lg-6" data-aos="fade-up" data-aos-delay="100">
            <div class="pricing-item p-0<?php echo $featured;?>">
              <h3 class="mb-0 pt-5"><?php echo date('F', mktime(0,0,0,$m)); ?></h3>
              <table class="table table-bordered m-0">
                <tr>
                  <th>Mon</th>
                  <th>Tue</th>
                  <th>Wed</th>
                  <th>Thu</th>
                  <th>Fri</th>
                  <th>Sat</th>
                  <th>Sun</th>
                </tr>
                <?php
                $dayCount = 1;
                ?>
                <tr>
                <?php

                for ($i = 1; $i <= 7; $i++) {
                    
                    $date = "$dayCount-$m-$year";
                    if ($i < $firstDay) {
                        echo "<td></td>";
                    } else {
                        $date = "$dayCount-$m-$year";
                        if(date('l', strtotime($date)) == 'Saturday' && !in_array($date, $booked)) { 
                          $cellBg="class='table-info'"; 
                        } 
                        elseif(date('l', strtotime($date)) == 'Sunday' && !in_array($date, $booked)) {
                          $cellBg="class='table-info'"; 
                        }
                        elseif(in_array($date, $publicHolidays) && !in_array($date, $booked)) {
                          $cellBg="class='table-warning'"; 
                        } 
                        else {
                          $cellBg="class='table-light'"; 
                        }
                      
                        foreach($res as $key => $val) {
                          /*
                          $firstday = reset($val);
                          $lastday = end($val);
                          if($date = $firstday) {
                            $cellBg="class='table-primary'";
                          }
                          
                          elseif(in_array($date, array_splice($val,1,-1))) {
                            $cellBg="class='table-danger'"; 
                          }
                          
                          elseif($date = $lastday) {
                            $cellBg="class='table-primary'";
                          }
                          */
                          
                          if(in_array($date, array_splice($val,1,-1))) {
                            $cellBg="class='table-danger'"; 
                          }
                        }
                      
                        echo "<td $cellBg>$dayCount</td>";
                        $dayCount++;
                    }
                }
                echo "</tr>";
          
                while ($dayCount <= $daysInMonth) {
                    echo "<tr>";
                    for ($i = 1; $i <= 7 && $dayCount <= $daysInMonth; $i++) {
                        $date = "$dayCount-$m-$year";
                        if(date('l', strtotime($date)) == 'Saturday' && !in_array($date, $booked)) { 
                          $cellBg="class='table-info'"; 
                        }
                        elseif(date('l', strtotime($date)) == 'Sunday' && !in_array($date, $booked)) {
                          $cellBg="class='table-info'"; 
                        } 
                        elseif(in_array($date, $publicHolidays) && !in_array($date, $booked)) {
                          $cellBg="class='table-warning'"; 
                        } 
                        else {
                          $cellBg="class='table-light'"; 
                        }
                      
                        foreach($res as $key => $val) {
                          /*
                          $firstday = reset($val);
                          $lastday = end($val);
                          if($date = $firstday) {
                            $cellBg="class='table-primary'";
                          }
                          
                          elseif(in_array($date, array_splice($val,1,-1))) {
                            $cellBg="class='table-danger'"; 
                          }
                          
                          elseif($date = $lastday) {
                            $cellBg="class='table-primary'";
                          }
                          */
                          
                          if(in_array($date, array_splice($val,1,-1))) {
                            $cellBg="class='table-danger'"; 
                          }
                          
                        }
                      
                        echo "<td $cellBg>$dayCount</td>";
                        $dayCount++;
                    }
                ?>
                </tr>
                <?php
                }
                ?>
              </table>
          </div>
        </div>
        <?php
        }
        

Its reading the arrays, drawing the calendar and colorizing the weekends, public holidays and bookings. What i need is to change the check-in and check-out date color to reflect what they are. I've commented out what ive been trying but it isnt working.

 

here is the bookedarray function if anyone needs it


    public static function bookedArray($strDateFrom,$strDateTo)
    {

      $aryRange = [];

      $iDateFrom = strtotime($strDateFrom);
      $iDateTo = strtotime($strDateTo);

      if ($iDateTo >= $iDateFrom) {
          array_push($aryRange, date('j-n-Y', $iDateFrom)); // first entry
          while ($iDateFrom<$iDateTo) {
              $iDateFrom += 86400; // add 24 hours
              array_push($aryRange, date('j-n-Y', $iDateFrom));
          }
      }
      return $aryRange;

    }

Any help would be much appreciated or even a pointer as to were I could find a solution

 

Thanks in advance

Link to comment
https://forums.phpfreaks.com/topic/327580-bookingavailability-calendar-help/
Share on other sites

what exactly is the single $booked data for vs the array of $bookings?

i have the following recommendations -

  1. use a standard yyyy-mm-dd date format. if/when you store the data in a database, this will be necessary to allow queries to compare dates by order. it will also make your current code easier to understand.
  2. the bookings data should be stored in a database table.
  3. you should have a start_date and an end_date input to the code on this page, so that the code will work for any date range, from multiple years down to a single month.
  4. you are looping over the $res array for every date being displayed, currently for the whole year. i recommend that you instead produce an array using the date as the array index, and the stored value indicating what is occurring on that date, limited to be between the start_date and end_date mentioned above. as you are producing the output, you can simply test, no loop required, if there is an entry in this array, using isset(), then get the stored value if there is one, and use it to control what you output for the date.
  5. with a little conditional logic, you don't need separate logic to deal with the first (partial) week, then repeat that logic for the remainder of each month.
  6. if you use php's short-open-print tag and leave out the ; right before a closing tag, you can use simple syntax like - <?=$some_var?> to output values in the markup.
  7. use php's DateInterval and DatePeriod to expand the booking date ranges.

here's example code for item #7 -

$start = new DateTime($start);
$end = new DateTime($end);
$end = $end->modify('+1 day'); // include the end point

$interval = new DateInterval('P1D'); // 1 day
$daterange = new DatePeriod($start, $interval ,$end);

$dates = array();
foreach($daterange as $date){
    $dates[] = $date->format("Y-m-d");
}

 

Edited by mac_gyver

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.