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();
      }
    }
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc