room_reservation module as it exists on rooms.library.upei.ca. rooms.lib.. seemed like a clean module from drupal.org. Due to covid we have had to make some changes, I am tracking them here (pp).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
6.9 KiB

<?php
/**
* Reservation CRUD
*/
/**
* Create REPEATING reservations
*
* @param mixed $node
*/
function room_reservations_insert($node) {
if ($node->type != 'room_reservations_reservation') {
return;
}
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail
if (isset($node->saved)){
return;
}
$rtype = $node->reservation_repeat_type[LANGUAGE_NONE][0]['value'];
$start = $node->reservation_date[LANGUAGE_NONE][0]['value'];
$start_yyyy_mm_dd = date('Y-m-d', strtotime($start));
$end = date('Y-m-d', strtotime($node->reservation_repeat_until[LANGUAGE_NONE][0]['value']));
$time = $node->reservation_time[LANGUAGE_NONE][0]['value'];
$length = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$rid = $node->reservation_room[LANGUAGE_NONE][0]['target_id'];
$day = date('l', strtotime($start));
$msg = '';
switch ($rtype) {
// no repeats
case 1:
return;
// every day until....
case 2:
$skip = '+1 day';
$back = '-1 day';
$msg = t('You have booked every day from %start until %end', array('%start' => $start_yyyy_mm_dd, '%end' => $end));
break;
// this day of the week until..
case 3:
$skip = '+7 day';
$back = '-7 day';
$msg = t('You have booked every %day from %start until %end', array('%day' => $day, '%start' => $start_yyyy_mm_dd, '%end' => $end));
break;
}
// set NID as Series ID for both the primary node and the repeat nodes
$node->reservation_series_id[LANGUAGE_NONE][0]['value'] = $node->nid;
$tmp = clone($node);
unset($tmp->nid, $tmp->vid);
// and must unset default date that we just used in hook_node_presave for the initial node
unset($tmp->date_default);
$date = $start;
$booked = array();
while (strtotime($date) <= strtotime($back, strtotime($end))) {
$date = date('Y-m-d', strtotime($skip, strtotime($date)));
// must check to see if next booking is available
// the first one we don't check as we could not have picked it if it wasn't
if (_room_reservations_is_slot_free($rid, $date, $time, $length)) {
$new = clone($tmp);
$new->reservation_date[LANGUAGE_NONE][0]['value'] = $date . ' 00:00:00'; // added 12:00:00 to fix TZ issues; this is unlikely correct way to do this
$new->saved = true;
node_save($new);
}
else {
$booked[] = $date;
}
}
// lets spit out some useful msgs
// first clear the msg stating we just created the reservation node
drupal_get_messages('status');
drupal_set_message(t('Your reservation series has been booked.'));
drupal_set_message($msg);
if (count($booked)) {
$dates = '<br>' . implode('<br>', $booked);
drupal_set_message(t('The following dates were not booked due to scheduling conflicts: !dates', array('!dates' => $dates)), 'warning');
}
}
// to handle Series edits
function room_reservations_update($node) {
if ($node->type != 'room_reservations_reservation') {
return;
}
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail
if (isset($node->saved)){
return;
}
// if not part of a Series or special single only url; do nothing
if (!isset($node->reservation_series_id[LANGUAGE_NONE][0]) || !($sid = $node->reservation_series_id[LANGUAGE_NONE][0]['value']) || isset($_GET['single'])) {
return;
}
// reservation details
$start = $node->reservation_date[LANGUAGE_NONE][0]['value'];
$end = date('Y-m-d', strtotime($node->reservation_repeat_until[LANGUAGE_NONE][0]['value']));
$time = $node->reservation_time[LANGUAGE_NONE][0]['value'];
$length = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$rid = $node->reservation_room[LANGUAGE_NONE][0]['target_id'];
$day = date('l', strtotime($start));
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
$deleted = array();
if (isset($result['node'])) {
$result_nids = array_keys($result['node']);
$results = entity_load('node', $result_nids);
foreach ($results as $data) {
// for now, only allow changing Title, Blocked title, Length
// first 2 are easy; but to change length we need to check if that period is available and if not delete entry from Series
$data->title = $node->title;
$data->reservation_block_title[LANGUAGE_NONE][0]['value'] = $node->reservation_block_title[LANGUAGE_NONE][0]['value'];
$date = date('Y-m-d', strtotime($data->reservation_date[LANGUAGE_NONE][0]['value']));
if (_room_reservations_is_slot_free($rid, $date, $time, $length)) {
$data->reservation_length[LANGUAGE_NONE][0]['value'] = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$data->saved = true;
node_save($data);
}
// if slot is not available; delete that entry
else {
$deleted[] = $date;
node_delete($data->nid);
}
}
}
// lets spit out some useful msgs
drupal_set_message(t('Your reservation series has been modified.'));
if (count($deleted)) {
$dates = '<br>' . implode('<br>', $deleted);
drupal_set_message(t('The following dates were deleted from the series due to scheduling conflicts: !dates', array('!dates' => $dates)), 'warning');
}
}
function _room_reservations_series_delete($form) {
$sid = $form['#node']->reservation_series_id[LANGUAGE_NONE][0]['value'];
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
if (isset($result['node'])) {
$nids = array_keys($result['node']);
foreach ($nids as $nid) {
node_delete($nid);
}
}
$title = $form['#node']->title;
drupal_set_message(t('The reservation series @title was deleted.', array('@title' => $title)));
drupal_goto('room_reservations');
}
/**
* copy above function for API use only
* - pass SID
*
* @param mixed $sid
*/
function room_reservations_series_delete($sid) {
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
if (isset($result['node'])) {
$nids = array_keys($result['node']);
foreach ($nids as $nid) {
node_delete($nid);
}
}
$res = node_load($sid);
drupal_set_message(t('The reservation series @title was deleted.', array('@title' => $res->title)));
drupal_goto('room_reservations');
}