function book_units_per_type_form in Rooms - Drupal Booking for Hotels, B&Bs and Vacation Rentals 7
Book units per type booking form callback.
1 string reference to 'book_units_per_type_form'
- rooms_booking_manager_present_types in modules/
rooms_booking_manager/ rooms_booking_manager.module - Prepares Units on a per type basis.
File
- modules/
rooms_booking_manager/ rooms_booking_manager.module, line 1403 - Rooms Booking Manager brings together all the pieces required to find a room and book it - including the DrupalCommerce integration
Code
function book_units_per_type_form($form, $form_state, $units_per_type, $start_date, $end_date, $booking_parameters, $b_units, $type = '') {
if (isset($form_state['storage']['confirm'])) {
$form['#attached']['css'][] = array(
'data' => '.rooms-current-search__info { float: none; }',
'type' => 'inline',
);
$current_path = array(
'path' => current_path(),
'query' => drupal_get_query_parameters(),
);
return confirm_form($form, 'You have a booking request with overlapping dates, continuing will replace it.', $current_path, '', t('Continue'), 'Go Back To Search');
}
module_load_include('inc', 'rooms_booking_manager', 'rooms_booking_manager.units_per_type_form');
// Add stylesheets and classes.
$form['#attached']['css'] = array(
drupal_get_path('module', 'rooms_booking_manager') . '/css/booking_search.css',
);
$form['#attributes']['class'][] = 'rooms-availability-search-results';
$form = _rooms_booking_manager_setup_hidden_fields($form, $start_date, $end_date, $booking_parameters, $b_units);
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'];
// Check if there are multiple units chosen, and keep a running tally of
// the number of elements chosen.
$multiple_chosen = FALSE;
$chosen_unit_counter = 0;
// Sort the types by the one who has the cheapest option.
$sortorder = array();
// Before building our output, we execute one preliminary run through the
// types and units found, to gather some statistics and update sort order
// by price.
foreach ($units_per_type as $type => $units_per_price) {
foreach ($units_per_price as $price => $j) {
// Detect if units are chosen at each given price point for each type
// by inspecting the form state's "quanity" value, if some are
// selected, increment the counter.
if (isset($form_state['values']) && isset($form_state['values'][$type][$price]['quantity'])) {
$chosen_unit_counter += $form_state['values'][$type][$price]['quantity'];
}
// Build an array with the least expensive unit price per unit type.
// This is used below to sort which type should appear first.
if (!isset($sortorder[$type]) || $price < $sortorder[$type]) {
$sortorder[$type] = $price;
}
}
}
if ($chosen_unit_counter > 1) {
$multiple_chosen = TRUE;
}
// Reset the counter back to zero, so it can be used below as an incremental
// index.
$chosen_unit_counter = 0;
// Sort the types by least expensive first.
asort($sortorder);
// Calculate the period.
$nights = $form['end_date']['#value']
->diff($form['start_date']['#value'])->days;
foreach ($sortorder as $type => $least_expensive_base_price) {
// Load the units per price.
$units_per_price = $units_per_type[$type];
// Load the type obj and set a title.
$type_obj = rooms_unit_type_load($type);
// Decorate the available units by type as rows inside a table, which
// sits inside a container wrapper.
$form[$type] = array(
'#type' => 'container',
'#tree' => TRUE,
'#attributes' => array(
'class' => array(
'rooms-search-result__unit-type',
),
),
);
$form[$type]['title'] = array(
'#prefix' => '<h3 class="rooms-search-result__unit-type-name">',
'#markup' => t($type_obj->label),
'#suffix' => '</h3>',
);
$form[$type]['open-markup'] = array(
'#markup' => '<table class="rooms-search-result__booking-form">',
);
// Sort by least expensive first.
ksort($units_per_price, SORT_NUMERIC);
foreach ($units_per_price as $price => $units) {
$form[$type][$price] = array();
$form = _rooms_booking_manager_load_description($form, $type_obj, $type, $price);
$form = _rooms_booking_manager_load_price_info($form, $type_obj, $type, $price, $currency_code, $units_per_price, $units);
$form = _rooms_booking_manager_display_book_button($form, $type, $price);
// Display price options.
$form[$type][$price]['field_start'] = array(
'#markup' => '<tr id="rooms_' . $type . '_' . $price . '" style="display:none;"><td class="rooms-search-result__unit_options_wrapper" colspan="2">',
);
$form[$type][$price]['fieldset'] = array(
'#prefix' => '<div class="rooms-search-result__unit_options form-wrapper" id="' . $type . '_' . $price . '_container">',
'#type' => 'container',
'#suffix' => '</div>',
);
if (isset($form_state['values'][$type][$price]['quantity'])) {
$units_keys = array_keys($units);
for ($c = 1; $c <= $form_state['values'][$type][$price]['quantity']; $c++) {
// Looking for unit options.
$rooms_unit_options = rooms_unit_get_unit_options($units[$units_keys[$c - 1]]['unit']);
// Display each row as a fieldset.
$form[$type][$price]['fieldset'][$c]['#type'] = 'fieldset';
// If there are options or pricing is not "PER PERSON" add a css
// class and remove fieldset style.
if (empty($rooms_unit_options) && variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) != ROOMS_PER_PERSON) {
$form[$type][$price]['fieldset'][$c]['#attributes']['class'][] = 'no-unit-fieldset';
}
// Display a clean title for each unit. If there are multiple units
// chosen, add a cumulative index to the unit label. You can disable
// this feature by overriding the string used below in your
// settings.php file.
// Eg:
// $conf['locale_custom_strings_en']['']['Unit @num - @label'] = '@label';
//
$unit_label = $type_obj->label;
if ($multiple_chosen) {
$unit_label = rooms_string(t('Unit @num - @label', array(
'@num' => ++$chosen_unit_counter,
'@label' => $type_obj->label,
)), $context = array(
'#component' => 'units_results_fieldset_legend_label',
'#purpose' => 'display_fieldset_label',
'#data' => array(
'chosen_unit_counter' => $chosen_unit_counter,
'type' => $type_obj,
),
));
}
$form[$type][$price]['fieldset'][$c]['#title'] = $unit_label;
// Add options checkboxes.
foreach ($rooms_unit_options as $option) {
$form = _rooms_booking_manager_add_options($form, $form_state, $type, $price, $c, $option);
}
$tmp_unit = $units[$units_keys[$c - 1]]['unit'];
if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {
$form = _rooms_booking_manager_handle_per_person_pricing($form, $form_state, $tmp_unit, $units, $units_keys, $c, $type, $price);
}
// When prices are shown as per person, display this one as a subtotal
// for all people in the room.
$unit_type_label = rooms_unit_get_types($units[$units_keys[$c - 1]]['unit']->type)->label;
if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {
$label = rooms_string(t('Subtotal'), $context = array(
'#component' => 'units_per_type_form_subtotal_label',
'#purpose' => 'display_base_subtotal_label',
'#data' => array(
'type' => $unit_type_label,
'nights' => $nights,
'unit_number' => $c,
),
));
}
else {
$label = rooms_string(t('Price'), $context = array(
'#component' => 'units_per_type_form_price_label',
'#purpose' => 'display_base_price_label',
'#data' => array(
'type' => $unit_type_label,
'nights' => $nights,
'unit_number' => $c,
),
));
}
// 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[$type][$price]['fieldset'][$c]['price'] = array(
'#prefix' => '<div class="rooms-search-result__unit-price" id="' . $type . '_' . $price . '_' . $c . '_price"><label>' . $label . ':</label> <span class="rooms-search-result__unit-price-amount">',
'#markup' => commerce_currency_format($price_amount, $currency_code),
'#suffix' => '</span></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[$type][$price]['fieldset'][$c]['price'] = array(
'#prefix' => '<div class="rooms-search-result__unit-price" id="' . $type . '_' . $price . '_' . $c . '_price"><label>' . $label . ':</label> <span class="rooms-search-result__unit-price-amount">',
'#markup' => t('@@amount - Payable now: @deposit', array(
'@amount' => commerce_currency_format($price_amount, $currency_code),
'@deposit' => commerce_currency_format($deposit_amount, $currency_code),
)),
'#suffix' => '</span></div>',
);
}
$price_modifiers = array();
foreach (rooms_unit_get_unit_options($units[$units_keys[$c - 1]]['unit']) as $option) {
$option_name = rooms_options_machine_name($option['name']);
if ($option['type'] == ROOMS_OPTION_MANDATORY) {
$quantity = 1;
if (isset($form_state['values'][$type][$price]['fieldset'][$c][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
$quantity = $form_state['values'][$type][$price]['fieldset'][$c][$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'][$type][$price]['fieldset'][$c][$option_name])) {
$quantity = 1;
if (isset($form_state['values'][$type][$price]['fieldset'][$c][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
$quantity = $form_state['values'][$type][$price]['fieldset'][$c][$option_name . ':quantity'] + 1;
}
if ($form_state['values'][$type][$price]['fieldset'][$c][$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,
);
}
}
}
}
if (isset($form_state['values'][$type][$price]['fieldset'][$c]['persons'])) {
$group_size = $form_state['values'][$type][$price]['fieldset'][$c]['persons'];
}
else {
$group_size = $tmp_unit->max_sleeps;
}
if (isset($form_state['values'][$type][$price]['fieldset'][$c]['children'])) {
$group_size_children = $form_state['values'][$type][$price]['fieldset'][$c]['children'] + $tmp_unit->min_children;
}
else {
$group_size_children = $tmp_unit->min_children;
}
$childrens_age = array();
if (isset($form_state['values'][$type][$price]['fieldset'][$c]['persons'])) {
for ($t = 1; $t <= $form_state['values'][$type][$price]['fieldset'][$c]['children']; $t++) {
$childrens_age[] = $form_state['values'][$type][$price]['fieldset'][$c]['childrens_age'][$t];
}
}
$booking_info = array(
'start_date' => clone $start_date,
'end_date' => clone $end_date,
'unit' => $units[$units_keys[$c - 1]]['unit'],
'booking_parameters' => array(
'group_size' => $group_size,
'group_size_children' => $group_size_children,
'childrens_age' => $childrens_age,
),
);
// Price is calculated as 'Price per person per night'
if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {
// 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($units[$units_keys[$c - 1]]['unit']->unit_id, $price_modifiers);
$temp_end_date = clone $end_date;
$temp_end_date
->sub(new DateInterval('P1D'));
if (isset($form_state['values'][$type][$price]['fieldset'][$c]['persons'])) {
if (variable_get('rooms_display_children', ROOMS_DISPLAY_CHILDREN_NO) == ROOMS_DISPLAY_CHILDREN) {
$new_price = $price_calendar
->calculatePrice($start_date, $temp_end_date, $form_state['values'][$type][$price]['fieldset'][$c]['persons'], $form_state['values'][$type][$price]['fieldset'][$c]['children'], $childrens_age);
}
else {
$new_price = $price_calendar
->calculatePrice($start_date, $temp_end_date, $form_state['values'][$type][$price]['fieldset'][$c]['persons']);
}
}
else {
$new_price = $price_calendar
->calculatePrice($start_date, $temp_end_date, $tmp_unit->max_sleeps);
}
}
else {
// 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($units[$units_keys[$c - 1]]['unit']->unit_id, $price_modifiers);
// Let us make sure we remove a day.
$temp_end_date = clone $end_date;
$temp_end_date
->sub(new DateInterval('P1D'));
$new_price = $price_calendar
->calculatePrice($start_date, $temp_end_date);
}
$new_price = $new_price['full_price'];
$deposit_amount = rooms_booking_manager_check_for_deposit($new_price, $start_date);
if (empty($deposit_amount)) {
$new_price_amount = $new_price * 100;
if (module_exists('commerce_multicurrency')) {
$new_price_amount = commerce_currency_convert($new_price_amount, commerce_default_currency(), $currency_code);
}
// Replace old price with the new calculated value.
$form[$type][$price]['fieldset'][$c]['price']['#markup'] = rooms_string(commerce_currency_format($new_price_amount, $currency_code), $context = array(
'#component' => 'units_per_type_form',
'#purpose' => 'display_room_recalculated_price',
'#data' => array(
'unit_id' => $units[$units_keys[$c - 1]]['unit']->unit_id,
'unit_type' => $type_obj->label,
'price' => $price,
'new_price' => $new_price,
'currency_symbol' => $currency_symbol,
'amount' => $price,
'units' => $units_per_price,
),
));
}
else {
$new_price_amount = $new_price * 100;
if (module_exists('commerce_multicurrency')) {
$new_price_amount = commerce_currency_convert($new_price_amount, commerce_default_currency(), $currency_code);
}
$deposit_amount = $deposit_amount * 100;
if (module_exists('commerce_multicurrency')) {
$deposit_amount = commerce_currency_convert($deposit_amount, commerce_default_currency(), $currency_code);
}
// Replace old price with the new calculated value.
$form[$type][$price]['fieldset'][$c]['price']['#markup'] = rooms_string(t('@amount - Payable now: @deposit', array(
'@amount' => commerce_currency_format($new_price_amount, $currency_code),
'@deposit' => commerce_currency_format($deposit_amount, $currency_code),
)), $context = array(
'#component' => 'units_per_type_form',
'#purpose' => 'display_room_recalculated_price',
'#data' => array(
'unit_id' => $units[$units_keys[$c - 1]]['unit']->unit_id,
'unit_type' => $type_obj->label,
'price' => $price,
'new_price' => $new_price,
'currency_symbol' => $currency_symbol,
'amount' => $price,
'units' => $units_per_price,
),
));
}
}
}
$form[$type][$price]['close-row'] = array(
'#markup' => '</td></tr>',
);
}
$form[$type]['close-markup'] = array(
'#markup' => '</table> <!-- /.rooms-search-result__booking-form -->',
);
}
$form['actions'] = array(
'#type' => 'actions',
'#tree' => FALSE,
'#weight' => 400,
'#attributes' => array(
'class' => array(
'rooms-search-result__actions',
),
),
);
$form['actions']['place_booking'] = array(
'#type' => 'submit',
'#value' => variable_get_value('rooms_booking_manager_button_place_booking'),
'#submit' => array(
'book_units_per_type_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_units_per_type_form_validate';
return $form;
}