MDL-23187 Generic ratings and comments permissions now appear on course pages, AND...
[moodle.git] / enrol / renderer.php
CommitLineData
a70eb30f
SH
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * This is the main renderer for the enrol section.
20 *
21 * @package moodlecore
22 * @copyright 2010 Sam Hemelryk
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26/**
27 * This is the core renderer
28 *
29 * @copyright 2010 Sam Hemelryk
30 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 */
32class core_enrol_renderer extends plugin_renderer_base {
33
34 /**
35 * Renders a course enrolment table
36 *
37 * @param course_enrolment_table $table
38 * @return string
39 */
40 protected function render_course_enrolment_table(course_enrolment_table $table) {
41 $content = '';
42 $enrolmentselector = $table->get_enrolment_selector($this->page);
43 if ($enrolmentselector) {
44 $content .= $this->output->render($enrolmentselector);
45 }
2ec702c9
SH
46 $cohortenroller = $table->get_cohort_enrolment_control($this->page);
47 if ($cohortenroller) {
48 $content .= $this->output->render($cohortenroller);
49 }
a70eb30f
SH
50 $content .= $this->output->render($table->get_enrolment_type_filter());
51 $content .= $this->output->render($table->get_paging_bar());
52 $content .= html_writer::table($table);
53 $content .= $this->output->render($table->get_paging_bar());
54 $enrolmentselector = $table->get_enrolment_selector($this->page);
55 if ($enrolmentselector) {
56 $content .= $this->output->render($enrolmentselector);
57 }
2ec702c9
SH
58 $cohortenroller = $table->get_cohort_enrolment_control($this->page);
59 if ($cohortenroller) {
60 $content .= $this->output->render($cohortenroller);
61 }
a70eb30f
SH
62 return $content;
63 }
64
65 /**
66 * Generates HTML to display the users roles and any available actions
67 *
68 * @param int $userid
69 * @param array $roles
70 * @param array $assignableroles
71 * @param moodle_url $pageurl
72 * @return string
73 */
74 public function user_roles_and_actions($userid, $roles, $assignableroles, $canassign, $pageurl) {
75 $iconenroladd = $this->output->pix_url('t/enroladd');
76 $iconenrolremove = $this->output->pix_url('t/delete');
77
78 // get list of roles
79 $rolesoutput = '';
80 foreach ($roles as $roleid=>$role) {
81 if ($canassign && !$role['unchangeable']) {
82 $strunassign = get_string('unassignarole', 'role', $role['text']);
83 $icon = html_writer::empty_tag('img', array('alt'=>$strunassign, 'src'=>$iconenrolremove));
84 $url = new moodle_url($pageurl, array('action'=>'unassign', 'role'=>$roleid, 'user'=>$userid));
85 $rolesoutput .= html_writer::tag('div', $role['text'] . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$roleid, 'title'=>$strunassign)), array('class'=>'role role_'.$roleid));
86 } else {
87 $rolesoutput .= html_writer::tag('div', $role['text'], array('class'=>'role unchangeable', 'rel'=>$roleid));
88 }
89 }
90 $output = '';
91 if (!empty($assignableroles) && $canassign) {
92 $roleids = array_keys($roles);
93 $hasallroles = true;
94 foreach (array_keys($assignableroles) as $key) {
95 if (!in_array($key, $roleids)) {
96 $hasallroles = false;
97 break;
98 }
99 }
100 if (!$hasallroles) {
101 $url = new moodle_url($pageurl, array('action'=>'assign', 'user'=>$userid));
102 $icon = html_writer::empty_tag('img', array('alt'=>get_string('assignroles', 'role'), 'src'=>$iconenroladd));
103 $output = html_writer::tag('div', html_writer::link($url, $icon, array('class'=>'assignrolelink', 'title'=>get_string('assignroles', 'role'))), array('class'=>'addrole'));
104 }
105 }
106 $output .= html_writer::tag('div', $rolesoutput, array('class'=>'roles'));
107 return $output;
108 }
109
110 /**
111 * Generates the HTML to view the users groups and available group actions
112 *
113 * @param int $userid
114 * @param array $groups
115 * @param array $allgroups
116 * @param bool $canmanagegroups
117 * @param moodle_url $pageurl
118 * @return string
119 */
120 public function user_groups_and_actions($userid, $groups, $allgroups, $canmanagegroups, $pageurl) {
121 $iconenroladd = $this->output->pix_url('t/enroladd');
122 $iconenrolremove = $this->output->pix_url('t/delete');
123 $straddgroup = get_string('addgroup', 'group');
124
125 $groupoutput = '';
126 foreach($groups as $groupid=>$name) {
127 if ($canmanagegroups) {
128 $icon = html_writer::empty_tag('img', array('alt'=>get_string('removefromgroup', 'group', $name), 'src'=>$iconenrolremove));
129 $url = new moodle_url($pageurl, array('action'=>'removemember', 'group'=>$groupid, 'user'=>$userid));
130 $groupoutput .= html_writer::tag('div', $name . html_writer::link($url, $icon), array('class'=>'group', 'rel'=>$groupid));
131 } else {
132 $groupoutput .= html_writer::tag('div', $name, array('class'=>'group', 'rel'=>$groupid));
133 }
134 }
135 $groupoutput = html_writer::tag('div', $groupoutput, array('class'=>'groups'));
136 if ($canmanagegroups && (count($groups) < count($allgroups))) {
137 $icon = html_writer::empty_tag('img', array('alt'=>$straddgroup, 'src'=>$iconenroladd));
138 $url = new moodle_url($pageurl, array('action'=>'addmember', 'user'=>$userid));
139 $groupoutput .= html_writer::tag('div', html_writer::link($url, $icon), array('class'=>'addgroup'));
140 }
141 return $groupoutput;
142 }
143
144 /**
145 * Generates the HTML for the given enrolments + available actions
146 *
147 * @param int $userid
148 * @param array $enrolments
149 * @param moodle_url $pageurl
150 * @return string
151 */
152 public function user_enrolments_and_actions($userid, $enrolments, $pageurl) {
153 $iconedit = $this->output->pix_url('t/edit');
154 $iconenrolremove = $this->output->pix_url('t/delete');
155 $strunenrol = get_string('unenrol', 'enrol');
156 $stredit = get_string('edit');
157
158 $output = '';
159 foreach ($enrolments as $ueid=>$enrolment) {
160 $enrolmentoutput = $enrolment['text'].' '.$enrolment['period'];
161 if ($enrolment['dimmed']) {
162 $enrolmentoutput = html_writer::tag('span', $enrolmentoutput, array('class'=>'dimmed_text'));
163 }
164 if ($enrolment['canunenrol']) {
165 $icon = html_writer::empty_tag('img', array('alt'=>$strunenrol, 'src'=>$iconenrolremove));
166 $url = new moodle_url($pageurl, array('action'=>'unenrol', 'ue'=>$ueid));
167 $enrolmentoutput .= html_writer::link($url, $icon, array('class'=>'unenrollink', 'rel'=>$ueid));
168 }
169 if ($enrolment['canmanage']) {
170 $icon = html_writer::empty_tag('img', array('alt'=>$stredit, 'src'=>$iconedit));
171 $url = new moodle_url($url, array('action'=>'edit', 'ue'=>$ueid));
172 $enrolmentoutput .= html_writer::link($url, $icon, array('class'=>'editenrollink', 'rel'=>$ueid));
173 }
174 $output .= html_writer::tag('div', $enrolmentoutput, array('class'=>'enrolment'));
175 }
176 return $output;
177 }
178
179}
180
181/**
182 * Main course enrolment table
183 *
184 * This table is used to display the enrolment information for a course.
185 * It requires that a course enrolment manager be provided during constuct with
186 * provides all of the information for the table.
187 * The control then produces the table, the paging, and the associated JS actions
188 * for the page.
189 *
190 * @package core
191 * @subpackage enrol
192 * @copyright 2010 Sam Hemelryk
193 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
194 */
195class course_enrolment_table extends html_table implements renderable {
196
197 /**
198 * The get/post variable that is used to identify the page.
199 * Default: page
200 */
201 const PAGEVAR = 'page';
202
203 /**
204 * The get/post variable to is used to identify the number of items to display
205 * per page.
206 * Default: perpage
207 */
208 const PERPAGEVAR = 'perpage';
209
210 /**
211 * The get/post variable that is used to identify the sort field for the table.
212 * Default: sort
213 */
214 const SORTVAR = 'sort';
215
216 /**
217 * The get/post variable that is used to identify the sort direction for the table.
218 * Default: dir
219 */
220 const SORTDIRECTIONVAR = 'dir';
221
222 /**
223 * The default number of items per page.
23cee7a4 224 * Default: 100
a70eb30f 225 */
23cee7a4 226 const DEFAULTPERPAGE = 100;
a70eb30f
SH
227
228 /**
229 * The default sort, options are course_enrolment_table::$sortablefields
230 * Default: lastname
231 */
232 const DEFAULTSORT = 'lastname';
233
234 /**
235 * The default direction
236 * Default: ASC
237 */
238 const DEFAULTSORTDIRECTION = 'ASC';
239
240 /**
241 * The current page, starting from 0
242 * @var int
243 */
244 public $page = 0;
245
246 /**
247 * The total number of pages
248 * @var int
249 */
250 public $pages = 0;
251
252 /**
253 * The number of items to display per page
254 * @var int
255 */
256 public $perpage = 0;
257
258 /**
259 * The URL of the page for this table
260 * @var moodle_url
261 */
262 public $pageurl;
263
264 /**
265 * The sort field for this table, should be one of course_enrolment_table::$sortablefields
266 * @var string
267 */
268 public $sort;
269
270 /**
271 * The sort direction, either ASC or DESC
272 * @var string
273 */
274 public $sortdirection;
275
276 /**
277 * The course manager this table is displaying for
278 * @var course_enrolment_manager
279 */
280 protected $manager;
281
282 /**
283 * The paging bar that controls the paging for this table
284 * @var paging_bar
285 */
286 protected $pagingbar = null;
287
288 /**
289 * The total number of users enrolled in the course
290 * @var int
291 */
292 protected $totalusers = null;
293
294 /**
295 * The users enrolled in this course
296 * @var array
297 */
298 protected $users = null;
299
300 /**
301 * The fields for this table
302 * @var array
303 */
304 protected $fields = array();
305
306 protected static $sortablefields = array('firstname', 'lastname', 'email', 'lastaccess');
307
308 /**
309 * Constructs the table
310 *
311 * @param course_enrolment_manager $manager
312 */
313 public function __construct(course_enrolment_manager $manager, moodle_url $pageurl) {
314
315 $this->manager = $manager;
316 $this->pageurl = $pageurl;
317
318 $this->page = optional_param(self::PAGEVAR, 0, PARAM_INT);
319 $this->perpage = optional_param(self::PERPAGEVAR, self::DEFAULTPERPAGE, PARAM_INT);
320 $this->sort = optional_param(self::SORTVAR, self::DEFAULTSORT, PARAM_ALPHA);
321 $this->sortdirection = optional_param(self::SORTDIRECTIONVAR, self::DEFAULTSORTDIRECTION, PARAM_ALPHA);
322
323 $this->attributes = array('class'=>'userenrolment');
324 if (!in_array($this->sort, self::$sortablefields)) {
325 $this->sort = self::DEFAULTSORT;
326 }
327 if ($this->page < 0) {
328 $this->page = 0;
329 }
330 if ($this->sortdirection !== 'ASC' && $this->sortdirection !== 'DESC') {
331 $this->sortdirection = self::DEFAULTSORTDIRECTION;
332 }
333
334 $this->id = html_writer::random_id();
335 $this->set_total_users($manager->get_total_users());
336 }
337
338 /**
339 * Gets the sort direction for a given field
340 *
341 * @param string $field
342 * @return string ASC or DESC
343 */
344 public function get_field_sort_direction($field) {
345 if ($field == $this->sort) {
346 return ($this->sortdirection == 'ASC')?'DESC':'ASC';
347 }
348 return self::DEFAULTSORTDIRECTION;
349 }
350
351 /**
352 * Sets the fields for this table. These get added to the tables head as well.
353 *
354 * You can also use a multi dimensional array for this to have multiple fields
355 * in a single column
356 *
357 * @param array $fields An array of fields to set
358 * @param string $output
359 */
360 public function set_fields($fields, $output=null) {
361 global $OUTPUT;
362 if ($output === null) {
363 $output = $OUTPUT;
364 }
365 $this->fields = $fields;
366 $this->head = array();
367 $this->colclasses = array();
368 $this->align = array();
369 $url = new moodle_url($this->pageurl, $this->get_url_params()+$this->manager->get_url_params());
370 foreach ($fields as $name => $label) {
371 $newlabel = '';
372 if (is_array($label)) {
373 $bits = array();
374 foreach ($label as $n => $l) {
375 if ($l === false) {
376 continue;
377 }
378 if (!in_array($n, self::$sortablefields)) {
379 $bits[] = $l;
380 } else {
381 $link = html_writer::link(new moodle_url($url, array(self::SORTVAR=>$n)), $fields[$name][$n]);
382 if ($this->sort == $n) {
383 $link .= ' '.html_writer::link(new moodle_url($url, array(self::SORTVAR=>$n, self::SORTDIRECTIONVAR=>$this->get_field_sort_direction($n))), $this->get_direction_icon($output, $n));
384 }
385 $bits[] = html_writer::tag('span', $link, array('class'=>'subheading_'.$n));
386
387 }
388 }
389 $newlabel = join(' / ', $bits);
390 } else {
391 if (!in_array($name, self::$sortablefields)) {
392 $newlabel = $label;
393 } else {
394 $newlabel = html_writer::link(new moodle_url($url, array(self::SORTVAR=>$name)), $fields[$name]);
395 if ($this->sort == $name) {
396 $newlabel .= ' '.html_writer::link(new moodle_url($url, array(self::SORTVAR=>$name, self::SORTDIRECTIONVAR=>$this->get_field_sort_direction($name))), $this->get_direction_icon($output, $name));
397 }
398 }
399 }
400 $this->head[] = $newlabel;
401 $this->colclasses[] = 'field col_'.$name;
402 }
403 }
404 /**
405 * Sets the total number of users
406 *
407 * @param int $totalusers
408 */
409 public function set_total_users($totalusers) {
410 $this->totalusers = $totalusers;
411 $this->pages = ceil($this->totalusers / $this->perpage);
412 if ($this->page > $this->pages) {
413 $this->page = $this->pages;
414 }
415 }
416 /**
417
418 */
419 /**
420 * Sets the users for this table
421 *
422 * @param array $users
423 * @param moodle_page $page
424 */
425 public function set_users(array $users, moodle_page $page=null) {
426 global $PAGE;
427 if ($page === null) {
428 $page = $PAGE;
429 }
430 foreach ($users as $userid=>$user) {
431 $user = (array)$user;
432 $row = new html_table_row();
433 $row->attributes = array('class' => 'userinforow');
434 $row->id = 'user_'.$userid;
435 $row->cells = array();
436 foreach ($this->fields as $field => $label) {
437 if (is_array($label)) {
438 $bits = array();
439 foreach (array_keys($label) as $subfield) {
440 if (array_key_exists($subfield, $user)) {
441 $bits[] = html_writer::tag('div', $user[$subfield], array('class'=>'subfield subfield_'.$subfield));
442 }
443 }
444 if (empty($bits)) {
445 $bits[] = '&nbsp;';
446 }
447 $row->cells[] = new html_table_cell(join(' ', $bits));
448 } else {
449 if (!array_key_exists($field, $user)) {
450 $user[$field] = '&nbsp;';
451 }
452 $row->cells[] = new html_table_cell($user[$field]);
453 }
454 }
455 $this->data[] = $row;
456 }
457 if (has_capability('moodle/role:assign', $this->manager->get_context())) {
458 $arguments = array(array('containerId'=>$this->id, 'userIds'=>array_keys($users), 'courseId'=>$this->manager->get_course()->id));
459 $page->requires->yui_module(array('moodle-enrol-rolemanager', 'moodle-enrol-rolemanager-skin'), 'M.enrol.rolemanager.init', $arguments);
460 }
461 }
462
463 /**
464 * Gets the paging bar instance for this table
465 *
466 * @return paging_bar
467 */
468 public function get_paging_bar() {
469 if ($this->pagingbar == null) {
470 $this->pagingbar = new paging_bar($this->totalusers, $this->page, $this->perpage, $this->pageurl, self::PAGEVAR);
471 }
472 return $this->pagingbar;
473 }
474
475 /**
476 * Gets the direction icon for the sortable field within this table
477 *
478 * @param core_renderer $output
479 * @param string $field
480 * @return string
481 */
482 protected function get_direction_icon($output, $field) {
483 $direction = self::DEFAULTSORTDIRECTION;
484 if ($this->sort == $field) {
485 $direction = $this->sortdirection;
486 }
487 if ($direction === 'ASC') {
488 return html_writer::empty_tag('img', array('alt'=>'', 'src'=>$output->pix_url('t/down')));
489 } else {
490 return html_writer::empty_tag('img', array('alt'=>'', 'src'=>$output->pix_url('t/up')));
491 }
492 }
493
494 /**
495 * Gets the params that will need to be added to the url in order to return to this page.
496 *
497 * @return array
498 */
499 public function get_url_params() {
500 return array(
501 self::PAGEVAR => $this->page,
502 self::PERPAGEVAR => $this->perpage,
503 self::SORTVAR => $this->sort,
504 self::SORTDIRECTIONVAR => $this->sortdirection
505 );
506 }
507
508 /**
509 * Gets the enrolment type filter control for this table
510 *
511 * @return single_select
512 */
513 public function get_enrolment_type_filter() {
514 $url = new moodle_url($this->pageurl, $this->manager->get_url_params()+$this->get_url_params());
2ec702c9 515 $selector = new single_select($url, 'ifilter', array(0=>get_string('all')) + (array)$this->manager->get_enrolment_instance_names(), $this->manager->get_enrolment_filter(), array());
a70eb30f
SH
516 $selector->set_label( get_string('enrolmentinstances', 'enrol'));
517 return $selector;
518 }
519
2ec702c9
SH
520 /**
521 * Returns a button to enrol cohorts or thier users
522 *
523 * @staticvar int $count
524 * @param moodle_page $page
525 * @return single_button|false
526 */
527 public function get_cohort_enrolment_control(moodle_page $page) {
528 static $count = 0;
529
530 // First make sure that cohorts is enabled
531 $plugins = $this->manager->get_enrolment_plugins();
532 if (!array_key_exists('cohort', $plugins)) {
533 return false;
534 }
535 $count ++;
536 $course = $this->manager->get_course();
537 $cohorturl = new moodle_url('/enrol/cohort/addinstance.php', array('id'=>$course->id));
538 $control = new single_button($cohorturl, get_string('enrolcohort', 'enrol'), 'get');
539 $control->class = 'singlebutton enrolcohortbutton instance'.$count;
540 $control->formid = 'manuallyenrol_single_'+$count;
541 if ($count == 1) {
542 $page->requires->strings_for_js(array('enrol','synced','enrolcohort','enrolcohortusers'), 'enrol');
543 $page->requires->string_for_js('assignroles', 'role');
544 $page->requires->string_for_js('cohort', 'cohort');
545 $page->requires->string_for_js('users', 'moodle');
546 $url = new moodle_url($this->pageurl, $this->manager->get_url_params()+$this->get_url_params());
547
548 $hasmanualinstance = false;
549 // No point showing this at all if the user cant manually enrol users
550 if (has_capability('enrol/manual:manage', $this->manager->get_context())) {
551 // Make sure manual enrolments instance exists
552 $instances = $this->manager->get_enrolment_instances();
553 foreach ($instances as $instance) {
554 if ($instance->enrol == 'manual') {
555 $hasmanualinstance = true;
556 break;
557 }
558 }
559 }
560
561 $arguments = array(array(
562 'courseid'=>$course->id,
563 'ajaxurl'=>'/enrol/ajax.php',
564 'url'=>$url->out(false),
565 'manualEnrolment'=>$hasmanualinstance));
566 $page->requires->yui_module(array('moodle-enrol-quickcohortenrolment', 'moodle-enrol-quickcohortenrolment-skin'), 'M.enrol.quickcohortenrolment.init', $arguments);
567 }
568 return $control;
569 }
570
a70eb30f
SH
571 /**
572 * Gets the enrolment selector control for this table and initialises its
573 * JavaScript
574 *
575 * @return single_button|url_select
576 */
577 public function get_enrolment_selector(moodle_page $page) {
578 static $count = 0;
579
580 $instances = $this->manager->get_enrolment_instances();
581 $plugins = $this->manager->get_enrolment_plugins();
582 // print enrol link or selection
583 $links = array();
584 foreach($instances as $instance) {
585 $plugin = $plugins[$instance->enrol];
586 if ($link = $plugin->get_manual_enrol_link($instance)) {
587 $links[$instance->id] = $link;
588 }
589 }
590 if (!empty($links)) {
591 $arguments = array();
592 $count ++;
593 if (count($links) == 1) {
594 $control = new single_button(reset($links), get_string('enrolusers', 'enrol_manual'), 'get');
595 $control->class = 'singlebutton enrolusersbutton instance'.$count;
596 $control->formid = 'manuallyenrol_single_'+$count;
597 $arguments[] = array('id'=>key($links), 'name'=>$plugins[$instances[key($links)]->enrol]->get_instance_name($instances[key($links)]));
598 } else if (count($links) > 1) {
599 $inames = $this->manager->get_enrolment_instance_names();
600 $options = array();
601 foreach ($links as $i=>$link) {
602 $options[$link->out(false)] = $inames[$i];
603 $arguments[] = array('id'=>$i, 'name'=>$plugins[$instances[$i]->enrol]->get_instance_name($instances[$i]));
604 }
605 $control = new url_select($options, '', array(''=>get_string('enrolusers', 'enrol_manual').'...'));
606 $control->class = 'singlebutton enrolusersbutton instance'.$count;
607 $control->formid = 'manuallyenrol_select_'+$count;
608 }
609 $course = $this->manager->get_course();
610 $url = new moodle_url($this->pageurl, $this->manager->get_url_params()+$this->get_url_params());
611 $timeformat = get_string('strftimedatefullshort');
612 $today = time();
613 $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
614 $startdateoptions = array();
615 if ($course->startdate > 0) {
616 $startdateoptions[2] = get_string('coursestart') . ' (' . userdate($course->startdate, $timeformat) . ')';
617 }
618 $startdateoptions[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
619
620 if ($count == 1) {
621 $page->requires->strings_for_js(array(
622 'ajaxoneuserfound',
623 'ajaxxusersfound',
624 'ajaxnext25',
625 'enrol',
626 'enrolmentoptions',
627 'enrolusers',
628 'errajaxfailedenrol',
629 'errajaxsearch',
630 'none',
631 'usersearch',
632 'unlimitedduration',
633 'startdatetoday',
634 'durationdays',
635 'enrolperiod'), 'enrol');
636 $page->requires->string_for_js('assignroles', 'role');
637 $page->requires->string_for_js('startingfrom', 'moodle');
638
639
640 $arguments = array(array(
641 'instances'=>$arguments,
642 'courseid'=>$course->id,
643 'ajaxurl'=>'/enrol/ajax.php',
644 'url'=>$url->out(false),
23cee7a4
SH
645 'optionsStartDate'=>$startdateoptions,
646 'defaultRole'=>get_config('enrol_manual', 'roleid')));
a70eb30f
SH
647 $page->requires->yui_module(array('moodle-enrol-enrolmentmanager', 'moodle-enrol-enrolmentmanager-skin'), 'M.enrol.enrolmentmanager.init', $arguments);
648 }
649 return $control;
650 }
651 return null;
652 }
2ec702c9 653}