$group_id)) ->fetchObject(); if (! $studygroup) { drupal_set_message("Error: Could not find matching study group ID. Unable to edit leaders/helpers.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } $prefix = t("
Allocate a leader/helper session for attendees.
", array('!descrip' => $studygroup->booking_studygroup_descrip)); //select the number of study group sessions //assume they all have the same number of sessions $num_sessions = $studygroup->booking_num_group_sessions; $session_options[0] = ''; for ($i = 1; $i <= $num_sessions; $i++) $session_options[$i] = $i; $session_options['Remove'] = 'Remove'; //select any entries already in the mapping table $group_mapping_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $group_mapping = $group_mapping_query->fetchAllAssoc('sid'); //***form starts here*** $form['booking_studygroup'] = array ( '#type' => 'hidden', '#value' => $group_id, ); $header = array ( 'booking_nid' => array('data' => t('Booking ID'), 'field' => 'nid'), 'booking_name' => array('data' => t('Name'), 'field' => 'booking_lastname'), 'booking_baptised' => array('data' => t('Baptised?'), 'field' => 'booking_baptised'), 'booking_age' => array('data' => t('Age (start of week)'), 'field' => 'booking_dob', 'sort' => 'asc'), 'booking_state' => array('data' => t('State'), 'field' => 'booking_state'), 'booking_status' => array('data' => t('Status'), 'field' => 'booking_status'), 'booking_assign_leader_session' => array('data' => t('Leader Session')), 'booking_assign_helper_session' => array('data' => t('Helper Session')), 'booking_assign_reserveleader_session' => array('data' => t('Reserve Leader Session')), 'booking_currently_leadhelp' => array('data' => t('Currently leading/helping')), ); $query = db_select('booking_person', 'p'); //only select people that are either booked in or on the waiting list $db_or = db_or(); $db_or->condition('p.booking_status', 1, '='); $db_or->condition('p.booking_status', 2, '='); //also restrict to males from the current event $db_and = db_and(); $db_and->condition('p.booking_event_id', $event->eid, '='); $db_and->condition('p.booking_gender', 'M', '='); $db_and->condition($db_or); $query->condition($db_and); $query->fields('p'); $table_sort = $query->extend('TableSort')->orderbyHeader($header); $result = $table_sort->execute(); foreach($result as $data) { $role_listing = ""; $assigned_role = 0; $session_id = 0; //work out what this person is currently leading/helping foreach ($group_mapping as $group) { $role = $group->booking_studygroup_role; //add to the listing of all the roles this person is doing if ($group->booking_node_id == $data->nid && $role > 0) { $text = _booking_studygroup_role_lookup($role); $role_listing .= $text . " group " . $group->booking_studygroup_id . " #" . $group->booking_session_id . "; "; } //also record if they are doing anything for our current group if ($group->booking_node_id == $data->nid && $group->booking_studygroup_id == $group_id) { $assigned_role = $role; $session_id = $group->booking_session_id; } } $options[$data->nid] = array ( 'booking_nid' => l(t('!id', array('!id' => $data->nid)), t('node/!id', array('!id' => $data->nid))), 'booking_name' => l(t($data->booking_firstname . " " . $data->booking_lastname), t('node/!id', array('!id' => $data->nid))), 'booking_baptised' => $data->booking_baptised == 'Y' ? 'Yes' : 'No', 'booking_age' => _booking_avg_age($data->booking_dob, 1, $event->booking_event_start), 'booking_state' => $data->booking_state, 'booking_status' => _booking_status_generate($data->booking_status), 'booking_assign_leader_session' => array('data' => array( '#type' => 'select', '#options' => $session_options, '#name' => 'booking_assign_leader_session[' . $data->nid . ']', '#value' => $assigned_role == 1 ? $session_id : 0, ) ), 'booking_assign_helper_session' => array('data' => array( '#type' => 'select', '#options' => $session_options, '#name' => 'booking_assign_helper_session[' . $data->nid . ']', '#value' => $assigned_role == 2 ? $session_id : 0, ) ), 'booking_assign_reserveleader_session' => array('data' => array( '#type' => 'select', '#options' => $session_options, '#name' => 'booking_assign_reserveleader_session[' . $data->nid . ']', '#value' => $assigned_role == 3 ? $session_id : 0, ) ), 'booking_currently_leadhelp' => $role_listing, ); } $form['table'] = array ( '#type' => 'tableselect', '#header' => $header, '#options' => $options, '#empty' => t('No attendees found.'), '#attributes' => array('id' => 'sort-table'), ); //so we can access the dropdown elements $form['booking_assign_leader_session'] = array( '#type' => 'value', ); $form['booking_assign_reserveleader_session'] = array( '#type' => 'value', ); $form['booking_assign_helper_session'] = array( '#type' => 'value', ); $form['submit'] = array ( '#type' => 'submit', '#value' => t('Submit'), ); return array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'form' => $form, ); } /** * Validate the submission for defining which study group sessions people will lead or help */ function booking_available_leadhelp_select_form_validate($form, &$form_state) { //check that a study group was selected if ($booking_studygroup = $form_state['values']['booking_studygroup'] == 0) { form_set_error('booking_studygroup', t('You forgot to select which study group to apply this list to.') ); } } /** * Process the submission for number of study group sessions to lead/help */ function booking_available_leadhelp_select_form_submit($form, &$form_state) { global $event; $counter = 0; $checkboxes = $form_state['values']['table']; $booking_studygroup = $form_state['values']['booking_studygroup']; $leader_session = $form_state['values']['booking_assign_leader_session']; $reserve_leader_session = $form_state['values']['booking_assign_reserveleader_session']; $helper_session = $form_state['values']['booking_assign_helper_session']; //watchdog('booking', "Leader list: @info", array('@info' => var_export($form_state['values'], TRUE))); //watchdog('booking', "Helper list: @info", array('@info' => var_export($reserve_leader_session, TRUE))); //select any entries already in the mapping table $group_mapping_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $group_mapping = $group_mapping_query->fetchAllAssoc('sid'); //update the attendees as specified foreach($checkboxes as $key => $value) { $leader = 'N'; $helper = 'N'; $reserve_leader = 'N'; $session = 0; $role = 0; $found = FALSE; //remove from being a leader? if ($leader_session[$key] == "Remove") { $num_deleted = db_delete('booking_studygroup_mapping') ->condition('booking_eventid', $event->eid) ->condition('booking_node_id', $key) ->condition('booking_studygroup_id', $booking_studygroup) // ->condition('booking_session_id', $leader_session[$key]) // ->condition('booking_is_leader', 'Y') ->execute(); watchdog('booking', 'Removed person !nid from being a leader in study group !sid, affected !num rows.', array ('!nid' => $key, '!sid' => $booking_studygroup, '!num' => $num_deleted)); //skip to the next person $counter++; continue; } //remove from being a helper? elseif ($helper_session[$key] == "Remove") { $num_deleted = db_delete('booking_studygroup_mapping') ->condition('booking_eventid', $event->eid) ->condition('booking_node_id', $key) ->condition('booking_studygroup_id', $booking_studygroup) // ->condition('booking_session_id', $helper_session[$key]) // ->condition('booking_is_helper', 'Y') ->execute(); watchdog('booking', 'Removed person !nid from being a helper in study group !sid, affected !num rows.', array ('!nid' => $key, '!sid' => $booking_studygroup, '!num' => $num_deleted)); //skip to the next person $counter++; continue; } //remove from being a reserve leader? elseif ($reserve_leader_session[$key] == "Remove") { $num_deleted = db_delete('booking_studygroup_mapping') ->condition('booking_eventid', $event->eid) ->condition('booking_node_id', $key) ->condition('booking_studygroup_id', $booking_studygroup) // ->condition('booking_session_id', $reserve_leader_session[$key]) // ->condition('booking_is_reserveleader', 'Y') ->execute(); watchdog('booking', 'Removed person !nid from being a reserve leader in study group !sid, affected !num rows.', array ('!nid' => $key, '!sid' => $booking_studygroup, '!num' => $num_deleted)); //skip to the next person $counter++; continue; } //was this person set as a leader? elseif ($leader_session[$key] <> 0) { $role = 1; $session = $leader_session[$key]; watchdog('booking', 'Person !nid is set to be a leader in session !sid, group !group', array ('!nid' => $key, '!sid' => $leader_session[$key], '!group' => $booking_studygroup)); } //was this person set as a helper? elseif ($helper_session[$key] <> 0) { $role = 2; $session = $helper_session[$key]; watchdog('booking', 'Person !nid is set to be a helper in session !sid, group !group', array ('!nid' => $key, '!sid' => $helper_session[$key], '!group' => $booking_studygroup)); } elseif ($reserve_leader_session[$key] <> 0) { $role = 3; $session = $reserve_leader_session[$key]; watchdog('booking', 'Person !nid is set to be a reserve leader in session !sid, group !group', array('!nid' => $key, '!sid' => $helper_session[$key], '!group' => $booking_studygroup)); } //if we reach the else something weird happened, make sure we don't insert else continue; //check if this person already exists in the booking_studygroup_mapping table foreach ($group_mapping as $person) { if ($person->booking_node_id == $key && $person->booking_studygroup_id == $booking_studygroup) { $found = TRUE; break; } } if ($found == FALSE) { //run an insert db_insert('booking_studygroup_mapping') ->fields(array( 'booking_eventid' => $event->eid, 'booking_node_id' => $key, 'booking_studygroup_id' => $booking_studygroup, 'booking_session_id' => $session, 'booking_studygroup_role' => $role, //'booking_is_leader' => $leader, //'booking_is_helper' => $helper, //'booking_is_reserveleader' => $reserve_leader, )) ->execute(); } else { //run an update db_update('booking_studygroup_mapping') ->fields(array ( 'booking_session_id' => $session, 'booking_studygroup_role' => $role, //'booking_is_leader' => $leader, //'booking_is_helper' => $helper, //'booking_is_reserveleader' => $reserve_leader, )) ->condition('booking_node_id', $key) ->condition('booking_studygroup_id', $booking_studygroup) ->execute(); } $counter++; } $message = t("Processed !num leader/helper sessions for group id !id", array('!num' => $counter, '!id' => $booking_studygroup)); drupal_set_message($message, 'status', FALSE); watchdog('booking', $message); } /** * Function for manually assigning study group sessions for a person */ function booking_studygroups_edit_form($node, &$form_state, $nid) { global $event; //see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios $form = array (); $options = array (); $session_options = array(); $session_options[0] = ''; //verify that $nid is a number if (! preg_match('/^[0-9]+$/', $nid)) { drupal_set_message("Error: Invalid registration ID '" . $nid . "' supplied. Unable to edit study group sessions.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } //check that this person exists $person = db_query("SELECT person.nid, person.booking_firstname, person.booking_lastname " . "FROM {booking_person} person " . "WHERE nid = :nid", array(':nid' => $nid)) ->fetchObject(); //throw an error if they don't exist if (! $person) { drupal_set_message("Error: Unable to find booking corresponding with registration ID '" . $nid . "'.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } $prefix = t("Manually assign/update study group sessions for !first !last.
If updating an existing session ID, this will also copy any role assigned (leader, helper, etc).
Note: Still under testing!
", array('!first' => $person->booking_firstname, '!last' => $person->booking_lastname)); //select the groups this person is already assigned to, indexed by studygroup id $person_groups_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid AND booking_node_id = :nid", array(':eid' => $event->eid, ':nid' => $nid)); $person_groups = $person_groups_query->fetchAllAssoc('booking_studygroup_id'); //select all the study groups for this event id $studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $studygroups = $studygroups_query->fetchAll(); //retrieve the number of study group sessions, assume they all have the same number of sessions $num_sessions = reset($studygroups)->booking_num_group_sessions; //create the array for our html select fields for ($i = 1; $i <= $num_sessions; $i++) { $session_options[$i] = $i; } $session_options['Remove'] = 'Remove'; //select any entries already in the mapping table $group_mapping_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $group_mapping = $group_mapping_query->fetchAllAssoc('sid'); //***form starts here*** $header = array( 'booking_studygroup_descrip' => array('data' => t('Study Group')), 'booking_current_session_id' => array('data' => t('Current Session Number')), 'booking_session_id' => array('data' => t('Select Session Number')), ); //create a new row for each group foreach ($studygroups as $group) { $default = ''; $role = ''; //retrieve the current session id for this group if defined already if (! empty($person_groups[$group->sid])) { $default = $person_groups[$group->sid]->booking_session_id; //check if the person has an assigned role for this session $role = _booking_studygroup_role_lookup($person_groups[$group->sid]->booking_studygroup_role) . " Session #"; /* if ($person_groups[$group->sid]->booking_is_leader == 'Y') $role = "Leader Session #"; elseif ($person_groups[$group->sid]->booking_is_helper == 'Y') $role = "Helper Session #"; elseif ($person_groups[$group->sid]->booking_is_reserveleader == 'Y') $role = "Reserve Leader Session #"; */ } $options[] = array ( 'booking_studygroup_descrip' => $group->booking_studygroup_descrip, 'booking_current_session_id' => $default == '' ? 'Not Set' : $role . $default, 'booking_session_id' => array('data' => array( '#type' => 'select', '#options' => $session_options, '#value' => $default, '#name' => 'booking_assign_sessionid[' . $group->sid . ']', ) ), ); } //so we can access the dropdown elements $form['booking_assign_sessionid'] = array( '#type' => 'value', ); //generate the render array $form['personid'] = array( '#type' => 'hidden', '#value' => $nid, ); $form['table'] = array ( '#type' => 'tableselect', '#header' => $header, '#options' => $options, ); $form['submit'] = array ( '#type' => 'submit', '#value' => t('Submit'), ); return array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'form' => $form, ); } /** * Process the submission to manually assign study group sessions for a person */ function booking_studygroups_edit_form_submit($form, &$form_state) { global $event; $counter = 0; $checkboxes = $form_state['values']['table']; $studygroup_ids = $form_state['values']['booking_assign_sessionid']; $values = $form_state['input']; //check that $values['personid'] is a number if (! preg_match('/^[0-9]+$/', $values['personid'])) { //parameter from url is not what we were expecting drupal_set_message("Error: Invalid form data supplied. Please use the contact us form to let us know.", 'error', FALSE); return ""; } $nid = $values['personid']; //watchdog('booking', "Study Groups Edit submission:\n@info", array('@info' => print_r( $form_state, true))); //select the groups this person is already assigned to, indexed by studygroup id $person_groups_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid AND booking_node_id = :nid", array(':eid' => $event->eid, ':nid' => $nid)); $person_groups = $person_groups_query->fetchAllAssoc('booking_studygroup_id'); //select all the study groups for this event id $studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $studygroups = $studygroups_query->fetchAll(); //loop through array of study group IDs and compare against existing database entries foreach ($studygroup_ids as $key => $value) { //watchdog('booking', "
Study Group key:\n@key\nValue\n@value", array('@key' => print_r( $key, true), '@value' => print_r( $value, true))); //check if there is a valid value to process if ($value > 0 || $value == 'Remove') { //check to see if we need to remove a study group mapping if (! empty($person_groups[$key]) && $value == 'Remove') { watchdog('booking', "Removing an existing Study Group session id: @id from group @group.\n
@info", array('@id' => $value, '@group' => $key, '@info' => print_r( $person_groups[$key], true))); $num_deleted = db_delete('booking_studygroup_mapping') ->condition('sid', $person_groups[$key]->sid) ->execute(); } //check for an existing study group mapping to change elseif ((!empty($person_groups[$key])) && $person_groups[$key]->booking_session_id != $value) { watchdog('booking', "Updating Study Group session from: @key to @value", array('@key' => $person_groups[$key]->booking_session_id, '@value' => $value)); db_update('booking_studygroup_mapping') ->fields(array( 'booking_session_id' => $value, 'booking_is_leader' => $person_groups[$key]->booking_is_leader, 'booking_is_helper' => $person_groups[$key]->booking_is_helper, 'booking_is_reserveleader' => $person_groups[$key]->booking_is_reserveleader, 'booking_studygroup_role' => $person_groups[$key]->booking_studygroup_role, )) ->condition('sid', $person_groups[$key]->sid) ->execute(); } //found this entry already, so no change needed elseif ((!empty($person_groups[$key])) && $person_groups[$key]->booking_session_id == $value) { watchdog('booking', "Study Group @group session already set to @session.", array('@group' => $key, '@session' => $value)); } //no previously defined value, so add a new entry to the mapping table else { watchdog('booking', "Adding Study Group session id: @id for group @group.", array('@id' => $value, '@group' => $key)); db_insert('booking_studygroup_mapping') ->fields(array( 'booking_eventid' => $event->eid, 'booking_node_id' => $nid, 'booking_studygroup_id' => $key, 'booking_session_id' => $value, 'booking_is_leader' => 'N', 'booking_is_helper' => 'N', 'booking_is_reserveleader' => 'N', 'booking_studygroup_role' => 0, )) ->execute(); } } } } /** * Function for defining the number of study group sessions * Note: This is hard-coded for now in the install file */ /** * Function to correctly clone an associative array storing objects * Taken from http://stackoverflow.com/questions/1532618/is-there-a-function-to-make-a-copy-of-a-php-array-to-another */ function booking_clone_array($copied_array) { return array_map(function($element) { return ( ((is_array($element)) ? call_user_func(__FUNCTION__, $element) : ((is_object($element)) ? clone $element : $element ) ) ); }, $copied_array); } /** * Function to randomise the ordering of an array * taken from http://stackoverflow.com/questions/4102777/php-random-shuffle-array-maintaining-key-value */ function booking_shuffle_assoc($list) { if (!is_array($list)) return $list; $keys = array_keys($list); shuffle($keys); $random = array(); foreach ($keys as $key) { $random[$key] = $list[$key]; } return $random; } /** * Function to mark an attendee as processed for group calculations * @param $input string containing passport number to be verified */ function booking_assign_attendee_group($nid, $session_id, $gender, $age, &$attendee_list, &$session_count) { if (empty($nid)) { drupal_set_message(t('Attempting to process a non-existent node id.')); return; } //mark this person as processed in the working list $attendee_list[$nid]->processed = 1; $attendee_list[$nid]->session = $session_id; //record the category of person $session_count[$session_id][$gender]++; $session_count[$session_id]['total']++; //record the age bracket //$age = _booking_get_age_years($attendee_list[$nid]->booking_dob); if ($age < 20) $session_count[$session_id]['under20']++; elseif($age >= 20 && $age < 25) $session_count[$session_id]['20to25']++; else $session_count[$session_id]['over25']++; } /** * Function for calculating who belongs to which study group */ function booking_studygroups_calculate() { global $event; //master attendee list $attendees = array(); //temporary working copy of attendee list $working_list = array(); //create an array to keep track of the number of people in each session for each group $session_count = array(); //delete from booking_studygroup_mapping; //alter table booking_studygroup_mapping AUTO_INCREMENT=1; //TODO: consider using a lock as per https://api.drupal.org/api/drupal/includes!lock.inc/group/lock/7 //select all the study groups for this event id $studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $studygroups = $studygroups_query->fetchAllAssoc('sid'); //calculate the max number of attendees in a group $firstgroup = reset($studygroups); $limit = variable_get('booking_regn_limit','500'); //add an extra one to the maximum size, to cater for some larger groups when the number of people doesn't divide evenly $max_people = (int) ($limit / $firstgroup->booking_num_group_sessions) + 2; //select all the attendees booked in $query = db_query("SELECT * FROM {booking_person} WHERE booking_event_id = :eid", array(':eid' => $event->eid)); $attendees = $query->fetchAllAssoc('nid'); //calculate the ratios of males to females, and various age groups $statistics = _booking_generate_statistics($attendees); $gender_ratio = ($statistics['males'] / $statistics['females']) * ($max_people / 2); //store them in a nice easy to access array $maximums = array( 'male' => ceil($gender_ratio), 'female' => ceil($max_people - $gender_ratio), 'under20' => floor(($statistics['under20'] / $limit) * ($max_people - 2)), '20to25' => floor(($statistics['20to25'] / $limit) * ($max_people - 2)), 'over25' => floor(($statistics['over25'] / $limit) * ($max_people - 2)), ); drupal_set_message(t('Aiming for !males males, !females females in group. Made up of !20s under 20, !low20s between 20 and 25, and !high20s over 25. Total count in group is !max.', array('!20s' => $maximums['under20'], '!low20s' => $maximums['20to25'], '!high20s' => $maximums['over25'], '!males' => $maximums['male'], '!females' => $maximums['female'], '!max' => $max_people) )); //select any entries already in the mapping table $group_mapping_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $group_mapping = $group_mapping_query->fetchAllAssoc('sid'); //TODO: search for entries already in the mapping table that have a booking_status of 3 (not coming) and remove them from the mapping table $to_remove_query = db_query("SELECT m.* FROM {booking_studygroup_mapping} m inner join {booking_person} p on p.nid = m.booking_node_id WHERE booking_eventid = :eid AND p.booking_status = 3", array(':eid' => $event->eid)); $to_remove = $to_remove_query->fetchAll(); watchdog('booking', "
Study group mappings to remove:\n@info", array('@info' => print_r( $to_remove, true))); //iterate over the attendee associative array and add some fields foreach ($attendees as $person) { //flag that indicates processed or not $person->processed = 0; //make sure we skip attendees that do not have the status of "booked in" if ($person->booking_status <> 1) $person->processed = 1; //field that indicates the session id the person is assigned to $person->session = 0; $person->booking_studygroup_role = 0; $person->is_leader = 'N'; $person->is_helper = 'N'; $person->is_reserveleader = 'N'; } //watchdog('booking', "
Attendee list:\n@info", array('@info' => print_r( $attendees, true))); //watchdog('booking', "Attendee list: @info", array('@info' => var_export($attendees, TRUE))); //process each study group (eg Monday Tuesday Wednesday etc) foreach ($studygroups as $group) { drupal_set_message(t('Processing study group !group with !sessions sessions.', array('!group' => $group->booking_studygroup_descrip, '!sessions' => $group->booking_num_group_sessions))); //create a temporary copy of the attendee list to work with for this study group $working_list = array(); $working_list = booking_shuffle_assoc(booking_clone_array($attendees)); //set up the iterator $obj = new ArrayObject( $working_list ); $it = $obj->getIterator(); //clear the array keeping track of the number of people in each session for this group for ($i = 1; $i <= $group->booking_num_group_sessions; $i++) { $session_count[$i] = array( 'total' => 0, 'male' => 0, 'female' => 0, 'under20' => 0, '20to25' => 0, 'over25' => 0, ); } // $session_count[$i] = 0; //search for the leaders and helpers for this study group foreach ($group_mapping as $person) { //if ($person->booking_studygroup_id == $group->sid && ($person->booking_is_leader == 'Y' || $person->booking_is_helper == 'Y' || // $person->booking_is_reserveleader == 'Y')) if ($person->booking_studygroup_id == $group->sid && $person->booking_studygroup_role > 0) { drupal_set_message(t('Leader/helper with id !id assigned to session !session (currently with !num people).', array('!id' => $person->booking_node_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) )); //mark this position as being used $age = _booking_get_age_years($working_list[$person->booking_node_id]->booking_dob); booking_assign_attendee_group($person->booking_node_id, $person->booking_session_id, 'male', $age, $working_list, $session_count); //get any potential spouse or boyfriend/girlfriend $spouse_id = $working_list[$person->booking_node_id]->booking_partner_id; $bf_gf_id = $working_list[$person->booking_node_id]->booking_bf_gf_nid; if ($spouse_id > 0) { drupal_set_message(t('Spouse with id !id assigned to session !session (currently with !num people).', array('!id' => $spouse_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) )); //allocate the spouse to the same session $age = _booking_get_age_years($working_list[$spouse_id]->booking_dob); booking_assign_attendee_group($spouse_id, $person->booking_session_id, 'female', $age, $working_list, $session_count); } elseif ($bf_gf_id > 0) { drupal_set_message(t('BF/GF with id !id assigned to session !session (currently with !num people).', array('!id' => $spouse_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) )); //allocate the boyfriend/girlfriend to the same session booking_assign_attendee_group($bf_gf_id, $person->booking_session_id, $working_list[$bf_gf_id]->booking_gender == 'M' ? 'male' : 'female', _booking_get_age_years($working_list[$bf_gf_id]->booking_dob), $working_list, $session_count); } } } //end searching for leaders and helpers //watchdog('booking', "Attendee list working copy after leader/helper spouse processing: @info", array('@info' => var_export($working_list, TRUE))); //watchdog('booking', "Attendee list session count after leader/helper spouse processing: @info", array('@info' => var_export($session_count, TRUE))); //reset the iterator to starting position $it->rewind(); //watchdog('booking', "Attendee list: @info", array('@info' => var_export($attendees, TRUE))); //watchdog('booking', "Attendee list working copy: @info", array('@info' => var_export($working_list, TRUE))); $session_id = 1; $rewound = FALSE; //watchdog('booking', "Attendee list: @info", array('@info' => var_export($session_count, TRUE))); //reset the iterator to starting position of the attendee list //$it->rewind(); //set our counter $i = 1; //iterate over the attendee list while ( $it->valid() ) { //go to the first unprocessed attendee while ($it->current()->processed == 1) { drupal_set_message(t('Person with id !id has already been processed earlier.', array('!id' => $it->key()))); $it->next(); //double check we didn't run out of people right here if (! $it->valid() ) { drupal_set_message("Ran out of attendees to process."); break; } } //cycle the session counter if we already reached the end if ($i > $group->booking_num_group_sessions) $i = 1; //get the current attendee element and their stats $current = $it->current(); $gender = $current->booking_gender == 'M' ? 'male' : 'female'; $age = _booking_get_age_years($current->booking_dob); if ($age < 20) $age_type = 'under20'; elseif($age >= 20 && $age < 25) $age_type = '20to25'; else $age_type = 'over25'; //make sure this person is going to fit in with our calculated gender ratios _booking_loop_carefully($session_count, $gender, $i, $maximums[$gender], $group->booking_num_group_sessions, 3); //make sure this person is going to fit in with our calculated age ratios _booking_loop_carefully($session_count, $age_type, $i, $maximums[$age_type], $group->booking_num_group_sessions, 3); //check for maximum group size _booking_loop_carefully($session_count, 'total', $i, $max_people, $group->booking_num_group_sessions, 3); //assign this attendee to this session if unprocessed so far if ($current->processed == 0) { drupal_set_message(t('Assigning person with id !id with gender !gender and age group !age to session !session (currently with !num people).', array('!id' => $it->key(), '!session' => $i, '!num' => $session_count[$i]['total'], '!gender' => $gender, '!age' => $age_type ) )); $partner_id = $current->booking_partner_id; $bf_gf_id = $current->booking_bf_gf_nid; booking_assign_attendee_group($it->key(), $i, $gender, $age, $working_list, $session_count); //check if the attendee was married if ($partner_id > 0) { //add the spouse to the same session and mark as processed in the temporary attendee list drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session (currently with !num people).', array('!id' => $it->key(), '!session' => $i, '!spouse' => $current->booking_partner_id, '!num' => $session_count[$i]['total']))); booking_assign_attendee_group($partner_id, $i, $working_list[$partner_id]->booking_gender == 'M' ? 'male' : 'female', _booking_get_age_years($working_list[$partner_id]->booking_dob), $working_list, $session_count); } //Check for boyfriend/girlfriend if ($bf_gf_id> 0) { //add the spouse to the same session and mark as processed in the temporary attendee list drupal_set_message(t('Assigning bf/gf (id !spouse) of id !id to session !session (currently with !num people).', array('!id' => $it->key(), '!session' => $i, '!spouse' => $current->booking_bf_gf_nid, '!num' => $session_count[$i]['total']))); booking_assign_attendee_group($bf_gf_id, $i, $working_list[$bf_gf_id]->booking_gender == 'M' ? 'male' : 'female', _booking_get_age_years($working_list[$bf_gf_id]->booking_dob), $working_list, $session_count); } } //move to the next unprocessed attendee in the list while ($it->valid() && $it->current()->processed == 1) { //drupal_set_message(t("Skipping attendee ID !id, already processed.", array('!id' => $it->key()))); $it->next(); } //move to the next session $i++; } //finished looping through attendees for this study group //iterate over the attendee list and write to the database the session they're assigned to //use the multi-insert query type at https://drupal.org/node/310079 $insert_query = db_insert('booking_studygroup_mapping')->fields(array('booking_eventid', 'booking_node_id', 'booking_studygroup_id', 'booking_session_id', 'booking_is_leader', 'booking_is_helper', 'booking_is_reserveleader', 'booking_studygroup_role')); foreach($working_list as $person) { //watchdog('booking', "
Working list person:\n@info", array('@info' => print_r( $person, true))); //check to update existing records rather than inserting new one // if already in $group_mapping then just run an update query here $found = FALSE; foreach ($group_mapping as $mapping) { //check if we can find a study group session already for this user and this study group (eg Monday Tuesday or Wednesday) if ($person->nid == $mapping->booking_node_id && $group->sid == $mapping->booking_studygroup_id) { $found = TRUE; //drupal_set_message(t('Found existing study group session for user id !id. Running update query on table id !sid to set session id to !session', // array('!id' => $person->nid, '!sid' => $mapping->sid, '!session' => $person->session))); //update the entry /* db_update('booking_studygroup_mapping') ->fields(array( 'booking_session_id' => $person->session, 'booking_is_leader' => $person->is_leader, 'booking_is_helper' => $person->is_helper, 'booking_studygroup_role' => $person->booking_studygroup_role, )) ->condition('sid', $mapping->sid) ->execute(); break; */ } } //if we didn't find an existing record, add it to the list to insert if (! $found && $person->session <> 0) { //drupal_set_message(t('Found no existing study group session for user id !id. Adding to list of inserts.', // array('!id' => $person->nid, '!sid' => $mapping->sid, '!session' => $person->session))); $record = array( 'booking_eventid' => $event->eid, 'booking_node_id' => $person->nid, 'booking_studygroup_id' => $group->sid, 'booking_session_id' => $person->session, 'booking_is_leader' => $person->is_leader, 'booking_is_helper' => $person->is_helper, 'booking_is_reserveleader' => $person->is_reserveleader, 'booking_studygroup_role' => $person->booking_studygroup_role, ); $insert_query->values($record); } } $insert_query->execute(); //watchdog('booking', "
Session statistics list:\n@info", array('@info' => print_r( $session_count, true))); //clear the arrays we've been using for this iteration unset($session_count); unset($working_list); drupal_set_message(t('Finished processing study group !group.', array('!group' => $group->booking_studygroup_descrip))); } //finished processing study groups //watchdog('booking', "Attendee list final version: @info", array('@info' => var_export($attendees, TRUE))); } /** * Function for listing the study groups and links to view each one */ function booking_studygroups_view_summary() { global $event; $output = ""; $header = array('Link','Study Group', 'Session Count', 'Select Leaders'); $attributes = array('style' => 'max-width:30%'); //get study groups $query = db_select('booking_studygroup_list', 's') ->fields('s') ->condition('s.booking_eventid', $event->eid, '='); $result = $query->execute(); foreach ($result as $group) { $rows[] = array( l(t('View', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/view', array('!id' => $group->sid))), $group->booking_studygroup_descrip, $group->booking_num_group_sessions, l(t('Edit Leaders/Helpers', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/selectleaders', array('!id' => $group->sid))), ); } //output everything $output .= t("
Group printable format:\n@info", array('@info' => print_r( $result, true))); return $result; } /** * Function for viewing who belongs to which study group */ function booking_studygroups_view_form($node, &$form_state, $group_id) { global $event; $form = array(); $options = array(); $last_session = ""; $class_array = array( 0 => "normal-row", 1 => "leader-row", 2 => "helper-row", 3 => "helper-row", ); //attach the custom css $form['#attached']['css'] = array( drupal_get_path('module', 'booking') . '/booking.css', ); //verify that $group_id is a number if (! preg_match('/^[0-9]+$/', $group_id)) { drupal_set_message("Error: Invalid study group ID '" . $group_id . "' supplied. Unable to view group membership.", 'error', FALSE); drupal_goto('admin/config/booking'); return ""; } //collect information on the study group $group = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid and sid = :sid", array(':eid' => $event->eid, ':sid' => $group_id)) ->fetchObject(); if (! $group) { drupal_set_message("Error: Could not find matching study group ID. Unable to view group membership.", 'error', FALSE); drupal_goto('admin/config/booking'); return ""; } $header = array( 'booking_session_id' => array('data' => t('Study Group Session'), 'field' => 'm.booking_session_id', 'sort' => 'asc'), 'booking_name' => array('data' => t('Name'), 'field' => 'p.booking_lastname'), 'booking_status' => array('data' => t('Booking Status'), 'field' => 'p.booking_status'), 'booking_studygroup_role' => array('data' => t('Studygroup Role'), 'field' => 'p.booking_studygroup_role'), //'booking_is_leader' => array('data' => t('Leader?'), 'field' => 'm.booking_is_leader'), //'booking_is_helper' => array('data' => t('Helper?'), 'field' => 'm.booking_is_helper'), //'booking_is_reserveleader' => array('data' => t('Reserve Leader?'), 'field' => 'm.booking_is_reserveleader'), ); $query = db_select('booking_person', 'p'); $query->leftJoin('booking_studygroup_mapping', 'm', 'm.booking_node_id = p.nid'); $db_and = db_and(); $db_and->condition('p.booking_event_id', $event->eid, '='); $db_and->condition('m.booking_studygroup_id', $group_id, '='); $query->condition($db_and); $query->fields('p')->fields('m'); $table_sort = $query->extend('TableSort')->orderbyHeader($header); $result = $table_sort->execute(); //watchdog('booking', 'Study groups raw data: @info', array ('@info' => var_export($result, TRUE))); //retrieve which sort is active in the current view $sort = tablesort_get_order($header); foreach($result as $data) { $class = $class_array[$data->booking_studygroup_role]; /* //apply theme as required if ($data->booking_is_leader == 'Y') $class = "leader-row"; elseif ($data->booking_is_helper == 'Y') $class = "helper-row"; elseif ($data->booking_is_reserveleader == 'Y') $class = "helper-row"; else $class = "normal-row"; */ //only add the lines separating groups if we're sorting by the session id if ($sort['sql'] == "m.booking_session_id") { //Add a different id for first entry of new session, with a border-top to distinguish it if ($last_session <> $data->booking_session_id && $last_session <> "") { if ($class === "leader-row") $class = "leader-new-group-row"; elseif ($class === "helper-row") $class = "helper-new-group-row"; else $class = "new-group-row"; } } $options[$data->nid] = array ( 'booking_session_id' => $data->booking_session_id, 'booking_name' => l(t('!first !last', array('!first' => $data->booking_firstname, '!last' => $data->booking_lastname)), t('admin/booking/!id/edit-studygroup', array('!id' => $data->nid))), 'booking_status' => _booking_status_generate($data->booking_status), 'booking_studygroup_role' => _booking_studygroup_role_lookup($data->booking_studygroup_role), //'booking_is_leader' => $data->booking_is_leader == 'Y' ? 'Yes' : 'No', //'booking_is_helper' => $data->booking_is_helper == 'Y' ? 'Yes' : 'No', //'booking_is_reserveleader' => $data->booking_is_reserveleader == 'Y' ? 'Yes' : 'No', '#attributes' => array('id' => array($class)) ); $last_session = $data->booking_session_id; } $prefix = t("