Skip to content

Instantly share code, notes, and snippets.

@agssl
Created October 17, 2024 07:30
Show Gist options
  • Select an option

  • Save agssl/e4e422bac682cfe145da1e09f9bd14a1 to your computer and use it in GitHub Desktop.

Select an option

Save agssl/e4e422bac682cfe145da1e09f9bd14a1 to your computer and use it in GitHub Desktop.
Inventory Demo
<?php
class SetInventory {
public $form_id;
public $inventory_field_id;
public $date_field_id;
public $days;
function __construct($args){
$this->form_id = $args['form_id'];
$this->inventory_field_id = $args['inventory_field_id'];
$this->date_field_id = $args['date_field_id'];
$this->days = $args['days'];
}
public function init() {
$this->setLimit();
$this->disableDates();
}
// *
// * Set timeslot capacity
// * ------------------------------------------
public function set_timeslot_capacity($day) {
$choices = array();
$i = 0;
if($day['opened']):
foreach($day['time_slots'] as $time_slot):
$i++;
$text = $time_slot['timeslot_start'] . ' - ' . $time_slot['timeslot_end'] . ' Uhr';
$value = 'slot_' .$i;
$capacity = $time_slot['capacity'];
if($time_slot['capacity'] == 0):
$text = 'Keine Kapazität';
endif;
if((isset($time_slot['bookable']) && $time_slot['bookable'] == 0) ||
$time_slot['timeslot_start'] == '' ||
$time_slot['timeslot_end'] == ''
):
$capacity = 0;
$text = $value = 'not_bookable';
endif;
$choices[] = array(
'text' => $text,
'value' => $value,
'inventory_limit' => $capacity
);
endforeach;
//Always add a choice to prevent disabling
$choices[] = array(
'text' => 'prevent_disabling',
'value' => 'prevent_disabling',
'inventory_limit' => 0
);
endif;
return $choices;
}
// *
// * Set Limits and exceptions
// * ------------------------------------------
public function setLimit() {
add_filter( 'gppa_input_choices_' . $this->form_id . '_' . $this->inventory_field_id, function( $choices, $field, $objects ) {
$days = $this->days;
$selectedDate = get_field_value('bookingdate', true) ?? null;
$selectedDateTimestamp = $selectedDate ? strtotime($selectedDate) : null;
$dayOfWeek = date('w', $selectedDateTimestamp);
$choices = array();
$i = 0;
/**
* * Run trough all weekdays
*/
while ($i <= 6):
if($dayOfWeek == $i) {
$weekday = get_field( $i, 'options');
if(!$weekday) {
show_error('Es wurden keine buchbaren Zeiten geladen');
}
if($weekday && $weekday['opened']):
$choices = $this->set_timeslot_capacity($weekday);
endif;
}
$i++;
endwhile;
/**
* * Overwrite with exceptions
*/
if( $days ):
foreach( $days as $day):
//date range
if($day['is_date_range'] && $day['opened']):
$date_range = $day['date_range'];
$is_in_range = check_in_range($date_range['date_start'], $date_range['date_end'], $selectedDate);
if($is_in_range && !empty($day['time_slots'])):
$choices = $this->set_timeslot_capacity($day);
endif;
endif;
//Single day always overwrites date range
if (isset($day['date']) && ($selectedDateTimestamp == strtotime($day['date'])) && !$day['is_date_range']):
if(!empty($day['time_slots'])):
$choices = $this->set_timeslot_capacity($day);
endif;
endif;
endforeach;
endif;
return $choices;
}, 10, 3 );
}
/**
* * Get all days which are regularly open
*/
public function regularClosedDays() {
$i = 0;
$openedDays = array(); //all dates available by default
while ($i <= 6):
$weekday = get_field( $i, 'options');
if($weekday && !$weekday['opened']):
$openedDays[] = $i;
endif;
$i++;
endwhile;
return $openedDays;
}
/**
* * Get all days which are opened by exception
*/
public function openedByException() {
$days = $this->days;
if(!$days) {
return;
}
$openend_exceptions = array();
foreach( $days as $day):
if($day['opened'] && !$day['is_date_range']):
$openend_exceptions[] = $day['date'];
endif;
endforeach;
return $openend_exceptions;
}
/**
* * Get all days which are closes by excepton
*/
public function closedByException($available_months) {
$days = $this->days;
$regularClosedDays = $this->regularClosedDays();
$closedDays = array();
$openend_exceptions = array();
$max_date_limit = get_field('max_date_limit', 'options') ?? false;
//set the regulary closed days
if( $days ):
//get all single exceptions which are open
foreach( $days as $day):
if($day['opened'] && !$day['is_date_range']):
$openend_exceptions[] = $day['date'];
elseif($day['opened'] && $day['is_date_range']):
$date_range_group = $day['date_range'];
$date_range = get_range($date_range_group['date_start'], $date_range_group['date_end']);
foreach ( $date_range as $date ):
$openend_exceptions[] = $date->format( 'm/d/Y' );
endforeach;
endif;
endforeach;
//set limits
foreach( $days as $day):
if(!$day['opened']):
if($day['is_date_range']):
$date_range_group = $day['date_range'];
$date_range = get_range($date_range_group['date_start'], $date_range_group['date_end']);
foreach ( $date_range as $date ) {
$date = $date->format( 'm/d/Y' );
//mark as closed if not overwritten by exception
if (!in_array($date, $openend_exceptions)):
$closedDays[] = $date;
endif;
};
$closedDays[] = $date_range_group['date_end'];
else:
$closedDays[] = $day['date'];
endif;
endif;
endforeach;
endif;
//Set the regular closed days, if not overwritten from exception
$start_date = new DateTime('today');
if($max_date_limit):
$end_date = new DateTime($max_date_limit);
else:
$end_date = new DateTime('+' . $available_months. ' months');
endif;
$period = new DatePeriod( $start_date, new DateInterval( 'P1D' ), $end_date );
foreach ( $period as $date ) {
$weekday_int = $date->format( 'N' );
$formatted_date = $date->format( 'm/d/Y' );
if (in_array($weekday_int, $regularClosedDays) && !in_array($formatted_date, $openend_exceptions)) {
$closedDays[] = $formatted_date;
}
};
return $closedDays;
}
/**
* * Disable dates in the calender
*/
public function disableDates() {
add_filter( 'gpld_limit_dates_options_' . $this->form_id . '_' . $this->date_field_id . '', function( $options, $form, $field ) {
$available_months = get_field('datepicker_activated', 'options') ?? 4;
$max_date_limit = get_field('max_date_limit', 'options') ?? false;
$closedByExcetion = $this->closedByException($available_months);
$timezone = new DateTimeZone('Europe/Berlin');
$currentDateTime = new DateTime('now', $timezone);
$currentHour = $currentDateTime->format('H');
$today = $currentDateTime->format('m/d/Y');
$max_date_limit_timestamp = strtotime($max_date_limit) ?? false;
$today_timestamp = strtotime($today) ?? null;
//* Set the min book date
if ($currentHour < 15) {
$nextDate = '+1 day';
} else {
$nextDate = '+2 days';
}
//* Get all exceptions
foreach ($closedByExcetion as $closedDate ) {
$exception_date = new DateTime( $closedDate );
$options['exceptions'][] = $exception_date ->format( 'm/d/Y' );
}
$options['minDate'] = '{today}';
$options['minDateMod'] = $nextDate;
//Limit the available dates
if($max_date_limit_timestamp && $max_date_limit_timestamp >= $today_timestamp) {
$regularClosedDays = $this->regularClosedDays();
$max_date_weekday = date('N', strtotime($max_date_limit));
while (in_array($max_date_weekday, $regularClosedDays)) {
$max_date_limit = date('Y-m-d', strtotime($max_date_limit . ' -1 day'));
$max_date_weekday = date('N', strtotime($max_date_limit));
};
$options['maxDate'] = $max_date_limit;
} else {
$options['maxDate'] = '{today}';
$options['maxDateMod'] = '+' . $available_months. ' months';
}
$options['exceptionMode'] = 'disable';
return $options;
}, 10, 3 );
}
}
$inventory = new SetInventory( array(
'form_id' => get_form_id(Babalu::BIRTHDAY_BOOKING_FORM_NAME),
'inventory_field_id' => get_field_id('timeslot'),
'date_field_id' => get_field_id('bookingdate'),
'days' => get_field('additional_dates', 'options')
));
$inventory->init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment