Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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. 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 * This is the main renderer for the enrol section. 19 * 20 * @package core_enrol 21 * @copyright 2010 Sam Hemelryk 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 /** 26 * This is the core renderer 27 * 28 * @copyright 2010 Sam Hemelryk 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 class core_enrol_renderer extends plugin_renderer_base { 32 33 /** 34 * Renderers the enrol_user_button. 35 * 36 * @param enrol_user_button $button 37 * @return string XHTML 38 */ 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 btn-secondary my-1'); 45 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); 51 } 52 } 53 $button->initialise_js($this->page); 54 55 // first the input element 56 $output = html_writer::empty_tag('input', $attributes); 57 58 // then hidden fields 59 $params = $button->url->params(); 60 if ($button->method === 'post') { 61 $params['sesskey'] = sesskey(); 62 } 63 foreach ($params as $var => $val) { 64 $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $var, 'value' => $val)); 65 } 66 67 // then div wrapper for xhtml strictness 68 $output = html_writer::tag('div', $output); 69 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 75 } 76 if ($url === '') { 77 $url = '#'; // there has to be always some action 78 } 79 $attributes = array('method' => $button->method, 80 'action' => $url, 81 'id' => $button->formid); 82 $output = html_writer::tag('form', $output, $attributes); 83 84 // and finally one more wrapper with class 85 return html_writer::tag('div', $output, array('class' => $button->class)); 86 } 87 88 /** 89 * Renders a course enrolment table 90 * 91 * @param course_enrolment_table $table 92 * @return string 93 */ 94 protected function render_course_enrolment_other_users_table(course_enrolment_other_users_table $table) { 95 96 $table->initialise_javascript(); 97 98 $content = ''; 99 $searchbutton = $table->get_user_search_button(); 100 if ($searchbutton) { 101 $content .= $this->output->render($searchbutton); 102 } 103 $content .= html_writer::tag('div', get_string('otheruserdesc', 'enrol'), array('class'=>'otherusersdesc')); 104 $content .= $this->output->render($table->get_paging_bar()); 105 $content .= html_writer::table($table); 106 $content .= $this->output->render($table->get_paging_bar()); 107 $searchbutton = $table->get_user_search_button(); 108 if ($searchbutton) { 109 $content .= $this->output->render($searchbutton); 110 } 111 return $content; 112 } 113 114 /** 115 * Generates HTML to display the users roles and any available actions 116 * 117 * @param int $userid 118 * @param array $roles 119 * @param array $assignableroles 120 * @param moodle_url $pageurl 121 * @return string 122 */ 123 public function user_roles_and_actions($userid, $roles, $assignableroles, $canassign, $pageurl) { 124 125 // Get list of roles. 126 $rolesoutput = ''; 127 foreach ($roles as $roleid=>$role) { 128 if ($canassign and (is_siteadmin() or isset($assignableroles[$roleid])) and !$role['unchangeable']) { 129 $strunassign = get_string('unassignarole', 'role', $role['text']); 130 $icon = $this->output->pix_icon('t/delete', $strunassign); 131 $url = new moodle_url($pageurl, array('action'=>'unassign', 'roleid'=>$roleid, 'user'=>$userid)); 132 $rolesoutput .= html_writer::tag('div', $role['text'] . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$roleid, 'title'=>$strunassign)), array('class'=>'role role_'.$roleid)); 133 } else { 134 $rolesoutput .= html_writer::tag('div', $role['text'], array('class'=>'role unchangeable', 'rel'=>$roleid)); 135 } 136 } 137 $output = ''; 138 if (!empty($assignableroles) && $canassign) { 139 $roleids = array_keys($roles); 140 $hasallroles = true; 141 foreach (array_keys($assignableroles) as $key) { 142 if (!in_array($key, $roleids)) { 143 $hasallroles = false; 144 break; 145 } 146 } 147 if (!$hasallroles) { 148 $url = new moodle_url($pageurl, array('action' => 'assign', 'user' => $userid)); 149 $roleicon = $this->output->pix_icon('i/assignroles', get_string('assignroles', 'role')); 150 $link = html_writer::link($url, $roleicon, array('class' => 'assignrolelink')); 151 $output = html_writer::tag('div', $link, array('class'=>'addrole')); 152 } 153 } 154 $output .= html_writer::tag('div', $rolesoutput, array('class'=>'roles')); 155 return $output; 156 } 157 158 /** 159 * Generates the HTML to view the users groups and available group actions 160 * 161 * @param int $userid 162 * @param array $groups 163 * @param array $allgroups 164 * @param bool $canmanagegroups 165 * @param moodle_url $pageurl 166 * @return string 167 */ 168 public function user_groups_and_actions($userid, $groups, $allgroups, $canmanagegroups, $pageurl) { 169 $groupicon = $this->output->pix_icon('i/group', get_string('addgroup', 'group')); 170 171 $groupoutput = ''; 172 foreach($groups as $groupid=>$name) { 173 if ($canmanagegroups and groups_remove_member_allowed($groupid, $userid)) { 174 $icon = $this->output->pix_icon('t/delete', get_string('removefromgroup', 'group', $name)); 175 $url = new moodle_url($pageurl, array('action'=>'removemember', 'group'=>$groupid, 'user'=>$userid)); 176 $groupoutput .= html_writer::tag('div', $name . html_writer::link($url, $icon), array('class'=>'group', 'rel'=>$groupid)); 177 } else { 178 $groupoutput .= html_writer::tag('div', $name, array('class'=>'group', 'rel'=>$groupid)); 179 } 180 } 181 $output = ''; 182 if ($canmanagegroups && (count($groups) < count($allgroups))) { 183 $url = new moodle_url($pageurl, array('action'=>'addmember', 'user'=>$userid)); 184 $output .= html_writer::tag('div', html_writer::link($url, $groupicon), array('class'=>'addgroup')); 185 } 186 $output = $output.html_writer::tag('div', $groupoutput, array('class'=>'groups')); 187 return $output; 188 } 189 190 /** 191 * Generates the HTML for the given enrolments + available actions 192 * 193 * @param int $userid 194 * @param array $enrolments 195 * @param moodle_url $pageurl 196 * @return string 197 */ 198 public function user_enrolments_and_actions($enrolments) { 199 $output = ''; 200 foreach ($enrolments as $ue) { 201 $enrolmentoutput = $ue['text'].' '.$ue['period']; 202 if ($ue['dimmed']) { 203 $enrolmentoutput = html_writer::tag('span', $enrolmentoutput, array('class'=>'dimmed_text')); 204 } else { 205 $enrolmentoutput = html_writer::tag('span', $enrolmentoutput); 206 } 207 foreach ($ue['actions'] as $action) { 208 $enrolmentoutput .= $this->render($action); 209 } 210 $output .= html_writer::tag('div', $enrolmentoutput, array('class'=>'enrolment')); 211 } 212 return $output; 213 } 214 215 /** 216 * Renders a user enrolment action 217 * @param user_enrolment_action $icon 218 * @return string 219 */ 220 protected function render_user_enrolment_action(user_enrolment_action $icon) { 221 return html_writer::link($icon->get_url(), $this->output->render($icon->get_icon()), $icon->get_attributes()); 222 } 223 } 224 225 /** 226 * Main course enrolment table 227 * 228 * This table is used to display the enrolment information for a course. 229 * It requires that a course enrolment manager be provided during constuct with 230 * provides all of the information for the table. 231 * The control then produces the table, the paging, and the associated JS actions 232 * for the page. 233 * 234 * @package core 235 * @subpackage enrol 236 * @copyright 2010 Sam Hemelryk 237 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 238 */ 239 class course_enrolment_table extends html_table implements renderable { 240 241 /** 242 * The get/post variable that is used to identify the page. 243 * Default: page 244 */ 245 const PAGEVAR = 'page'; 246 247 /** 248 * The get/post variable to is used to identify the number of items to display 249 * per page. 250 * Default: perpage 251 */ 252 const PERPAGEVAR = 'perpage'; 253 254 /** 255 * The get/post variable that is used to identify the sort field for the table. 256 * Default: sort 257 */ 258 const SORTVAR = 'sort'; 259 260 /** 261 * The get/post variable that is used to identify the sort direction for the table. 262 * Default: dir 263 */ 264 const SORTDIRECTIONVAR = 'dir'; 265 266 /** 267 * The default number of items per page. 268 * Default: 100 269 */ 270 const DEFAULTPERPAGE = 100; 271 272 /** 273 * The default sort, options are course_enrolment_table::$sortablefields 274 * Default: lastname 275 */ 276 const DEFAULTSORT = 'lastname'; 277 278 /** 279 * The default direction 280 * Default: ASC 281 */ 282 const DEFAULTSORTDIRECTION = 'ASC'; 283 284 /** 285 * The current page, starting from 0 286 * @var int 287 */ 288 public $page = 0; 289 290 /** 291 * The total number of pages 292 * @var int 293 */ 294 public $pages = 0; 295 296 /** 297 * The number of items to display per page 298 * @var int 299 */ 300 public $perpage = 0; 301 302 /** 303 * The sort field for this table, should be one of course_enrolment_table::$sortablefields 304 * @var string 305 */ 306 public $sort; 307 308 /** 309 * The sort direction, either ASC or DESC 310 * @var string 311 */ 312 public $sortdirection; 313 314 /** 315 * The course manager this table is displaying for 316 * @var course_enrolment_manager 317 */ 318 protected $manager; 319 320 /** 321 * The paging bar that controls the paging for this table 322 * @var paging_bar 323 */ 324 protected $pagingbar = null; 325 326 /** 327 * The total number of users enrolled in the course 328 * @var int 329 */ 330 protected $totalusers = null; 331 332 /** 333 * The users enrolled in this course 334 * @var array 335 */ 336 protected $users = null; 337 338 /** 339 * The fields for this table 340 * @var array 341 */ 342 protected $fields = array(); 343 344 /** 345 * An array of bulk user enrolment operations 346 * @var array 347 */ 348 protected $bulkoperations = array(); 349 350 /** 351 * An array of sortable fields 352 * @static 353 * @var array 354 */ 355 protected static $sortablefields = array('firstname', 'lastname', 'firstnamephonetic', 'lastnamephonetic', 'middlename', 356 'alternatename', 'username', 'idnumber', 'email', 'phone1', 'phone2', 357 'institution', 'department', 'lastaccess', 'lastcourseaccess'); 358 359 /** 360 * Constructs the table 361 * 362 * @param course_enrolment_manager $manager 363 */ 364 public function __construct(course_enrolment_manager $manager) { 365 366 $this->manager = $manager; 367 368 $this->page = optional_param(self::PAGEVAR, 0, PARAM_INT); 369 $this->perpage = optional_param(self::PERPAGEVAR, self::DEFAULTPERPAGE, PARAM_INT); 370 $this->sort = optional_param(self::SORTVAR, self::DEFAULTSORT, PARAM_ALPHANUM); 371 $this->sortdirection = optional_param(self::SORTDIRECTIONVAR, self::DEFAULTSORTDIRECTION, PARAM_ALPHA); 372 373 $this->attributes = array('class' => 'userenrolment table-striped'); 374 if (!in_array($this->sort, self::$sortablefields)) { 375 $this->sort = self::DEFAULTSORT; 376 } 377 if ($this->page < 0) { 378 $this->page = 0; 379 } 380 if ($this->sortdirection !== 'ASC' && $this->sortdirection !== 'DESC') { 381 $this->sortdirection = self::DEFAULTSORTDIRECTION; 382 } 383 384 $this->id = html_writer::random_id(); 385 386 // Collect the bulk operations for the currently filtered plugin if there is one. 387 $plugin = $manager->get_filtered_enrolment_plugin(); 388 if ($plugin and enrol_is_enabled($plugin->get_name())) { 389 $this->bulkoperations = $plugin->get_bulk_operations($manager); 390 } 391 } 392 393 /** 394 * Returns an array of enrol_user_buttons that are created by the different 395 * enrolment plugins available. 396 * 397 * @return array 398 */ 399 public function get_manual_enrol_buttons() { 400 return $this->manager->get_manual_enrol_buttons(); 401 } 402 403 /** 404 * Gets the sort direction for a given field 405 * 406 * @param string $field 407 * @return string ASC or DESC 408 */ 409 public function get_field_sort_direction($field) { 410 if ($field == $this->sort) { 411 return ($this->sortdirection == 'ASC')?'DESC':'ASC'; 412 } 413 return self::DEFAULTSORTDIRECTION; 414 } 415 416 /** 417 * Sets the fields for this table. These get added to the tables head as well. 418 * 419 * You can also use a multi dimensional array for this to have multiple fields 420 * in a single column 421 * 422 * @param array $fields An array of fields to set 423 * @param string $output 424 */ 425 public function set_fields($fields, $output) { 426 $this->fields = $fields; 427 $this->head = array(); 428 $this->colclasses = array(); 429 $this->align = array(); 430 $url = $this->manager->get_moodlepage()->url; 431 432 if (!empty($this->bulkoperations)) { 433 // If there are bulk operations add a column for checkboxes. 434 $this->head[] = ''; 435 $this->colclasses[] = 'field col_bulkops'; 436 } 437 438 foreach ($fields as $name => $label) { 439 $newlabel = ''; 440 if (is_array($label)) { 441 $bits = array(); 442 foreach ($label as $n => $l) { 443 if ($l === false) { 444 continue; 445 } 446 if (!in_array($n, self::$sortablefields)) { 447 $bits[] = $l; 448 } else { 449 $sorturl = new moodle_url($url, array(self::SORTVAR => $n, self::SORTDIRECTIONVAR => $this->get_field_sort_direction($n))); 450 $link = html_writer::link($sorturl, $fields[$name][$n]); 451 if ($this->sort == $n) { 452 $link .= $this->get_direction_icon($output, $n); 453 } 454 $bits[] = html_writer::tag('span', $link, array('class'=>'subheading_'.$n)); 455 456 } 457 } 458 $newlabel = join(' / ', $bits); 459 } else { 460 if (!in_array($name, self::$sortablefields)) { 461 $newlabel = $label; 462 } else { 463 $sorturl = new moodle_url($url, array(self::SORTVAR => $name, self::SORTDIRECTIONVAR => $this->get_field_sort_direction($name))); 464 $newlabel = html_writer::link($sorturl, $fields[$name]); 465 if ($this->sort == $name) { 466 $newlabel .= $this->get_direction_icon($output, $name); 467 } 468 } 469 } 470 $this->head[] = $newlabel; 471 $this->colclasses[] = 'field col_'.$name; 472 } 473 } 474 /** 475 * Sets the total number of users 476 * 477 * @param int $totalusers 478 */ 479 public function set_total_users($totalusers) { 480 $this->totalusers = $totalusers; 481 $this->pages = ceil($this->totalusers / $this->perpage); 482 if ($this->page > $this->pages) { 483 $this->page = $this->pages; 484 } 485 } 486 /** 487 * Sets the users for this table 488 * 489 * @param array $users 490 * @return void 491 */ 492 public function set_users(array $users) { 493 $this->users = $users; 494 $hasbulkops = !empty($this->bulkoperations); 495 foreach ($users as $userid=>$user) { 496 $user = (array)$user; 497 $row = new html_table_row(); 498 $row->attributes = array('class' => 'userinforow'); 499 $row->id = 'user_'.$userid; 500 $row->cells = array(); 501 if ($hasbulkops) { 502 // Add a checkbox into the first column. 503 $input = html_writer::empty_tag('input', array('type' => 'checkbox', 'name' => 'bulkuser[]', 'value' => $userid)); 504 $row->cells[] = new html_table_cell($input); 505 } 506 foreach ($this->fields as $field => $label) { 507 if (is_array($label)) { 508 $bits = array(); 509 foreach (array_keys($label) as $subfield) { 510 if (array_key_exists($subfield, $user)) { 511 $bits[] = html_writer::tag('div', $user[$subfield], array('class'=>'subfield subfield_'.$subfield)); 512 } 513 } 514 if (empty($bits)) { 515 $bits[] = ' '; 516 } 517 $row->cells[] = new html_table_cell(join(' ', $bits)); 518 } else { 519 if (!array_key_exists($field, $user)) { 520 $user[$field] = ' '; 521 } 522 $row->cells[] = new html_table_cell($user[$field]); 523 } 524 } 525 $this->data[] = $row; 526 } 527 } 528 529 public function initialise_javascript() { 530 if (has_capability('moodle/role:assign', $this->manager->get_context())) { 531 $this->manager->get_moodlepage()->requires->strings_for_js(array( 532 'assignroles', 533 'confirmunassign', 534 'confirmunassigntitle', 535 'confirmunassignyes', 536 'confirmunassignno' 537 ), 'role'); 538 $modules = array('moodle-enrol-rolemanager', 'moodle-enrol-rolemanager-skin'); 539 $function = 'M.enrol.rolemanager.init'; 540 $arguments = array( 541 'containerId'=>$this->id, 542 'userIds'=>array_keys($this->users), 543 'courseId'=>$this->manager->get_course()->id, 544 'otherusers'=>isset($this->otherusers)); 545 $this->manager->get_moodlepage()->requires->yui_module($modules, $function, array($arguments)); 546 } 547 } 548 549 /** 550 * Gets the paging bar instance for this table 551 * 552 * @return paging_bar 553 */ 554 public function get_paging_bar() { 555 if ($this->pagingbar == null) { 556 $this->pagingbar = new paging_bar($this->totalusers, $this->page, $this->perpage, $this->manager->get_moodlepage()->url, self::PAGEVAR); 557 } 558 return $this->pagingbar; 559 } 560 561 /** 562 * Gets the direction icon for the sortable field within this table 563 * 564 * @param core_renderer $output 565 * @param string $field 566 * @return string 567 */ 568 protected function get_direction_icon($output, $field) { 569 $direction = self::DEFAULTSORTDIRECTION; 570 if ($this->sort == $field) { 571 $direction = $this->sortdirection; 572 } 573 if ($direction === 'ASC') { 574 return $output->pix_icon('t/sort_asc', get_string('sort')); 575 } else { 576 return $output->pix_icon('t/sort_desc', get_string('sort')); 577 } 578 } 579 580 /** 581 * Gets the params that will need to be added to the url in order to return to this page. 582 * 583 * @return array 584 */ 585 public function get_url_params() { 586 return array( 587 self::PAGEVAR => $this->page, 588 self::PERPAGEVAR => $this->perpage, 589 self::SORTVAR => $this->sort, 590 self::SORTDIRECTIONVAR => $this->sortdirection 591 ); 592 } 593 594 /** 595 * Returns an array of URL params for both the table and the manager. 596 * 597 * @return array 598 */ 599 public function get_combined_url_params() { 600 return $this->get_url_params() + $this->manager->get_url_params(); 601 } 602 603 /** 604 * Sets the bulk operations for this table. 605 * 606 * @param array $bulkoperations 607 */ 608 public function set_bulk_user_enrolment_operations(array $bulkoperations) { 609 $this->bulkoperations = $bulkoperations; 610 } 611 612 /** 613 * Returns an array of bulk operations. 614 * 615 * @return array 616 */ 617 public function get_bulk_user_enrolment_operations() { 618 return $this->bulkoperations; 619 } 620 621 /** 622 * Returns true fi the table is aware of any bulk operations that can be performed on users 623 * selected from the currently filtered enrolment plugins. 624 * 625 * @return bool 626 */ 627 public function has_bulk_user_enrolment_operations() { 628 return !empty($this->bulkoperations); 629 } 630 } 631 632 /** 633 * Table control used for enrolled users 634 * 635 * @copyright 2010 Sam Hemelryk 636 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 637 */ 638 class course_enrolment_users_table extends course_enrolment_table { 639 640 } 641 642 /** 643 * Table used for other users 644 * 645 * Other users are users who have roles but are not enrolled. 646 * 647 * @copyright 2010 Sam Hemelryk 648 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 649 */ 650 class course_enrolment_other_users_table extends course_enrolment_table { 651 652 public $otherusers = true; 653 654 /** 655 * Constructs the table 656 * 657 * @param course_enrolment_manager $manager 658 */ 659 public function __construct(course_enrolment_manager $manager) { 660 parent::__construct($manager); 661 $this->attributes = array('class'=>'userenrolment otheruserenrolment'); 662 } 663 664 /** 665 * Gets a button to search users and assign them roles in the course. 666 * 667 * @staticvar int $count 668 * @param int $page 669 * @return single_button 670 */ 671 public function get_user_search_button() { 672 static $count = 0; 673 if (!has_capability('moodle/role:assign', $this->manager->get_context())) { 674 return false; 675 } 676 $count++; 677 $url = new moodle_url('/admin/roles/assign.php', array('contextid'=>$this->manager->get_context()->id, 'sesskey'=>sesskey())); 678 $control = new single_button($url, get_string('assignroles', 'role'), 'get'); 679 $control->class = 'singlebutton assignuserrole instance'.$count; 680 if ($count == 1) { 681 $this->manager->get_moodlepage()->requires->strings_for_js(array( 682 'ajaxoneuserfound', 683 'ajaxxusersfound', 684 'ajaxxmoreusersfound', 685 'ajaxnext25', 686 'enrol', 687 'enrolmentoptions', 688 'enrolusers', 689 'enrolxusers', 690 'errajaxfailedenrol', 691 'errajaxsearch', 692 'foundxcohorts', 693 'none', 694 'usersearch', 695 'unlimitedduration', 696 'startdatetoday', 697 'durationdays', 698 'enrolperiod'), 'enrol'); 699 $this->manager->get_moodlepage()->requires->string_for_js('assignrole', 'role'); 700 701 $modules = array('moodle-enrol-otherusersmanager', 'moodle-enrol-otherusersmanager-skin'); 702 $function = 'M.enrol.otherusersmanager.init'; 703 $arguments = array( 704 'courseId'=> $this->manager->get_course()->id, 705 'ajaxUrl' => '/enrol/ajax.php', 706 'url' => $this->manager->get_moodlepage()->url->out(false)); 707 $this->manager->get_moodlepage()->requires->yui_module($modules, $function, array($arguments)); 708 } 709 return $control; 710 } 711 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body