Page 1 of 2
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 8:12 am
by Celauran
Look in classes/class_calendar.php
Code: Select all
public $day_closed = array("Saturday", "Sunday"); // If you don't want any 'closed' days, remove the day so it becomes: = array();
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 8:46 am
by Celauran
You would probably want to convert $booking_start_time and $booking_end_time to arrays of values, either one entry per day, or one entry per exception day plus one default. You would then also need to change where the arrays are referenced to reflect your new array structure.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 1:00 pm
by Celauran
I would leave most of the functionality as is. booking_start_time and booking_end_time are fine. You could add an exceptions array, indexed by day, with start and end times for those specific days. When you're building the booking form, check if the current day is specified in the exceptions and override booking_start_time and booking_end_time with those values. Otherwise, do nothing.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 1:46 pm
by Celauran
Yes, absolutely.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 1:57 pm
by Celauran
Without even worrying about writing new code yet, look through the class you're modifying to see the flow and think about what steps you'd want to take to allow for these exceptions. You've got them defined, how do you use them? Where?
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 2:09 pm
by Celauran
make_calendar takes a booking date as a parameter and chains all the class methods together. Once we know what day we're booking for, we can check if that's in the exception array. Does that help?
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 2:21 pm
by Celauran
Here are the modifications I've made. Can you see what I'm doing and how it works?
Code: Select all
<?php
class booking_diary {
// Mysqli connection
function __construct($link) {
$this->link = $link;
}
// Settings you can change:
// Time Related Variables
public $booking_start_time = "09:00"; // The time of the first slot in 24 hour H:M format
public $booking_end_time = "19:00"; // The time of the last slot in 24 hour H:M format
public $booking_frequency = 30; // The slot frequency per hour, expressed in minutes.
// Allowing for days to have different business hours. Indexed by day name
// to match conventions set forth by $day_closed
protected $booking_exceptions = [
'Saturday' => [
'start_time' => "09:00",
'end_time' => "12:00",
],
];
// Day Related Variables
public $day_format = 1; // Day format of the table header. Possible values (1, 2, 3)
// 1 = Show First digit, eg: "M"
// 2 = Show First 3 letters, eg: "Mon"
// 3 = Full Day, eg: "Monday"
public $day_closed = array("Sunday"); // If you don't want any 'closed' days, remove the day so it becomes: = array();
public $day_closed_text = "CLOSED"; // If you don't want any any 'closed' remove the text so it becomes: = "";
// Cost Related Variables
public $cost_per_slot = 20.00; // The cost per slot
public $cost_currency_tag = "$"; // The currency tag in HTML such as € £ ¥
// DO NOT EDIT BELOW THIS LINE
public $day_order = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
public $day, $month, $year, $selected_date, $back, $back_month, $back_year, $forward, $forward_month, $forward_year, $bookings, $count, $days, $is_slot_booked_today;
/*========================================================================================================================================================*/
function make_calendar($selected_date, $back, $forward, $day, $month, $year) {
// $day, $month and $year are the $_GET variables in the URL
$this->day = $day;
$this->month = $month;
$this->year = $year;
// $back and $forward are Unix Timestamps of the previous / next month, used to give the back arrow the correct month and year
$this->selected_date = $selected_date;
$this->back = $back;
$this->back_month = date("m", $back);
$this->back_year = date("Y", $back); // Minus one month back arrow
$this->forward = $forward;
$this->forward_month = date("m", $forward);
$this->forward_year = date("Y", $forward); // Add one month forward arrow
// Now that we know the day we're booking for, check its hours
$this->getBusinessHours();
// Make the booking array
$this->make_booking_array($year, $month);
}
// Overwrite start/end properties if today has special hours
protected function getBusinessHours() {
$date = new \DateTime("{$this->year}-{$this->month}-{$this->day}");
$day = $date->format('l');
if (array_key_exists($day, $this->booking_exceptions)) {
$this->booking_start_time = $this->booking_exceptions[$day]['start_time'];
$this->booking_end_time = $this->booking_exceptions[$day]['end_time'];
}
}
//...
// Everything else is the same
} // Close Class
?>
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 2:46 pm
by Celauran
ianhaney wrote:I don't get what this part is doing
Code: Select all
// Now that we know the day we're booking for, check its hours
$this->getBusinessHours();
It's calling the function getBusinessHours.
ianhaney wrote:I don't get what this part is doing
Code: Select all
// Overwrite start/end properties if today has special hours
protected function getBusinessHours() {
$date = new \DateTime("{$this->year}-{$this->month}-{$this->day}");
$day = $date->format('l');
if (array_key_exists($day, $this->booking_exceptions)) {
$this->booking_start_time = $this->booking_exceptions[$day]['start_time'];
$this->booking_end_time = $this->booking_exceptions[$day]['end_time'];
}
}
Is that calling the function to get it displayed in the calendar?
The booking_start_time and booking_end_time properties are hardcoded and are being used to generate the available bookings. The above method creates a
DateTime object based on the date passed to make_calendar (which stores it as instance properties). We use that object to get the name of the day (Monday, Tuesday, etc). This isn't necessarily the best approach, but it is consistent with other configuration settings in the class. Finally, it checks if that day name exists as a key in the booking_exceptions array and, if it does, sets the start and end times to those specified in the exceptions array.
ianhaney wrote:Also what is the difference between public and protected?
Public properties and methods can be accessed from anywhere. Protected properties and methods can be accessed from within the class or its children. Private properties and methods can only be accessed from within the class.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 2:58 pm
by Celauran
Are you using an old version of PHP? Or does Dreamweaver think you are? Short array syntax was introduced in 5.4, way back in March, 2012.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 3:03 pm
by Celauran
Old version of Dreamweaver, perhaps? Alternately, check if PHP version can be specified in the settings.
Re: ajax availability calendar help
Posted: Wed Jan 20, 2016 3:16 pm
by Celauran
I wouldn't worry too much about it. The editor's wrong, the code is fine, and that's simple enough to confirm.
Re: ajax availability calendar help
Posted: Thu Jan 21, 2016 7:51 am
by Celauran
I would actually consider taking a different approach to it. You're not overriding the standard business hours per se, you're adding a set of specific dates to the closed array. It currently expects days of the week, though, and you want specific dates, so you may want to add a separate property to handle those. Also, we're not concerned about modifying the booking form here; we want the day to be marked as closed and the booking form to be entirely unavailable.
I have made some changes below. // ... indicates parts of the class I have trimmed for brevity; they are still very much required for things to run. Gives this a look and see if you understand how it works and why. We can discuss further once you've gone over it.
Code: Select all
<?php
class booking_diary {
// Mysqli connection
function __construct($link) {
$this->link = $link;
}
// Settings you can change:
// Time Related Variables
public $booking_start_time = "09:00"; // The time of the first slot in 24 hour H:M format
public $booking_end_time = "19:00"; // The time of the last slot in 24 hour H:M format
public $booking_frequency = 30; // The slot frequency per hour, expressed in minutes.
// Allowing for days to have different business hours. Indexed by day name
// to match conventions set forth by $day_closed
protected $booking_exceptions = [
'Saturday' => [
'start_time' => "09:00",
'end_time' => "12:00",
],
];
// Holidays are another exception; business is closed but on a specific date
// rather than on a day of the week
protected $holidays = [
'01-01',
'24-12',
'25-12',
'31-12',
];
// Day Related Variables
public $day_format = 1; // Day format of the table header. Possible values (1, 2, 3)
// 1 = Show First digit, eg: "M"
// 2 = Show First 3 letters, eg: "Mon"
// 3 = Full Day, eg: "Monday"
public $day_closed = array("Sunday"); // If you don't want any 'closed' days, remove the day so it becomes: = array();
public $day_closed_text = "CLOSED"; // If you don't want any any 'closed' remove the text so it becomes: = "";
// ...
function make_calendar($selected_date, $back, $forward, $day, $month, $year) {
// $day, $month and $year are the $_GET variables in the URL
$this->day = $day;
$this->month = $month;
$this->year = $year;
// $back and $forward are Unix Timestamps of the previous / next month, used to give the back arrow the correct month and year
$this->selected_date = $selected_date;
$this->back = $back;
$this->back_month = date("m", $back);
$this->back_year = date("Y", $back); // Minus one month back arrow
$this->forward = $forward;
$this->forward_month = date("m", $forward);
$this->forward_year = date("Y", $forward); // Add one month forward arrow
$this->getBusinessHours();
// Make the booking array
$this->make_booking_array($year, $month);
}
// Overwrite start/end properties if today has special hours
protected function getBusinessHours() {
$date = new \DateTime("{$this->year}-{$this->month}-{$this->day}");
$day = $date->format('l');
if (array_key_exists($day, $this->booking_exceptions)) {
$this->booking_start_time = $this->booking_exceptions[$day]['start_time'];
$this->booking_end_time = $this->booking_exceptions[$day]['end_time'];
}
}
// ...
function make_cells($table = '') {
echo "<tr>";
foreach($this->days as $i => $r) { // Loop through the date array
$j = $i + 1; $tag = 0;
$dm = null;
if ($r['dayname'] !== 'blank') {
$day = str_pad($r['daynumber'], 2, '0', STR_PAD_LEFT);
$dm = "{$day}-{$this->month}";
}
// If the the current day is found in the day_closed array, bookings are not allowed on this day
// OR if the current date is in the holidays array
if (in_array($r['dayname'], $this->day_closed) || ($dm && in_array($dm, $this->holidays))) {
echo "\r\n<td width='21' valign='top' class='closed'>" . $this->day_closed_text . "</td>";
$tag = 1;
}
// Past days are greyed out
if (mktime(0, 0, 0, $this->month, sprintf("%02s", $r['daynumber']) + 1, $this->year) < strtotime("now") && $tag != 1) {
echo "\r\n<td width='21' valign='top' class='past'>";
// Output day number
if($r['daynumber'] != 'blank') echo $r['daynumber'];
echo "</td>";
$tag = 1;
}
// If the element is set as 'blank', insert blank day
if($r['dayname'] == 'blank' && $tag != 1) {
echo "\r\n<td width='21' valign='top' class='unavailable'></td>";
$tag = 1;
}
// Now check the booking array $this->booking to see whether we have a booking on this day
$current_day = $this->year . '-' . $this->month . '-' . sprintf("%02s", $r['daynumber']);
if(isset($this->bookings_per_day[$current_day]) && $tag == 0) {
$current_day_slots_booked = count($this->bookings_per_day[$current_day]);
if($current_day_slots_booked < $this->slots_per_day) {
echo "\r\n<td width='21' valign='top'>
<a href='calendar.php?month=" . $this->month . "&year=" . $this->year . "&day=" . sprintf("%02s", $r['daynumber']) . "' class='part_booked' title='This day is part booked'>" .
$r['daynumber'] . "</a></td>";
$tag = 1;
} else {
echo "\r\n<td width='21' valign='top'>
<a href='calendar.php?month=" . $this->month . "&year=" . $this->year . "&day=" . sprintf("%02s", $r['daynumber']) . "' class='fully_booked' title='This day is fully booked'>" .
$r['daynumber'] . "</a></td>";
$tag = 1;
} // Close else
} // Close if
if($tag == 0) {
echo "\r\n<td width='21' valign='top'>
<a href='calendar.php?month=" . $this->month . "&year=" . $this->year . "&day=" . sprintf("%02s", $r['daynumber']) . "' class='green' title='Please click to view bookings'>" .
$r['daynumber'] . "</a></td>";
}
// The modulus function below ($j % 7 == 0) adds a <tr> tag to every seventh cell + 1;
if($j % 7 == 0 && $i >1) {
echo "\r\n</tr>\r\n<tr>"; // Use modulus to give us a <tr> after every seven <td> cells
}
}
echo "</tr></table></div><!-- Close outer_calendar DIV -->";
if(isset($_GET['year']))
$this->basket();
echo "</div><!-- Close LHS DIV -->";
// Check booked slots for selected date and only show the booking form if there are available slots
$current_day = $this->year . '-' . $this->month . '-' . $this->day;
$slots_selected_day = 0;
if(isset($this->bookings_per_day[$current_day]))
$slots_selected_day = count($this->bookings_per_day[$current_day]);
if($this->day != 0 && $slots_selected_day < $this->slots_per_day) {
$this->booking_form();
}
} // Close function
// ...
} // Close Class
Re: ajax availability calendar help
Posted: Thu Jan 21, 2016 8:47 am
by Celauran
It needs to be day-month, or you need to change the holidays array to be month-day. There's a mismatch.
Code: Select all
$dm = null;
if ($r['dayname'] !== 'blank') {
$day = str_pad($r['daynumber'], 2, '0', STR_PAD_LEFT);
$dm = "{$this->month}-{$day}";
}
$r is an array containing the day name and the date (day number). I am prepending a 0 to the days so you'll get 01-01 rather than 1-01
Re: ajax availability calendar help
Posted: Thu Jan 21, 2016 8:58 am
by Celauran
Re: ajax availability calendar help
Posted: Thu Jan 21, 2016 9:27 am
by Celauran
You're also missing the check for if $dm is in the holidays array.
Code: Select all
if(in_array($r['dayname'], $this->day_closed)) {
needs to be
Code: Select all
if(in_array($r['dayname'], $this->day_closed) || ($dm && in_array($dm, $this->holidays))) {
Do you see why? Do you see what the above is doing?