You are here

function book_unit_form_builder in Rooms - Drupal Booking for Hotels, B&Bs and Vacation Rentals 7

The form builder builds the form (where visible is simply the purchase button) for individual bookable units.

The builder gets called for each unit from the rooms_booking_manager_present_individual_rooms function above.

The available units have already been identified by rooms_booking_manager_results_page.

2 string references to 'book_unit_form_builder'
rooms_booking_manager_forms in modules/rooms_booking_manager/rooms_booking_manager.module
Implements hook_forms().
rooms_periodic_pricing_rooms_string_alter in modules/rooms_pricing/modules/rooms_periodic_pricing/rooms_periodic_pricing.module
Implements hook_rooms_string_alter().

File

modules/rooms_booking_manager/rooms_booking_manager.module, line 829
Rooms Booking Manager brings together all the pieces required to find a room and book it - including the DrupalCommerce integration

Code

function book_unit_form_builder($form_id, $form_state, $unit, $start_date, $end_date, $booking_parameters, $status, $price, $price_log) {

  // Add classes.
  $form['#attributes']['class'][] = 'rooms-book-unit-form';
  if (module_exists('commerce_multicurrency')) {
    $currency_code = commerce_multicurrency_get_user_currency_code();
  }
  else {
    $currency_code = commerce_default_currency();
  }
  $currency_setting = commerce_currency_load($currency_code);
  $currency_symbol = $currency_setting['symbol'];
  $form['unit_id'] = array(
    '#type' => 'hidden',
    '#value' => $unit->unit_id,
  );
  $form['status'] = array(
    '#type' => 'hidden',
    '#value' => $status,
  );
  $form['start_date'] = array(
    '#type' => 'hidden',
    '#value' => $start_date
      ->format('Y-m-d'),
  );
  $form['end_date'] = array(
    '#type' => 'hidden',
    '#value' => $end_date
      ->format('Y-m-d'),
  );
  $form['rooms_group_size'] = array(
    '#type' => 'hidden',
    '#value' => $booking_parameters[1]['adults'],
  );
  if (isset($booking_parameters[1]['children'])) {
    $form['rooms_children'] = array(
      '#type' => 'hidden',
      '#value' => $booking_parameters[1]['children'],
    );
  }

  // Calculate the period.
  $nights = $end_date
    ->diff($start_date)->days;

  // Check for a deposit.
  $deposit_amount = rooms_booking_manager_check_for_deposit($price, $start_date);
  if (empty($deposit_amount)) {
    $price_amount = $price * 100;
    if (module_exists('commerce_multicurrency')) {
      $price_amount = commerce_currency_convert($price_amount, commerce_default_currency(), $currency_code);
    }
    $form['price'] = array(
      '#prefix' => '<div class="rooms-search-result__unit-base-price" id="unit_' . $unit->unit_id . '_base_price">',
      '#markup' => rooms_string('<label>' . t('Base price') . ':</label> <span class="rooms-search-result__base-price-amount">' . commerce_currency_format($price_amount, $currency_code) . '</span>', array(
        '#component' => 'book_unit_form_builder',
        '#purpose' => 'display_base_price',
        '#data' => array(
          'price' => $price,
          'currency_symbol' => $currency_symbol,
          'amount' => $price,
          'unit' => $unit,
          'nights' => $nights,
          'arrival' => $start_date,
          'departure' => $end_date,
          'price_log' => $price_log,
        ),
      )),
      '#suffix' => '</div>',
    );
  }
  else {
    $deposit_amount = $deposit_amount * 100;
    if (module_exists('commerce_multicurrency')) {
      $deposit_amount = commerce_currency_convert($deposit_amount, commerce_default_currency(), $currency_code);
    }
    $price_amount = $price * 100;
    if (module_exists('commerce_multicurrency')) {
      $price_amount = commerce_currency_convert($price_amount, commerce_default_currency(), $currency_code);
    }
    $form['price'] = array(
      '#prefix' => '<div class="rooms-search-result__unit-base-price" id="unit_' . $unit->unit_id . '_base_price">',
      '#markup' => rooms_string('<label>' . t('Base price') . ':</label> <span class="rooms-search-result__base-price-amount">' . commerce_currency_format($price, $currency_code) . '</span>' . '<label>' . ' - ' . t('Payable now') . ':</label> <span class="rooms-search-result__base-price-amount">' . commerce_currency_format($deposit_amount, $currency_code) . '</span>', array(
        '#component' => 'book_unit_form_builder',
        '#purpose' => 'display_base_price',
        '#data' => array(
          'price' => $price,
          'currency_symbol' => $currency_symbol,
          'amount' => $price,
          'unit' => $unit,
          'nights' => $nights,
          'arrival' => $start_date,
          'departure' => $end_date,
          'price_log' => $price_log,
        ),
      )),
      '#suffix' => '</div>',
    );
  }
  if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {

    // Calculate the price per person for the period.
    $price_per_person = $price / $unit->max_sleeps * 100;

    // Calculate the price per person per night, too.
    $base_price = $price_per_person / $nights;
    if (module_exists('commerce_multicurrency')) {
      $price_per_person = commerce_currency_convert($price_per_person, commerce_default_currency(), $currency_code);
      $base_price = commerce_currency_convert($base_price, commerce_default_currency(), $currency_code);
    }
    $form['price']['#markup'] = rooms_string(format_plural($nights, t('Book this unit for 1 night at <b>@price per person</b> (@base_price per person per night)'), t('Book this unit for @count nights at <b>@price per person</b> (@base_price per person per night)'), array(
      '@price' => commerce_currency_format($price_per_person, $currency_code),
      '@base_price' => commerce_currency_format($base_price, $currency_code),
    )), array(
      '#component' => 'book_unit_form_builder',
      '#purpose' => 'display_base_price_per_person',
      '#data' => array(
        'price' => $price,
        'currency_symbol' => $currency_symbol,
        'amount' => $price,
        'unit' => $unit,
        'nights' => $nights,
        'arrival' => $start_date,
        'departure' => $end_date,
      ),
    ));
  }
  $form['options'] = array(
    '#tree' => TRUE,
  );

  // Add options checkboxes and convert Price options in Price modifiers.
  $price_modifiers = array();
  foreach (rooms_unit_get_unit_options($unit) as $option) {
    $option_name = rooms_options_machine_name($option['name']);
    $form['options'][$option_name] = array(
      '#type' => 'checkbox',
      '#title' => t($option['name']),
      '#ajax' => array(
        'callback' => 'rooms_booking_manager_options_change_callback',
        'wrapper' => 'unit_' . $unit->unit_id . '_price',
      ),
    );
    if ($option['type'] == ROOMS_OPTION_MANDATORY) {
      $form['options'][$option_name]['#default_value'] = '1';
      $form['options'][$option_name]['#disabled'] = TRUE;
    }

    // Show quantity field selector if in option quantity is set.
    if (is_numeric($option['quantity'])) {
      if ((isset($form_state['values']['options'][$option_name]) && $form_state['values']['options'][$option_name] == 1 || $option['type'] == ROOMS_OPTION_MANDATORY) && $option['quantity'] > 1) {
        $form['options'][$option_name . ':quantity'] = array(
          '#type' => 'select',
          '#title' => t('Quantity'),
          '#options' => range(1, $option['quantity']),
          '#ajax' => array(
            'callback' => 'rooms_booking_manager_options_change_callback',
            'wrapper' => 'unit_' . $unit->unit_id . '_price',
          ),
          '#prefix' => '<div class="rooms-search-result__unit-quantity" id="unit_' . $unit->unit_id . '_' . $option_name . '_quantity">',
          '#suffix' => '</div>',
        );
      }
      else {
        $form['options'][$option_name . ':quantity'] = array(
          '#prefix' => '<div class="rooms-search-result__unit-quantity" id="unit_' . $unit->unit_id . '_' . $option_name . '_quantity">',
          '#suffix' => '</div>',
        );
      }
    }
    if ($option['type'] == ROOMS_OPTION_MANDATORY) {
      $quantity = 1;
      if (isset($form_state['values']['options'][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
        $quantity = $form_state['values']['options'][$option_name . ':quantity'] + 1;
      }
      $price_modifiers[$option_name] = array(
        '#type' => ROOMS_DYNAMIC_MODIFIER,
        '#op_type' => $option['operation'],
        '#amount' => $option['value'],
        '#quantity' => $quantity,
      );
    }
    elseif (isset($form_state['values']['options'][$option_name])) {
      $quantity = 1;
      if (isset($form_state['values']['options'][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
        $quantity = $form_state['values']['options'][$option_name . ':quantity'] + 1;
      }
      if ($form_state['values']['options'][$option_name] == 1) {
        if ($option['type'] != ROOMS_OPTION_ONREQUEST) {
          $price_modifiers[$option_name] = array(
            '#type' => ROOMS_DYNAMIC_MODIFIER,
            '#op_type' => $option['operation'],
            '#amount' => $option['value'],
            '#quantity' => $quantity,
          );
        }
      }
    }
  }

  // Price is calculated as 'Price per person per night'
  if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {
    $form['persons'] = array(
      '#type' => 'select',
      '#field_suffix' => t('Guests'),
      '#options' => range($unit->min_sleeps, $unit->max_sleeps),
      '#default_value' => $unit->max_sleeps - $unit->min_sleeps,
      '#ajax' => array(
        'callback' => 'rooms_booking_manager_quantity_change_callback',
        'wrapper' => 'unit_' . $unit->unit_id . '_price',
      ),
      '#title' => t('How many people in this unit (including adults and children)?'),
      '#prefix' => '<div class="rooms-search-result__select-guests">',
      '#suffix' => '</div>',
    );
    $max_children = $unit->max_children;
    if (isset($form_state['values']['persons'])) {
      $persons = $form_state['values']['persons'] + $unit->min_sleeps;
      if ($persons < $unit->max_children) {
        $max_children = $persons;
      }
    }
    if ($max_children > $unit->min_children) {
      $form['children'] = array(
        '#type' => 'select',
        '#title' => t('How many of the guests are children?'),
        '#field_suffix' => t('Children'),
        '#options' => range($unit->min_children, $max_children),
        '#default_value' => 0,
        '#ajax' => array(
          'callback' => 'rooms_booking_manager_children_change_callback',
          'wrapper' => 'unit_' . $unit->unit_id . '_childrensage',
        ),
        '#prefix' => '<div class="rooms-search-result__select-children">',
        '#suffix' => '</div>',
      );
    }
    $form['childrens_age'] = array(
      '#prefix' => '<div class="rooms-search-result__select-childrensage" id="unit_' . $unit->unit_id . '_childrensage">',
      '#suffix' => '</div>',
      '#tree' => TRUE,
    );
    if (isset($form_state['values']['children'])) {
      if ($form_state['values']['children'] > 0) {
        for ($t = 1; $t <= $form_state['values']['children']; $t++) {
          $form['childrens_age'][$t] = array(
            '#type' => 'select',
            '#field_prefix' => t('Age of child @num', array(
              '@num' => $t,
            )),
            '#options' => range(0, 18),
            '#ajax' => array(
              'callback' => 'rooms_booking_manager_options_change_callback',
              'wrapper' => 'unit_' . $unit->unit_id . '_price',
            ),
            '#attributes' => array(
              'class' => array(
                'rooms-search-result__childrens-age',
              ),
            ),
          );
        }
      }
    }
  }
  $form['price_amount'] = array(
    '#type' => 'hidden',
    '#value' => $price,
  );

  // Check for a deposit.
  $deposit_amount = rooms_booking_manager_check_for_deposit($price, $start_date);
  if (!empty($deposit_amount)) {
    $form['deposit_amount'] = array(
      '#type' => 'hidden',
      '#value' => $deposit_amount,
    );
  }
  $unit_options = rooms_unit_get_unit_options($unit);
  if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON || !empty($unit_options)) {
    if (isset($form_state['values']['persons'])) {
      $group_size = $form_state['values']['persons'] + $unit->min_sleeps;
    }
    else {
      $group_size = $unit->max_sleeps;
    }
    $group_size_children = isset($form_state['values']['children']) ? $form_state['values']['children'] + $unit->min_children : 0;
    $temp_end_date = clone $end_date;
    $temp_end_date
      ->sub(new DateInterval('P1D'));
    $childrens_age = array();
    if (isset($form_state['values']['persons'])) {
      for ($t = 1; $t <= $form_state['values']['children']; $t++) {
        $childrens_age[] = $form_state['values']['childrens_age'][$t];
      }
    }
    $booking_info = array(
      'start_date' => clone $start_date,
      'end_date' => clone $end_date,
      'unit' => $unit,
      'booking_parameters' => array(
        'group_size' => $group_size,
        'group_size_children' => $group_size_children,
        'childrens_age' => $childrens_age,
      ),
    );

    // Give other modules a chance to change the price modifiers.
    drupal_alter('rooms_price_modifier', $price_modifiers, $booking_info);

    // Apply price modifiers and replace unit price.
    $price_calendar = new UnitPricingCalendar($unit->unit_id, $price_modifiers);
    if (isset($form_state['values']['persons'])) {
      $new_price = $price_calendar
        ->calculatePrice($start_date, $temp_end_date, $form_state['values']['persons'] + $unit->min_sleeps, $form_state['values']['children'] + $unit->min_children, $childrens_age);
    }
    else {
      $new_price = $price_calendar
        ->calculatePrice($start_date, $temp_end_date, $unit->max_sleeps);
    }

    // Check for a deposit.
    $deposit_amount = rooms_booking_manager_check_for_deposit($new_price['full_price'], $start_date);
    $form['price_amount']['#value'] = $new_price['full_price'];
    $new_price['full_price'] = $new_price['full_price'] * 100;
    if (module_exists('commerce_multicurrency')) {
      $new_price['full_price'] = commerce_currency_convert($new_price['full_price'], commerce_default_currency(), $currency_code);
    }
    if (empty($deposit_amount)) {
      $form['new_price'] = array(
        '#prefix' => '<div class="rooms-search-result__new-price" id="unit_' . $unit->unit_id . '_price">',
        '#markup' => '<label>' . t('Cost') . ':</label> <span class="rooms-search-result__new-price-amount">' . commerce_currency_format($new_price['full_price'], $currency_code) . '</span>',
        '#suffix' => '</div>',
      );
    }
    else {
      $form['deposit_amount']['#value'] = $deposit_amount;
      $form['new_price'] = array(
        '#prefix' => '<div class="rooms-search-result__new-price" id="unit_' . $unit->unit_id . '_price">',
        '#markup' => '<label>' . t('Cost') . ':</label> <span class="rooms-search-result__new-price-amount">' . commerce_currency_format($new_price['full_price'], $currency_code) . '</span>' . '<label>' . ' - ' . t('Payable Now') . ':</label> <span class="rooms-search-result__new-price-deposit">' . commerce_currency_format($deposit_amount * 100, $currency_code) . '</span>',
        '#suffix' => '</div>',
      );
    }
  }

  // We add the form's #submit array to this button along with the actual submit
  // handler to preserve any submit handlers added by a form callback_wrapper.
  $submit = array();
  if (!empty($form['#submit'])) {
    $submit += $form['#submit'];
  }
  $form['actions'] = array(
    '#type' => 'container',
    '#tree' => FALSE,
    '#attributes' => array(
      'class' => array(
        'rooms-search-result__actions',
      ),
    ),
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Book This'),
    '#submit' => $submit + array(
      'book_unit_form_submit',
    ),
  );

  // We append the validate handler to #validate in case a form callback_wrapper
  // is used to add validate handlers earlier.
  $form['#validate'][] = 'book_unit_form_validate';
  return $form;
}