Branch 4.0.x-roblib is currently the same as Drupals main branch but with our patches applied.
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.
 
 
 
 

196 lines
6.8 KiB

<?php
/**
* Reservation CRUD for supporting Series
*/
use Drupal\Core\Render\Markup;
/**
* Create REPEATING reservations
*
* NOTE: first reservation has aready been saved at this point - we are just saving the others in series
* BUT - we do need to update the original entity with the Series ID
*
* @param mixed $node
*/
function reserve_reserve_reservation_insert($entity) {
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail
if (isset($entity->saved)){
return;
}
$repeat_type = $entity->reservation_repeat_type->getString();
// if No Repeat, do nothing
if (!$repeat_type) {
return;
}
$eid = $entity->id();
$start = $entity->reservation_date->getString();
$start_yyyy_mm_dd = date('Y-m-d', strtotime($start));
$end = date('Y-m-d', strtotime($entity->reservation_repeat_until->getString()));
$time = $entity->reservation_time->getString();
$length = $entity->reservation_length->getString();
$rid = $entity->reservable_id->getString();
$rtype = $entity->reservable_content_type->getString();
$ebundle = $rtype . '.' . \Drupal::entityTypeManager()
->getStorage($rtype)->load($rid)->bundle();
$day = date('l', strtotime($start));
$msg = '';
switch ($repeat_type) {
// every day until....
case 1:
$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 2:
$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 entity and the repeat nodes
$entity->set('reservation_series_id', $eid);
// then lets save the original reservation with Series ID but set SAVED so we skip the update hook
$entity->saved = true;
$entity->save();
// lets build the rest of the reservations in the series
$tmp = $entity->createDuplicate();
$date = $start;
$failed = 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 (reserve_is_slot_free($rid, $ebundle, $date, $time, $length)) {
$new = $tmp->createDuplicate();
$new->set('reservation_date', $date);
$new->saved = true;
$new->save();
}
else {
$failed[] = $date;
}
}
// lets spit out some useful msgs
// first clear the msg stating we just created the reservation entity
\Drupal::messenger()->addStatus('status');
\Drupal::messenger()->addStatus(t('Your reservation series has been booked.'));
\Drupal::messenger()->addStatus($msg);
if (count($failed)) {
$dates = Markup::create('<br>' . implode('<br>', $failed));
\Drupal::messenger()->addWarning(t('The following dates were not booked due to scheduling conflicts: %dates', array('%dates' => $dates)));
}
}
/*
* to handle Series edits
*
* this is only run on the OTHER reservations in series triggered from submitting changes to one of the
* reservations in that series
*
* the changes to which ever reservation is being edited will be done in normal entity_save()
*
*/
function reserve_reserve_reservation_update($entity) {
// when we do a node_save below or when we insert from hook_insert above; it will hit this hook - so lets skip
if (isset($entity->saved)){
return;
}
$sid = $entity->reservation_series_id->getString();
// if not part of a Series or special single only url -> do nothing
if (!$sid || isset($_GET['single'])) {
return;
}
// reservation details
$start = $entity->reservation_date->getString();
$time = $entity->reservation_time->getString();
$length = $entity->reservation_length->getString();
$rid = $entity->reservable_id->getString();
$rtype = $entity->reservable_content_type->getString();
$ebundle = $rtype . '.' . \Drupal::entityTypeManager()
->getStorage($rtype)->load($rid)->bundle();
$private = $entity->reservation_private->getString();
// grab all reservations in this series except the one being submitted
$ids = \Drupal::service('entity_type.manager')
->getStorage('reserve_reservation')->getQuery()
->accessCheck(TRUE)
->condition('status', TRUE)
->condition('reservation_series_id', $sid)
->condition('id', $entity->id(), '!=')
->execute();
$results = \Drupal::entityTypeManager()->getStorage('reserve_reservation')->loadMultiple($ids);
$failed = array();
foreach ($results as $data) {
// for now, only allow changing Title, Privacy, 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->set('name', $entity->getName());
$data->set('reservation_private', $private);
$date = date('Y-m-d', strtotime($data->reservation_date->getString()));
if (reserve_is_slot_free($rid, $ebundle, $date, $time, $length)) {
$data->set('reservation_length', $length);
}
// if slot is not available; do not update the length of this reservation
// this is different than D7 version - in D7 we simply deleted the reservation; which seems silly.
else {
$failed[] = $date;
}
// update this reservation in our series
$data->saved = true;
$data->save();
}
// lets spit out some useful msgs
\Drupal::messenger()->addStatus(t('Your reservation series has been modified.'));
if (count($failed)) {
$dates = Markup::create('<br>' . implode('<br>', $failed));
\Drupal::messenger()->addStatus(t('NOTE: The following dates did not have their length changed due to scheduling conflicts: %dates', array('%dates' => $dates)));
}
}
/**
*
* Handle deleting other reservations in a series (selected reservation should already be handle through entity->delete()
*
* @param $entity
*/
function reserve_reserve_reservation_delete($entity) {
if($_SESSION['reserve_delete_type']) {
_reserve_series_delete($entity);
}
return;
}
function _reserve_series_delete($entity) {
$sid = $entity->get('reservation_series_id')->getString();
// grab all reservations in this series
$ids = \Drupal::service('entity_type.manager')
->getStorage('reserve_reservation')->getQuery()
->accessCheck(TRUE)
->condition('reservation_series_id', $sid)
->execute();
$results = \Drupal::entityTypeManager()->getStorage('reserve_reservation')->loadMultiple($ids);
foreach ($results as $result) {
$result->delete();
}
$title = $entity->get('name')->getString();
\Drupal::messenger()->addStatus(t('The reservation series @title was deleted.', array('@title' => $title)));
}