Loads of changes

This commit is contained in:
2014-02-24 23:53:12 +11:00
parent 66d4c89679
commit b710954bdd
10 changed files with 357 additions and 251 deletions

View File

@@ -354,7 +354,7 @@ function booking_available_leadhelp_select_form_submit($form, &$form_state) {
* 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 clone_array($copied_array) {
function booking_clone_array($copied_array) {
return array_map(function($element) {
return (
((is_array($element))
@@ -368,8 +368,12 @@ function clone_array($copied_array) {
}, $copied_array);
}
//taken from http://stackoverflow.com/questions/4102777/php-random-shuffle-array-maintaining-key-value
function shuffle_assoc($list) {
/**
* 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);
@@ -381,6 +385,31 @@ function shuffle_assoc($list) {
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)
{
//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
*/
@@ -406,18 +435,31 @@ function booking_studygroups_calculate() {
//calculate the max number of attendees in a group
$firstgroup = reset($studygroups);
$limit = variable_get('booking_regn_limit','500');
//add an extra two 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;
//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) + 1;
//select all the attendees booked in
/*
$query = db_query("SELECT p.nid, p.booking_partner_id, p.booking_event_id, p.booking_status, l.booking_total_lead, l.booking_available_lead, l.booking_total_help, l.booking_available_help FROM {booking_person} p left outer join {booking_leadhelp_list} l on p.nid = l.booking_node_id WHERE p.booking_event_id = :eid AND p.booking_status = 1",
array(':eid' => $event->eid));
*/
$query = db_query("SELECT * FROM {booking_person} WHERE booking_event_id = :eid",
array(':eid' => $event->eid));
$attendees = $query->fetchAllAssoc('nid');
$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');
@@ -436,11 +478,12 @@ function booking_studygroups_calculate() {
$person->session = 0;
$person->is_leader = 'N';
$person->is_helper = 'N';
$person->is_reserveleader = 'N';
}
//watchdog('booking', "Attendee list: @info", array('@info' => var_export($attendees, TRUE)));
//iterate over each study group (eg Monday Tuesday Wednesday etc)
//process each study group (eg Monday Tuesday Wednesday etc)
foreach ($studygroups as $group)
{
drupal_set_message(t('Processing study group !group with !sessions sessions.',
@@ -448,43 +491,61 @@ function booking_studygroups_calculate() {
//create a temporary copy of the attendee list to work with for this study group
$working_list = array();
$working_list = shuffle_assoc(clone_array($attendees));
$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] = 0;
{
$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_is_leader == 'Y' || $person->booking_is_helper == 'Y' ||
$person->booking_is_reserveleader == 'Y'))
{
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'])
));
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])));
//mark a position in this session as being used
$session_count[$person->booking_session_id]++;
//mark this person as processed in the working list
$working_list[$person->booking_node_id]->processed = 1;
//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);
//search for a spouse
//get any potential spouse info
$spouse_id = $working_list[$person->booking_node_id]->booking_partner_id;
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])));
//allocate the spouse to the same session
$working_list[$spouse_id]->session = $person->booking_session_id;
$working_list[$spouse_id]->processed = 1;
$session_count[$person->booking_session_id]++;
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);
}
//TODO: search for a boyfriend/girlfriend
}
}
//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)));
//return;
//reset the iterator to starting position
$it->rewind();
@@ -521,49 +582,48 @@ function booking_studygroups_calculate() {
//cycle the session counter if we already reached the end
if ($i > $group->booking_num_group_sessions)
$i = 1;
//check this session has room in it
$break_condition = false;
while ($session_count[$i] >= $max_people)
{
drupal_set_message(t("Session ID !id is full, moving to next session for user id !nid", array('!id' => $i, '!nid' => $it->key())));
$i++;
//reset the counter if we go past the end
if ($i > $group->booking_num_group_sessions)
{
$i = 1;
//make sure we don't get stuck in an infinite loop - only go past the end once
if ($break_condition == true)
{
drupal_set_message(t("Ran out of sessions that aren't full to place attendees into for '!id' group.", array('!id' => $group->booking_studygroup_descrip)), 'error', FALSE);
break;
}
$break_condition = true;
}
}
//get the current attendee element
$current = $it->current();
//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, 2);
//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, 2);
//check for maximum group size
_booking_loop_carefully($session_count, 'total', $i, $max_people, $group->booking_num_group_sessions, 2);
//assign this attendee to this session if unprocessed so far
if ($current->processed == 0)
{
drupal_set_message(t('Assigning person with id !id to session !session (currently with !num people).', array('!id' => $it->key(), '!session' => $i, '!num' => $session_count[$i])));
$current->session = $i;
$current->processed = 1;
$partner_id = $current->booking_partner_id;
$session_count[$i]++;
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 )
));
booking_assign_attendee_group($it->key(), $i, $gender, $age, $working_list, $session_count);
$partner_id = $current->booking_partner_id;
//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])));
array('!id' => $it->key(), '!session' => $i, '!spouse' => $current->booking_partner_id, '!num' => $session_count[$i]['total'])));
booking_assign_attendee_group($partner_id, $i, $gender, $age, $working_list, $session_count);
$working_list[$partner_id]->session = $i;
$working_list[$partner_id]->processed = 1;
$session_count[$i]++;
}
}
@@ -630,22 +690,20 @@ function booking_studygroups_calculate() {
'booking_session_id' => $person->session,
'booking_is_leader' => $person->is_leader,
'booking_is_helper' => $person->is_helper,
'booking_is_reserveleader' => $person->is_reserveleader,
);
$insert_query->values($record);
}
}
$insert_query->execute();
//$insert_query->execute();
//watchdog('booking', "Attendee list: @info", array('@info' => var_export($session_count, TRUE)));
watchdog('booking', "<pre>Attendee list:\n@info</pre>", array('@info' => print_r( $session_count, true)));
//clear the arrays we've been using for this iteration
unset($session_count);
unset($working_list);
//
} //finished processing study groups
//watchdog('booking', "Attendee list final version: @info", array('@info' => var_export($attendees, TRUE)));