bee-8.x-1.1/modules/bee_webform/bee_webform.module
modules/bee_webform/bee_webform.module
<?php use Drupal\Component\Render\HtmlEscapedText; use Drupal\Core\Form\FormStateInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; use Drupal\webform\Entity\Webform; use Drupal\webform\Entity\WebformSubmission; use RRule\RRule; /** * Implements hook_form_alter(). */ function bee_webform_form_alter(&$form, FormStateInterface $form_state, $form_id) { if (isset($form['#webform_id'])) { $webform = Webform::load($form['#webform_id']); if ($form['#form_id'] == 'webform_submission_' . $webform->id() . '_add_form') { if (_bee_webform_get_webform_bee_reservation_element($webform)) { $form['actions']['submit']['#submit'][] = 'bee_webform_form_submit'; } } } } /** * Webform submission handler. */ function bee_webform_form_submit($form, FormStateInterface $form_state) { $webform = Webform::load($form['#webform_id']); $webform_submission = $form_state->getFormObject()->getEntity(); $webform_bee_element = _bee_webform_get_webform_bee_reservation_element($webform); $bee_element_id = $webform_bee_element['#id']; if ($webform->getHandlers('commerce_webform_order')->count()) { bee_webform_add_reservation_to_cart($webform, $webform_submission, $bee_element_id); } if (empty($webform_bee_element['#only_check_availability'])) { $value = $form_state->getValue($bee_element_id); if (empty($value['capacity'])) { $value['capacity'] = 1; } if ($value['node'] && $value['start_date'] && $value['end_date']) { $start_date = $value['start_date']; $end_date = $value['end_date']; $node = Node::load($value['node']); $node_type = NodeType::load($node->bundle()); assert($node_type instanceof NodeType); $available_units = bee_webform_get_available_units_for_node($node, $webform_submission, $bee_element_id); $events_created = []; $bee_settings = $node_type->getThirdPartySetting('bee', 'bee'); if ($bee_settings['bookable_type'] == 'daily') { $booked_state = bat_event_load_state_by_machine_name('bee_daily_booked'); $event_type = 'availability_daily'; } else { $booked_state = bat_event_load_state_by_machine_name('bee_hourly_booked'); $event_type = 'availability_hourly'; } $start_date = new \DateTime($start_date); $end_date = new \DateTime($end_date); foreach ($available_units as $unit) { if ($value['repeat']) { $repeat_until = new \DateTime($value['repeat_until'] . 'T235959Z'); $frequency = t('Day'); if ($value['repeat_frequency'] == 'weekly') { $frequency = $start_date->format('l'); } elseif ($value['repeat_frequency'] == 'monthly') { $frequency = t('@day of Month', ['@day' => $start_date->format('jS')]); } $label = t('Reservations for @node Every @frequency from @start_time-@end_time from @start_date -> @end_date', [ '@node' => $node->label(), '@frequency' => $frequency, '@start_time' => $start_date->format('gA'), '@end_time' => $end_date->format('gA'), '@start_date' => $start_date->format('M j Y'), '@end_date' => $repeat_until->format('M j Y'), ]); $rrule = new RRule([ 'FREQ' => strtoupper($value['repeat_frequency']), 'UNTIL' => $value['repeat_until'] . 'T235959Z', ]); $event = bat_event_series_create([ 'type' => $event_type, 'label' => $label, 'rrule' => $rrule->rfcString(), ]); } else { $event = bat_event_create(['type' => $event_type]); } $event_dates = [ 'value' => $start_date->format('Y-m-d\TH:i:00'), 'end_value' => $end_date->format('Y-m-d\TH:i:00'), ]; $event->set('event_dates', $event_dates); $event->set('event_state_reference', $booked_state->id()); $event->set('field_event_webform_submission', $webform_submission->id()); $event->set('event_bat_unit_reference', $unit); $event->save(); if ($value['repeat']) { $query = \Drupal::entityQuery('bat_event') ->condition('event_series.target_id', $event->id()); $events_created = $query->execute(); foreach ($events_created as $event_id) { $repeat_event = bat_event_load($event_id); $repeat_event->set('field_event_webform_submission', $webform_submission->id()); $repeat_event->save(); } } else { $events_created[] = $event->id(); } $data = $webform_submission->getData(); $data[$bee_element_id]['events'] = implode(',', $events_created); $webform_submission->setElementData($bee_element_id, $data[$bee_element_id]); $webform_submission->save(); } // Send email with summary of any allocations made. if (count($events_created) == 0) { $message = t("No nodes with sufficient capacity were found, therefore no reservations were created.\nTo view the submission, please go to @submission", ['@submission' => $webform_submission->url('canonical', ['absolute' => TRUE])]); } else { $events = bat_event_load_multiple($events_created); $event_links = []; foreach ($events as $event) { $event_links[] = $event->url('canonical', ['absolute' => TRUE]); } $message = t("The following BEE reservations were created for a new webform submission:\n\n@event_links\n\nTo view the submission, please go to @submission", ['@event_links' => implode("\n", $event_links), '@submission' => $webform_submission->url('canonical', ['absolute' => TRUE])]); } $mailManager = \Drupal::service('plugin.manager.mail'); $module = 'bee_webform'; $key = 'bee_webform_submission'; $webform_owner = ($webform->getOwner()) ? $webform->getOwner() : \Drupal::currentUser(); $to = $webform_owner->getEmail(); $params['webform_title'] = $webform->get('title'); $params['message'] = $message; $langcode = $webform_owner->getPreferredLangcode(); $send = TRUE; $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send); if ($result['result'] !== TRUE) { $message = t('There was a problem sending your email notification to @email for creating a webform BEE reservation.', ['@email' => $to]); \Drupal::messenger()->addError($message); \Drupal::logger('bee_webform')->error($message); return; } $message = t('An email notification has been sent to @email for creating a webform BEE reservation.', ['@email' => $to]); \Drupal::messenger()->addMessage($message); \Drupal::logger('bee_webform')->notice($message); } } } /** * Get available Units. * * @param $values * * return array */ function bee_webform_get_available_units($values) { $start_date = $values['start_date']; $end_date = $values['end_date']; $node = Node::load($values['node']); $node_type = NodeType::load($node->bundle()); assert($node_type instanceof NodeType); $bee_settings = $node_type->getThirdPartySetting('bee', 'bee'); $availability_type = $bee_settings['bookable_type']; $field_name = 'field_availability_' . $availability_type . '_target_id'; $query = \Drupal::database()->select('node__field_availability_' . $availability_type, 'nfa'); $query->addField('nfa', $field_name); $query->condition('nfa.entity_id', $node->id()); $unit_ids = $query->execute()->fetchCol(); $drupal_units = bat_unit_load_multiple($unit_ids); if ($bee_settings['bookable_type'] == 'daily') { $start_date = new \DateTime($start_date); $end_date = new \DateTime($end_date); $end_date->sub(new \DateInterval('PT1M')); $available_units_ids = bat_event_get_matching_units($start_date, $end_date, ['bee_daily_available'], [$bee_settings['type_id']], 'availability_daily', FALSE, $drupal_units); } else { $start_date = new \DateTime($start_date); $end_date = new \DateTime($end_date); $end_date->sub(new \DateInterval('PT1M')); $available_units_ids = bat_event_get_matching_units($start_date, $end_date, ['bee_hourly_available'], [$bee_settings['type_id']], 'availability_hourly', FALSE, $drupal_units); } // Remove unavailable units from mapping. $units = array_intersect($unit_ids, $available_units_ids); return $units; } /** * Get available Units for a given node. * * @param $node * @param \Drupal\webform\Entity\WebformSubmission $webform_submission * @param $bee_element_id * * return array */ function bee_webform_get_available_units_for_node($node, WebformSubmission $webform_submission, $bee_element_id) { $data = $webform_submission->getData(); $start_date = $data[$bee_element_id]['start_date']; $end_date = $data[$bee_element_id]['end_date']; $node_type = NodeType::load($node->bundle()); assert($node_type instanceof NodeType); $bee_settings = $node_type->getThirdPartySetting('bee', 'bee'); $drupal_units = []; foreach ($node->get('field_availability_' . $bee_settings['bookable_type']) as $unit) { $drupal_units[$unit->entity->id()] = $unit->entity; } if ($bee_settings['bookable_type'] == 'daily') { $start_date = new \DateTime($start_date); $end_date = new \DateTime($end_date); $end_date->sub(new \DateInterval('PT1M')); $available_units_ids = bat_event_get_matching_units($start_date, $end_date, ['bee_daily_available'], $bee_settings['type_id'], 'availability_daily', FALSE, $drupal_units); } else { $start_date = new \DateTime($start_date); $end_date = new \DateTime($end_date); $end_date->sub(new \DateInterval('PT1M')); $available_units_ids = bat_event_get_matching_units($start_date, $end_date, ['bee_hourly_available'], $bee_settings['type_id'], 'availability_hourly', FALSE, $drupal_units); } return $available_units_ids; } /** * @param $field_name * @param $event_type */ function bee_webform_add_event_webform_reference_field($field_name, $event_type) { $field_storage = FieldStorageConfig::loadByName('bat_event', $field_name); $field = FieldConfig::loadByName('bat_event', $event_type, $field_name); if (empty($field_storage)) { $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'bat_event', 'type' => 'entity_reference', 'cardinality' => 1, 'locked' => 1, 'settings' => [ 'target_type' => 'webform_submission', ], ]); $field_storage->save(); } if (empty($field)) { $field = FieldConfig::create([ 'field_storage' => $field_storage, 'entity_type' => 'bat_event', 'label' => 'Webform', 'bundle' => $event_type, 'required' => FALSE, 'settings' => [ 'handler' => 'default', 'handler_settings' => [], ], ]); $field->save(); } } /** * @param $field_name * @param $event_type */ function bee_webform_add_event_series_webform_reference_field($field_name, $event_type) { $field_storage = FieldStorageConfig::loadByName('bat_event_series', $field_name); $field = FieldConfig::loadByName('bat_event_series', $event_type, $field_name); if (empty($field_storage)) { $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'bat_event_series', 'type' => 'entity_reference', 'cardinality' => 1, 'locked' => 1, 'settings' => [ 'target_type' => 'webform_submission', ], ]); $field_storage->save(); } if (empty($field)) { $field = FieldConfig::create([ 'field_storage' => $field_storage, 'entity_type' => 'bat_event_series', 'label' => 'Webform', 'bundle' => $event_type, 'required' => FALSE, 'settings' => [ 'handler' => 'default', 'handler_settings' => [], ], ]); $field->save(); } } /** * Implements hook_mail(). */ function bee_webform_mail($key, &$message, $params) { $options = [ 'langcode' => $message['langcode'], ]; switch ($key) { case 'bee_webform_submission': $message['from'] = \Drupal::config('system.site')->get('mail'); $message['subject'] = t('Reservations created from webform @title', ['@title' => $params['webform_title']], $options); $message['body'][] = new HtmlEscapedText($params['message']); break; } } /** * @param \Drupal\webform\Entity\Webform $webform * * @return array|false */ function _bee_webform_get_webform_bee_reservation_element(Webform $webform) { foreach ($webform->getElementsDecodedAndFlattened() as $element_id => $element) { if ($element['#type'] == 'webform_bee_reservation_form') { $element['#id'] = $element_id; return $element; } } return FALSE; } /** * @param \Drupal\webform\Entity\Webform $webform * @param \Drupal\webform\Entity\WebformSubmission $webform_submission * @param $bee_element_id */ function bee_webform_add_reservation_to_cart(Webform $webform, WebformSubmission $webform_submission, $bee_element_id) { $data = $webform_submission->getData(); $store = \Drupal::service('commerce_store.current_store')->getStore(); $cart_provider = \Drupal::service('commerce_cart.cart_provider'); $cart = $cart_provider->getCart('default', $store); $start_date = new \DateTime($data[$bee_element_id]['start_date']); $end_date = new \DateTime($data[$bee_element_id]['end_date']); $node = Node::load($data[$bee_element_id]['node']); foreach ($cart->getItems() as $order_item) { if ($order_item->bundle() == 'bee') { if (bee_webform_get_available_units_for_node($node, $webform_submission, $bee_element_id)) { $booking = bat_booking_create([ 'type' => 'bee', 'label' => $node->label(), ]); $booking->set('booking_start_date', $start_date->format('Y-m-d\TH:i:s')); $booking->set('booking_end_date', $end_date->format('Y-m-d\TH:i:s')); $booking->set('booking_capacity', $data[$bee_element_id]['capacity']); $booking->save(); $unit_price = bee_get_unit_price($node, $booking, $start_date, $end_date); $order_item->set('field_booking', $booking); $order_item->set('field_node', $node); $order_item->setUnitPrice($unit_price, TRUE); $order_item->save(); } } } }