"normal-row", 1 => "leader-row", 2 => "helper-row", 3 => "reserveleader-row", ); //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 edit group leaders and helpers.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } //select all the study groups for this event id $studygroup = db_query("SELECT * FROM {booking_studygroup_list} WHERE sid = :sid", array(':sid' => $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 ""; } $form['#attached']['css'] = array( drupal_get_path('module', 'booking') . '/booking.css', ); $prefix = t("

Study Group ‐ !descrip

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')), 'booking_group_edit' => array('data' => t('Edit')), ); $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_eventid', $event->eid, '='); $db_and->condition('p.booking_gender', 'M', '='); $db_and->condition($db_or); $query->condition($db_and); $query->fields('p'); //$query->groupBy('booking_gender'); $table_sort = $query->extend('TableSort')->orderbyHeader($header); $result = $table_sort->execute(); foreach($result as $data) { $role_listing = ""; $assigned_role = 0; $session_id = 0; $class = $class_array[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; //list any role for this current group if ($role > 0) { $text = _booking_studygroup_role_lookup($role); $role_listing .= "" . $text . " group " . $group->booking_studygroup_id . " #" . $group->booking_session_id . "; "; $class = $class_array[$role]; } } } $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, 'booking_group_edit' => l(t('Edit'), t('admin/booking/!id/edit-studygroup-membership', array('!id' => $data->nid))), '#attributes' => array('id' => array($class)), ); } $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) ->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) ->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) ->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, )) ->execute(); } else { //run an update db_update('booking_studygroup_mapping') ->fields(array ( 'booking_session_id' => $session, 'booking_studygroup_role' => $role, )) ->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 (); $rows = array (); $session_options = array(); $readinggroup_options = array(); $session_options[0] = ''; $readinggroup_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).

