502 lines
19 KiB
PHP
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 ‐ !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;
|
|
}
|