';
$output .= drupal_get_form('signup_status_node_admin_form', $node);
// Add a form to allow the administrator to signup other users.
$output .= drupal_get_form('signup_form', $node, 'admin');
return $output;
}
/**
* Provide what is essentially a replacement for the signup module's \
* node admin summary form.
*
* @param $node
* The node object to provide the form for.
* @return
* A structured form array.
*/
function signup_status_node_admin_summary_form($node) {
$limits = signup_status_get_node_code_limits($node->nid);
$totals = signup_status_get_node_code_totals($node->nid);
$total_approved = signup_status_get_total_approved_signups($node->nid);
$totals[1] = $total_approved;
$codes = signup_status_codes();
$help_codes = array();
foreach ($codes as $cid => $code) {
if (!$code['mod_signup_count']) {
$help_codes[] = $code['name'];
}
}
$help = '
'. t('The following statuses are considered to be %approved: %codes.', array('%approved' => $codes[1]['name'], '%codes' => implode($help_codes, ', '))) .'
';
$row[] = drupal_render($form);
$output = theme('table', $header, array($row));
$output .= $help;
return $output;
}
/**
* Provide the signup status node admin form (for bulk updating signups)
*
* @param $node
* The full node object to display the form for.
* @return
* A form array.
*/
function signup_status_node_admin_form($node) {
drupal_set_title(check_plain($node->title));
$form = array();
$codes = signup_status_codes();
$signups = signup_status_get_signups($node->nid);
$limits = signup_status_get_node_code_limits($node->nid);
$totals = signup_status_get_node_code_totals($node->nid);
$total_approved = signup_status_get_total_approved_signups($node->nid);
$totals[1] = $total_approved;
$form['options'] = array('#type' => 'fieldset',
'#title' => t('Update options'),
'#prefix' => '
',
'#suffix' => '
',
);
$options = array();
foreach (module_invoke_all('signup_status_operations') as $operation => $array) {
$options[$operation] = $array['label'];
}
$form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => 'approve');
$form['options']['submit'] = array('#type' => 'submit', '#value' => t('Update'));
foreach ($signups as $signup) {
$key = $signup->anon_mail ? $signup->uid .':'. $signup->anon_mail : $signup->uid;
$data = unserialize($signup->form_data);
$username = $signup->uid ? theme('username', $signup) : t('!name (%mail)', array('!name' => $data['Name'], '%mail' => $signup->anon_mail));
$users[$key] = '';
$form['username'][$key] = array('#value' => $username);
$form['formatted_data'][$key] = array('#value' => signup_build_signup_data($data, 'output', $signup, $node->nid));
$form['signup_time'][$key] = array('#value' => format_date($signup->signup_time));
$form['signup_status'][$key] = array('#value' => $codes[$signup->status]['name']);
$form['signup_anon_mail'][$key] = array('#type' => 'hidden', '#value' => $signup->anon_mail);
}
$form['users'] = array('#type' => 'checkboxes', '#options' => $users);
$form['nid'] = array('#type' => 'hidden', '#value' => $node->nid);
$form['#node'] = $node;
return $form;
}
/**
* Theme the signup status node admin form
*/
function theme_signup_status_node_admin_form($form) {
$output = '';
$header = array(
theme('table_select_header_cell'),
t('Name'),
t('Extra Information'),
t('Signup time'),
t('Status'),
);
$output .= drupal_render($form['options']);
$output .= drupal_render($form['availability']);
if (isset($form['username']) && is_array($form['username'])) {
foreach (element_children($form['username']) as $key) {
$row = array();
$row[] = drupal_render($form['users'][$key]);
$row[] = drupal_render($form['username'][$key]);
$row[] = drupal_render($form['formatted_data'][$key]);
$row[] = drupal_render($form['signup_time'][$key]);
$row[] = drupal_render($form['signup_status'][$key]);
$rows[] = $row;
}
}
else {
$rows[] = array(array('data' => t('No signups available.'), 'colspan' => '6'));
}
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
/**
* Handle submission of the signup status node admin form by calling the
* specified callback.
*/
function signup_status_node_admin_form_submit($form_id, $form_values) {
$operations = module_invoke_all('signup_status_operations');
$operation = $operations[$form_values['operation']];
// Filter out unchecked users
$users = array_filter($form_values['users']);
if ($function = $operation['callback']) {
// Add in callback arguments if present.
if (isset($operation['callback arguments'])) {
$args = array_merge(array($users), array($form_values['nid']), $operation['callback arguments']);
}
else {
$args = array_merge(array($users), array($form_values['nid']));
}
call_user_func_array($function, $args);
}
}
/**
* Handle validation of the signup status node admin form
*/
function signup_status_node_admin_form_validate($form_id, $form_values) {
$users = array_filter($form_values['users']);
if (count($users) == 0) {
form_set_error('', t('No items selected.'));
}
// Stop validation if user is cancelling signups - this should always pass
if ($form_values['operation'] == 'cancel') {
return;
}
// Make sure the user hasn't selected more users than is possible for the
// new status
$operations = module_invoke_all('signup_status_operations');
$operation = $operations[$form_values['operation']];
if ($operation['callback'] == 'signup_status_operations') {
$nid = $form_values['nid'];
$cid = $operation['callback arguments'][1];
$users = array_filter($form_values['users']);
$signups = signup_status_get_signups($nid);
$codes = signup_status_codes();
$limits = signup_status_get_node_code_limits($nid);
$totals = signup_status_get_node_code_totals($nid);
$total_approved = signup_status_get_total_approved_signups($nid);
$totals[1] = $total_approved;
$target_limit = $codes[$cid]['mod_signup_count'] ? $limits[$cid] : $limits[1];
$target_total = $codes[$cid]['mod_signup_count'] ? $totals[$cid] : $totals[1];
// Only perform the check for available seats if the target limit isn't
// set to "0", which would mean the user doesn't want a signup limit
if ($target_limit != 0) {
foreach ($signups as $signup) {
if (in_array($signup->uid, $users)) {
$cmp_cid = $signup->status;
// Increase the target limit cid if the user is already signed up
// for that cid,
// OR the user is already "approved" and is switching to another
// "approved" equivalent code
// OR switching from a "approved" equivalent code to "approved"
// OR switch from a "approved" equivalent code to a "approved"
// equivalent code
if ($cmp_cid == $cid ||
($cmp_cid == 1 && !$codes[$cid]['mod_signup_count']) ||
(!$codes[$cmp_cid]['mod_signup_count'] && $cid == 1) ||
(!$codes[$cmp_cid]['mod_signup_count'] && !$codes[$cid]['mod_signup_count'])) {
$target_limit += 1;
}
}
}
$available = $target_limit - $target_total;
if (count($users) > $available) {
form_set_error('', t('There are not enough seats available in that status for all of the users you have selected.'));
}
}
}
}
/**
* Get the total number of approved signups for a given nid. This includes
* any signups set at a status code that essentially equals "approved."
*
* @param $nid
* The nid for the node.
* @return
* An integer - the total number of approved signups.
*/
function signup_status_get_total_approved_signups($nid) {
$cids = array(1);
$codes = signup_status_codes();
foreach ($codes as $cid => $code) {
if (!$codes[$cid]['mod_signup_count'] || $cid == 1) {
$cids[] = $cid;
}
}
$sql = "SELECT COUNT(*) FROM {signup_log} WHERE nid = %d AND status IN (%s)";
$result = db_result(db_query($sql, $nid, implode($cids, ', ')));
return $result;
}
/**
* Implementation of hook_signup_status_operations
*/
function signup_status_signup_status_operations() {
$codes = signup_status_codes();
foreach ($codes as $cid => $code) {
$operations['code_'. $cid] = array(
'label' => t('Status') .': '. $code['name'],
'callback' => 'signup_status_operations',
'callback arguments' => array('status_code', $cid),
);
}
$operations['cancel'] = array(
'label' => t('Cancel Signup'),
'callback' => 'signup_status_operations',
'callback arguments' => array('cancel'),
);
return $operations;
}
/**
* Act upon changes submitted via the signup status admin form for nodes.
* Invokes hook_update_signup_status.
*
* @param $users
* An array of user uids. The uid may be of the format "0:user@example.com",
* in which case it is an anonymous signup.
* @param $nid
* The nid of the node for which signup status is being altered.
* @param $op
* The operation being invoked.
* @param $cid
* The status code id that was selected
*/
function signup_status_operations($users, $nid, $op, $cid = NULL) {
$accounts = signup_status_users_to_accounts($users);
// Cancel the user's signup
if ($op == 'cancel') {
foreach ($accounts as $account) {
$curr_cid = signup_status_user_signup_status($account['uid'], $nid, $account['anon_mail']);
signup_status_invoke_all($account['uid'], $nid, $curr_cid, 0, $account['anon_mail']);
signup_cancel_signup($account['uid'], $nid, $account['anon_mail']);
}
}
// Update the user's signup status code
if ($op == 'status_code') {
foreach ($accounts as $account) {
$curr_cid = signup_status_user_signup_status($account['uid'], $nid, $account['anon_mail']);
signup_status_invoke_all($account['uid'], $nid, $curr_cid, $cid, $account['anon_mail']);
}
drupal_set_message(t('Updated signup status for selected users.'));
}
}
/**
* Parse through an array of user signup "user ids," which could include
* anonymous signups, and prepare a more structural data format.
*
* @param $users
* An array of uids, which could also include ids of the format
* 0:user@example.com, for anonymouse signups
* @return
* An array of associative arrays, each with keys:
* uid: The user id of the signup, or 0 for anonymous users
* anon_mail: The email address for anonymous users
*/
function signup_status_users_to_accounts($users) {
$accounts = array();
foreach ($users as $uid) {
$anon_mail = NULL;
if (strstr($uid, ':')) {
$data = explode(':', $uid);
$uid = $data[0];
$anon_mail = $data[1];
}
$accounts[] = array(
'uid' => $uid,
'anon_mail' => $anon_mail,
);
}
return $accounts;
}
/**
* Implementation of hook_form_alter
*/
function signup_status_form_alter($form_id, &$form) {
switch ($form_id) {
case $form['type']['#value'] .'_node_form' && isset($form['signup']):
signup_status_alter_node_form($form_id, $form);
break;
case 'signup_admin_node_form':
signup_status_alter_signup_admin_node_form($form_id, $form);
break;
case 'signup_broadcast_form':
signup_status_alter_signup_broadcast_form($form_id, $form);
break;
case 'signup_form':
signup_status_alter_signup_form($form_id, $form);
break;
}
}
/**
* Alter the node add / edit form to get all available statuses that modify
* the signup limit and add a field for their limit.
*/
function signup_status_alter_node_form($form_id, &$form) {
$node = $form['#node'];
$codes = signup_status_codes(array('mod_signup_count = 1'));
$has_codes = count($codes);
if ($has_codes) {
$form['signup']['node_settings']['settings']['signup_status_close_cid_limits'] = array(
'#type' => 'fieldset',
'#title' => t('Signup limits'),
'#tree' => TRUE
);
foreach ($codes as $cid => $code) {
$has_codes = TRUE;
$form['signup']['node_settings']['settings']['signup_status_close_cid_limits'][$cid] = array(
'#type' => 'textfield',
'#title' => t('%name status limit', array('%name' => $code['name'])),
'#default_value' => isset($node->signup_status_close_cid_limits[$cid]) ? $node->signup_status_close_cid_limits[$cid] : 0,
'#size' => 4, '#maxlength' => 8,
'#description' => t('Maximum number of users who can signup for the %name status. If set to 0, there is no limit. If set to -1, this status will not be available to users during signup. Status description: %description', array('%name' => $code['name'], '%description' => $code['description'])),
);
}
$form['signup']['node_settings']['settings']['signup_close_signup_limit']['#type'] = 'value';
}
}
/**
* Alter the signup broadcast form to allow broadcasting to just a single status
*/
function signup_status_alter_signup_broadcast_form($form_id, &$form) {
$options = array();
$codes = signup_status_codes();
$options[-1] = t('');
foreach ($codes as $cid => $code) {
$options[$cid] = $code['name'];
}
$form['signup_status_codes'] = array(
'#type' => 'select',
'#title' => t('Limit recipients'),
'#description' => t('Send this email to a specific set of users based on signup status.'),
'#multiple' => TRUE,
'#options' => $options,
'#default_value' => -1,
);
$form['send']['#weight'] = 10;
// Overwrite the submit hook, in case the user selects a specific status
$form['#validate']['signup_status_signup_broadcast_form_validate'] = array();
$form['#submit'] = array('signup_status_signup_broadcast_form_submit' => array());
}
/**
* Validate altered broadcast form
*/
function signup_status_signup_broadcast_form_validate($form_id, $form_values) {
$codes = $form_values['signup_status_codes'];
if (!in_array(-1, $codes)) {
$signups = signup_status_get_signups($form_values['nid']);
$count = 0;
foreach ($signups as $signup) {
if (in_array($signup->status, $codes)) {
$count++;
}
}
if (!$count) {
form_set_error('signup_status_codes', t('No users are signed up with that status.'));
}
}
}
/**
* Handle submission of the altered broadcast form
*/
function signup_status_signup_broadcast_form_submit($form_id, $form_values) {
$codes = $form_values['signup_status_codes'];
// Just use standard submit handler if no code was selected
if (in_array(-1, $codes)) {
signup_broadcast_form_submit('signup_broadcast_form', $form_values);
}
else {
$nid = $form_values['nid'];
$sent = FALSE;
$signups = signup_status_get_signups($nid);
if (is_array($signups)) {
$from = $form_values['from'];
$subject = $form_values['subject'];
$event = node_load($nid);
foreach ($signups as $signup) {
if (in_array($signup->status, $codes)) {
$sent = TRUE;
$mail_address = $signup->anon_mail ? $signup->anon_mail : $signup->mail;
$trans = array(
'%event' => $event->title,
'%username' => $signup->uid ? $signup->name : variable_get('anonymous', t('Anonymous')),
'%useremail' => $mail_address,
);
$trans['%time'] = signup_format_date($event);
$message = strtr($form_values['message'], $trans);
drupal_mail('signup_broadcast_mail', $mail_address, $subject, $message, $from);
watchdog('signup', t('Broadcast email for %event sent to %email.', array('%event' => $event->title, '%email' => $mail_address)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $event->nid));
}
}
if ($sent) {
drupal_set_message(t('Message sent to all users who are signed up with the specified status.'));
}
}
}
}
/**
* Alter the signup form to add a status selector, if available.
*/
function signup_status_alter_signup_form($form_id, &$form) {
$node = node_load($form['nid']['#value']);
$args = array('show_on_form = 1');
$codes = signup_status_codes($args, FALSE);
if (!count($codes)) {
return;
}
foreach ($codes as $cid => $code) {
$limit = $node->signup_status_close_cid_limits[$cid];
$total = $node->signup_status_cid_totals[$cid];
if ($total < $limit || $limit == 0) {
$options[$cid] = $code['name'];
}
}
if (count($options)) {
$form['collapse']['signup_status'] = array(
'#type' => 'select',
'#title' => t('Status'),
'#options' => $options,
);
}
$form['collapse']['submit']['#weight'] = 10;
$form['#submit']['signup_status_alter_signup_form_submit'] = array();
}
/**
* Additional submission handler for the signup form
*/
function signup_status_alter_signup_form_submit($form_id, $form_values) {
signup_status_update_signup_status($form_values['uid'], $form_values['nid'], NULL, $form_values['signup_status'], $form_values['anon_mail']);
}
/**
* Alter the signup admin node form, provided in signup.module. We simply
* make it so users can't alter the signup limit.
*/
function signup_status_alter_signup_admin_node_form($form_id, &$form) {
$form['limit']['#type'] = 'markup';
$form['limit']['#value'] = $form['limit']['#default_value'];
if (!isset($form['status']['#options'])) {
unset($form['submit']);
}
}
/**
* Implementation of hook_nodeapi
*/
function signup_status_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if ($node->signup) {
// load
if ($op == 'load') {
$limits = signup_status_get_node_code_limits($node->nid);
$totals = signup_status_get_node_code_totals($node->nid);
$node->signup_status_close_cid_limits = $limits;
$node->signup_status_cid_totals = $totals;
}
// submit
if ($op == 'submit') {
global $form_values;
// Programmatically set (override) the overall signup limit.
// We do this here to be sure it happens before the insert / update hooks are called.
$node->signup_close_signup_limit = 0;
$codes = signup_status_codes();
foreach ($codes as $cid => $code) {
$limit = $node->signup_status_close_cid_limits[$cid];
$node->signup_close_signup_limit += ($limit == -1 ? 0 : $limit);
}
$form_values['signup_close_signup_limit'] = $node->signup_close_signup_limit;
}
// insert / update
if ($op == 'insert' || $op == 'update') {
$codes = signup_status_codes();
$cur_limit = db_result(db_query("SELECT close_signup_limit FROM {signup} WHERE nid = %d", $node->nid));
foreach ($codes as $cid => $code) {
// Store the saved signup status code limits
$limit = $node->signup_status_close_cid_limits[$cid];
signup_status_set_node_code_limit($node->nid, $cid, $limit);
}
// if the signup limit has been increased, migrate users to "approved" status, if necessary
if ($node->nid && $node->signup_close_signup_limit > $cur_limit) {
signup_status_auto_transition($node->nid);
}
}
}
}
/**
* Auto-transition users from non-approved status to approved, if seats are
* available to move users into. Generally called via cron.
*
* @param $nid
* The nid for the node.
* @return
* Void.
*/
function signup_status_auto_transition($nid) {
// check to see if there are "approved" seats available
$limits = signup_status_get_node_code_limits($nid);
$totals = signup_status_get_node_code_totals($nid);
$seats_available = $limits[1] - $totals[1];
if ($seats_available <= 0) {
// do nothing, we can't transition any users because "approved" slots are full
}
else {
$codes = signup_status_codes(array('mod_signup_count = 1'));
$auto_transition_codes = array();
foreach ($codes as $cid => $code) {
if ($code['auto_transition']) {
$auto_transition_codes[] = $cid;
}
}
if (count($auto_transition_codes)) {
$sql = "SELECT * FROM {signup_log} WHERE nid = %d AND status IN (%s) ORDER BY signup_time DESC LIMIT %d";
$result = db_query($sql, $nid, implode($auto_transition_codes, ', '), $seats_available);
while ($row = db_fetch_object($result)) {
signup_status_invoke_all($row->uid, $nid, $row->status, 1, $row->anon_mail);
}
drupal_set_message(t('Automatically transitioned %num users to the %approved status.', array('%num' => db_num_rows($result), '%approved' => $codes[1]['name'])));
}
}
}
/**
* Set the limit for the number of signups allowed for a given status code.
*
* @param $nid
* The nid for the node.
* @param $cid
* The status code to set a limit on.
* @param $limit
* An integer defining the limit to set.
* @return
* Void.
*/
function signup_status_set_node_code_limit($nid, $cid, $limit) {
db_query("DELETE FROM {signup_status_node_limits} WHERE nid = %d AND cid = %d", $nid, $cid);
db_query("INSERT INTO {signup_status_node_limits} (nid, cid, close_signup_limit) VALUES (%d, %d, %d)", $nid, $cid, $limit);
}
/**
* Get the limit for each signup status code for a given node.
*
* @param $nid
* The nid for the node.
* @return
* An array, keyed by status code id (cid) with the value being the limit on the number of signups with that status code
*/
function signup_status_get_node_code_limits($nid) {
$limits = array();
$result = db_query("SELECT cid, close_signup_limit FROM {signup_status_node_limits} WHERE nid = %d", $nid);
while ($row = db_fetch_object($result)) {
$limits[$row->cid] = $row->close_signup_limit;
}
return $limits;
}
/**
* Get total signups for each signup status code for a given node
*
* @param $nid
* The nid for the node.
* @return
* An array, keyed by status code id (cid) with the value being the total
* number of signups with that status code
*/
function signup_status_get_node_code_totals($nid) {
$totals = array();
$codes = signup_status_codes();
foreach ($codes as $cid => $code) {
$totals[$cid] = 0;
}
$signups = signup_status_get_signups($nid);
foreach ($signups as $signup) {
$totals[$signup->status] += 1;
}
return $totals;
}
/**
* Output a printable roster of signups for the given node.
*
* @param $node
* The node to display a roster for.
* @return
* None. Outputs a printable page containing the themed HTML of the roster.
*/
function signup_status_print_roster($node, $type = NULL) {
$print_path = 'node/'. $node->nid;
if (arg(3) == 'print') {
$print_path .= '/signups/print';
}
else {
$print_path .= '/signups-print';
}
if (!$type) {
$links = array(
'html' => array('title' => t('Print to HTML'), 'href' => $print_path .'/html'),
);
if (module_exists('dompdf')) {
$links['pdf'] = array('title' => t('Download PDF'), 'href' => $print_path .'/pdf');
}
if (function_exists('fputcsv')) {
$links['csv'] = array('title' => t('Download CSV'), 'href' => $print_path .'/csv');
}
return theme('links', $links);
}
// Print to HTML or PDF
if ($type == 'html' || ($type == 'pdf' && module_exists('dompdf'))) {
$content = signup_status_prepare_roster($node);
$html = theme('signup_status_export_html', $node, $content);
if ($type == 'html') {
print $html;
}
if ($type == 'pdf') {
$filename = substr(check_url($node->title), 0, 16) .'.'. t('roster') .'.'. format_date(time(), 'custom', "Ymd") .'.pdf';
dompdf_stream_pdf($html, $filename);
}
}
// Print to CSV
if ($type == 'csv') {
if (!function_exists('fputcsv')) {
drupal_set_message(t('PHP 5.1 or greater required for CSV generation.'), 'error');
return '';
}
$rows = signup_status_prepare_roster_csv($node);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="signups-'. $node->nid .'-'. date('Ymd') .'.csv"');
$output = fopen('php://output', 'w');
foreach ($rows as $row) {
fputcsv($output, $row);
}
fclose($output);
}
}
/**
* Prepare a roster of signups for the given node
*
* @param $node
* The node to prepare a roster for.
* @return
* The themed HTML of the roster.
*/
function signup_status_prepare_roster($node) {
$output = '';
$codes = signup_status_codes();
$signups = signup_status_get_signups($node->nid);
$header = array(
theme('table_select_header_cell'),
t('Name'),
t('Extra Information'),
t('Signup time'),
t('Status'),
);
$rows = array();
if (count($signups)) {
foreach ($signups as $signup) {
$name = $signup->uid ? theme('username', $signup) : $signup->anon_mail;
$data = unserialize($signup->form_data);
$formatted_data = signup_build_signup_data($data, 'output', $signup, $node->nid);
$row = array();
$row[] = '';
$row[] = $name;
$row[] = $formatted_data;
$row[] = format_date($signup->signup_time);
$row[] = $codes[$signup->status]['name'];
$rows[] = $row;
}
}
else {
$rows[] = array(array('data' => t('No signups available.'), 'colspan' => '6'));
}
$output .= theme('table', $header, $rows);
return $output;
}
function signup_status_prepare_roster_csv($node) {
$rows = array();
$codes = signup_status_codes();
$signups = signup_status_get_signups($node->nid);
if (!count($signups)) {
return t('No signups available for output.');
}
// build / get the signup form so we can see all the fields
$signup_form = drupal_retrieve_form('signup_form');
foreach (module_implements('form_alter') as $module) {
$function = $module .'_form_alter';
$function('signup_form', $signup_form);
}
$header = array(
t('UID'),
t('Username'),
t('Anonymous email'),
t('Signup time'),
t('Status'),
);
foreach ($signup_form['collapse']['signup_user_form']['signup_form_data'] as $key => $value) {
if (is_array($value)) {
$header[] = t($key);
}
}
if (module_exists('signup_status_cert')) {
$header[] = t('Completion time');
$header[] = t('Certificate ID');
}
$rows[] = $header;
foreach ($signups as $signup) {
$account = user_load(array('uid' => $signup->uid));
$username = $account->name;
$themed_name = strip_tags(theme('username', $account));
if ($themed_name != $username) {
$username = $themed_name .' ('. $account->name .')';
}
$form_data = unserialize($signup->form_data);
$row = array(
$signup->uid,
$username,
$signup->anon_mail,
format_date($signup->signup_time, 'small'),
$codes[$signup->status]['name'],
);
foreach ($signup_form['collapse']['signup_user_form']['signup_form_data'] as $key => $value) {
if (is_array($value)) {
$row[] = $form_data[$key];
}
}
if (module_exists('signup_status_cert')) {
$row[] = format_date($signup->completion_time, 'small');
$row[] = $signup->cert_id;
}
$rows[] = $row;
}
return $rows;
}
/**
* Theme function for the signup roster
*/
function theme_signup_status_export_html($node, $content) {
global $base_url;
$header = '';
$roster_contents = module_invoke_all('signup_status_roster_content', $node);
foreach ($roster_contents as $roster_content) {
$header .= $roster_content;
}
$title = t('Roster for !title', array('!title' => check_plain($node->title)));
$body = "
". $title ."
\n\n";
$body .= '
'. $header ."
\n\n";
$body .= $content;
$html = "\n";
$html .= '';
$html .= "\n". $title ."\n";
$html .= '';
$html .= "\n";
$html .= "\n";
$html .= "\n\n". $body ."\n\n\n";
return $html;
}
/**
* Retrieve all available status codes.
*
* @param $mod_only
* Only return status codes that modify the signup count.
* @param $with_cancelled
* Include "cancelled" as a status code.
* @return
* An array of status code arrays, keyed using the status code id, cid.
* Each status code array contains the following keys / values:
* name: The display name of the status code.
* description: The long-form description of the status code.
* mod_signup_count: A boolean value stating whether signups using the
* status code should modify the total signup count (i.e. for the "wait
* listed" status code).
*/
function signup_status_codes($args = array(), $with_cancelled = FALSE) {
$sql = "SELECT * FROM {signup_status_codes}";
if (is_array($args) && count($args)) {
$sql .= " WHERE ";
$sql .= implode(' AND ', $args);
}
$result = db_query($sql);
while ($row = db_fetch_object($result)) {
$codes[$row->cid] = array(
'name' => $row->name,
'description' => $row->description,
'mod_signup_count' => $row->mod_signup_count,
'auto_transition' => $row->auto_transition,
'show_on_form' => $row->show_on_form,
);
}
if ($with_cancelled) {
$codes[0] = array(
'name' => t('Cancelled'),
);
}
return $codes;
}
/**
* Get all signups for a given node.
*
* @param $nid
* The nid for the node object for which to retrieve signup information .
* @return
* An array of signup objects that will contain the following properties:
* uid: The uid of the user.
* name: The name of the user.
* anon_mail: The email address provided by the user when she signed up,
* if applicable.
* signup_time: A UNIX timestamp indicating the time of the user's signup.
* form_data: A serialized array of the user's signup form data. See
* signup_build_signup_data for usage.
* status: The current status code of the user's signup.
*/
function signup_status_get_signups($nid) {
$signups = array();
$result = db_query("SELECT u.uid, u.name, u.mail, s.* FROM {signup_log} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.nid = %d ORDER BY u.name", $nid);
while ($row = db_fetch_object($result)) {
$signups[] = $row;
}
return $signups;
}
/**
* Get a user's current signup status to a node
*
* @param $uid
* The uid for the user.
* @param $nid
* The nid for the node.
* @param $anon_mail
* The email address provided by the user when she registered, if
* applicable.
* @return
* The status code or NULL, if the user is not signed up.
*/
function signup_status_user_signup_status($uid, $nid, $anon_mail = NULL) {
return db_result(db_query("SELECT status FROM {signup_log} WHERE uid = %d AND nid = %d AND anon_mail = '%s'", $uid, $nid, $anon_mail));
}
/**
* Invoke the "update_signup_status" hook, but only do so if the status has
* changed.
*
* @param $uid
* The uid of the user being updated.
* @param $nid
* The nid of the node for which the signup is being updated.
* @param $curr_cid
* The current status code id (cid)
* @param $new_cid
* The new cid
* @param $anon_mail
* The anon_mail value of the signup, if it was anonymous.
*/
function signup_status_invoke_all($uid, $nid, $curr_cid, $new_cid = 0, $anon_mail = NULL) {
if ($curr_cid != $new_cid) {
module_invoke_all('update_signup_status', $uid, $nid, $curr_cid, $new_cid, $anon_mail);
}
}
/**
* Implementation of hook_update_signup_status
*/
function signup_status_update_signup_status($uid, $nid, $curr_cid, $new_cid, $anon_mail = NULL) {
db_query("UPDATE {signup_log} SET status = %d WHERE uid = %d AND nid = %d AND anon_mail = '%s'", $new_cid, $uid, $nid, $anon_mail);
}
/**
* Implementation of hook_signup_data_alter
* Note: This has not been added to the base signup module yet.
* See: http://drupal.org/node/209954
*/
function signup_status_signup_data_alter(&$data, $signup, $nid) {
// Only show this on the node page (for the user to see their current status)
if (!arg(2)) {
$codes = signup_status_codes();
$status = signup_status_user_signup_status($signup->uid, $nid, isset($signup->anon_mail) ? $signup->anon_mail : NULL);
$data['Status'] = $codes[$status]['name'];
}
}
/**
* Implementation of hook_views_tables()
*/
function signup_status_views_tables() {
$tables['signup_status_node_limits'] = array(
'name' => 'signup_status_node_limits',
'join' => array(
'type' => 'inner',
'left' => array(
'table' => 'node',
'field' => 'nid'
),
'right' => array(
'field' => 'nid'
),
),
'fields' => array(
'signup_limits' => array(
'name' => t('Signup Status: Limits'),
'handler' => 'views_handler_field_signup_status_limits',
'sortable' => false,
'notafield' => true,
),
),
'filters' => array(),
);
return $tables;
}
/**
* Implementation of hook_views_tables_alter:
* Provide views columns for the signup_log table
*/
function signup_status_views_tables_alter(&$tables) {
$tables['signup_log']['fields']['status'] = array(
'name' => t('Signup: User: Status'),
'handler' => 'views_handler_field_signup_status_code',
);
$codes = signup_status_codes();
$options = array();
foreach ($codes as $cid => $code) {
$options[$cid] = $code['name'];
}
$tables['signup_log']['filters']['signup_status'] = array(
'name' => t('Signup: User: Status'),
'field' => 'status',
'operator' => array('=' => t('is')),
'value' => array(
'#type' => 'select',
'#options' => $options,
),
);
}
/**
* Views field handler for displaying signup status limits
*/
function views_handler_field_signup_status_limits($fieldinfo, $fielddata, $value, $data) {
$nid = $data->nid;
$codes = signup_status_codes(array('mod_signup_count = 1'));
$limits = signup_status_get_node_code_limits($nid);
$totals = signup_status_get_node_code_totals($nid);
$total_approved = signup_status_get_total_approved_signups($nid);
$totals[1] = $total_approved;
$full = TRUE;
$output = '';
$items = array();
foreach ($codes as $cid => $code) {
// Don't show the status code in the list if it's set to -1 (unavailable)
if ($limits[$cid] != -1) {
if ($limits[$cid] > $totals[$cid] || $limits[$cid] == 0) {
$full = FALSE;
}
$total = $totals[$cid];
$limit = $limits[$cid] > 0 ? $limits[$cid] : t('No limit');
$name = $code['name'];
$items[] = t('!name: @total / @limit', array('!name' => $name, '@total' => $total, '@limit' => $limit));
}
}
if ($full) {
$output .= "". t('No signups available') ." ";
}
$output .= theme('item_list', $items);
return $output;
}
/**
* Views field handler for display the status code name
*/
function views_handler_field_signup_status_code($fieldinfo, $fielddata, $value, $data) {
$codes = signup_status_codes();
return $codes[$value]['name'];
}