", 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; $readinggroup_options[$i] = _booking_readinggroup_colour_lookup($i); } $session_options['Remove'] = 'Remove'; $readinggroup_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 #"; */ } //if ($group->sid == variable_get('booking_readinggroup_id','7')) if ($group->booking_is_readinggroup == 'Y') { $options = $readinggroup_options; } else { $options = $session_options; } $rows[] = 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' => $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' => $rows, ); $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 any readings groups so we know if we need to update colours $reading_groups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid AND booking_is_readinggroup = 'Y'", array(':eid' => $event->eid)); $reading_groups = $reading_groups_query->fetchAllAssoc('sid'); //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') { //if there was no previous mapping but Remove has been selected anyway, just skip to the next value to look at if (empty($person_groups[$key]) && $value == 'Remove') { continue; } //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 for id @id", array('@key' => $person_groups[$key]->booking_session_id, '@value' => $value, '@id' => $nid)); db_update('booking_studygroup_mapping') ->fields(array( 'booking_session_id' => $value, 'booking_studygroup_role' => $person_groups[$key]->booking_studygroup_role, )) ->condition('sid', $person_groups[$key]->sid) ->execute(); //check if there is a readings group colour to update foreach ($reading_groups as $group) { if ($group->sid == $key) { booking_studygroups_process_colours(); } } } //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_studygroup_role' => 0, )) ->execute(); //check if there is a readings group colour to update foreach ($reading_groups as $group) { if ($group->sid == $key) { booking_studygroups_process_colours(); } } } //end new value check } //end valid data check } //end checkbox loop } /** * Function for defining the number of study group sessions * Note: This is hard-coded for now in the install file */ /** * 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_eventid = :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'); //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 the study group id matches the group we're currently looking at, and they have a role defined 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' => $bf_gf_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) )); //allocate the boyfriend/girlfriend to the same session $age = _booking_get_age_years($working_list[$bf_gf_id]->booking_dob); $gender = $working_list[$bf_gf_id]->booking_gender == 'M' ? 'male' : 'female'; _booking_assign_attendee_group($bf_gf_id, $person->booking_session_id, $gender, $age, $working_list, $session_count); } } //end current group check } //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))); //watchdog('booking', "Attendee list distribution: @info", array('@info' => var_export($session_count, TRUE))); //initialise our counters $session_id = 1; $rewound = FALSE; $i = 1; //iterate over the attendee list while ($it->valid()) { //cycle the session counter if we already reached the end if ($i > $group->booking_num_group_sessions) { $i = 1; } //get the current attendee element $current = $it->current(); //assign this attendee to this session if unprocessed so far if ($current->processed == 0) { //generate stats about this attendee $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); 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); } } //end processed check //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_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 calculating who belongs to which study group */ function booking_studygroups_update_form($node, &$form_state, $sid) { 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(); //the form to return $form = array(); $calculation_messages = array(); $update_messages = array(); $prefix = ""; $intro_text = ""; $reading_group_id = variable_get('booking_readinggroup_id','7'); //store our calculated updates in this array which will then get serialized and added to the form for processing $updates_to_confirm = array(); $inserts_to_confirm = array(); //verify that $nid is a number if (! preg_match('/^[0-9]+$/', $sid)) { drupal_set_message("Error: Invalid group ID '" . $sid . "' supplied. Unable to update study group session.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } //select the study group for the supplied ID //$studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE sid = :sid", array(':sid' => $sid)); $studygroups = $studygroups_query->fetchAllAssoc('sid'); //select any entries already in the mapping table $group_mapping_query = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid AND booking_studygroup_id = :sid", array(':eid' => $event->eid, ':sid' => $sid)); $group_mapping = $group_mapping_query->fetchAllAssoc('sid'); //throw an error if we got no groups if (! $studygroups) { drupal_set_message("Error: Unable to find group with corresponding ID '" . $sid . "'.", 'error', FALSE); drupal_goto('admin/booking/studygroups'); return ""; } //calculate the max number of attendees in a group $firstgroup = reset($studygroups); $limit = variable_get('booking_regn_limit','500'); //be a bit more lenient with maximums to avoid excessive re-arrangement of groups $fudge_factor = 0; $max_people = (int) ($limit / $firstgroup->booking_num_group_sessions) + $fudge_factor; //select all the attendees for this event $query = db_query("SELECT * FROM {booking_person} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); $attendees = $query->fetchAllAssoc('nid'); //TODO: Move statistics generation to separate function //calculate the ratios of males to females, and various age groups $statistics = _booking_generate_statistics($attendees); if ($statistics['males'] == 0 || $statistics['females'] == 0 || $max_people == 0) { $gender_ratio = 1; } else { $gender_ratio = ($statistics['males'] / $statistics['females']) * ($max_people / 2); } //really stretch the tolerances for placement by setting this to zero $fudge_factor = 1; //store our final maximums as an array for easy access later $maximums = array( 'male' => ceil($gender_ratio), 'female' => ceil($max_people - $gender_ratio), 'under20' => ceil(($statistics['under20'] / $limit) * ($max_people - $fudge_factor)), '20to25' => ceil(($statistics['20to25'] / $limit) * ($max_people - $fudge_factor)), 'over25' => ceil(($statistics['over25'] / $limit) * ($max_people - $fudge_factor)), ); //remove the mappings for people no longer coming _booking_studygroup_cleanup(); //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; } //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) { $prefix .= t('

Processing study group !group with !sessions sessions

