Commit | Line | Data |
---|---|---|
aa6c1ced | 1 | <?php |
a2ed6e69 SH |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * Lists all the users within a given course. | |
19 | * | |
20 | * @copyright 1999 Martin Dougiamas http://dougiamas.com | |
21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
22 | * @package core_user | |
23 | */ | |
24 | ||
25 | require_once('../config.php'); | |
0ff203b6 | 26 | require_once($CFG->dirroot.'/user/lib.php'); |
5fa2d502 | 27 | require_once($CFG->dirroot.'/course/lib.php'); |
b5b81de3 | 28 | require_once($CFG->dirroot.'/notes/lib.php'); |
a2ed6e69 SH |
29 | require_once($CFG->libdir.'/tablelib.php'); |
30 | require_once($CFG->libdir.'/filelib.php'); | |
a78ed71c | 31 | require_once($CFG->dirroot.'/enrol/locallib.php'); |
a2ed6e69 | 32 | |
8146335f SL |
33 | use core_table\local\filter\filter; |
34 | use core_table\local\filter\integer_filter; | |
35 | use core_table\local\filter\string_filter; | |
8146335f | 36 | |
a2ed6e69 SH |
37 | define('DEFAULT_PAGE_SIZE', 20); |
38 | define('SHOW_ALL_PAGE_SIZE', 5000); | |
a2ed6e69 SH |
39 | |
40 | $page = optional_param('page', 0, PARAM_INT); // Which page to show. | |
41 | $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // How many per page. | |
a2ed6e69 SH |
42 | $contextid = optional_param('contextid', 0, PARAM_INT); // One of this or. |
43 | $courseid = optional_param('id', 0, PARAM_INT); // This are required. | |
5fa2d502 | 44 | $newcourse = optional_param('newcourse', false, PARAM_BOOL); |
fe214295 | 45 | $roleid = optional_param('roleid', 0, PARAM_INT); |
9f33d5ac | 46 | $groupparam = optional_param('group', 0, PARAM_INT); |
a2ed6e69 SH |
47 | |
48 | $PAGE->set_url('/user/index.php', array( | |
49 | 'page' => $page, | |
50 | 'perpage' => $perpage, | |
a2ed6e69 | 51 | 'contextid' => $contextid, |
5fa2d502 DW |
52 | 'id' => $courseid, |
53 | 'newcourse' => $newcourse)); | |
a2ed6e69 SH |
54 | |
55 | if ($contextid) { | |
56 | $context = context::instance_by_id($contextid, MUST_EXIST); | |
57 | if ($context->contextlevel != CONTEXT_COURSE) { | |
58 | print_error('invalidcontext'); | |
59 | } | |
60 | $course = $DB->get_record('course', array('id' => $context->instanceid), '*', MUST_EXIST); | |
61 | } else { | |
62 | $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); | |
63 | $context = context_course::instance($course->id, MUST_EXIST); | |
64 | } | |
65 | // Not needed anymore. | |
66 | unset($contextid); | |
67 | unset($courseid); | |
f9903ed0 | 68 | |
a2ed6e69 | 69 | require_login($course); |
f9903ed0 | 70 | |
a2ed6e69 SH |
71 | $systemcontext = context_system::instance(); |
72 | $isfrontpage = ($course->id == SITEID); | |
f9903ed0 | 73 | |
a2ed6e69 | 74 | $frontpagectx = context_course::instance(SITEID); |
4f0c2d00 | 75 | |
a2ed6e69 SH |
76 | if ($isfrontpage) { |
77 | $PAGE->set_pagelayout('admin'); | |
93b47710 | 78 | course_require_view_participants($systemcontext); |
a2ed6e69 SH |
79 | } else { |
80 | $PAGE->set_pagelayout('incourse'); | |
93b47710 | 81 | course_require_view_participants($context); |
a2ed6e69 | 82 | } |
224aa44a | 83 | |
0ff203b6 JL |
84 | // Trigger events. |
85 | user_list_view($course, $context); | |
a2ed6e69 SH |
86 | |
87 | $bulkoperations = has_capability('moodle/course:bulkmessaging', $context); | |
88 | ||
a2ed6e69 SH |
89 | $PAGE->set_title("$course->shortname: ".get_string('participants')); |
90 | $PAGE->set_heading($course->fullname); | |
91 | $PAGE->set_pagetype('course-view-' . $course->format); | |
92 | $PAGE->add_body_class('path-user'); // So we can style it independently. | |
93 | $PAGE->set_other_editing_capability('moodle/course:manageactivities'); | |
2cb2ce61 | 94 | |
b34fd2cc DW |
95 | // Expand the users node in the settings navigation when it exists because those pages |
96 | // are related to this one. | |
97 | $node = $PAGE->settingsnav->find('users', navigation_node::TYPE_CONTAINER); | |
98 | if ($node) { | |
b0b6ff3c | 99 | $node->force_open(); |
b34fd2cc DW |
100 | } |
101 | ||
a2ed6e69 | 102 | echo $OUTPUT->header(); |
4e1f6047 | 103 | echo $OUTPUT->heading(get_string('participants')); |
caa8363f | 104 | |
9651e491 | 105 | // Get the currently applied filters. |
7cf4331a | 106 | $filtersapplied = optional_param_array('unified-filters', [], PARAM_NOTAGS); |
32e5109d | 107 | $filterwassubmitted = optional_param('unified-filter-submitted', 0, PARAM_BOOL); |
a78ed71c | 108 | |
fe214295 MN |
109 | // If they passed a role make sure they can view that role. |
110 | if ($roleid) { | |
111 | $viewableroles = get_profile_roles($context); | |
112 | ||
113 | // Check if the user can view this role. | |
114 | if (array_key_exists($roleid, $viewableroles)) { | |
115 | $filtersapplied[] = USER_FILTER_ROLE . ':' . $roleid; | |
116 | } else { | |
117 | $roleid = 0; | |
118 | } | |
119 | } | |
120 | ||
9651e491 JP |
121 | // Default group ID. |
122 | $groupid = false; | |
123 | $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context); | |
124 | if ($course->groupmode != NOGROUPS) { | |
125 | if ($canaccessallgroups) { | |
9f33d5ac MN |
126 | // Change the group if the user can access all groups and has specified group in the URL. |
127 | if ($groupparam) { | |
128 | $groupid = $groupparam; | |
129 | } | |
9651e491 JP |
130 | } else { |
131 | // Otherwise, get the user's default group. | |
132 | $groupid = groups_get_course_group($course, true); | |
133 | if ($course->groupmode == SEPARATEGROUPS && !$groupid) { | |
134 | // The user is not in the group so show message and exit. | |
135 | echo $OUTPUT->notification(get_string('notingroup')); | |
136 | echo $OUTPUT->footer(); | |
137 | exit; | |
138 | } | |
139 | } | |
a2ed6e69 | 140 | } |
9651e491 JP |
141 | $hasgroupfilter = false; |
142 | $lastaccess = 0; | |
143 | $searchkeywords = []; | |
9651e491 | 144 | $enrolid = 0; |
8146335f | 145 | |
77ba77f1 AN |
146 | $participanttable = new \core_user\table\participants("user-index-participants-{$course->id}"); |
147 | ||
8146335f SL |
148 | $filterset = new \core_user\table\participants_filterset(); |
149 | $filterset->add_filter(new integer_filter('courseid', filter::JOINTYPE_DEFAULT, [(int)$course->id])); | |
150 | $enrolfilter = new integer_filter('enrolments'); | |
151 | $groupfilter = new integer_filter('groups'); | |
152 | $keywordfilter = new string_filter('keywords'); | |
153 | $lastaccessfilter = new integer_filter('accesssince'); | |
154 | $rolefilter = new integer_filter('roles'); | |
155 | $statusfilter = new integer_filter('status'); | |
156 | ||
9651e491 JP |
157 | foreach ($filtersapplied as $filter) { |
158 | $filtervalue = explode(':', $filter, 2); | |
159 | $value = null; | |
160 | if (count($filtervalue) == 2) { | |
161 | $key = clean_param($filtervalue[0], PARAM_INT); | |
162 | $value = clean_param($filtervalue[1], PARAM_INT); | |
163 | } else { | |
164 | // Search string. | |
a997dc9d AN |
165 | $key = USER_FILTER_STRING; |
166 | $value = clean_param($filtervalue[0], PARAM_TEXT); | |
9651e491 | 167 | } |
99cca847 | 168 | |
9651e491 JP |
169 | switch ($key) { |
170 | case USER_FILTER_ENROLMENT: | |
171 | $enrolid = $value; | |
8146335f | 172 | $enrolfilter->add_filter_value($value); |
9651e491 JP |
173 | break; |
174 | case USER_FILTER_GROUP: | |
175 | $groupid = $value; | |
8146335f | 176 | $groupfilter->add_filter_value($value); |
9651e491 JP |
177 | $hasgroupfilter = true; |
178 | break; | |
179 | case USER_FILTER_LAST_ACCESS: | |
180 | $lastaccess = $value; | |
8146335f | 181 | $lastaccessfilter->add_filter_value($value); |
9651e491 JP |
182 | break; |
183 | case USER_FILTER_ROLE: | |
184 | $roleid = $value; | |
8146335f | 185 | $rolefilter->add_filter_value($value); |
9651e491 JP |
186 | break; |
187 | case USER_FILTER_STATUS: | |
188 | // We only accept active/suspended statuses. | |
189 | if ($value == ENROL_USER_ACTIVE || $value == ENROL_USER_SUSPENDED) { | |
190 | $status = $value; | |
8146335f | 191 | $statusfilter->add_filter_value($value); |
9651e491 JP |
192 | } |
193 | break; | |
194 | default: | |
195 | // Search string. | |
a997dc9d | 196 | $searchkeywords[] = $value; |
8146335f | 197 | $keywordfilter->add_filter_value($value); |
9651e491 JP |
198 | break; |
199 | } | |
a2ed6e69 | 200 | } |
32e5109d | 201 | // If course supports groups we may need to set a default. |
58af736d | 202 | if (!empty($groupid)) { |
9f33d5ac MN |
203 | if ($canaccessallgroups) { |
204 | // User can access all groups, let them filter by whatever was selected. | |
205 | $filtersapplied[] = USER_FILTER_GROUP . ':' . $groupid; | |
ef4109d2 | 206 | $groupfilter->add_filter_value((int)$groupid); |
9f33d5ac MN |
207 | } else if (!$filterwassubmitted && $course->groupmode == VISIBLEGROUPS) { |
208 | // If we are in a course with visible groups and the user has not submitted anything and does not have | |
209 | // access to all groups, then set a default group. | |
32e5109d | 210 | $filtersapplied[] = USER_FILTER_GROUP . ':' . $groupid; |
ef4109d2 | 211 | $groupfilter->add_filter_value((int)$groupid); |
9f33d5ac | 212 | } else if (!$hasgroupfilter && $course->groupmode != VISIBLEGROUPS) { |
32e5109d MN |
213 | // The user can't access all groups and has not set a group filter in a course where the groups are not visible |
214 | // then apply a default group filter. | |
215 | $filtersapplied[] = USER_FILTER_GROUP . ':' . $groupid; | |
ef4109d2 | 216 | $groupfilter->add_filter_value((int)$groupid); |
32e5109d MN |
217 | } else if (!$hasgroupfilter) { // No need for the group id to be set. |
218 | $groupid = false; | |
219 | } | |
24c3db91 | 220 | } |
a2ed6e69 | 221 | |
5290d060 | 222 | if ($groupid > 0 && ($course->groupmode != SEPARATEGROUPS || $canaccessallgroups)) { |
349b705d AG |
223 | $grouprenderer = $PAGE->get_renderer('core_group'); |
224 | $groupdetailpage = new \core_group\output\group_details($groupid); | |
225 | echo $grouprenderer->group_details($groupdetailpage); | |
226 | } | |
227 | ||
e0e7b19f AN |
228 | // Should use this variable so that we don't break stuff every time a variable is added or changed. |
229 | $baseurl = new moodle_url('/user/index.php', array( | |
230 | 'contextid' => $context->id, | |
231 | 'id' => $course->id, | |
232 | 'perpage' => $perpage)); | |
233 | ||
234 | $participanttable = new \core_user\table\participants("user-index-participants-{$course->id}"); | |
e0e7b19f AN |
235 | $participanttable->define_baseurl($baseurl); |
236 | ||
9651e491 JP |
237 | // Manage enrolments. |
238 | $manager = new course_enrolment_manager($PAGE, $course); | |
239 | $enrolbuttons = $manager->get_manual_enrol_buttons(); | |
240 | $enrolrenderer = $PAGE->get_renderer('core_enrol'); | |
241 | $enrolbuttonsout = ''; | |
242 | foreach ($enrolbuttons as $enrolbutton) { | |
243 | $enrolbuttonsout .= $enrolrenderer->render($enrolbutton); | |
bc47b706 | 244 | } |
e0e7b19f AN |
245 | echo html_writer::div($enrolbuttonsout, 'float-right', [ |
246 | 'data-region' => 'wrapper', | |
247 | 'data-table-uniqueid' => $participanttable->uniqueid, | |
248 | ]); | |
a2ed6e69 | 249 | |
bb4a7923 SA |
250 | // Render the unified filter. |
251 | $renderer = $PAGE->get_renderer('core_user'); | |
252 | echo $renderer->unified_filter($course, $context, $filtersapplied, $baseurl); | |
253 | ||
77ba77f1 AN |
254 | // Render the user filters. |
255 | $userrenderer = $PAGE->get_renderer('core_user'); | |
256 | echo $userrenderer->participants_filter($context, $participanttable->uniqueid); | |
257 | ||
bb4a7923 SA |
258 | echo '<div class="userlist">'; |
259 | ||
7fde8358 | 260 | // Add filters to the baseurl after creating unified_filter to avoid losing them. |
89e27d99 JF |
261 | foreach (array_unique($filtersapplied) as $filterix => $filter) { |
262 | $baseurl->param('unified-filters[' . $filterix . ']', $filter); | |
7fde8358 | 263 | } |
8146335f SL |
264 | |
265 | if (count($groupfilter)) { | |
266 | $filterset->add_filter($groupfilter); | |
267 | } | |
268 | ||
269 | if (count($lastaccessfilter)) { | |
270 | $filterset->add_filter($lastaccessfilter); | |
271 | } | |
272 | ||
273 | if (count($rolefilter)) { | |
274 | $filterset->add_filter($rolefilter); | |
275 | } | |
276 | ||
277 | if (count($enrolfilter)) { | |
278 | $filterset->add_filter($enrolfilter); | |
279 | } | |
280 | ||
281 | if (count($statusfilter)) { | |
282 | $filterset->add_filter($statusfilter); | |
283 | } | |
284 | ||
285 | if (count($keywordfilter)) { | |
286 | $filterset->add_filter($keywordfilter); | |
287 | } | |
288 | ||
bc47b706 MN |
289 | // Do this so we can get the total number of rows. |
290 | ob_start(); | |
e0e7b19f | 291 | $participanttable->set_filterset($filterset); |
bc47b706 MN |
292 | $participanttable->out($perpage, true); |
293 | $participanttablehtml = ob_get_contents(); | |
294 | ob_end_clean(); | |
3e219038 | 295 | |
a2ed6e69 | 296 | if ($bulkoperations) { |
bae72dd0 AN |
297 | echo html_writer::start_tag('form', [ |
298 | 'action' => 'action_redir.php', | |
299 | 'method' => 'post', | |
300 | 'id' => 'participantsform', | |
301 | 'data-course-id' => $course->id, | |
302 | 'data-table-unique-id' => $participanttable->uniqueid, | |
07c91064 | 303 | 'data-table-default-per-page' => ($perpage < DEFAULT_PAGE_SIZE) ? $perpage : DEFAULT_PAGE_SIZE, |
bae72dd0 | 304 | ]); |
a2ed6e69 SH |
305 | echo '<div>'; |
306 | echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; | |
307 | echo '<input type="hidden" name="returnto" value="'.s($PAGE->url->out(false)).'" />'; | |
308 | } | |
77c645df | 309 | |
ed23725b AN |
310 | echo html_writer::tag( |
311 | 'p', | |
312 | get_string('countparticipantsfound', 'core_user', $participanttable->totalrows), | |
313 | [ | |
314 | 'data-region' => 'participant-count', | |
315 | ] | |
316 | ); | |
317 | ||
bc47b706 | 318 | echo $participanttablehtml; |
4c7593ff | 319 | |
8dd42b38 AH |
320 | $perpageurl = clone($baseurl); |
321 | $perpageurl->remove_params('perpage'); | |
50ba817f AN |
322 | $perpagesize = DEFAULT_PAGE_SIZE; |
323 | $perpagevisible = false; | |
7f228675 | 324 | $perpagestring = ''; |
50ba817f | 325 | |
bc47b706 | 326 | if ($perpage == SHOW_ALL_PAGE_SIZE && $participanttable->totalrows > DEFAULT_PAGE_SIZE) { |
7f228675 AN |
327 | $perpageurl->param('perpage', $participanttable->totalrows); |
328 | $perpagesize = SHOW_ALL_PAGE_SIZE; | |
50ba817f | 329 | $perpagevisible = true; |
7f228675 | 330 | $perpagestring = get_string('showperpage', '', DEFAULT_PAGE_SIZE); |
bc47b706 | 331 | } else if ($participanttable->get_page_size() < $participanttable->totalrows) { |
8dd42b38 | 332 | $perpageurl->param('perpage', SHOW_ALL_PAGE_SIZE); |
7f228675 | 333 | $perpagesize = SHOW_ALL_PAGE_SIZE; |
50ba817f | 334 | $perpagevisible = true; |
7f228675 | 335 | $perpagestring = get_string('showall', '', $participanttable->totalrows); |
50ba817f AN |
336 | } |
337 | ||
338 | $perpageclasses = ''; | |
339 | if (!$perpagevisible) { | |
340 | $perpageclasses = 'hidden'; | |
8dd42b38 | 341 | } |
50ba817f AN |
342 | echo $OUTPUT->container(html_writer::link( |
343 | $perpageurl, | |
7f228675 | 344 | $perpagestring, |
50ba817f AN |
345 | [ |
346 | 'data-action' => 'showcount', | |
347 | 'data-target-page-size' => $perpagesize, | |
348 | 'class' => $perpageclasses, | |
349 | ] | |
350 | ), [], 'showall'); | |
8dd42b38 | 351 | |
a2ed6e69 | 352 | if ($bulkoperations) { |
8df785f9 | 353 | echo '<br /><div class="buttons"><div class="form-inline">'; |
5b7c500a | 354 | |
b27c8d81 | 355 | echo html_writer::start_tag('div', array('class' => 'btn-group')); |
ed23725b | 356 | |
bc47b706 | 357 | if ($participanttable->get_page_size() < $participanttable->totalrows) { |
ed23725b | 358 | // Select all users, refresh table showing all users and mark them all selected. |
bc47b706 | 359 | $label = get_string('selectalluserswithcount', 'moodle', $participanttable->totalrows); |
ed23725b AN |
360 | echo html_writer::empty_tag('input', [ |
361 | 'type' => 'button', | |
362 | 'id' => 'checkall', | |
363 | 'class' => 'btn btn-secondary', | |
364 | 'value' => $label, | |
365 | 'data-target-page-size' => $participanttable->totalrows, | |
366 | ]); | |
5b7c500a | 367 | } |
b27c8d81 | 368 | echo html_writer::end_tag('div'); |
a2ed6e69 | 369 | $displaylist = array(); |
713934f9 ND |
370 | if (!empty($CFG->messaging)) { |
371 | $displaylist['#messageselect'] = get_string('messageselectadd'); | |
372 | } | |
a2ed6e69 | 373 | if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) { |
b5b81de3 | 374 | $displaylist['#addgroupnote'] = get_string('addnewnote', 'notes'); |
a2ed6e69 SH |
375 | } |
376 | ||
e5abe2af LB |
377 | $params = ['operation' => 'download_participants']; |
378 | ||
379 | $downloadoptions = []; | |
380 | $formats = core_plugin_manager::instance()->get_plugins_of_type('dataformat'); | |
381 | foreach ($formats as $format) { | |
382 | if ($format->is_enabled()) { | |
383 | $params = ['operation' => 'download_participants', 'dataformat' => $format->name]; | |
384 | $url = new moodle_url('bulkchange.php', $params); | |
385 | $downloadoptions[$url->out(false)] = get_string('dataformat', $format->component); | |
386 | } | |
387 | } | |
388 | ||
389 | if (!empty($downloadoptions)) { | |
390 | $displaylist[] = [get_string('downloadas', 'table') => $downloadoptions]; | |
391 | } | |
392 | ||
ca560952 | 393 | if ($context->id != $frontpagectx->id) { |
f4ddc4ec DW |
394 | $instances = $manager->get_enrolment_instances(); |
395 | $plugins = $manager->get_enrolment_plugins(false); | |
396 | foreach ($instances as $key => $instance) { | |
397 | if (!isset($plugins[$instance->enrol])) { | |
398 | // Weird, some broken stuff in plugin. | |
399 | continue; | |
400 | } | |
401 | $plugin = $plugins[$instance->enrol]; | |
ca560952 DW |
402 | $bulkoperations = $plugin->get_bulk_operations($manager); |
403 | ||
404 | $pluginoptions = []; | |
405 | foreach ($bulkoperations as $key => $bulkoperation) { | |
406 | $params = ['plugin' => $plugin->get_name(), 'operation' => $key]; | |
407 | $url = new moodle_url('bulkchange.php', $params); | |
408 | $pluginoptions[$url->out(false)] = $bulkoperation->get_title(); | |
409 | } | |
410 | if (!empty($pluginoptions)) { | |
411 | $name = get_string('pluginname', 'enrol_' . $plugin->get_name()); | |
412 | $displaylist[] = [$name => $pluginoptions]; | |
413 | } | |
689ccae5 DW |
414 | } |
415 | } | |
416 | ||
df92be9d JP |
417 | $selectactionparams = array( |
418 | 'id' => 'formactionid', | |
419 | 'class' => 'ml-2', | |
420 | 'data-action' => 'toggle', | |
421 | 'data-togglegroup' => 'participants-table', | |
422 | 'data-toggle' => 'action', | |
6754ceae | 423 | 'disabled' => 'disabled' |
df92be9d | 424 | ); |
8aecd857 SR |
425 | $label = html_writer::tag('label', get_string("withselectedusers"), |
426 | ['for' => 'formactionid', 'class' => 'col-form-label d-inline']); | |
427 | $select = html_writer::select($displaylist, 'formaction', '', ['' => 'choosedots'], $selectactionparams); | |
428 | echo html_writer::tag('div', $label . $select); | |
429 | ||
430 | echo '<input type="hidden" name="id" value="' . $course->id . '" />'; | |
bae72dd0 | 431 | echo '<div class="d-none" data-region="state-help-icon">' . $OUTPUT->help_icon('publishstate', 'notes') . '</div>'; |
8df785f9 | 432 | echo '</div></div></div>'; |
a2ed6e69 SH |
433 | echo '</form>'; |
434 | ||
bae72dd0 AN |
435 | $options = (object) [ |
436 | 'uniqueid' => $participanttable->uniqueid, | |
437 | 'noteStateNames' => note_get_state_names(), | |
438 | ]; | |
b5b81de3 | 439 | $PAGE->requires->js_call_amd('core_user/participants', 'init', [$options]); |
a2ed6e69 | 440 | } |
b90e2f19 | 441 | |
a2ed6e69 | 442 | echo '</div>'; // Userlist. |
f9903ed0 | 443 | |
a78ed71c | 444 | $enrolrenderer = $PAGE->get_renderer('core_enrol'); |
5db1ce53 | 445 | echo '<div class="float-right">'; |
3dec4c6c SR |
446 | // Need to re-generate the buttons to avoid having elements with duplicate ids on the page. |
447 | $enrolbuttons = $manager->get_manual_enrol_buttons(); | |
a78ed71c DW |
448 | foreach ($enrolbuttons as $enrolbutton) { |
449 | echo $enrolrenderer->render($enrolbutton); | |
450 | } | |
451 | echo '</div>'; | |
452 | ||
5fa2d502 DW |
453 | if ($newcourse == 1) { |
454 | $str = get_string('proceedtocourse', 'enrol'); | |
5fa2d502 | 455 | // The margin is to make it line up with the enrol users button when they are both on the same line. |
d470c68b | 456 | $classes = 'my-1'; |
5fa2d502 DW |
457 | $url = course_get_url($course); |
458 | echo $OUTPUT->single_button($url, $str, 'GET', array('class' => $classes)); | |
459 | } | |
460 | ||
a2ed6e69 | 461 | echo $OUTPUT->footer(); |