diff --git a/booking.module b/booking.module index 95f0f04..38cef3e 100644 --- a/booking.module +++ b/booking.module @@ -597,6 +597,7 @@ function booking_menu() { //'type' => MENU_NORMAL_ITEM, ); + //use this for testing the autocomplete fields $items['admin/booking/rooms/test/%/assign'] = array( 'title' => 'Assign Rooms', 'description' => 'Assign attendees to rooms', @@ -605,6 +606,14 @@ function booking_menu() { 'access arguments' => array('edit room allocations'), //'type' => MENU_NORMAL_ITEM, ); + + //callback for autocomplete lookup + $items['booking/rooms/autocomplete'] = array( + 'title' => 'Autocomplete for room allocations', + 'page callback' => '_booking_rooms_name_autocomplete', + 'access arguments' => array('edit room allocations'), + 'type' => MENU_CALLBACK + ); $items['admin/booking/rooms/%/view'] = array( 'title' => 'View Allocated Rooms', diff --git a/booking.test_rooms.inc b/booking.test_rooms.inc index 799ac96..166cf1d 100644 --- a/booking.test_rooms.inc +++ b/booking.test_rooms.inc @@ -1,7 +1,33 @@ fields('p', array('nid', 'booking_firstname', 'booking_lastname')); + $db_and = db_and()->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')->condition('p.booking_event_id', $event->eid, '='); + $result = $query->condition($db_and) + ->execute(); + + // save the query to matches + foreach ($result as $row) { + $name = $row->booking_lastname . ', ' . $row->booking_firstname . ' [' . $row->nid . ']'; + $matches[$name] = $name; + } + + // Return the result to the form in json + drupal_json_output($matches); +} + +/** + * Test function for allocating people to rooms with an autocomplete field + * Using a regular table of elements as per https://passingcuriosity.com/2011/drupal-7-forms-tables/ */ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { global $event; @@ -18,11 +44,12 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { } //query for existing room allocations - $room_mapping_query = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid", - array(':eid' => $event->eid)); - //$room_mapping = $room_mapping_query->fetchAll(); - $room_mapping = $room_mapping_query->fetchAllAssoc('booking_nodeid'); - + $query = db_select('booking_person', 'p'); + $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); + $query->condition('p.booking_event_id', $event->eid, '='); + $query->fields('p', array('booking_lastname', 'booking_firstname'))->fields('m'); + $room_mapping = $query->execute()->fetchAllAssoc('booking_nodeid'); + //query for room definitions $room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid ORDER BY CAST(booking_room_number as SIGNED INTEGER) ASC", array(':lid' => $location_id)); @@ -32,27 +59,8 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { " FROM {booking_person} " . " WHERE booking_event_id = :eid and (booking_status=1 or booking_status=5) order by booking_lastname, booking_firstname", array(':eid' => $event->eid)); - - //make a list of all attendees that are booked in - $attendee_select[] = ''; - - foreach($query as $row) - { - $married = $row->booking_partner_id > 0 ? ' *' : ''; - $age = _booking_get_age_years($row->booking_dob); - $assigned_flag = empty($room_mapping[$row->nid]) ? '' : ' - '; - $attendee_select[$row->nid] = $assigned_flag . $row->booking_lastname . ', ' . $row->booking_firstname . ' ' . ' ['. $age . ' ' . $row->booking_gender . ']' . $married; - - } - - //watchdog('booking', "
Loading existing room allocations:\n@info
", array('@info' => print_r( $room_mapping, true))); - - //attach the custom css - $form['#attached']['css'] = array( - drupal_get_path('module', 'booking') . '/booking.css', - ); - - //define the header + + //define the table header $header = array ( 'booking_room_location' => array('data' => t('Room Location'), 'field' => 'booking_room_location_id'), 'booking_room_number' => array('data' => t('Room Number')), @@ -61,8 +69,24 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { 'booking_room_doublebed_p2' => array('data' => t('Double Bed Person 2')), 'booking_room_queenbed_p1' => array('data' => t('Queen Bed Person 1')), 'booking_room_queenbed_p2' => array('data' => t('Queen Bed Person 2')), + ); + + //attach the custom css + $form['#attached']['css'] = array( + drupal_get_path('module', 'booking') . '/booking.css', + ); + + //create the container element for the whole table + $form['rooms'] = array( + '#prefix' => '
', + '#suffix' => '
', + '#tree' => TRUE, + '#theme' => 'table', + '#header' => $header, + '#rows' => array(), ); + //define the default fields in a table row $default_row = array(); $default_row['booking_room_location'] = ""; $default_row['booking_room_number'] = ""; @@ -70,11 +94,11 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { $default_row['booking_room_doublebed_p1'] = ""; $default_row['booking_room_doublebed_p2'] = ""; $default_row['booking_room_queenbed_p1'] = ""; - $default_row['booking_room_queenbed_p2'] = ""; - + $default_row['booking_room_queenbed_p2'] = ""; + foreach ($room_query as $data) { - //load the existing bed mappings for this room + //create an array representing the existing bed mappings for this room $existing_beds = array(); for ($i = 1; $i <= 3; $i++) { @@ -84,102 +108,31 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { //and also the bed type matches the first dimension in the array if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i) { - $existing_beds[$i][] = $mapping->booking_nodeid; + $existing_beds[$i][] = $mapping->booking_lastname . ', ' . $mapping->booking_firstname . ' [' . $mapping->booking_nodeid . ']'; } } } - //watchdog('booking', "
Existing bed mappings:\n@info
", array('@info' => print_r( $existing_beds, true))); - - //create a row that contains just the room location and number - $row = _booking_clone_array($default_row); - $row['booking_room_location'] = _booking_room_location_lookup($data->booking_room_location_id); - $row['booking_room_number'] = $data->booking_room_number; - $row['#attributes'] = array('id' => array("new-group-row")); - $options[$counter++] = $row; - - //create an additional row for each single bed - for ($i = 0; $i < $data->booking_room_singlebeds; $i++) - { - //retrieve the default value if one exists - $default = (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : 0; + //create a row that contains just the room location and number and the custom css id for a separating line between the rooms + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_location'] = _booking_room_location_lookup($data->booking_room_location_id); + $new_row['booking_room_number'] = $data->booking_room_number; + $form['rooms']['#rows'][$counter++] = array( + 'data' => $new_row, + 'id' => array("new-group-row"), + ); - $row = _booking_clone_array($default_row); - $row['booking_room_singlebed'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_singlebed[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - $options[$counter++] = $row; - } - + //create an additional row for each single bed + _booking_rooms_allocate_generate_singlebeds($data, $existing_beds, $default_row, &$counter, &$form); + //create an additional row for each double bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 0; $i < $data->booking_room_doublebeds; $i++) - { - $row = _booking_clone_array($default_row); - $row['booking_room_doublebed_p1'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_doublebed_p1[' . $data->rid . '][' . $i . ']', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0, - )); - $row['booking_room_doublebed_p2'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_doublebed_p2[' . $data->rid . '][' . $i . ']', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0, - )); - $options[$counter++] = $row; - } + _booking_rooms_allocate_generate_doublebeds($data, $existing_beds, $default_row, &$counter, &$form); //create an additional row for each queen bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 1; $i <= $data->booking_room_queenbeds; $i++) - { - $row = _booking_clone_array($default_row); - $default = (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0; - - $row['booking_room_queenbed_p1'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_queenbed_p1[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - - //find the default for the second bed - $default = (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0; - - $row['booking_room_queenbed_p2'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_queenbed_p2[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - - //add this row to the table - $options[$counter++] = $row; - } - + _booking_rooms_allocate_generate_queenbeds($data, $existing_beds, $default_row, &$counter, &$form); + } - - $form['table'] = array ( - '#type' => 'tableselect', - '#header' => $header, - '#options' => $options, - '#empty' => t('No rooms found for this room location id.'), - ); - - //so we can access the dropdown elements - $form['booking_room_singlebed'] = array( '#type' => 'value' ); - $form['booking_room_queenbed_p1'] = array( '#type' => 'value' ); - $form['booking_room_queenbed_p2'] = array( '#type' => 'value' ); - $form['booking_room_doublebed_p1'] = array( '#type' => 'value' ); - $form['booking_room_doublebed_p2'] = array( '#type' => 'value' ); - + $form['submit'] = array ( '#type' => 'submit', '#value' => t('Submit'), @@ -190,3 +143,190 @@ function booking_rooms_allocate_test_form($node, &$form_state, $location_id) { ); } + +/** + * Process the submission for room assignment + */ +function booking_rooms_allocate_test_form_submit($form, &$form_state) { + global $event; + + $values = $form_state['input']; + watchdog('booking_debug', "
Room assignment test submission form state:\n@info
", array('@info' => print_r( $values, true))); + + //query for existing room allocations + $room_mapping_query = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); + $room_mapping = $room_mapping_query->fetchAllAssoc('booking_nodeid'); + + $bed_inputs = array( + 'booking_room_singlebed' => 1, + 'booking_room_doublebed_p1' => 2, + 'booking_room_doublebed_p2' => 2, + 'booking_room_queenbed_p1' => 3, + 'booking_room_queenbed_p2' => 3, + ); + + //go through the different bed types + foreach ($bed_inputs as $type => $type_id) + { + + //if this bed type wasn't defined in the form, skip it + if (empty($values[$type])) + continue; + + watchdog('booking_debug', "
Room assignment submission for !type:\n@info
", array('!type' => $type, '@info' => print_r( $values[$type], true))); + + //go through each room + foreach($values[$type] as $room => $data) + { + //go through each bed + foreach ($data as $bed_index => $person) + { + if (! empty($person)) { + watchdog('booking_debug', "
Processing room assignment for person:\n@info
", array('@info' => print_r( $person, true))); + + //TODO: + //extract nid from $person using regex + + //run query to see if someone was previously assigned to this bed + //if someone was, then remove the mapping if it was a different person + + //add a new mapping for this person to this bed + } + + } //next bed + } //next room + } //next bed type +} //end function + +/** + * function to generate table rows for each single bed defined in this room + */ +function _booking_rooms_allocate_generate_singlebeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each single bed + for ($i = 0; $i < $data->booking_room_singlebeds; $i++) + { + $single_bed = array ( + '#id' => 'booking-room-singlebed-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_singlebed[' . $data->rid . '][' . $i . ']', + '#size' => 50, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : '', + ); + + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-singlebed' => &$single_bed, + ); + + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_singlebed'] = array('data' => &$single_bed); + + $form['rooms']['#rows'][$counter] = $new_row; + + unset($single_bed); + $counter++; + } +} + +/** + * function to generate table rows for each double bed defined in this room + */ +function _booking_rooms_allocate_generate_doublebeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each double bed + //$j is our counter that increments twice as fast as $i to cater for both beds + $j = 0; + for ($i = 0; $i < $data->booking_room_doublebeds; $i++) + { + $double_bed_p1 = array ( + '#id' => 'booking-room-doublebed-p1-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_doublebed_p1[' . $data->rid . '][' . $i . ']', + '#size' => 50, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', + ); + $double_bed_p2 = array ( + '#id' => 'booking-room-doublebed-p2-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_doublebed_p2[' . $data->rid . '][' . $i . ']', + '#size' => 50, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', + ); + + //include fields for rendering + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-doublebed-p1' => &$double_bed_p1, + 'booking-room-doublebed-p2' => &$double_bed_p2, + ); + + //add references to the fields for the row so that theme_table can theme appropriately + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_doublebed_p1'] = array('data' => &$double_bed_p1); + $new_row['booking_room_doublebed_p2'] = array('data' => &$double_bed_p2); + $form['rooms']['#rows'][$counter] = $new_row; + + unset($double_bed_p1); + unset($double_bed_p2); + $counter++; + } +} + +/** + * function to generate table rows for each queen bed defined in this room + */ +function _booking_rooms_allocate_generate_queenbeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each double bed + //$j is our counter that increments twice as fast as $i to cater for both beds + $j = 0; + for ($i = 0; $i < $data->booking_room_queenbeds; $i++) + { + //calculate the two form elements for queen beds + $queen_bed_p1 = array ( + '#id' => 'booking-room-queenbed-p1-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_queenbed_p1[' . $data->rid . '][' . $i . ']', + '#size' => 50, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', + ); + $queen_bed_p2 = array ( + '#id' => 'booking-room-queenbed-p2-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_queenbed_p2[' . $data->rid . '][' . $i . ']', + '#size' => 50, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', + ); + + // Include the fields so they'll be rendered and named + // correctly, but they'll be ignored here when rendering as + // we're using #theme => table. + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-queenbed-p1' => &$queen_bed_p1, + 'booking-room-queenbed-p2' => &$queen_bed_p2, + ); + + // Now add references to the fields to the rows that + // `theme_table()` will use. + + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_queenbed_p1'] = array('data' => &$queen_bed_p1); + $new_row['booking_room_queenbed_p2'] = array('data' => &$queen_bed_p2); + $form['rooms']['#rows'][$counter] = $new_row; + + unset($queen_bed_p1); + unset($queen_bed_p2); + $counter++; + } +}