', array('!group' => $group->booking_studygroup_descrip, '!sessions' => $group->booking_num_group_sessions)); $prefix .= 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) ); //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, ); } //search for the leaders helpers, spouses and boyfriend/girlfriend for this study group to pre-allocate foreach ($group_mapping as $person) { //dereference a bunch of fields we'll be using $committee_flag = $working_list[$person->booking_node_id]->booking_committee_member; $manually_allocated_flag = $working_list[$person->booking_node_id]->booking_session_manually_allocated; $spouse_id = $working_list[$person->booking_node_id]->booking_partner_id; $bf_gf_id = $working_list[$person->booking_node_id]->booking_bf_gf_nid; $gender = $working_list[$person->booking_node_id]->booking_gender == 'M' ? 'male' : 'female'; $session_id = $person->booking_session_id; //if the study group id matches the group we're currently looking at if ($person->booking_studygroup_id == $group->sid) { //if they have a role defined //or if they are a committee member and this is the readings group //or if the manually allocated flag is set //then make sure they stay where they are if (($person->booking_studygroup_role > 0) || ($committee_flag == 'Y' && $group->booking_is_readinggroup == 'Y') || ($manually_allocated_flag == 'Y')) { $calculation_messages[] = t('Leader/helper/committee 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 $working_list[$person->booking_node_id]->booking_studygroup_role = $person->booking_studygroup_role; $age = _booking_get_age_years($working_list[$person->booking_node_id]->booking_dob); _booking_assign_attendee_group($person->booking_node_id, $session_id, 'male', $age, $working_list, $session_count, $calculation_messages); //make sure the leader/helper's partner gets updated now, otherwise they could still end up in different groups if ($spouse_id > 0) { //also mark their spouse as allocated to this group $calculation_messages[] = 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']) ); $age = _booking_get_age_years($working_list[$spouse_id]->booking_dob); $spouse_gender = $working_list[$spouse_id]->booking_gender == 'M' ? 'male' : 'female'; _booking_assign_attendee_group($spouse_id, $session_id, $spouse_gender, $age, $working_list, $session_count, $calculation_messages); } elseif ($bf_gf_id > 0) { //also mark their boyfriend/girlfriend as allocated to this group $calculation_messages[] = t('BF/GF with id !id assigned to session !session (currently with !num people).', array('!id' => $bf_gf_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) ); $age = _booking_get_age_years($working_list[$bf_gf_id]->booking_dob); $bfgf_gender = $working_list[$bf_gf_id]->booking_gender == 'M' ? 'male' : 'female'; _booking_assign_attendee_group($bf_gf_id, $session_id, $bfgf_gender, $age, $working_list, $session_count, $calculation_messages); } } //anyone else already assigned to this group previously elseif ($working_list[$person->booking_node_id]->processed == 0) { if ($spouse_id > 0) { //if the spouse has already been processed due to being a leader or helper, use that session if ($working_list[$spouse_id]->processed == 1) { $session_id = $working_list[$spouse_id]->session; } //mark this person as allocated to this group $calculation_messages[] = t('Married person 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']) ); $age = _booking_get_age_years($working_list[$person->booking_node_id]->booking_dob); _booking_assign_attendee_group($person->booking_node_id, $session_id, $gender, $age, $working_list, $session_count, $calculation_messages); //also mark their spouse as allocated to this group $calculation_messages[] = 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']) ); $age = _booking_get_age_years($working_list[$spouse_id]->booking_dob); $spouse_gender = $working_list[$spouse_id]->booking_gender == 'M' ? 'male' : 'female'; _booking_assign_attendee_group($spouse_id, $session_id, $spouse_gender, $age, $working_list, $session_count, $calculation_messages); } elseif ($bf_gf_id > 0) { //if the bf/gf has already been processed due to being a leader or helper, use that session if ($working_list[$bf_gf_id]->processed == 1) { $session_id = $working_list[$bf_gf_id]->session; } //mark this person as allocated to this group $calculation_messages[] = t('Person with id !id in relationship 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']) ); $age = _booking_get_age_years($working_list[$person->booking_node_id]->booking_dob); _booking_assign_attendee_group($person->booking_node_id, $session_id, $gender, $age, $working_list, $session_count, $calculation_messages); //also mark their boyfriend/girlfriend as allocated to this group $calculation_messages[] = t('BF/GF with id !id assigned to session !session (currently with !num people).', array('!id' => $bf_gf_id, '!session' => $person->booking_session_id, '!num' => $session_count[$person->booking_session_id]['total']) ); $age = _booking_get_age_years($working_list[$bf_gf_id]->booking_dob); $bfgf_gender = $working_list[$bf_gf_id]->booking_gender == 'M' ? 'male' : 'female'; _booking_assign_attendee_group($bf_gf_id, $session_id, $bfgf_gender, $age, $working_list, $session_count, $calculation_messages); } //for anyone else, just record what session they're currently in else { $working_list[$person->booking_node_id]->session = $session_id; } } //end looking at people with spouse or bf/gf } //end checking for matching study group id } //end searching for people to pre-allocate //watchdog('booking', "
Attendee list working copy after pre-processing:\n@info
", array('@info' => print_r( $working_list, true))); //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))); //watchdog('booking', "Attendee list distribution: @info", array('@info' => var_export($session_count, TRUE))); //initialise our counters $session_id = 1; $rewound = FALSE; $i = 1; //iterate over the attendee list while ( $it->valid() ) { //cycle the session counter if we already reached the end if ($i > $group->booking_num_group_sessions) $i = 1; //get the current attendee element $current = $it->current(); //assign this attendee to this session if unprocessed so far if ($current->processed == 0) { //use their existing study group as a starting point, if already defined if ($current->session > 0) $start = $current->session; else $start = $i; //generate stats about this attendee $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, $start, $maximums[$gender], $group->booking_num_group_sessions, 3, $calculation_messages); //make sure this person is going to fit in with our calculated age ratios _booking_loop_carefully($session_count, $age_type, $start, $maximums[$age_type], $group->booking_num_group_sessions, 3, $calculation_messages); //check for maximum group size _booking_loop_carefully($session_count, 'total', $start, $max_people, $group->booking_num_group_sessions, 4, $calculation_messages); $calculation_messages[] = 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' => $start, '!num' => $session_count[$start]['total'], '!gender' => $gender, '!age' => $age_type ) ); _booking_assign_attendee_group($it->key(), $start, $gender, $age, $working_list, $session_count, $calculation_messages); } //end processed check //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 //now calculate the updates for the database foreach($working_list as $person) { $found = FALSE; $message = ""; //iterate all the groups for each person 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) { //keep track of our success to avoid doing an insert $found = TRUE; //if the existing session is not the same as our newly calculated session, run an update query //if ($mapping->booking_session_id !== $person->session && $group->sid != $reading_group_id) if ($mapping->booking_session_id !== $person->session && $group->booking_is_readinggroup == 'N') { $message = t('Suggest changing user !id (!name) from session !old to !session. Role id is !role', array('!id' => $person->nid, '!old' => $mapping->booking_session_id, '!session' => $person->session, '!role' => $person->booking_studygroup_role, '!name' => $person->booking_firstname . " " . $person->booking_lastname)); $update = array( 'booking_session_id' => $person->session, 'booking_studygroup_role' => $person->booking_studygroup_role, ); $updates_to_confirm[] = array('sid' => $mapping->sid, 'fields' => $update); } //elseif ($mapping->booking_session_id !== $person->session && $group->sid == $reading_group_id) elseif ($mapping->booking_session_id !== $person->session && $group->booking_is_readinggroup == 'Y') { $message = t('Suggest changing user !id (!name) from reading group session !old to !session. Role id is !role', array('!id' => $person->nid, '!old' => $mapping->booking_session_id, '!session' => $person->session, '!role' => $person->booking_studygroup_role, '!name' => $person->booking_firstname . " " . $person->booking_lastname)); $update = array( 'booking_session_id' => $person->session, 'booking_studygroup_role' => $person->booking_studygroup_role, ); $updates_to_confirm[] = array('sid' => $mapping->sid, 'fields' => $update); } //stop looping through the list since we found a match break; } //end checking for existing group session } //end looping through study group mappings //if we didn't find an existing record, add it to the list to insert if (! $found && $person->session <> 0) { $message = t('Found no existing study group session for user id !id (!name). Adding to list of inserts for session !session.', array('!id' => $person->nid, '!sid' => $mapping->sid, '!session' => $person->session, '!name' => $person->booking_firstname . " " . $person->booking_lastname )); $inserts_to_confirm[] = array( 'booking_eventid' => $event->eid, 'booking_node_id' => $person->nid, 'booking_studygroup_id' => $group->sid, 'booking_session_id' => $person->session, 'booking_studygroup_role' => $person->booking_studygroup_role, ); } //log any update we made if ($message !== "") { $update_messages[] = $message; //watchdog('booking', $message); } } //end loop through working copy of attendee list //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); $final_message = t('Finished processing study group !group.', array('!group' => $group->booking_studygroup_descrip)); drupal_set_message($final_message); watchdog('booking', "
" . $final_message . "\n" . implode("\n", $update_messages) . "
"); //make sure to update team colours if necessary if ($group->booking_is_readinggroup == 'Y') { booking_studygroups_process_colours(); } } //finished processing study groups /* //make sure to update team colours if necessary if ($sid == $reading_group_id) { booking_studygroups_process_colours(); } */ //watchdog('booking', "Attendee list final version: @info", array('@info' => var_export($attendees, TRUE))); $form['log'] = array( '#type' => 'fieldset', '#title' => 'Calculated Actions', '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['log']['messages'] = array( '#type' => 'item', '#title' => '', '#markup' => "

