From 8a2e5194ad3f614cb4827540c9d026b4f161f4c7 Mon Sep 17 00:00:00 2001 From: Cameron Ball Date: Wed, 12 Oct 2022 12:06:55 +0800 Subject: [PATCH] Allow users to bulk sign up for every session in the activity --- db/install.xml | 3 ++- db/upgrade.php | 13 +++++++++++ lang/en/facetoface.php | 8 +++++++ lib.php | 31 +++++++++++++++++++------- mod_form.php | 21 ++++++++++++++++++ signup.php | 49 ++++++++++++++++++++++++++++++++++++++---- version.php | 2 +- 7 files changed, 113 insertions(+), 14 deletions(-) diff --git a/db/install.xml b/db/install.xml index 2f34b11..8f490e7 100644 --- a/db/install.xml +++ b/db/install.xml @@ -1,5 +1,5 @@ - @@ -38,6 +38,7 @@ + diff --git a/db/upgrade.php b/db/upgrade.php index fc7f7b3..1a468f8 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -771,5 +771,18 @@ function xmldb_facetoface_upgrade($oldversion=0) { upgrade_mod_savepoint(true, 2022091900, 'facetoface'); } + if ($oldversion < 2022101100) { + $table = new xmldb_table('facetoface'); + $field = new xmldb_field('multiplesignupmethod', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'signuptype'); + + // Conditionally launch add field multiplesignupmethod. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Facetoface savepoint reached. + upgrade_mod_savepoint(true, 2022101100, 'facetoface'); + } + return $result; } diff --git a/lang/en/facetoface.php b/lang/en/facetoface.php index eedefd3..1c2fd20 100644 --- a/lang/en/facetoface.php +++ b/lang/en/facetoface.php @@ -252,6 +252,10 @@ $string['moreinfo'] = 'More info'; $string['multidate'] = '(multi-date)'; $string['multiple'] = 'Multiple'; +$string['multiplesignupmethod'] = 'Multiple signup method'; +$string['multiplesignupmethod_help'] = 'When set to "single" each session within the activity will have an individual sign up link. When set to "multiple" only one link wil be displayed for the entire activity, any student who registers using this single link will be registered for all sessions within the activity.'; +$string['multiplesignuppersession'] = 'Per session'; +$string['multiplesignupperactivity'] = 'Per activity'; $string['newmanageremailaddress'] = 'Manager\'s email address'; $string['noactionableunapprovedrequests'] = 'No actionable unapproved requests'; $string['nocustomfields'] = '

No custom fields are defined.

'; @@ -543,11 +547,13 @@ $string['single'] = 'Single'; $string['signups'] = 'Sign-ups'; $string['signupfor'] = 'Sign-up for {$a}'; +$string['signupforstream'] = 'Sign-up for stream'; $string['signuptype'] = 'Signup type'; $string['signuptype_help'] = 'When set to "single" a student may only register for one session per Face-to-Face actvitiy. When set to "multiple" a student may register for multiple sessions per activity.'; $string['signupforsession'] = 'Sign-up for an available upcoming session'; $string['signupforthissession'] = 'Sign-up for this Face-to-Face session'; $string['sign-ups'] = 'Sign-ups'; +$string['signuptypemismatch'] = 'Signup type must be "multiple" when signup method is per activity'; $string['sitenoticesheading'] = 'Site Notices'; $string['subject'] = 'Change in booking in the course {$a->coursename} ({$a->duedate})'; $string['submissions'] = 'Submissions'; @@ -565,6 +571,7 @@ $string['status_approved'] = 'Approved'; $string['status_declined'] = 'Declined'; $string['status_session_cancelled'] = 'Session Cancelled'; +$string['somesessionsfull'] = 'You have not been signed up for some sessions in the stream as they are at capacity.'; $string['summary'] = 'Summary'; $string['takeattendance'] = 'Take attendance'; $string['time'] = 'Time'; @@ -592,6 +599,7 @@ $string['usersignedup'] = 'Status: signed up'; $string['usersignedupon'] = 'User signed up on {$a}'; $string['userwillbewaitlisted'] = 'This session is currently full. By clicking the "Sign-up" button, you will be placed on the sessions\'s wait-list.'; +$string['upcomingsessions'] = 'Upcoming sessions'; $string['validation:needatleastonedate'] = 'You need to provide at least one date or mark the session as wait-listed.'; $string['venue'] = 'Venue'; $string['viewallsessions'] = 'View all sessions'; diff --git a/lib.php b/lib.php index 17d7702..6a6423d 100644 --- a/lib.php +++ b/lib.php @@ -73,6 +73,8 @@ // Signup setting constants. define('MOD_FACETOFACE_SIGNUP_SINGLE', 0); define('MOD_FACETOFACE_SIGNUP_MULTIPLE', 1); +define('MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION', 0); +define('MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_ACTIVITY', 1); // Signup status codes (remember to update facetoface_statuses()). define('MDL_F2F_STATUS_USER_CANCELLED', 10); @@ -2784,9 +2786,8 @@ function facetoface_cm_info_view(cm_info $coursemodule) { continue; } else { $signupurl = new moodle_url('/mod/facetoface/signup.php', array('s' => $session->id)); - $signuptext = 'signup'; - $moreinfolink = html_writer::link($signupurl, get_string($signuptext, 'facetoface'), array('class' => 'f2fsessionlinks f2fsessioninfolink')); - + $signupstr = $facetoface->multiplesignupmethod == MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION ? 'signup' : 'signupforstream'; + $moreinfolink = html_writer::link($signupurl, get_string($signupstr, 'facetoface'), array('class' => 'f2fsessionlinks f2fsessioninfolink')); $span = html_writer::tag('span', get_string('options', 'facetoface').':', array('class' => 'f2fsessionnotice')); } @@ -2844,13 +2845,27 @@ function facetoface_cm_info_view(cm_info $coursemodule) { if (!empty($futuresessions)) { $output .= html_writer::start_tag('div', array('class' => 'f2fsessiongroup')); - $output .= html_writer::tag('span', get_string('signupforsession', 'facetoface'), array('class' => 'f2fsessionnotice')); + + if ($facetoface->multiplesignupmethod == MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION) { + $output .= html_writer::tag('span', get_string('signupforsession', 'facetoface'), array('class' => 'f2fsessionnotice')); + } else { + $output .= html_writer::tag('span', get_string('upcomingsessions', 'facetoface'), array('class' => 'f2fsessionnotice')); + + if (!empty($futuresessions)) { + $firstsession = $futuresessions[array_keys($futuresessions)[0]]; + $output .= html_writer::tag('div', $firstsession->moreinfolink, array('class' => 'f2foptions')); + } + } foreach ($futuresessions as $session) { $output .= html_writer::start_tag('div', array('class' => 'f2fsession f2ffuture')) - . html_writer::tag('div', $session->date.$session->multidate, array('class' => 'f2fsessiontime')) - . html_writer::tag('div', $session->options . $session->moreinfolink, array('class' => 'f2foptions')) - . html_writer::end_tag('div'); + . html_writer::tag('div', $session->date.$session->multidate, array('class' => 'f2fsessiontime')); + + if ($facetoface->multiplesignupmethod == MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION) { + $output .= html_writer::tag('div', $session->options . $session->moreinfolink, array('class' => 'f2foptions')); + } + + $output .= html_writer::end_tag('div'); } $output .= html_writer::end_tag('div'); } @@ -3518,8 +3533,8 @@ function facetoface_session_has_capacity($session, $context=false) { } $signupcount = facetoface_get_num_attendees($session->id); - if ($signupcount >= $session->capacity) { + if ($signupcount >= $session->capacity) { // If session is full, check if overbooking is allowed for this user. if (!$context || !has_capability('mod/facetoface:overbook', $context)) { return false; diff --git a/mod_form.php b/mod_form.php index 4a49210..bd24139 100644 --- a/mod_form.php +++ b/mod_form.php @@ -85,6 +85,15 @@ public function definition() { $mform->setDefault('signuptype', MOD_FACETOFACE_SIGNUP_SINGLE); $mform->addHelpButton('signuptype', 'signuptype', 'facetoface'); + $multiplesignupmethods = array( + MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION => get_string('multiplesignuppersession', 'facetoface'), + MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_ACTIVITY => get_string('multiplesignupperactivity', 'facetoface'), + ); + $mform->addElement('select', 'multiplesignupmethod', get_string('multiplesignupmethod', 'facetoface'), $multiplesignupmethods); + $mform->setDefault('signuptype', MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_SESSION); + $mform->addHelpButton('multiplesignupmethod', 'multiplesignupmethod', 'facetoface'); + $mform->hideIf('multiplesignupmethod', 'signuptype', 'eq', MOD_FACETOFACE_SIGNUP_SINGLE); + $mform->addElement('header', 'calendaroptions', get_string('calendaroptions', 'facetoface')); $calendaroptions = array( @@ -264,4 +273,16 @@ public function data_preprocessing(&$defaultvalues) { ]; } } + + public function validation($data, $files) { + $errors = parent::validation($data, $files); + + if (isset($data['multiplesignupmethod']) && + $data['signuptype'] == MOD_FACETOFACE_SIGNUP_SINGLE && + $data['multiplesignupmethod'] == MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_ACTIVITY) { + $errors['signuptype'] = get_string('signuptypemismatch', 'facetoface'); + } + + return $errors; + } } diff --git a/signup.php b/signup.php index f4f6799..8a25c6a 100644 --- a/signup.php +++ b/signup.php @@ -37,6 +37,7 @@ if (!$session = facetoface_get_session($s)) { throw new moodle_exception('error:incorrectcoursemodulesession', 'facetoface'); } + if (!$facetoface = $DB->get_record('facetoface', array('id' => $session->facetoface))) { throw new moodle_exception('error:incorrectfacetofaceid', 'facetoface'); } @@ -93,6 +94,7 @@ redirect($returnurl); } +$isbulksignup = $facetoface->multiplesignupmethod == MOD_FACETOFACE_SIGNUP_MULTIPLE_PER_ACTIVITY; if ($fromform = $mform->get_data()) { // Form submitted. if (empty($fromform->submitbutton)) { @@ -113,6 +115,8 @@ $event->trigger(); } + // get all sessions + // Get signup type. if (!$session->datetimeknown) { $statuscode = MDL_F2F_STATUS_WAITLISTED; @@ -124,6 +128,41 @@ $statuscode = MDL_F2F_STATUS_WAITLISTED; } + if ($isbulksignup) { + $error = ''; + $message = get_string('bookingcompleted', 'facetoface'); + foreach (facetoface_get_sessions($facetoface->id) as $session) { + if (!facetoface_session_has_capacity($session, $context) && (!$session->allowoverbook)) { + $error = html_writer::empty_tag('br') . html_writer::empty_tag('br') . get_string('somesessionsfull', 'facetoface'); + continue; + } + + // This shouldn't happen. Bulk signup can only be enabled when multiple signups are allowed. + if ($facetoface->signuptype == MOD_FACETOFACE_SIGNUP_SINGLE && facetoface_get_user_submissions($facetoface->id, $USER->id)) { + throw new moodle_exception('alreadysignedup', 'facetoface', $returnurl); + } + + if (facetoface_manager_needed($facetoface) && !facetoface_get_manageremail($USER->id)) { + throw new moodle_exception('error:manageremailaddressmissing', 'facetoface', $returnurl); + } + + if ($submissionid = facetoface_user_signup($session, $facetoface, $course, $fromform->discountcode, $fromform->notificationtype, $statuscode, false, false)) { + // Logging and events trigger. + $params = array( + 'context' => $contextmodule, + 'objectid' => $session->id + ); + $event = \mod_facetoface\event\signup_success::create($params); + $event->add_record_snapshot('facetoface_sessions', $session); + $event->add_record_snapshot('facetoface', $facetoface); + $event->trigger(); + } + } + + $timemessage = 4; + redirect($returnurl, $message . $error, $timemessage); + } + if (!facetoface_session_has_capacity($session, $context) && (!$session->allowoverbook)) { throw new moodle_exception('sessionisfull', 'facetoface', $returnurl); } else if ($facetoface->signuptype == MOD_FACETOFACE_SIGNUP_SINGLE && facetoface_get_user_submissions($facetoface->id, $USER->id)) { @@ -192,7 +231,7 @@ $timenow = time(); -if ($session->datetimeknown && facetoface_has_session_started($session, $timenow)) { +if (!$isbulksignup && $session->datetimeknown && facetoface_has_session_started($session, $timenow)) { $inprogressstr = get_string('cannotsignupsessioninprogress', 'facetoface'); $overstr = get_string('cannotsignupsessionover', 'facetoface'); @@ -204,16 +243,18 @@ exit; } -if (!$signedup && !facetoface_session_has_capacity($session, $context) && (!$session->allowoverbook)) { +if (!$isbulksignup && !$signedup && !facetoface_session_has_capacity($session, $context) && (!$session->allowoverbook)) { throw new moodle_exception('sessionisfull', 'facetoface', $returnurl); echo $OUTPUT->box_end(); echo $OUTPUT->footer($course); exit; } -echo facetoface_print_session($session, $viewattendees); +if (!$isbulksignup) { + echo facetoface_print_session($session, $viewattendees); +} -if ($signedup) { +if (!$isbulksignup && $signedup) { if (!($session->datetimeknown && facetoface_has_session_started($session, $timenow)) && $session->allowcancellations) { // Cancellation link. diff --git a/version.php b/version.php index c1dec0e..25c4dae 100644 --- a/version.php +++ b/version.php @@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2022091900; +$plugin->version = 2022101100; $plugin->requires = 2022031500; // Requires 4.0 $plugin->release = '2022091900'; $plugin->component = 'mod_facetoface';