Files
booking/booking.studygroup_leaders.inc
2018-06-18 06:18:08 +10:00

502 lines
19 KiB
PHP

<?php
/**
* @file
* Functions for automatically calculating leaders and helpers for discussion groups
*/
/**
* Function for calculating and assigning leaders and helpers to active study group sessions
*/
function booking_studygroups_leaders_calculate() {
global $event;
$calculation_messages = array();
//get a randomly ordered list of people to work with
$people = _booking_shuffle_assoc(_booking_studygroups_retrieve_eligible_people());
//get details of the study groups
$groups = _booking_studygroups_retrieve_groups();
//loop through the list of people
foreach ($people as $person)
{
$age = _booking_get_age_years($person->booking_dob);
$calculation_messages[] = t('Processing eligible Leader/helper with id !id and age !age',
array('!id' => $person->nid, '!age' => $age)
);
foreach ($groups as $studygroup)
{
//watchdog('booking_debug', "<pre>Study Group Element\n@info</pre>", array('@info' => print_r( $studygroup, true)));
if ($age >= 22 && $studygroup->leader_nid == 0)
{
$studygroup->leader_nid = $person->nid;
$calculation_messages[] = t("Study Group Assignment as leader for nid !nid to group !descrip at session id !sid",
array('!nid' => $person->nid, '!descrip' => $studygroup->booking_studygroup_descrip, '!sid' => $studygroup->session_id, '@info' => print_r( $studygroup, true)));
break;
}
elseif ($age < 22 && $studygroup->helper_nid == 0)
{
$studygroup->helper_nid = $person->nid;
$calculation_messages[] = t("Study Group Assignment as helper for nid !nid to group !descrip at session id !sid",
array('!nid' => $person->nid, '!descrip' => $studygroup->booking_studygroup_descrip, '!sid' => $studygroup->session_id, '@info' => print_r( $studygroup, true)));
break;
}
}
//if someone is 22 or over, they're a leader
//$next_group_index = $groups[_booking_get_next_studygroup('leader_nid', $groups)];
//$groups[$next_group_index]->leader_nid = $person->nid;
//if someone is under 22, they're a helper
//left over people become a reserve leader
}
watchdog('booking', "<pre>Study Group Leader/Helper calculation\n" . implode("\n", $calculation_messages) . "</pre>");
//input the data to the database
}
function _booking_get_next_studygroup($type, $studygroups) {
$count = count($studygroups) - 1;
for ($i = 0; $i < $count; $i++) {
$group = $studygroups[$i];
$leader = $group->leader_nid;
//watchdog('booking_debug', "<pre>Study Group Element at index $i:\n@info</pre>", array('@info' => print_r( $group, true)));
//watchdog('booking_debug', "<pre>Study Group Leader NID at index $i:\n@info</pre>", array('@info' => var_dump($group)));
if ($leader == 0) {
return $i;
}
}
}
/**
* Function for
*/
function _booking_studygroups_retrieve_eligible_people() {
global $event;
$attendees = array();
//select males that are booked in
$query = db_select('booking_person', 'p');
$db_and = db_and();
$db_and->condition('p.booking_eventid', $event->eid, '=');
$db_and->condition('p.booking_gender', 'M', '=');
$db_and->condition('p.booking_status', 1, '=');
$query->condition($db_and);
$query->fields('p');
$bookedin_result = $query->execute();
//iterate over the attendee associative array and add some fields
foreach ($bookedin_result as $person) {
$person->processed = 0;
$person->leading = array();
$person->helping = array();
$person->reserve_leading = array();
$attendees[] = $person;
}
//select males that are on the waiting list up to position number 100
$result2 = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country, booking_status, booking_dob, booking_gender
FROM (
SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date, p.booking_status, p.booking_gender, p.booking_dob
FROM {booking_person} p, {booking_payment} pay
WHERE p.booking_eventid = :eid and p.nid = pay.booking_person_nid and ( p.booking_status = 2 or p.booking_status = 4)
LIMIT 100
) AS booking
WHERE booking_gender = \'M\'
ORDER BY booking_status, booking_payment_date',
array(':eid' => $event->eid));
//iterate over the attendee associative array and add some fields
foreach ($result2 as $person){
$person->processed = 0;
$person->leading = array();
$person->helping = array();
$person->reserve_leading = array();
$attendees[] = $person;
}
//watchdog('booking', "<pre>Eligible Leaders/Helpers List:\n@info</pre>", array('@info' => print_r( $attendees, true)));
return $attendees;
}
/**
* Function for
*/
function _booking_studygroups_retrieve_groups() {
global $event;
$groups = array();
//select all the study groups for this event id
$studygroup = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid));
$group_mapping = $studygroup->fetchAllAssoc('sid');
//select the number of study group sessions
//assume they all have the same number of sessions
//$num_sessions = $studygroup->booking_num_group_sessions;
foreach ($group_mapping as $group) {
//watchdog('booking_debug', "<pre>Study Group Element:\n@info</pre>", array('@info' => print_r( $group, true)));
for ($i = 1; $i <= 16; $i++) {
$new_group = clone $group;
$new_group->session_id = $i;
$new_group->leader_nid = 0;
$new_group->helper_nid = 0;
$new_group->reserve_nid = 0;
$new_group->processed = 0;
$groups[] = $new_group;
}
}
//watchdog('booking', "<pre>Study Group Sessions:\n@info</pre>", array('@info' => print_r( $groups, true)));
return $groups;
}
/**
* autocomplete helper to look up names for room allocations
* based on https://www.drupal.org/node/854216
* $string = string for search
*/
function _booking_studygroups_name_autocomplete($string) {
global $event;
$matches = array();
$query = db_select('booking_person', 'p')
->fields('p', array('nid', 'booking_firstname', 'booking_lastname'));
$db_or = db_or()
->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.nid', $string, "=");
$db_and = db_and()->condition($db_or)->condition('p.booking_eventid', $event->eid, '=');
$result = $query->condition($db_and)
->execute();
// save the query to matches
foreach ($result as $row) {
$name = $row->booking_lastname . ', ' . $row->booking_firstname . ' [' . $row->nid . ']';
$matches[$name] = $name;
}
// Return the result to the form in json
drupal_json_output($matches);
}
/**
* Function to allow admin to edit leaders and helpers for a study group
* Not sure where the original idea came from but https://knackforge.com/blog/selvam/drupal-7-creating-editable-table-form-api is similar
*/
function booking_studygroup_leadhelp_edit_form($node, &$form_state, $group_id) {
global $event;
//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 "";
}
//try to select the study group for this $group_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 "";
}
//define the table header
$header = array (
'sid' => array('data' => t('Study Group Session ID'), 'field' => 'sid'),
'booking_assign_leader' => array('data' => t('Leader')),
'booking_assign_helper' => array('data' => t('Helper')),
'booking_assign_reserveleader' => array('data' => t('Reserve Leader')),
'booking_assign_reservehelper' => array('data' => t('Reserve Helper')),
);
//attach the custom css
$form['#attached']['css'] = array(
drupal_get_path('module', 'booking') . '/booking.css',
);
$prefix = t("<h2>Edit Leaders/Helpers for Study Group &dash; !descrip</h2>",
array('!descrip' => $studygroup->booking_studygroup_descrip));
$prefix .= "<p>Enter part of a person's name in the text field and wait for the blue spinning circle to autocomplete with the person's details. " .
"Make sure you click on the person from the dropdown list that appears.</p>";
$form['first_para'] = array (
'#type' => 'markup',
'#markup' => $prefix,
);
//add this to the form in a hidden field so we can update the right studygroup
$form['booking_gid'] = array (
'#type' => 'hidden',
'#value' => $group_id,
);
//create the container element for the whole table
$form['studygroups'] = array(
'#prefix' => '<div id="studygroups">',
'#suffix' => '</div>',
'#tree' => TRUE,
'#theme' => 'table',
'#header' => $header,
'#rows' => array(),
);
//get the list of study group session memberships
$session_members_query = db_query("SELECT m.*, p.* FROM {booking_studygroup_mapping} m
inner join {booking_person} p on p.nid = m.booking_node_id
WHERE m.booking_studygroup_id = :gid AND m.booking_studygroup_role > 0",
array(':gid' => $group_id));
$session_members = $session_members_query->fetchAllAssoc('booking_node_id');
//create an array representing the existing leaders/helpers for this group
$existing_leaders = array();
foreach ($session_members as $person) {
$existing_leaders[$person->booking_session_id][$person->booking_studygroup_role] =
$person->booking_lastname . ', ' . $person->booking_firstname . ' [' . $person->booking_node_id . ']';
}
//create the rows for the individual sessions (instances really) of this study group
for ($i = 1; $i <= $studygroup->booking_num_group_sessions; $i++) {
$leader = array (
'#id' => 'booking-studygroup-leader-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_leader[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][1])) ? $existing_leaders[$i][1] : '',
'#attributes' => array('style' => array('width:200px')),
);
$helper = array (
'#id' => 'booking-studygroup-helper-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_helper[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][2])) ? $existing_leaders[$i][2] : '',
'#attributes' => array('style' => array('width:200px')),
);
$reserveleader = array (
'#id' => 'booking-studygroup-reserveleader-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_reserveleader[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][3])) ? $existing_leaders[$i][3] : '',
'#attributes' => array('style' => array('width:200px')),
);
$reservehelper = array (
'#id' => 'booking-studygroup-reservehelper-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_reservehelper[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][4])) ? $existing_leaders[$i][4] : '',
'#attributes' => array('style' => array('width:200px')),
);
$form['studygroups'][$i] = array(
'booking-studygroup-leader' => &$leader,
'booking-studygroup-helper' => &$helper,
'booking-studygroup-reserveleader' => &$reserveleader,
'booking-studygroup-reservehelper' => &$reservehelper,
);
$new_row = array();
//handle readings group differently
if ($studygroup->booking_is_readinggroup == 'Y') {
$new_row['sid'] = _booking_readinggroup_colour_lookup($i);
}
//non readings groups just show the session ID
else {
$new_row['sid'] = $i;
}
$new_row['booking_studygroup_leader'] = array('data' => &$leader);
$new_row['booking_studygroup_helper'] = array('data' => &$helper);
$new_row['booking_studygroup_reserveleader'] = array('data' => &$reserveleader);
$new_row['booking_studygroup_reservehelper'] = array('data' => &$reservehelper);
$form['studygroups']['#rows'][$i] = $new_row;
//clean up references
unset($leader);
unset($helper);
unset($reserveleader);
unset($reservehelper);
}
//record whether this was a reading group, so we can update colours if necessary
$form['booking_readinggroup'] = array (
'#type' => 'hidden',
'#value' => $studygroup->booking_is_readinggroup,
);
//close out the form
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Submit'),
);
return array (
'form' => $form,
);
}
/**
* Process the submission for leaders/helpers
*/
function booking_studygroup_leadhelp_edit_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
$group_id = $form_state['values']['booking_gid'];
$update_messages = array();
$counter = 0;
//watchdog('booking_debug', "<pre>Studygroup leader/helper test submission form :\n@info</pre>", array('@info' => print_r( $form_state, true)));
$role_types = array(
'booking_studygroup_leader' => 1,
'booking_studygroup_helper' => 2,
'booking_studygroup_reserveleader' => 3,
'booking_studygroup_reservehelper' => 4,
);
//iterate over the different role types
foreach ($role_types as $type => $type_id) {
//iterate over the sessions for that role type
foreach ($values[$type] as $session_id => $person) {
//get the previous value
$previous_value = _booking_studygroup_leadhelp_edit_get_previous_value($form, $type, $type . '[' . $session_id . ']');
//watchdog('booking_debug', "<pre>Studygroup assignment previous value:\n@info\nCurrent value:\n@current</pre>",
// array('@info' => print_r( $previous_value, true), '@current' => print_r( $person, true)));
//compare it against $person
//if $person is now empty, set the person's role to zero
if (empty($person) && $previous_value != 0) {
$update_messages[] = t("Clearing leader/helper role for nid @id and session @session in group @group. Used to have role @role.",
array('@id' => $previous_value, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => 0,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $previous_value)
->condition('booking_session_id', $session_id)
->execute();
$counter++;
}
elseif (!empty($person)) {
preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches);
$person_nid = $matches[1];
//if $person is now different, run an update query
if ($person_nid != $previous_value) {
//check if this person is already a member of this studygroup
$group_query = db_query("SELECT * FROM {booking_studygroup_mapping} " .
"WHERE booking_eventid = :eid AND booking_node_id = :nid AND booking_studygroup_id = :gid",
array(':eid' => $event->eid, ':nid' => $person_nid, ':gid' => $group_id))
->fetchObject();
if (! $group_query) {
//this person doesn't seem to already be in this study group so insert a record
$update_messages[] = t("Adding via insert: role @role to nid @id in group @group and session @session.",
array('@id' => $person_nid, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_insert('booking_studygroup_mapping')
->fields(array(
'booking_eventid' => $event->eid,
'booking_node_id' => $person_nid,
'booking_studygroup_id' => $group_id,
'booking_session_id' => $session_id,
'booking_studygroup_role' => $type_id,
))
->execute();
}
else {
//update the role for the new person
$update_messages[] = t("Adding via update: role @role to nid @id in group @group and session @session.",
array('@id' => $person_nid, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => $type_id,
'booking_session_id' => $session_id,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $person_nid)
->execute();
}
$counter++;
//remove the role from the old person if there was someone else there before
if ($previous_value != 0) {
$update_messages[] = t("Removing role @role from nid @id in group @group and session @session.",
array('@id' => $previous_value, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => 0,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $previous_value)
->condition('booking_session_id', $session_id)
->execute();
$counter++;
} //end previous value check
} //end different person check
} //end empty person check
} //iterate session
} //iterate role type
//do we need to update colours for reading group?
if ($form_state['values']['booking_readinggroup'] == 'Y') {
booking_studygroups_process_colours();
}
$final_message = "Made $counter update(s) to leader/helper roles for study group id $group_id. Changing one person to another counts as two updates.";
drupal_set_message($final_message, 'status', FALSE);
watchdog('booking', "<pre>" . $final_message . "\n" . implode("\n", $update_messages) . "</pre>");
}
/**
* look through the previous form data and return the matching element
*/
function _booking_studygroup_leadhelp_edit_get_previous_value(&$form, $type, $name) {
foreach($form['form']['studygroups']['#rows'] as $key => $value) {
//watchdog('booking_debug', "<pre>Studygroup assignment checker for type !type in session !name:\n@info</pre>",
// array('!session' => $name, '!type' => $type, '@info' => print_r( $value, true)));
//return;
if ((!empty($value[$type]['data']['#value'])) && ($value[$type]['data']['#name'] == $name)) {
//found the correct element, extract the node id
$person = $value[$type]['data']['#value'];
if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) {
return $matches[1];
}
}
}
//in case there was no matching value, return an empty string
return 0;
}