" . implode("
\n", $calculation_messages) . "

", ); $form['result'] = array( '#type' => 'fieldset', '#title' => 'Suggested Updates', '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['result']['messages'] = array( '#type' => 'item', '#title' => '', '#markup' => "

" . implode("
\n", $update_messages) . "

", ); $form['update_string'] = array ( '#type' => 'hidden', '#value' => serialize($updates_to_confirm), ); $form['insert_string'] = array ( '#type' => 'hidden', '#value' => serialize($inserts_to_confirm), ); $form['confirm'] = array ( '#type' => 'submit', '#value' => t('Confirm Updates'), ); return array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'form' => $form, ); } /** * Process the submission to accept calculated study group membership updates */ function booking_studygroups_update_form_submit($form, &$form_state) { global $event; $values = $form_state['input']; $raw_updates = unserialize($values['update_string']); $raw_inserts = unserialize($values['insert_string']); watchdog('booking', "
Study group insert confirmation array:\n@info
", array('@info' => print_r( $raw_inserts, true))); watchdog('booking', "
Study group update confirmation array:\n@info
", array('@info' => print_r( $raw_updates, true))); //process the updates foreach($raw_updates as $update) { $rows = db_update('booking_studygroup_mapping') ->fields($update['fields']) ->condition('sid', $update['sid']) ->execute(); //watchdog('booking', "Updated sid !sid affecting !rows rows.", array('!sid' => $update['sid'], '!rows' => $rows)); } //process the inserts using 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_studygroup_role')); foreach($raw_inserts as $insert) { $insert_query->values($insert); } $insert_query->execute(); drupal_set_message(t('Study group update confirmation processed.')); //redirect the user back to the study groups page $form_state['redirect'] = array('admin/booking/studygroups'); } /** * Function for viewing a printable format of who belongs to which study group */ function booking_studygroups_printview_form($node, &$form_state, $group_id) { global $event; $form = array(); $rows = array(); $last_session = ""; /* //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'), 'booking_name' => array('data' => t('Name'), 'field' => 'p.booking_lastname', 'sort' => 'asc'), 'booking_mobilenum' => array('data' => t('Mobile Number'), 'field' => 'p.booking_mobile'), 'booking_email' => array('data' => t('Email'), 'field' => 'p.booking_email'), 'booking_studygroup_role' => array('data' => t('Role')), ); $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_eventid', $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(); //$result = $query->execute(); //watchdog('booking', 'Study groups raw data: @info', array ('@info' => var_export($result, TRUE))); foreach($result as $data) { $class = ""; $role = ""; //apply theme as required if ($data->booking_is_leader == 'Y') { $class = "leader-row"; $role = "Leader"; } elseif ($data->booking_is_helper == 'Y') { $class = "helper-row"; $role = "Helper"; } elseif ($data->booking_is_reserveleader == 'Y') { $class = "helper-row"; $role = "Reserve Leader"; } else $class = "normal-row"; $rows[] = array ( 'data' => array( $data->booking_session_id, $data->booking_firstname . " " . $data->booking_lastname, $data->booking_mobile, $data->booking_email, $role, ), 'class' => array($class), ); } $prefix = t("

