[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Course and category management helper class. 19 * 20 * @package core_course 21 * @copyright 2013 Sam Hemelryk 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_course\management; 26 27 defined('MOODLE_INTERNAL') || die; 28 29 /** 30 * Course and category management interface helper class. 31 * 32 * This class provides methods useful to the course and category management interfaces. 33 * Many of the methods on this class are static and serve one of two purposes. 34 * 1. encapsulate functionality in an effort to ensure minimal changes between the different 35 * methods of interaction. Specifically browser, AJAX and webservice. 36 * 2. abstract logic for acquiring actions away from output so that renderers may use them without 37 * having to include any logic or capability checks. 38 * 39 * @package core_course 40 * @copyright 2013 Sam Hemelryk 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 class helper { 44 45 /** 46 * The expanded category structure if its already being loaded from the cache. 47 * @var null|array 48 */ 49 protected static $expandedcategories = null; 50 51 /** 52 * Returns course details in an array ready to be printed. 53 * 54 * @global \moodle_database $DB 55 * @param \course_in_list $course 56 * @return array 57 */ 58 public static function get_course_detail_array(\course_in_list $course) { 59 global $DB; 60 61 $canaccess = $course->can_access(); 62 63 $format = \course_get_format($course->id); 64 $modinfo = \get_fast_modinfo($course->id); 65 $modules = $modinfo->get_used_module_names(); 66 $sections = array(); 67 if ($format->uses_sections()) { 68 foreach ($modinfo->get_section_info_all() as $section) { 69 if ($section->uservisible) { 70 $sections[] = $format->get_section_name($section); 71 } 72 } 73 } 74 75 $category = \coursecat::get($course->category); 76 $categoryurl = new \moodle_url('/course/management.php', array('categoryid' => $course->category)); 77 $categoryname = $category->get_formatted_name(); 78 79 $details = array( 80 'fullname' => array( 81 'key' => \get_string('fullname'), 82 'value' => $course->get_formatted_fullname() 83 ), 84 'shortname' => array( 85 'key' => \get_string('shortname'), 86 'value' => $course->get_formatted_shortname() 87 ), 88 'idnumber' => array( 89 'key' => \get_string('idnumber'), 90 'value' => s($course->idnumber) 91 ), 92 'category' => array( 93 'key' => \get_string('category'), 94 'value' => \html_writer::link($categoryurl, $categoryname) 95 ) 96 ); 97 if (has_capability('moodle/site:accessallgroups', $course->get_context())) { 98 $groups = \groups_get_course_data($course->id); 99 $details += array( 100 'groupings' => array( 101 'key' => \get_string('groupings', 'group'), 102 'value' => count($groups->groupings) 103 ), 104 'groups' => array( 105 'key' => \get_string('groups'), 106 'value' => count($groups->groups) 107 ) 108 ); 109 } 110 if ($canaccess) { 111 $names = \role_get_names($course->get_context()); 112 $sql = 'SELECT ra.roleid, COUNT(ra.id) AS rolecount 113 FROM {role_assignments} ra 114 WHERE ra.contextid = :contextid 115 GROUP BY ra.roleid'; 116 $rolecounts = $DB->get_records_sql($sql, array('contextid' => $course->get_context()->id)); 117 $roledetails = array(); 118 foreach ($rolecounts as $result) { 119 $a = new \stdClass; 120 $a->role = $names[$result->roleid]->localname; 121 $a->count = $result->rolecount; 122 $roledetails[] = \get_string('assignedrolecount', 'moodle', $a); 123 } 124 125 $details['roleassignments'] = array( 126 'key' => \get_string('roleassignments'), 127 'value' => join('<br />', $roledetails) 128 ); 129 } 130 if ($course->can_review_enrolments()) { 131 $enrolmentlines = array(); 132 $instances = \enrol_get_instances($course->id, true); 133 $plugins = \enrol_get_plugins(true); 134 foreach ($instances as $instance) { 135 if (!isset($plugins[$instance->enrol])) { 136 // Weird. 137 continue; 138 } 139 $plugin = $plugins[$instance->enrol]; 140 $enrolmentlines[] = $plugin->get_instance_name($instance); 141 } 142 $details['enrolmentmethods'] = array( 143 'key' => \get_string('enrolmentmethods'), 144 'value' => join('<br />', $enrolmentlines) 145 ); 146 } 147 if ($canaccess) { 148 $details['format'] = array( 149 'key' => \get_string('format'), 150 'value' => \course_get_format($course)->get_format_name() 151 ); 152 $details['sections'] = array( 153 'key' => \get_string('sections'), 154 'value' => join('<br />', $sections) 155 ); 156 $details['modulesused'] = array( 157 'key' => \get_string('modulesused'), 158 'value' => join('<br />', $modules) 159 ); 160 } 161 return $details; 162 } 163 164 /** 165 * Returns an array of actions that can be performed upon a category being shown in a list. 166 * 167 * @param \coursecat $category 168 * @return array 169 */ 170 public static function get_category_listitem_actions(\coursecat $category) { 171 $baseurl = new \moodle_url('/course/management.php', array('categoryid' => $category->id, 'sesskey' => \sesskey())); 172 $actions = array(); 173 // Edit. 174 if ($category->can_edit()) { 175 $actions['edit'] = array( 176 'url' => new \moodle_url('/course/editcategory.php', array('id' => $category->id)), 177 'icon' => new \pix_icon('t/edit', new \lang_string('edit')), 178 'string' => new \lang_string('edit') 179 ); 180 } 181 182 // Show/Hide. 183 if ($category->can_change_visibility()) { 184 // We always show both icons and then just toggle the display of the invalid option with CSS. 185 $actions['hide'] = array( 186 'url' => new \moodle_url($baseurl, array('action' => 'hidecategory')), 187 'icon' => new \pix_icon('t/hide', new \lang_string('hide')), 188 'string' => new \lang_string('hide') 189 ); 190 $actions['show'] = array( 191 'url' => new \moodle_url($baseurl, array('action' => 'showcategory')), 192 'icon' => new \pix_icon('t/show', new \lang_string('show')), 193 'string' => new \lang_string('show') 194 ); 195 } 196 197 // Move up/down. 198 if ($category->can_change_sortorder()) { 199 $actions['moveup'] = array( 200 'url' => new \moodle_url($baseurl, array('action' => 'movecategoryup')), 201 'icon' => new \pix_icon('t/up', new \lang_string('up')), 202 'string' => new \lang_string('up') 203 ); 204 $actions['movedown'] = array( 205 'url' => new \moodle_url($baseurl, array('action' => 'movecategorydown')), 206 'icon' => new \pix_icon('t/down', new \lang_string('down')), 207 'string' => new \lang_string('down') 208 ); 209 } 210 211 if ($category->can_create_subcategory()) { 212 $actions['createnewsubcategory'] = array( 213 'url' => new \moodle_url('/course/editcategory.php', array('parent' => $category->id)), 214 'icon' => new \pix_icon('i/withsubcat', new \lang_string('createnewsubcategory')), 215 'string' => new \lang_string('createnewsubcategory') 216 ); 217 } 218 219 // Resort. 220 if ($category->can_resort_subcategories() && $category->has_children()) { 221 $actions['resortbyname'] = array( 222 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'name')), 223 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 224 'string' => new \lang_string('resortsubcategoriesby', 'moodle' , get_string('categoryname')) 225 ); 226 $actions['resortbynamedesc'] = array( 227 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'namedesc')), 228 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 229 'string' => new \lang_string('resortsubcategoriesbyreverse', 'moodle', get_string('categoryname')) 230 ); 231 $actions['resortbyidnumber'] = array( 232 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'idnumber')), 233 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 234 'string' => new \lang_string('resortsubcategoriesby', 'moodle', get_string('idnumbercoursecategory')) 235 ); 236 $actions['resortbyidnumberdesc'] = array( 237 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'idnumberdesc')), 238 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 239 'string' => new \lang_string('resortsubcategoriesbyreverse', 'moodle', get_string('idnumbercoursecategory')) 240 ); 241 } 242 243 // Delete. 244 if ($category->can_delete_full()) { 245 $actions['delete'] = array( 246 'url' => new \moodle_url($baseurl, array('action' => 'deletecategory')), 247 'icon' => new \pix_icon('t/delete', new \lang_string('delete')), 248 'string' => new \lang_string('delete') 249 ); 250 } 251 252 // Roles. 253 if ($category->can_review_roles()) { 254 $actions['assignroles'] = array( 255 'url' => new \moodle_url('/admin/roles/assign.php', array('contextid' => $category->get_context()->id, 256 'return' => 'management')), 257 'icon' => new \pix_icon('t/assignroles', new \lang_string('assignroles', 'role')), 258 'string' => new \lang_string('assignroles', 'role') 259 ); 260 } 261 262 // Permissions. 263 if ($category->can_review_permissions()) { 264 $actions['permissions'] = array( 265 'url' => new \moodle_url('/admin/roles/permissions.php', array('contextid' => $category->get_context()->id, 266 'return' => 'management')), 267 'icon' => new \pix_icon('i/permissions', new \lang_string('permissions', 'role')), 268 'string' => new \lang_string('permissions', 'role') 269 ); 270 } 271 272 // Cohorts. 273 if ($category->can_review_cohorts()) { 274 $actions['cohorts'] = array( 275 'url' => new \moodle_url('/cohort/index.php', array('contextid' => $category->get_context()->id)), 276 'icon' => new \pix_icon('t/cohort', new \lang_string('cohorts', 'cohort')), 277 'string' => new \lang_string('cohorts', 'cohort') 278 ); 279 } 280 281 // Filters. 282 if ($category->can_review_filters()) { 283 $actions['filters'] = array( 284 'url' => new \moodle_url('/filter/manage.php', array('contextid' => $category->get_context()->id, 285 'return' => 'management')), 286 'icon' => new \pix_icon('i/filter', new \lang_string('filters', 'admin')), 287 'string' => new \lang_string('filters', 'admin') 288 ); 289 } 290 291 if ($category->can_restore_courses_into()) { 292 $actions['restore'] = array( 293 'url' => new \moodle_url('/backup/restorefile.php', array('contextid' => $category->get_context()->id)), 294 'icon' => new \pix_icon('i/restore', new \lang_string('restorecourse', 'admin')), 295 'string' => new \lang_string('restorecourse', 'admin') 296 ); 297 } 298 299 return $actions; 300 } 301 302 /** 303 * Returns an array of actions for a course listitem. 304 * 305 * @param \coursecat $category 306 * @param \course_in_list $course 307 * @return string 308 */ 309 public static function get_course_listitem_actions(\coursecat $category, \course_in_list $course) { 310 $baseurl = new \moodle_url( 311 '/course/management.php', 312 array('courseid' => $course->id, 'categoryid' => $course->category, 'sesskey' => \sesskey()) 313 ); 314 $actions = array(); 315 // Edit. 316 if ($course->can_edit()) { 317 $actions[] = array( 318 'url' => new \moodle_url('/course/edit.php', array('id' => $course->id, 'returnto' => 'catmanage')), 319 'icon' => new \pix_icon('t/edit', \get_string('edit')), 320 'attributes' => array('class' => 'action-edit') 321 ); 322 } 323 // Delete. 324 if ($course->can_delete()) { 325 $actions[] = array( 326 'url' => new \moodle_url('/course/delete.php', array('id' => $course->id)), 327 'icon' => new \pix_icon('t/delete', \get_string('delete')), 328 'attributes' => array('class' => 'action-delete') 329 ); 330 } 331 // Show/Hide. 332 if ($course->can_change_visibility()) { 333 $actions[] = array( 334 'url' => new \moodle_url($baseurl, array('action' => 'hidecourse')), 335 'icon' => new \pix_icon('t/hide', \get_string('hide')), 336 'attributes' => array('data-action' => 'hide', 'class' => 'action-hide') 337 ); 338 $actions[] = array( 339 'url' => new \moodle_url($baseurl, array('action' => 'showcourse')), 340 'icon' => new \pix_icon('t/show', \get_string('show')), 341 'attributes' => array('data-action' => 'show', 'class' => 'action-show') 342 ); 343 } 344 // Move up/down. 345 if ($category->can_resort_courses()) { 346 $actions[] = array( 347 'url' => new \moodle_url($baseurl, array('action' => 'movecourseup')), 348 'icon' => new \pix_icon('t/up', \get_string('up')), 349 'attributes' => array('data-action' => 'moveup', 'class' => 'action-moveup') 350 ); 351 $actions[] = array( 352 'url' => new \moodle_url($baseurl, array('action' => 'movecoursedown')), 353 'icon' => new \pix_icon('t/down', \get_string('down')), 354 'attributes' => array('data-action' => 'movedown', 'class' => 'action-movedown') 355 ); 356 } 357 return $actions; 358 } 359 360 /** 361 * Returns an array of actions that can be performed on the course being displayed. 362 * 363 * @param \course_in_list $course 364 * @return array 365 */ 366 public static function get_course_detail_actions(\course_in_list $course) { 367 $params = array('courseid' => $course->id, 'categoryid' => $course->category, 'sesskey' => \sesskey()); 368 $baseurl = new \moodle_url('/course/management.php', $params); 369 $actions = array(); 370 // View. 371 if ($course->is_uservisible()) { 372 $actions['view'] = array( 373 'url' => new \moodle_url('/course/view.php', array('id' => $course->id)), 374 'string' => \get_string('view') 375 ); 376 } 377 // Edit. 378 if ($course->can_edit()) { 379 $actions['edit'] = array( 380 'url' => new \moodle_url('/course/edit.php', array('id' => $course->id)), 381 'string' => \get_string('edit') 382 ); 383 } 384 // Permissions. 385 if ($course->can_review_enrolments()) { 386 $actions['enrolledusers'] = array( 387 'url' => new \moodle_url('/enrol/users.php', array('id' => $course->id)), 388 'string' => \get_string('enrolledusers', 'enrol') 389 ); 390 } 391 // Delete. 392 if ($course->can_delete()) { 393 $actions['delete'] = array( 394 'url' => new \moodle_url('/course/delete.php', array('id' => $course->id)), 395 'string' => \get_string('delete') 396 ); 397 } 398 // Show/Hide. 399 if ($course->can_change_visibility()) { 400 if ($course->visible) { 401 $actions['hide'] = array( 402 'url' => new \moodle_url($baseurl, array('action' => 'hidecourse')), 403 'string' => \get_string('hide') 404 ); 405 } else { 406 $actions['show'] = array( 407 'url' => new \moodle_url($baseurl, array('action' => 'showcourse')), 408 'string' => \get_string('show') 409 ); 410 } 411 } 412 // Backup. 413 if ($course->can_backup()) { 414 $actions['backup'] = array( 415 'url' => new \moodle_url('/backup/backup.php', array('id' => $course->id)), 416 'string' => \get_string('backup') 417 ); 418 } 419 // Restore. 420 if ($course->can_restore()) { 421 $actions['restore'] = array( 422 'url' => new \moodle_url('/backup/restorefile.php', array('contextid' => $course->get_context()->id)), 423 'string' => \get_string('restore') 424 ); 425 } 426 return $actions; 427 } 428 429 /** 430 * Resorts the courses within a category moving the given course up by one. 431 * 432 * @param \course_in_list $course 433 * @param \coursecat $category 434 * @return bool 435 * @throws \moodle_exception 436 */ 437 public static function action_course_change_sortorder_up_one(\course_in_list $course, \coursecat $category) { 438 if (!$category->can_resort_courses()) { 439 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort'); 440 } 441 return \course_change_sortorder_by_one($course, true); 442 } 443 444 /** 445 * Resorts the courses within a category moving the given course down by one. 446 * 447 * @param \course_in_list $course 448 * @param \coursecat $category 449 * @return bool 450 * @throws \moodle_exception 451 */ 452 public static function action_course_change_sortorder_down_one(\course_in_list $course, \coursecat $category) { 453 if (!$category->can_resort_courses()) { 454 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort'); 455 } 456 return \course_change_sortorder_by_one($course, false); 457 } 458 459 /** 460 * Resorts the courses within a category moving the given course up by one. 461 * 462 * @global \moodle_database $DB 463 * @param int|\stdClass $courserecordorid 464 * @return bool 465 */ 466 public static function action_course_change_sortorder_up_one_by_record($courserecordorid) { 467 if (is_int($courserecordorid)) { 468 $courserecordorid = get_course($courserecordorid); 469 } 470 $course = new \course_in_list($courserecordorid); 471 $category = \coursecat::get($course->category); 472 return self::action_course_change_sortorder_up_one($course, $category); 473 } 474 475 /** 476 * Resorts the courses within a category moving the given course down by one. 477 * 478 * @global \moodle_database $DB 479 * @param int|\stdClass $courserecordorid 480 * @return bool 481 */ 482 public static function action_course_change_sortorder_down_one_by_record($courserecordorid) { 483 if (is_int($courserecordorid)) { 484 $courserecordorid = get_course($courserecordorid); 485 } 486 $course = new \course_in_list($courserecordorid); 487 $category = \coursecat::get($course->category); 488 return self::action_course_change_sortorder_down_one($course, $category); 489 } 490 491 /** 492 * Changes the sort order so that the first course appears after the second course. 493 * 494 * @param int|\stdClass $courserecordorid 495 * @param int $moveaftercourseid 496 * @return bool 497 * @throws \moodle_exception 498 */ 499 public static function action_course_change_sortorder_after_course($courserecordorid, $moveaftercourseid) { 500 $course = \get_course($courserecordorid); 501 $category = \coursecat::get($course->category); 502 if (!$category->can_resort_courses()) { 503 $url = '/course/management.php?categoryid='.$course->category; 504 throw new \moodle_exception('nopermissions', 'error', $url, \get_string('resortcourses', 'moodle')); 505 } 506 return \course_change_sortorder_after_course($course, $moveaftercourseid); 507 } 508 509 /** 510 * Makes a course visible given a \course_in_list object. 511 * 512 * @param \course_in_list $course 513 * @return bool 514 * @throws \moodle_exception 515 */ 516 public static function action_course_show(\course_in_list $course) { 517 if (!$course->can_change_visibility()) { 518 throw new \moodle_exception('permissiondenied', 'error', '', null, 'course_in_list::can_change_visbility'); 519 } 520 return course_change_visibility($course->id, true); 521 } 522 523 /** 524 * Makes a course hidden given a \course_in_list object. 525 * 526 * @param \course_in_list $course 527 * @return bool 528 * @throws \moodle_exception 529 */ 530 public static function action_course_hide(\course_in_list $course) { 531 if (!$course->can_change_visibility()) { 532 throw new \moodle_exception('permissiondenied', 'error', '', null, 'course_in_list::can_change_visbility'); 533 } 534 return course_change_visibility($course->id, false); 535 } 536 537 /** 538 * Makes a course visible given a course id or a database record. 539 * 540 * @global \moodle_database $DB 541 * @param int|\stdClass $courserecordorid 542 * @return bool 543 */ 544 public static function action_course_show_by_record($courserecordorid) { 545 if (is_int($courserecordorid)) { 546 $courserecordorid = get_course($courserecordorid); 547 } 548 $course = new \course_in_list($courserecordorid); 549 return self::action_course_show($course); 550 } 551 552 /** 553 * Makes a course hidden given a course id or a database record. 554 * 555 * @global \moodle_database $DB 556 * @param int|\stdClass $courserecordorid 557 * @return bool 558 */ 559 public static function action_course_hide_by_record($courserecordorid) { 560 if (is_int($courserecordorid)) { 561 $courserecordorid = get_course($courserecordorid); 562 } 563 $course = new \course_in_list($courserecordorid); 564 return self::action_course_hide($course); 565 } 566 567 /** 568 * Resort a categories subcategories shifting the given category up one. 569 * 570 * @param \coursecat $category 571 * @return bool 572 * @throws \moodle_exception 573 */ 574 public static function action_category_change_sortorder_up_one(\coursecat $category) { 575 if (!$category->can_change_sortorder()) { 576 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_sortorder'); 577 } 578 return $category->change_sortorder_by_one(true); 579 } 580 581 /** 582 * Resort a categories subcategories shifting the given category down one. 583 * 584 * @param \coursecat $category 585 * @return bool 586 * @throws \moodle_exception 587 */ 588 public static function action_category_change_sortorder_down_one(\coursecat $category) { 589 if (!$category->can_change_sortorder()) { 590 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_sortorder'); 591 } 592 return $category->change_sortorder_by_one(false); 593 } 594 595 /** 596 * Resort a categories subcategories shifting the given category up one. 597 * 598 * @param int $categoryid 599 * @return bool 600 */ 601 public static function action_category_change_sortorder_up_one_by_id($categoryid) { 602 $category = \coursecat::get($categoryid); 603 return self::action_category_change_sortorder_up_one($category); 604 } 605 606 /** 607 * Resort a categories subcategories shifting the given category down one. 608 * 609 * @param int $categoryid 610 * @return bool 611 */ 612 public static function action_category_change_sortorder_down_one_by_id($categoryid) { 613 $category = \coursecat::get($categoryid); 614 return self::action_category_change_sortorder_down_one($category); 615 } 616 617 /** 618 * Makes a category hidden given a \coursecat record. 619 * 620 * @param \coursecat $category 621 * @return bool 622 * @throws \moodle_exception 623 */ 624 public static function action_category_hide(\coursecat $category) { 625 if (!$category->can_change_visibility()) { 626 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_visbility'); 627 } 628 $category->hide(); 629 return true; 630 } 631 632 /** 633 * Makes a category visible given a \coursecat record. 634 * 635 * @param \coursecat $category 636 * @return bool 637 * @throws \moodle_exception 638 */ 639 public static function action_category_show(\coursecat $category) { 640 if (!$category->can_change_visibility()) { 641 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_visbility'); 642 } 643 $category->show(); 644 return true; 645 } 646 647 /** 648 * Makes a category visible given a \coursecat id or database record. 649 * 650 * @param int|\stdClass $categoryid 651 * @return bool 652 */ 653 public static function action_category_show_by_id($categoryid) { 654 return self::action_category_show(\coursecat::get($categoryid)); 655 } 656 657 /** 658 * Makes a category hidden given a \coursecat id or database record. 659 * 660 * @param int|\stdClass $categoryid 661 * @return bool 662 */ 663 public static function action_category_hide_by_id($categoryid) { 664 return self::action_category_hide(\coursecat::get($categoryid)); 665 } 666 667 /** 668 * Resorts the sub categories of the given category. 669 * 670 * @param \coursecat $category 671 * @param string $sort One of idnumber or name. 672 * @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later. 673 * @return bool 674 * @throws \moodle_exception 675 */ 676 public static function action_category_resort_subcategories(\coursecat $category, $sort, $cleanup = true) { 677 if (!$category->can_resort_subcategories()) { 678 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort'); 679 } 680 return $category->resort_subcategories($sort, $cleanup); 681 } 682 683 /** 684 * Resorts the courses within the given category. 685 * 686 * @param \coursecat $category 687 * @param string $sort One of fullname, shortname or idnumber 688 * @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later. 689 * @return bool 690 * @throws \moodle_exception 691 */ 692 public static function action_category_resort_courses(\coursecat $category, $sort, $cleanup = true) { 693 if (!$category->can_resort_courses()) { 694 throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort'); 695 } 696 return $category->resort_courses($sort, $cleanup); 697 } 698 699 /** 700 * Moves courses out of one category and into a new category. 701 * 702 * @param \coursecat $oldcategory The category we are moving courses out of. 703 * @param \coursecat $newcategory The category we are moving courses into. 704 * @param array $courseids The ID's of the courses we want to move. 705 * @return bool True on success. 706 * @throws \moodle_exception 707 */ 708 public static function action_category_move_courses_into(\coursecat $oldcategory, \coursecat $newcategory, array $courseids) { 709 global $DB; 710 711 list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED); 712 $params['categoryid'] = $oldcategory->id; 713 $sql = "SELECT c.id FROM {course} c WHERE c.id {$where} AND c.category <> :categoryid"; 714 if ($DB->record_exists_sql($sql, $params)) { 715 // Likely being tinkered with. 716 throw new \moodle_exception('coursedoesnotbelongtocategory'); 717 } 718 719 // All courses are currently within the old category. 720 return self::move_courses_into_category($newcategory, $courseids); 721 } 722 723 /** 724 * Returns the view modes for the management interface. 725 * @return array 726 */ 727 public static function get_management_viewmodes() { 728 return array( 729 'combined' => new \lang_string('categoriesandcoures'), 730 'categories' => new \lang_string('categories'), 731 'courses' => new \lang_string('courses') 732 ); 733 } 734 735 /** 736 * Search for courses with matching params. 737 * 738 * Please note that only one of search, blocklist, or modulelist can be specified at a time. 739 * Specifying more than one will result in only the first being used. 740 * 741 * @param string $search Words to search for. We search fullname, shortname, idnumber and summary. 742 * @param int $blocklist The ID of a block, courses will only be returned if they use this block. 743 * @param string $modulelist The name of a module (relates to database table name). Only courses containing this module 744 * will be returned. 745 * @param int $page The page number to display, starting at 0. 746 * @param int $perpage The number of courses to display per page. 747 * @return array 748 */ 749 public static function search_courses($search, $blocklist, $modulelist, $page = 0, $perpage = null) { 750 global $CFG; 751 752 if ($perpage === null) { 753 $perpage = $CFG->coursesperpage; 754 } 755 756 $searchcriteria = array(); 757 if (!empty($search)) { 758 $searchcriteria = array('search' => $search); 759 } else if (!empty($blocklist)) { 760 $searchcriteria = array('blocklist' => $blocklist); 761 } else if (!empty($modulelist)) { 762 $searchcriteria = array('modulelist' => $modulelist); 763 } 764 765 $courses = \coursecat::get(0)->search_courses($searchcriteria, array( 766 'recursive' => true, 767 'offset' => $page * $perpage, 768 'limit' => $perpage, 769 'sort' => array('fullname' => 1) 770 )); 771 $totalcount = \coursecat::get(0)->search_courses_count($searchcriteria, array('recursive' => true)); 772 773 return array($courses, \count($courses), $totalcount); 774 } 775 776 /** 777 * Moves one or more courses out of the category they are currently in and into a new category. 778 * 779 * This function works much the same way as action_category_move_courses_into however it allows courses from multiple 780 * categories to be moved into a single category. 781 * 782 * @param int|\coursecat $categoryorid The category to move them into. 783 * @param array|int $courseids An array of course id's or optionally just a single course id. 784 * @return bool True on success or false on failure. 785 * @throws \moodle_exception 786 */ 787 public static function move_courses_into_category($categoryorid, $courseids = array()) { 788 global $DB; 789 if (!is_array($courseids)) { 790 // Just a single course ID. 791 $courseids = array($courseids); 792 } 793 // Bulk move courses from one category to another. 794 if (count($courseids) === 0) { 795 return false; 796 } 797 if ($categoryorid instanceof \coursecat) { 798 $moveto = $categoryorid; 799 } else { 800 $moveto = \coursecat::get($categoryorid); 801 } 802 if (!$moveto->can_move_courses_out_of() || !$moveto->can_move_courses_into()) { 803 throw new \moodle_exception('cannotmovecourses'); 804 } 805 806 list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED); 807 $sql = "SELECT c.id, c.category FROM {course} c WHERE c.id {$where}"; 808 $courses = $DB->get_records_sql($sql, $params); 809 $checks = array(); 810 foreach ($courseids as $id) { 811 if (!isset($courses[$id])) { 812 throw new \moodle_exception('invalidcourseid'); 813 } 814 $catid = $courses[$id]->category; 815 if (!isset($checks[$catid])) { 816 $coursecat = \coursecat::get($catid); 817 $checks[$catid] = $coursecat->can_move_courses_out_of() && $coursecat->can_move_courses_into(); 818 } 819 if (!$checks[$catid]) { 820 throw new \moodle_exception('cannotmovecourses'); 821 } 822 } 823 return \move_courses($courseids, $moveto->id); 824 } 825 826 /** 827 * Returns an array of courseids and visiblity for all courses within the given category. 828 * @param int $categoryid 829 * @return array 830 */ 831 public static function get_category_courses_visibility($categoryid) { 832 global $DB; 833 $sql = "SELECT c.id, c.visible 834 FROM {course} c 835 WHERE c.category = :category"; 836 $params = array('category' => (int)$categoryid); 837 return $DB->get_records_sql($sql, $params); 838 } 839 840 /** 841 * Returns an array of all categoryids that have the given category as a parent and their visible value. 842 * @param int $categoryid 843 * @return array 844 */ 845 public static function get_category_children_visibility($categoryid) { 846 global $DB; 847 $category = \coursecat::get($categoryid); 848 $select = $DB->sql_like('path', ':path'); 849 $path = $category->path . '/%'; 850 851 $sql = "SELECT c.id, c.visible 852 FROM {course_categories} c 853 WHERE ".$select; 854 $params = array('path' => $path); 855 return $DB->get_records_sql($sql, $params); 856 } 857 858 /** 859 * Records when a category is expanded or collapsed so that when the user 860 * 861 * @param \coursecat $coursecat The category we're working with. 862 * @param bool $expanded True if the category is expanded now. 863 */ 864 public static function record_expanded_category(\coursecat $coursecat, $expanded = true) { 865 // If this ever changes we are going to reset it and reload the categories as required. 866 self::$expandedcategories = null; 867 $categoryid = $coursecat->id; 868 $path = $coursecat->get_parents(); 869 /* @var \cache_session $cache */ 870 $cache = \cache::make('core', 'userselections'); 871 $categories = $cache->get('categorymanagementexpanded'); 872 if (!is_array($categories)) { 873 if (!$expanded) { 874 // No categories recorded, nothing to remove. 875 return; 876 } 877 $categories = array(); 878 } 879 if ($expanded) { 880 $ref =& $categories; 881 foreach ($coursecat->get_parents() as $path) { 882 if (!isset($ref[$path]) || !is_array($ref[$path])) { 883 $ref[$path] = array(); 884 } 885 $ref =& $ref[$path]; 886 } 887 if (!isset($ref[$categoryid])) { 888 $ref[$categoryid] = true; 889 } 890 } else { 891 $found = true; 892 $ref =& $categories; 893 foreach ($coursecat->get_parents() as $path) { 894 if (!isset($ref[$path])) { 895 $found = false; 896 break; 897 } 898 $ref =& $ref[$path]; 899 } 900 if ($found) { 901 $ref[$categoryid] = null; 902 unset($ref[$categoryid]); 903 } 904 } 905 $cache->set('categorymanagementexpanded', $categories); 906 } 907 908 /** 909 * Returns the categories that should be expanded when displaying the interface. 910 * 911 * @param int|null $withpath If specified a path to require as the parent. 912 * @return \coursecat[] An array of Category ID's to expand. 913 */ 914 public static function get_expanded_categories($withpath = null) { 915 if (self::$expandedcategories === null) { 916 /* @var \cache_session $cache */ 917 $cache = \cache::make('core', 'userselections'); 918 self::$expandedcategories = $cache->get('categorymanagementexpanded'); 919 if (self::$expandedcategories === false) { 920 self::$expandedcategories = array(); 921 } 922 } 923 if (empty($withpath)) { 924 return array_keys(self::$expandedcategories); 925 } 926 $parents = explode('/', trim($withpath, '/')); 927 $ref =& self::$expandedcategories; 928 foreach ($parents as $parent) { 929 if (!isset($ref[$parent])) { 930 return array(); 931 } 932 $ref =& $ref[$parent]; 933 } 934 if (is_array($ref)) { 935 return array_keys($ref); 936 } else { 937 return array($parent); 938 } 939 } 940 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |