Skip to content
98 changes: 58 additions & 40 deletions cancelsignup.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
require_once('lib.php');

$s = required_param('s', PARAM_INT); // Facetoface session ID.
$f = optional_param('f', 0, PARAM_INT); // Facetoface ID.
$confirm = optional_param('confirm', false, PARAM_BOOL);
$backtoallsessions = optional_param('backtoallsessions', 0, PARAM_INT);

Expand Down Expand Up @@ -61,7 +62,7 @@
$returnurl = "$CFG->wwwroot/mod/facetoface/view.php?f=$backtoallsessions";
}

$mform = new mod_facetoface_cancelsignup_form(null, compact('s', 'backtoallsessions'));
$mform = new mod_facetoface_cancelsignup_form(null, compact('s', 'f', 'backtoallsessions'));
if ($mform->is_cancelled()) {
redirect($returnurl);
}
Expand All @@ -74,49 +75,66 @@
$timemessage = 4;

$errorstr = '';
if (facetoface_user_cancel($session, false, false, $errorstr, $fromform->cancelreason)) {
// Logging and events trigger.
$params = [
'context' => $contextmodule,
'objectid' => $session->id,
];
$event = \mod_facetoface\event\cancel_booking::create($params);
$event->add_record_snapshot('facetoface_sessions', $session);
$event->add_record_snapshot('facetoface', $facetoface);
$event->trigger();

$message = get_string('bookingcancelled', 'facetoface');

if ($session->datetimeknown) {
$error = facetoface_send_cancellation_notice($facetoface, $session, $USER->id);
if (empty($error)) {
if ($session->datetimeknown && $facetoface->cancellationinstrmngr) {
$message .= html_writer::empty_tag('br')
. html_writer::empty_tag('br')
. get_string('cancellationsentmgr', 'facetoface');

// Handle bulk signup cancellation
if (!empty($fromform->f)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this conditional does not include the logging and event triggers.


$facetofaceid = $fromform->f;

facetoface_user_cancel_bulk($facetofaceid, $USER->id, $fromform->cancelreason);

redirect(
new moodle_url('/mod/facetoface/view.php', ['f' => $facetofaceid]),
get_string('cancellationsuccessall', 'facetoface'),
$timemessage
);
} else {
// Handle standard signup cancellation

if (facetoface_user_cancel($session, false, false, $errorstr, $fromform->cancelreason)) {
// Logging and events trigger.
$params = [
'context' => $contextmodule,
'objectid' => $session->id,
];
$event = \mod_facetoface\event\cancel_booking::create($params);
$event->add_record_snapshot('facetoface_sessions', $session);
$event->add_record_snapshot('facetoface', $facetoface);
$event->trigger();

$message = get_string('bookingcancelled', 'facetoface');

if ($session->datetimeknown) {
$error = facetoface_send_cancellation_notice($facetoface, $session, $USER->id);
if (empty($error)) {
if ($session->datetimeknown && $facetoface->cancellationinstrmngr) {
$message .= html_writer::empty_tag('br')
. html_writer::empty_tag('br')
. get_string('cancellationsentmgr', 'facetoface');
} else {
$message .= html_writer::empty_tag('br')
. html_writer::empty_tag('br')
. get_string('cancellationsent', 'facetoface');
}
} else {
$message .= html_writer::empty_tag('br')
. html_writer::empty_tag('br')
. get_string('cancellationsent', 'facetoface');
throw new moodle_exception($error, 'facetoface');
}
} else {
throw new moodle_exception($error, 'facetoface');
}
}

redirect($returnurl, $message, $timemessage);
} else {
// Logging and events trigger.
$params = [
'context' => $contextmodule,
'objectid' => $session->id,
];
$event = \mod_facetoface\event\cancel_booking_failed::create($params);
$event->add_record_snapshot('facetoface_sessions', $session);
$event->add_record_snapshot('facetoface', $facetoface);
$event->trigger();

redirect($returnurl, $errorstr, $timemessage);
redirect($returnurl, $message, $timemessage);
} else {
// Logging and events trigger.
$params = [
'context' => $contextmodule,
'objectid' => $session->id,
];
$event = \mod_facetoface\event\cancel_booking_failed::create($params);
$event->add_record_snapshot('facetoface_sessions', $session);
$event->add_record_snapshot('facetoface', $facetoface);
$event->trigger();

redirect($returnurl, $errorstr, $timemessage);
}
}

redirect($returnurl);
Expand Down
16 changes: 15 additions & 1 deletion classes/cancelsignup_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,27 @@ public function definition() {

$mform->addElement('header', 'general', get_string('cancelbooking', 'facetoface'));

// Hidden element for standard signup cancellation
$mform->addElement('hidden', 's', $this->_customdata['s']);
$mform->setType('s', PARAM_INT);

// Hidden element bulk signup cancellation
$f = $this->_customdata['f'] ?? 0;
$mform->addElement('hidden', 'f', $this->_customdata['f']);
$mform->setType('f', PARAM_INT);

$mform->addElement('hidden', 'backtoallsessions', $this->_customdata['backtoallsessions']);
$mform->setType('backtoallsessions', PARAM_INT);

$mform->addElement('html', get_string('cancellationconfirm', 'facetoface')); // Instructions.
// Get signup cancellation message depending on type
$isbulkcancellation = !empty($f);
if ($isbulkcancellation) {
$confirmmessage = get_string('cancellationconfirmall', 'facetoface');
} else {
$confirmmessage = get_string('cancellationconfirm', 'facetoface');
}

$mform->addElement('html', $confirmmessage); // Instructions.

$mform->addElement('text', 'cancelreason', get_string('cancelreason', 'facetoface'), 'size="60" maxlength="255"');
$mform->setType('cancelreason', PARAM_TEXT);
Expand Down
4 changes: 4 additions & 0 deletions lang/en/facetoface.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
$string['calendareventdescriptionbooking'] = 'You are booked for this <a href="{$a}">Face-to-Face session</a>.';
$string['calendareventdescriptionsession'] = 'You have created this <a href="{$a}">Face-to-Face session</a>.';
$string['calendaroptions'] = 'Calendar options';
$string['cancellationconfirm'] = 'Are you sure you want to cancel your signup for this session?';
$string['cancellationconfirmall'] = 'Are you sure you want to cancel your signup for all sessions in this activity?';
$string['cancellationsuccessall'] = 'Your signup has been cancelled for all upcoming sessions.';
$string['cancelallbookings'] = 'Cancel all bookings';
$string['cancelbooking'] = 'Cancel booking';
$string['cancelbookingfor'] = 'Cancel booking for {$a}';
$string['cancellationsent'] = 'You should immediately receive a cancellation email.';
Expand Down
51 changes: 51 additions & 0 deletions lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -2223,6 +2223,57 @@ function facetoface_update_signup_status($signupid, $statuscode, $createdby, $no
}
}

/**
* Cancel a user from all sessions who signed up earlier.
*
* @param integer $facetofaceid ID of the activity
* @param integer $userid ID of the user to remove from the session
* @param string $cancelreason Optional justification for cancelling the signup
*/
function facetoface_user_cancel_bulk($facetofaceid, $userid, $cancelreason='') {

$now = time();

$submissions = facetoface_get_user_submissions($facetofaceid, $userid);

// Get all sessions for this activity.
$sessions = facetoface_get_sessions($facetofaceid);

// Extract all session IDs from the user's submissions.
$submissionids = array_map(function($submission) {
return $submission->sessionid;
}, $submissions);

// Filter the sessions to keep only those present in the user's submissions.
$sessions = array_filter($sessions, function($session) use ($submissionids) {
return in_array($session->id, $submissionids);
});

// Filter out invalid sessions in the past — keep only those with a future timestart.
$cancellable = array_filter($sessions, function($session) use ($now) {
if (empty($session->sessiondates) || !is_array($session->sessiondates)) {
return false;
}

// Return true if any sessiondate has a timestart in the future.
foreach ($session->sessiondates as $sessiondate) {
if (!empty($sessiondate->timestart) && $sessiondate->timestart > $now) {
return true;
}
}

return false;
});

foreach ($cancellable as $session) {
try {
facetoface_user_cancel($session, false, false, $errorstr, $cancelreason);
} catch (Exception $e) {
debugging("Could not cancel signup for session {$session->id}: " . $e->getMessage(), DEBUG_DEVELOPER);
}
}
}

/**
* Cancel a user who signed up earlier
*
Expand Down
5 changes: 5 additions & 0 deletions renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ public function print_session_list_table(
get_string('cancelbooking', 'facetoface'),
['title' => get_string('cancelbooking', 'facetoface')]
);
$options .= ' ' . html_writer::link(
'cancelsignup.php?s=' . $session->id . '&f=' . $session->facetoface,
get_string('cancelallbookings', 'facetoface'),
['title' => get_string('cancelallbookings', 'facetoface')]
);
} else {
$cancelrestriction = get_config('facetoface', 'cancelrestriction');
$options .= html_writer::link(
Expand Down
Loading
Loading