Study Group !descrip

", array('!descrip' => $group->booking_studygroup_descrip)); /* $form['table'] = array ( '#type' => 'tableselect', '#header' => $header, '#options' => $options, //'#attributes' => array('id' => 'sort-table'), ); */ $result = array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'table' => array ( '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'sort-table'), //'#sticky' => FALSE, ) ); watchdog('booking', "
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; $is_reading_group = FALSE; $form = array(); $options = array(); $rows = array(); $last_session = ""; $class_array = array( 0 => "normal-row", 1 => "leader-row", 2 => "helper-row", 3 => "reserveleader-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 ""; } /* if ($group_id == variable_get('booking_readinggroup_id','7')) { $is_reading_group = TRUE; } */ $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_gender' => array('data' => t('Gender'), 'field' => 'p.booking_gender'), 'booking_age' => array('data' => t('Age'), 'field' => 'p.booking_dob'), 'booking_baptised' => array('data' => t('Baptised?'), 'field' => 'p.booking_baptised'), 'booking_married' => array('data' => t('Married?'), 'field' => 'p.booking_married'), 'booking_phone' => array('data' => t('Phone Number'), 'field' => 'p.booking_mobile'), //'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_committee' => array('data' => t('Committee Member?'), 'field' => 'p.booking_committee_member'), ); if ($group->booking_is_readinggroup == 'Y') { $header['booking_session_id']['data'] = t('Team Colour'); } $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_eventid', $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); $last_session = 0; foreach($result as $data) { //apply theme as required $class = $class_array[$data->booking_studygroup_role]; //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) { switch ($data->booking_studygroup_role) { case 1: $class = "leader-new-group-row"; break; case 2: $class = "helper-new-group-row"; break; case 3: $class = "reserveleader-new-group-row"; break; default: $class = "new-group-row"; } } } //end class calculation $session = $group->booking_is_readinggroup == 'Y' ? _booking_readinggroup_colour_lookup($data->booking_session_id) : $data->booking_session_id; $rows[] = array ( 'data' => array( $session, l(t('!first !last', array('!first' => $data->booking_firstname, '!last' => $data->booking_lastname)), t('admin/booking/!id/edit-studygroup-membership', array('!id' => $data->nid))), //_booking_status_generate($data->booking_status), $data->booking_gender == 'M' ? 'Male' : 'Female', _booking_get_age_years($data->booking_dob), $data->booking_baptised == 'Y' ? 'Yes' : 'No', $data->booking_married == 'Y' ? 'Yes' : 'No', $data->booking_mobile, _booking_studygroup_role_lookup($data->booking_studygroup_role), $data->booking_committee_member == 'Y' ? 'Yes' : 'No', ), 'id' => array($class), ); $last_session = $data->booking_session_id; } $prefix = t("

Study Group !descrip

", array('!descrip' => $group->booking_studygroup_descrip)); /* $form['table'] = array ( '#type' => 'tableselect', '#header' => $header, '#options' => $options, //'#attributes' => array('id' => 'sort-table'), ); */ return array ( '#attached' => array ( 'css' => array(drupal_get_path('module', 'booking') . '/booking.css') ), 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'table' => array ( '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'sort-table'), //'#sticky' => FALSE, ) //'form' => $form, ); } /** * Function for updating the reading group colour based on the id automatically generated for them */ function booking_studygroups_process_colours() { global $event; //Query for all groups with the reading group flag set to Y, and loop through them all $query = db_select('booking_studygroup_mapping', 'm'); $query->join('booking_studygroup_list', 's', 's.sid = m.booking_studygroup_id'); $query->condition('s.booking_is_readinggroup', 'Y', '='); $query->fields('m')->fields('s', array('booking_studygroup_descrip')); $group_mapping = $query->execute()->fetchAllAssoc('sid'); foreach ($group_mapping as $mapping) { $colour = _booking_readinggroup_colour_lookup($mapping->booking_session_id); //drupal_set_message(t('Updating user !id to be in team !colour.', // array('!id' => $mapping->booking_node_id, '!colour' => $colour))); //run an update query db_update('booking_person') ->fields(array ( 'booking_readinggroup' => $colour, )) ->condition('nid', $mapping->booking_node_id) ->execute(); } drupal_set_message(t('Updated reading group colours')); }