diff --git a/booking.studygroups.inc b/booking.studygroups.inc index 536b53d..5c6ab5a 100644 --- a/booking.studygroups.inc +++ b/booking.studygroups.inc @@ -712,7 +712,7 @@ function booking_studygroups_update_form($node, &$form_state, $sid) { //set up the iterator $obj = new ArrayObject( $working_list ); - $it = $obj->getIterator(); + $iterator = $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++) { @@ -725,136 +725,29 @@ function booking_studygroups_update_form($node, &$form_state, $sid) { 'over25' => 0, ); } - + + //search for the leaders helpers, spouses and boyfriend/girlfriend for this study group to pre-allocate _booking_studygroups_update_preallocate($group, $group_mapping, $session_count, $working_list, $calculation_messages); - /* - //@todo move this foreach loop into a separate function - //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 = $person->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 - //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') || - ($manually_allocated_flag == 'Y')) { - - $calculation_messages[] = t('Leader/helper/committee/manual allocation 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, $gender, $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))); + //allocate everyone else to a session + _booking_studygroups_update_allocate($iterator, $group, $group_mapping, $session_count, $working_list, $calculation_messages); + + /* + //reset the iterator to starting position + $it->rewind(); + //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 @@ -879,12 +772,15 @@ function booking_studygroups_update_form($node, &$form_state, $sid) { $gender = $current->booking_gender == 'M' ? 'male' : 'female'; $age = _booking_get_age_years($current->booking_dob); - if ($age < 20) + if ($age < 20) { $age_type = 'under20'; - elseif($age >= 20 && $age < 25) + } + elseif($age >= 20 && $age < 25) { $age_type = '20to25'; - else + } + 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); @@ -910,7 +806,7 @@ function booking_studygroups_update_form($node, &$form_state, $sid) { //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) { @@ -1046,7 +942,7 @@ function booking_studygroups_update_form($node, &$form_state, $sid) { } /** - * Process attendee list to mark attendees that should be placed based on certain criteria rather than assigned based on age/gender + * Pre-process attendee list to mark attendees that should be placed based on certain criteria rather than assigned based on age/gender * Criteria include leader/helper role, spouse, relationship, committee member * @see booking_studygroups_update_form() */ @@ -1161,6 +1057,80 @@ function _booking_studygroups_update_preallocate($group, $group_mapping, &$sessi } +/** + * Process attendee list to allocate attendees to study group sessions based on statistical breakdown of attendees + * @see booking_studygroups_update_form() + */ +function _booking_studygroups_update_allocate($iterator, $group, $group_mapping, $session_count, $working_list, $calculation_messages) { + $starting_session = 0; + + //reset the iterator to starting position + $iterator->rewind(); + + //initialise our counters + //$session_id = 1; + $i = 1; + + //iterate over the attendee list + while ($iterator->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 = $iterator->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) { + $starting_session = $current->session; + } + else { + $starting_session = $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, $starting_session, $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, $starting_session, $maximums[$age_type], $group->booking_num_group_sessions, 3, $calculation_messages); + //check for maximum group size + _booking_loop_carefully($session_count, 'total', $starting_session, $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' => $iterator->key(), '!session' => $starting_session, + '!num' => $session_count[$starting_session]['total'], '!gender' => $gender, '!age' => $age_type ) + ); + _booking_assign_attendee_group($iterator->key(), $starting_session, $gender, $age, $working_list, $session_count, $calculation_messages); + + } //end processed check + + //move to the next unprocessed attendee in the list + while ($iterator->valid() && $iterator->current()->processed == 1) { + //drupal_set_message(t("Skipping attendee ID !id, already processed.", array('!id' => $iterator->key()))); + $iterator->next(); + } + + //move to the next session + $i++; + } //finished looping through attendees for this study group +} + /** * Process the submission to accept calculated study group membership updates */