Merge branch 'MDL-72523' of https://github.com/paulholden/moodle
[moodle.git] / enrol / renderer.php
blobc2458edec2294c5cbc7f607d74369642da347922
1 <?php
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.
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/>.
17 /**
18 * This is the main renderer for the enrol section.
20 * @package core_enrol
21 * @copyright 2010 Sam Hemelryk
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 /**
26 * This is the core renderer
28 * @copyright 2010 Sam Hemelryk
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 class core_enrol_renderer extends plugin_renderer_base {
33 /**
34 * Renderers the enrol_user_button.
36 * @param enrol_user_button $button
37 * @return string XHTML
39 protected function render_enrol_user_button(enrol_user_button $button) {
40 $attributes = array('type' => 'submit',
41 'value' => $button->label,
42 'disabled' => $button->disabled ? 'disabled' : null,
43 'title' => $button->tooltip,
44 'class' => 'btn ' . ($button->primary ? 'btn-primary' : 'btn-secondary'));
46 if ($button->actions) {
47 $id = html_writer::random_id('single_button');
48 $attributes['id'] = $id;
49 foreach ($button->actions as $action) {
50 $this->add_action_handler($action, $id);
53 $button->initialise_js($this->page);
55 // first the input element
56 $output = html_writer::empty_tag('input', $attributes);
58 // then hidden fields
59 $params = $button->url->params();
60 if ($button->method === 'post') {
61 $params['sesskey'] = sesskey();
63 foreach ($params as $var => $val) {
64 $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $var, 'value' => $val));
67 // then div wrapper for xhtml strictness
68 $output = html_writer::tag('div', $output);
70 // now the form itself around it
71 if ($button->method === 'get') {
72 $url = $button->url->out_omit_querystring(true); // url without params, the anchor part allowed
73 } else {
74 $url = $button->url->out_omit_querystring(); // url without params, the anchor part not allowed
76 if ($url === '') {
77 $url = '#'; // there has to be always some action
79 $attributes = array('method' => $button->method,
80 'action' => $url,
81 'id' => $button->formid);
82 $output = html_writer::tag('form', $output, $attributes);
84 // and finally one more wrapper with class
85 return html_writer::tag('div', $output, array('class' => $button->class));
88 /**
89 * Renders a course enrolment table
91 * @param course_enrolment_table $table
92 * @return string
94 protected function render_course_enrolment_other_users_table(course_enrolment_other_users_table $table) {
96 $table->initialise_javascript();
98 $content = '';
99 $content .= html_writer::tag('div', get_string('otheruserdesc', 'enrol'), array('class'=>'otherusersdesc'));
100 $content .= $this->output->render($table->get_paging_bar());
101 $content .= html_writer::table($table);
102 $content .= $this->output->render($table->get_paging_bar());
103 return $content;
107 * Generates HTML to display the users roles and any available actions
109 * @param int $userid
110 * @param array $roles
111 * @param array $assignableroles
112 * @param moodle_url $pageurl
113 * @return string
115 public function user_roles_and_actions($userid, $roles, $assignableroles, $canassign, $pageurl) {
117 // Get list of roles.
118 $rolesoutput = '';
119 foreach ($roles as $roleid=>$role) {
120 if ($canassign and (is_siteadmin() or isset($assignableroles[$roleid])) and !$role['unchangeable']) {
121 $strunassign = get_string('unassignarole', 'role', $role['text']);
122 $icon = $this->output->pix_icon('t/delete', $strunassign);
123 $url = new moodle_url($pageurl, array('action'=>'unassign', 'roleid'=>$roleid, 'user'=>$userid));
124 $rolesoutput .= html_writer::tag('div', $role['text'] . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$roleid, 'title'=>$strunassign)), array('class'=>'role role_'.$roleid));
125 } else {
126 $rolesoutput .= html_writer::tag('div', $role['text'], array('class'=>'role unchangeable', 'rel'=>$roleid));
129 $output = '';
130 if (!empty($assignableroles) && $canassign) {
131 $roleids = array_keys($roles);
132 $hasallroles = true;
133 foreach (array_keys($assignableroles) as $key) {
134 if (!in_array($key, $roleids)) {
135 $hasallroles = false;
136 break;
139 if (!$hasallroles) {
140 $url = new moodle_url($pageurl, array('action' => 'assign', 'user' => $userid));
141 $roleicon = $this->output->pix_icon('i/assignroles', get_string('assignroles', 'role'));
142 $link = html_writer::link($url, $roleicon, array('class' => 'assignrolelink'));
143 $output = html_writer::tag('div', $link, array('class'=>'addrole'));
146 $output .= html_writer::tag('div', $rolesoutput, array('class'=>'roles'));
147 return $output;
151 * Generates the HTML to view the users groups and available group actions
153 * @param int $userid
154 * @param array $groups
155 * @param array $allgroups
156 * @param bool $canmanagegroups
157 * @param moodle_url $pageurl
158 * @return string
160 public function user_groups_and_actions($userid, $groups, $allgroups, $canmanagegroups, $pageurl) {
161 $groupicon = $this->output->pix_icon('i/group', get_string('addgroup', 'group'));
163 $groupoutput = '';
164 foreach($groups as $groupid=>$name) {
165 if ($canmanagegroups and groups_remove_member_allowed($groupid, $userid)) {
166 $icon = $this->output->pix_icon('t/delete', get_string('removefromgroup', 'group', $name));
167 $url = new moodle_url($pageurl, array('action'=>'removemember', 'group'=>$groupid, 'user'=>$userid));
168 $groupoutput .= html_writer::tag('div', $name . html_writer::link($url, $icon), array('class'=>'group', 'rel'=>$groupid));
169 } else {
170 $groupoutput .= html_writer::tag('div', $name, array('class'=>'group', 'rel'=>$groupid));
173 $output = '';
174 if ($canmanagegroups && (count($groups) < count($allgroups))) {
175 $url = new moodle_url($pageurl, array('action'=>'addmember', 'user'=>$userid));
176 $output .= html_writer::tag('div', html_writer::link($url, $groupicon), array('class'=>'addgroup'));
178 $output = $output.html_writer::tag('div', $groupoutput, array('class'=>'groups'));
179 return $output;
183 * Generates the HTML for the given enrolments + available actions
185 * @param int $userid
186 * @param array $enrolments
187 * @param moodle_url $pageurl
188 * @return string
190 public function user_enrolments_and_actions($enrolments) {
191 $output = '';
192 foreach ($enrolments as $ue) {
193 $enrolmentoutput = $ue['text'].' '.$ue['period'];
194 if ($ue['dimmed']) {
195 $enrolmentoutput = html_writer::tag('span', $enrolmentoutput, array('class'=>'dimmed_text'));
196 } else {
197 $enrolmentoutput = html_writer::tag('span', $enrolmentoutput);
199 foreach ($ue['actions'] as $action) {
200 $enrolmentoutput .= $this->render($action);
202 $output .= html_writer::tag('div', $enrolmentoutput, array('class'=>'enrolment'));
204 return $output;
208 * Renders a user enrolment action
209 * @param user_enrolment_action $icon
210 * @return string
212 protected function render_user_enrolment_action(user_enrolment_action $icon) {
213 return html_writer::link($icon->get_url(), $this->output->render($icon->get_icon()), $icon->get_attributes());
218 * Main course enrolment table
220 * This table is used to display the enrolment information for a course.
221 * It requires that a course enrolment manager be provided during constuct with
222 * provides all of the information for the table.
223 * The control then produces the table, the paging, and the associated JS actions
224 * for the page.
226 * @package core
227 * @subpackage enrol
228 * @copyright 2010 Sam Hemelryk
229 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
231 class course_enrolment_table extends html_table implements renderable {
234 * The get/post variable that is used to identify the page.
235 * Default: page
237 const PAGEVAR = 'page';
240 * The get/post variable to is used to identify the number of items to display
241 * per page.
242 * Default: perpage
244 const PERPAGEVAR = 'perpage';
247 * The get/post variable that is used to identify the sort field for the table.
248 * Default: sort
250 const SORTVAR = 'sort';
253 * The get/post variable that is used to identify the sort direction for the table.
254 * Default: dir
256 const SORTDIRECTIONVAR = 'dir';
259 * The default number of items per page.
260 * Default: 100
262 const DEFAULTPERPAGE = 100;
265 * The default sort, options are course_enrolment_table::$sortablefields
266 * Default: lastname
268 const DEFAULTSORT = 'lastname';
271 * The default direction
272 * Default: ASC
274 const DEFAULTSORTDIRECTION = 'ASC';
277 * The current page, starting from 0
278 * @var int
280 public $page = 0;
283 * The total number of pages
284 * @var int
286 public $pages = 0;
289 * The number of items to display per page
290 * @var int
292 public $perpage = 0;
295 * The sort field for this table, should be one of course_enrolment_table::$sortablefields
296 * @var string
298 public $sort;
301 * The sort direction, either ASC or DESC
302 * @var string
304 public $sortdirection;
307 * The course manager this table is displaying for
308 * @var course_enrolment_manager
310 protected $manager;
313 * The paging bar that controls the paging for this table
314 * @var paging_bar
316 protected $pagingbar = null;
319 * The total number of users enrolled in the course
320 * @var int
322 protected $totalusers = null;
325 * The users enrolled in this course
326 * @var array
328 protected $users = null;
331 * The fields for this table
332 * @var array
334 protected $fields = array();
337 * An array of bulk user enrolment operations
338 * @var array
340 protected $bulkoperations = array();
343 * An array of sortable fields
344 * @static
345 * @var array
347 protected static $sortablefields = array('firstname', 'lastname', 'firstnamephonetic', 'lastnamephonetic', 'middlename',
348 'alternatename', 'username', 'idnumber', 'email', 'phone1', 'phone2',
349 'institution', 'department', 'lastaccess', 'lastcourseaccess');
352 * Constructs the table
354 * @param course_enrolment_manager $manager
356 public function __construct(course_enrolment_manager $manager) {
358 $this->manager = $manager;
360 $this->page = optional_param(self::PAGEVAR, 0, PARAM_INT);
361 $this->perpage = optional_param(self::PERPAGEVAR, self::DEFAULTPERPAGE, PARAM_INT);
362 $this->sort = optional_param(self::SORTVAR, self::DEFAULTSORT, PARAM_ALPHANUM);
363 $this->sortdirection = optional_param(self::SORTDIRECTIONVAR, self::DEFAULTSORTDIRECTION, PARAM_ALPHA);
365 $this->attributes = array('class' => 'userenrolment table-striped');
366 if (!in_array($this->sort, self::$sortablefields)) {
367 $this->sort = self::DEFAULTSORT;
369 if ($this->page < 0) {
370 $this->page = 0;
372 if ($this->sortdirection !== 'ASC' && $this->sortdirection !== 'DESC') {
373 $this->sortdirection = self::DEFAULTSORTDIRECTION;
376 $this->id = html_writer::random_id();
378 // Collect the bulk operations for the currently filtered plugin if there is one.
379 $plugin = $manager->get_filtered_enrolment_plugin();
380 if ($plugin and enrol_is_enabled($plugin->get_name())) {
381 $this->bulkoperations = $plugin->get_bulk_operations($manager);
386 * Returns an array of enrol_user_buttons that are created by the different
387 * enrolment plugins available.
389 * @return array
391 public function get_manual_enrol_buttons() {
392 return $this->manager->get_manual_enrol_buttons();
396 * Gets the sort direction for a given field
398 * @param string $field
399 * @return string ASC or DESC
401 public function get_field_sort_direction($field) {
402 if ($field == $this->sort) {
403 return ($this->sortdirection == 'ASC')?'DESC':'ASC';
405 return self::DEFAULTSORTDIRECTION;
409 * Sets the fields for this table. These get added to the tables head as well.
411 * You can also use a multi dimensional array for this to have multiple fields
412 * in a single column
414 * @param array $fields An array of fields to set
415 * @param string $output
417 public function set_fields($fields, $output) {
418 $this->fields = $fields;
419 $this->head = array();
420 $this->colclasses = array();
421 $this->align = array();
422 $url = $this->manager->get_moodlepage()->url;
424 if (!empty($this->bulkoperations)) {
425 // If there are bulk operations add a column for checkboxes.
426 $this->head[] = '';
427 $this->colclasses[] = 'field col_bulkops';
430 foreach ($fields as $name => $label) {
431 $newlabel = '';
432 if (is_array($label)) {
433 $bits = array();
434 foreach ($label as $n => $l) {
435 if ($l === false) {
436 continue;
438 if (!in_array($n, self::$sortablefields)) {
439 $bits[] = $l;
440 } else {
441 $sorturl = new moodle_url($url, array(self::SORTVAR => $n, self::SORTDIRECTIONVAR => $this->get_field_sort_direction($n)));
442 $link = html_writer::link($sorturl, $fields[$name][$n]);
443 if ($this->sort == $n) {
444 $link .= $this->get_direction_icon($output, $n);
446 $bits[] = html_writer::tag('span', $link, array('class'=>'subheading_'.$n));
450 $newlabel = join(' / ', $bits);
451 } else {
452 if (!in_array($name, self::$sortablefields)) {
453 $newlabel = $label;
454 } else {
455 $sorturl = new moodle_url($url, array(self::SORTVAR => $name, self::SORTDIRECTIONVAR => $this->get_field_sort_direction($name)));
456 $newlabel = html_writer::link($sorturl, $fields[$name]);
457 if ($this->sort == $name) {
458 $newlabel .= $this->get_direction_icon($output, $name);
462 $this->head[] = $newlabel;
463 $this->colclasses[] = 'field col_'.$name;
467 * Sets the total number of users
469 * @param int $totalusers
471 public function set_total_users($totalusers) {
472 $this->totalusers = $totalusers;
473 $this->pages = ceil($this->totalusers / $this->perpage);
474 if ($this->page > $this->pages) {
475 $this->page = $this->pages;
479 * Sets the users for this table
481 * @param array $users
482 * @return void
484 public function set_users(array $users) {
485 $this->users = $users;
486 $hasbulkops = !empty($this->bulkoperations);
487 foreach ($users as $userid=>$user) {
488 $user = (array)$user;
489 $row = new html_table_row();
490 $row->attributes = array('class' => 'userinforow');
491 $row->id = 'user_'.$userid;
492 $row->cells = array();
493 if ($hasbulkops) {
494 // Add a checkbox into the first column.
495 $input = html_writer::empty_tag('input', array('type' => 'checkbox', 'name' => 'bulkuser[]', 'value' => $userid));
496 $row->cells[] = new html_table_cell($input);
498 foreach ($this->fields as $field => $label) {
499 if (is_array($label)) {
500 $bits = array();
501 foreach (array_keys($label) as $subfield) {
502 if (array_key_exists($subfield, $user)) {
503 $bits[] = html_writer::tag('div', $user[$subfield], array('class'=>'subfield subfield_'.$subfield));
506 if (empty($bits)) {
507 $bits[] = '&nbsp;';
509 $row->cells[] = new html_table_cell(join(' ', $bits));
510 } else {
511 if (!array_key_exists($field, $user)) {
512 $user[$field] = '&nbsp;';
514 $row->cells[] = new html_table_cell($user[$field]);
517 $this->data[] = $row;
521 public function initialise_javascript() {
522 if (has_capability('moodle/role:assign', $this->manager->get_context())) {
523 $this->manager->get_moodlepage()->requires->strings_for_js(array(
524 'assignroles',
525 'confirmunassign',
526 'confirmunassigntitle',
527 'confirmunassignyes',
528 'confirmunassignno'
529 ), 'role');
530 $modules = array('moodle-enrol-rolemanager', 'moodle-enrol-rolemanager-skin');
531 $function = 'M.enrol.rolemanager.init';
532 $arguments = array(
533 'containerId'=>$this->id,
534 'userIds'=>array_keys($this->users),
535 'courseId'=>$this->manager->get_course()->id,
536 'otherusers'=>isset($this->otherusers));
537 $this->manager->get_moodlepage()->requires->yui_module($modules, $function, array($arguments));
542 * Gets the paging bar instance for this table
544 * @return paging_bar
546 public function get_paging_bar() {
547 if ($this->pagingbar == null) {
548 $this->pagingbar = new paging_bar($this->totalusers, $this->page, $this->perpage, $this->manager->get_moodlepage()->url, self::PAGEVAR);
550 return $this->pagingbar;
554 * Gets the direction icon for the sortable field within this table
556 * @param core_renderer $output
557 * @param string $field
558 * @return string
560 protected function get_direction_icon($output, $field) {
561 $direction = self::DEFAULTSORTDIRECTION;
562 if ($this->sort == $field) {
563 $direction = $this->sortdirection;
565 if ($direction === 'ASC') {
566 return $output->pix_icon('t/sort_asc', get_string('sort'));
567 } else {
568 return $output->pix_icon('t/sort_desc', get_string('sort'));
573 * Gets the params that will need to be added to the url in order to return to this page.
575 * @return array
577 public function get_url_params() {
578 return array(
579 self::PAGEVAR => $this->page,
580 self::PERPAGEVAR => $this->perpage,
581 self::SORTVAR => $this->sort,
582 self::SORTDIRECTIONVAR => $this->sortdirection
587 * Returns an array of URL params for both the table and the manager.
589 * @return array
591 public function get_combined_url_params() {
592 return $this->get_url_params() + $this->manager->get_url_params();
596 * Sets the bulk operations for this table.
598 * @param array $bulkoperations
600 public function set_bulk_user_enrolment_operations(array $bulkoperations) {
601 $this->bulkoperations = $bulkoperations;
605 * Returns an array of bulk operations.
607 * @return array
609 public function get_bulk_user_enrolment_operations() {
610 return $this->bulkoperations;
614 * Returns true fi the table is aware of any bulk operations that can be performed on users
615 * selected from the currently filtered enrolment plugins.
617 * @return bool
619 public function has_bulk_user_enrolment_operations() {
620 return !empty($this->bulkoperations);
625 * Table control used for enrolled users
627 * @copyright 2010 Sam Hemelryk
628 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
630 class course_enrolment_users_table extends course_enrolment_table {
635 * Table used for other users
637 * Other users are users who have roles but are not enrolled.
639 * @copyright 2010 Sam Hemelryk
640 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
642 class course_enrolment_other_users_table extends course_enrolment_table {
644 public $otherusers = true;
647 * Constructs the table
649 * @param course_enrolment_manager $manager
651 public function __construct(course_enrolment_manager $manager) {
652 parent::__construct($manager);
653 $this->attributes = array('class'=>'userenrolment otheruserenrolment');
657 * Gets a button to search users and assign them roles in the course.
659 * @staticvar int $count
660 * @param int $page
661 * @return single_button
663 public function get_user_search_button() {
664 static $count = 0;
665 if (!has_capability('moodle/role:assign', $this->manager->get_context())) {
666 return false;
668 $count++;
669 $url = new moodle_url('/admin/roles/assign.php', array('contextid'=>$this->manager->get_context()->id, 'sesskey'=>sesskey()));
670 $control = new single_button($url, get_string('assignroles', 'role'), 'get');
671 $control->class = 'singlebutton assignuserrole instance'.$count;
672 if ($count == 1) {
673 $this->manager->get_moodlepage()->requires->strings_for_js(array(
674 'ajaxoneuserfound',
675 'ajaxxusersfound',
676 'ajaxxmoreusersfound',
677 'ajaxnext25',
678 'enrol',
679 'enrolmentoptions',
680 'enrolusers',
681 'enrolxusers',
682 'errajaxfailedenrol',
683 'errajaxsearch',
684 'foundxcohorts',
685 'none',
686 'usersearch',
687 'unlimitedduration',
688 'startdatetoday',
689 'durationdays',
690 'enrolperiod'), 'enrol');
691 $this->manager->get_moodlepage()->requires->string_for_js('assignrole', 'role');
693 $modules = array('moodle-enrol-otherusersmanager', 'moodle-enrol-otherusersmanager-skin');
694 $function = 'M.enrol.otherusersmanager.init';
695 $arguments = array(
696 'courseId'=> $this->manager->get_course()->id,
697 'ajaxUrl' => '/enrol/ajax.php',
698 'url' => $this->manager->get_moodlepage()->url->out(false));
699 $this->manager->get_moodlepage()->requires->yui_module($modules, $function, array($arguments));
701 return $control;