[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 /** 19 * External course API 20 * 21 * @package core_course 22 * @category external 23 * @copyright 2009 Petr Skodak 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die; 28 29 require_once("$CFG->libdir/externallib.php"); 30 31 /** 32 * Course external functions 33 * 34 * @package core_course 35 * @category external 36 * @copyright 2011 Jerome Mouneyrac 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 * @since Moodle 2.2 39 */ 40 class core_course_external extends external_api { 41 42 /** 43 * Returns description of method parameters 44 * 45 * @return external_function_parameters 46 * @since Moodle 2.2 47 */ 48 public static function get_course_contents_parameters() { 49 return new external_function_parameters( 50 array('courseid' => new external_value(PARAM_INT, 'course id'), 51 'options' => new external_multiple_structure ( 52 new external_single_structure( 53 array('name' => new external_value(PARAM_ALPHANUM, 'option name'), 54 'value' => new external_value(PARAM_RAW, 'the value of the option, this param is personaly validated in the external function.') 55 ) 56 ), 'Options, not used yet, might be used in later version', VALUE_DEFAULT, array()) 57 ) 58 ); 59 } 60 61 /** 62 * Get course contents 63 * 64 * @param int $courseid course id 65 * @param array $options These options are not used yet, might be used in later version 66 * @return array 67 * @since Moodle 2.2 68 */ 69 public static function get_course_contents($courseid, $options = array()) { 70 global $CFG, $DB; 71 require_once($CFG->dirroot . "/course/lib.php"); 72 73 //validate parameter 74 $params = self::validate_parameters(self::get_course_contents_parameters(), 75 array('courseid' => $courseid, 'options' => $options)); 76 77 //retrieve the course 78 $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST); 79 80 //check course format exist 81 if (!file_exists($CFG->dirroot . '/course/format/' . $course->format . '/lib.php')) { 82 throw new moodle_exception('cannotgetcoursecontents', 'webservice', '', null, get_string('courseformatnotfound', 'error', '', $course->format)); 83 } else { 84 require_once($CFG->dirroot . '/course/format/' . $course->format . '/lib.php'); 85 } 86 87 // now security checks 88 $context = context_course::instance($course->id, IGNORE_MISSING); 89 try { 90 self::validate_context($context); 91 } catch (Exception $e) { 92 $exceptionparam = new stdClass(); 93 $exceptionparam->message = $e->getMessage(); 94 $exceptionparam->courseid = $course->id; 95 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam); 96 } 97 98 $canupdatecourse = has_capability('moodle/course:update', $context); 99 100 //create return value 101 $coursecontents = array(); 102 103 if ($canupdatecourse or $course->visible 104 or has_capability('moodle/course:viewhiddencourses', $context)) { 105 106 //retrieve sections 107 $modinfo = get_fast_modinfo($course); 108 $sections = $modinfo->get_section_info_all(); 109 110 //for each sections (first displayed to last displayed) 111 $modinfosections = $modinfo->get_sections(); 112 foreach ($sections as $key => $section) { 113 114 if (!$section->uservisible) { 115 continue; 116 } 117 118 // reset $sectioncontents 119 $sectionvalues = array(); 120 $sectionvalues['id'] = $section->id; 121 $sectionvalues['name'] = get_section_name($course, $section); 122 $sectionvalues['visible'] = $section->visible; 123 list($sectionvalues['summary'], $sectionvalues['summaryformat']) = 124 external_format_text($section->summary, $section->summaryformat, 125 $context->id, 'course', 'section', $section->id); 126 $sectioncontents = array(); 127 128 //for each module of the section 129 if (!empty($modinfosections[$section->section])) { 130 foreach ($modinfosections[$section->section] as $cmid) { 131 $cm = $modinfo->cms[$cmid]; 132 133 // stop here if the module is not visible to the user 134 if (!$cm->uservisible) { 135 continue; 136 } 137 138 $module = array(); 139 140 //common info (for people being able to see the module or availability dates) 141 $module['id'] = $cm->id; 142 $module['name'] = format_string($cm->name, true); 143 $module['instance'] = $cm->instance; 144 $module['modname'] = $cm->modname; 145 $module['modplural'] = $cm->modplural; 146 $module['modicon'] = $cm->get_icon_url()->out(false); 147 $module['indent'] = $cm->indent; 148 149 $modcontext = context_module::instance($cm->id); 150 151 if (!empty($cm->showdescription) or $cm->modname == 'label') { 152 // We want to use the external format. However from reading get_formatted_content(), $cm->content format is always FORMAT_HTML. 153 list($module['description'], $descriptionformat) = external_format_text($cm->content, 154 FORMAT_HTML, $modcontext->id, $cm->modname, 'intro', $cm->id); 155 } 156 157 //url of the module 158 $url = $cm->url; 159 if ($url) { //labels don't have url 160 $module['url'] = $url->out(false); 161 } 162 163 $canviewhidden = has_capability('moodle/course:viewhiddenactivities', 164 context_module::instance($cm->id)); 165 //user that can view hidden module should know about the visibility 166 $module['visible'] = $cm->visible; 167 168 // Availability date (also send to user who can see hidden module). 169 if ($CFG->enableavailability && ($canviewhidden || $canupdatecourse)) { 170 $module['availability'] = $cm->availability; 171 } 172 173 $baseurl = 'webservice/pluginfile.php'; 174 175 //call $modulename_export_contents 176 //(each module callback take care about checking the capabilities) 177 require_once($CFG->dirroot . '/mod/' . $cm->modname . '/lib.php'); 178 $getcontentfunction = $cm->modname.'_export_contents'; 179 if (function_exists($getcontentfunction)) { 180 if ($contents = $getcontentfunction($cm, $baseurl)) { 181 $module['contents'] = $contents; 182 } 183 } 184 185 //assign result to $sectioncontents 186 $sectioncontents[] = $module; 187 188 } 189 } 190 $sectionvalues['modules'] = $sectioncontents; 191 192 // assign result to $coursecontents 193 $coursecontents[] = $sectionvalues; 194 } 195 } 196 return $coursecontents; 197 } 198 199 /** 200 * Returns description of method result value 201 * 202 * @return external_description 203 * @since Moodle 2.2 204 */ 205 public static function get_course_contents_returns() { 206 return new external_multiple_structure( 207 new external_single_structure( 208 array( 209 'id' => new external_value(PARAM_INT, 'Section ID'), 210 'name' => new external_value(PARAM_TEXT, 'Section name'), 211 'visible' => new external_value(PARAM_INT, 'is the section visible', VALUE_OPTIONAL), 212 'summary' => new external_value(PARAM_RAW, 'Section description'), 213 'summaryformat' => new external_format_value('summary'), 214 'modules' => new external_multiple_structure( 215 new external_single_structure( 216 array( 217 'id' => new external_value(PARAM_INT, 'activity id'), 218 'url' => new external_value(PARAM_URL, 'activity url', VALUE_OPTIONAL), 219 'name' => new external_value(PARAM_RAW, 'activity module name'), 220 'description' => new external_value(PARAM_RAW, 'activity description', VALUE_OPTIONAL), 221 'visible' => new external_value(PARAM_INT, 'is the module visible', VALUE_OPTIONAL), 222 'modicon' => new external_value(PARAM_URL, 'activity icon url'), 223 'modname' => new external_value(PARAM_PLUGIN, 'activity module type'), 224 'modplural' => new external_value(PARAM_TEXT, 'activity module plural name'), 225 'availability' => new external_value(PARAM_RAW, 'module availability settings', VALUE_OPTIONAL), 226 'indent' => new external_value(PARAM_INT, 'number of identation in the site'), 227 'contents' => new external_multiple_structure( 228 new external_single_structure( 229 array( 230 // content info 231 'type'=> new external_value(PARAM_TEXT, 'a file or a folder or external link'), 232 'filename'=> new external_value(PARAM_FILE, 'filename'), 233 'filepath'=> new external_value(PARAM_PATH, 'filepath'), 234 'filesize'=> new external_value(PARAM_INT, 'filesize'), 235 'fileurl' => new external_value(PARAM_URL, 'downloadable file url', VALUE_OPTIONAL), 236 'content' => new external_value(PARAM_RAW, 'Raw content, will be used when type is content', VALUE_OPTIONAL), 237 'timecreated' => new external_value(PARAM_INT, 'Time created'), 238 'timemodified' => new external_value(PARAM_INT, 'Time modified'), 239 'sortorder' => new external_value(PARAM_INT, 'Content sort order'), 240 241 // copyright related info 242 'userid' => new external_value(PARAM_INT, 'User who added this content to moodle'), 243 'author' => new external_value(PARAM_TEXT, 'Content owner'), 244 'license' => new external_value(PARAM_TEXT, 'Content license'), 245 ) 246 ), VALUE_DEFAULT, array() 247 ) 248 ) 249 ), 'list of module' 250 ) 251 ) 252 ) 253 ); 254 } 255 256 /** 257 * Returns description of method parameters 258 * 259 * @return external_function_parameters 260 * @since Moodle 2.3 261 */ 262 public static function get_courses_parameters() { 263 return new external_function_parameters( 264 array('options' => new external_single_structure( 265 array('ids' => new external_multiple_structure( 266 new external_value(PARAM_INT, 'Course id') 267 , 'List of course id. If empty return all courses 268 except front page course.', 269 VALUE_OPTIONAL) 270 ), 'options - operator OR is used', VALUE_DEFAULT, array()) 271 ) 272 ); 273 } 274 275 /** 276 * Get courses 277 * 278 * @param array $options It contains an array (list of ids) 279 * @return array 280 * @since Moodle 2.2 281 */ 282 public static function get_courses($options = array()) { 283 global $CFG, $DB; 284 require_once($CFG->dirroot . "/course/lib.php"); 285 286 //validate parameter 287 $params = self::validate_parameters(self::get_courses_parameters(), 288 array('options' => $options)); 289 290 //retrieve courses 291 if (!array_key_exists('ids', $params['options']) 292 or empty($params['options']['ids'])) { 293 $courses = $DB->get_records('course'); 294 } else { 295 $courses = $DB->get_records_list('course', 'id', $params['options']['ids']); 296 } 297 298 //create return value 299 $coursesinfo = array(); 300 foreach ($courses as $course) { 301 302 // now security checks 303 $context = context_course::instance($course->id, IGNORE_MISSING); 304 $courseformatoptions = course_get_format($course)->get_format_options(); 305 try { 306 self::validate_context($context); 307 } catch (Exception $e) { 308 $exceptionparam = new stdClass(); 309 $exceptionparam->message = $e->getMessage(); 310 $exceptionparam->courseid = $course->id; 311 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam); 312 } 313 require_capability('moodle/course:view', $context); 314 315 $courseinfo = array(); 316 $courseinfo['id'] = $course->id; 317 $courseinfo['fullname'] = $course->fullname; 318 $courseinfo['shortname'] = $course->shortname; 319 $courseinfo['categoryid'] = $course->category; 320 list($courseinfo['summary'], $courseinfo['summaryformat']) = 321 external_format_text($course->summary, $course->summaryformat, $context->id, 'course', 'summary', 0); 322 $courseinfo['format'] = $course->format; 323 $courseinfo['startdate'] = $course->startdate; 324 if (array_key_exists('numsections', $courseformatoptions)) { 325 // For backward-compartibility 326 $courseinfo['numsections'] = $courseformatoptions['numsections']; 327 } 328 329 //some field should be returned only if the user has update permission 330 $courseadmin = has_capability('moodle/course:update', $context); 331 if ($courseadmin) { 332 $courseinfo['categorysortorder'] = $course->sortorder; 333 $courseinfo['idnumber'] = $course->idnumber; 334 $courseinfo['showgrades'] = $course->showgrades; 335 $courseinfo['showreports'] = $course->showreports; 336 $courseinfo['newsitems'] = $course->newsitems; 337 $courseinfo['visible'] = $course->visible; 338 $courseinfo['maxbytes'] = $course->maxbytes; 339 if (array_key_exists('hiddensections', $courseformatoptions)) { 340 // For backward-compartibility 341 $courseinfo['hiddensections'] = $courseformatoptions['hiddensections']; 342 } 343 $courseinfo['groupmode'] = $course->groupmode; 344 $courseinfo['groupmodeforce'] = $course->groupmodeforce; 345 $courseinfo['defaultgroupingid'] = $course->defaultgroupingid; 346 $courseinfo['lang'] = $course->lang; 347 $courseinfo['timecreated'] = $course->timecreated; 348 $courseinfo['timemodified'] = $course->timemodified; 349 $courseinfo['forcetheme'] = $course->theme; 350 $courseinfo['enablecompletion'] = $course->enablecompletion; 351 $courseinfo['completionnotify'] = $course->completionnotify; 352 $courseinfo['courseformatoptions'] = array(); 353 foreach ($courseformatoptions as $key => $value) { 354 $courseinfo['courseformatoptions'][] = array( 355 'name' => $key, 356 'value' => $value 357 ); 358 } 359 } 360 361 if ($courseadmin or $course->visible 362 or has_capability('moodle/course:viewhiddencourses', $context)) { 363 $coursesinfo[] = $courseinfo; 364 } 365 } 366 367 return $coursesinfo; 368 } 369 370 /** 371 * Returns description of method result value 372 * 373 * @return external_description 374 * @since Moodle 2.2 375 */ 376 public static function get_courses_returns() { 377 return new external_multiple_structure( 378 new external_single_structure( 379 array( 380 'id' => new external_value(PARAM_INT, 'course id'), 381 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 382 'categoryid' => new external_value(PARAM_INT, 'category id'), 383 'categorysortorder' => new external_value(PARAM_INT, 384 'sort order into the category', VALUE_OPTIONAL), 385 'fullname' => new external_value(PARAM_TEXT, 'full name'), 386 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 387 'summary' => new external_value(PARAM_RAW, 'summary'), 388 'summaryformat' => new external_format_value('summary'), 389 'format' => new external_value(PARAM_PLUGIN, 390 'course format: weeks, topics, social, site,..'), 391 'showgrades' => new external_value(PARAM_INT, 392 '1 if grades are shown, otherwise 0', VALUE_OPTIONAL), 393 'newsitems' => new external_value(PARAM_INT, 394 'number of recent items appearing on the course page', VALUE_OPTIONAL), 395 'startdate' => new external_value(PARAM_INT, 396 'timestamp when the course start'), 397 'numsections' => new external_value(PARAM_INT, 398 '(deprecated, use courseformatoptions) number of weeks/topics', 399 VALUE_OPTIONAL), 400 'maxbytes' => new external_value(PARAM_INT, 401 'largest size of file that can be uploaded into the course', 402 VALUE_OPTIONAL), 403 'showreports' => new external_value(PARAM_INT, 404 'are activity report shown (yes = 1, no =0)', VALUE_OPTIONAL), 405 'visible' => new external_value(PARAM_INT, 406 '1: available to student, 0:not available', VALUE_OPTIONAL), 407 'hiddensections' => new external_value(PARAM_INT, 408 '(deprecated, use courseformatoptions) How the hidden sections in the course are displayed to students', 409 VALUE_OPTIONAL), 410 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', 411 VALUE_OPTIONAL), 412 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', 413 VALUE_OPTIONAL), 414 'defaultgroupingid' => new external_value(PARAM_INT, 'default grouping id', 415 VALUE_OPTIONAL), 416 'timecreated' => new external_value(PARAM_INT, 417 'timestamp when the course have been created', VALUE_OPTIONAL), 418 'timemodified' => new external_value(PARAM_INT, 419 'timestamp when the course have been modified', VALUE_OPTIONAL), 420 'enablecompletion' => new external_value(PARAM_INT, 421 'Enabled, control via completion and activity settings. Disbaled, 422 not shown in activity settings.', 423 VALUE_OPTIONAL), 424 'completionnotify' => new external_value(PARAM_INT, 425 '1: yes 0: no', VALUE_OPTIONAL), 426 'lang' => new external_value(PARAM_SAFEDIR, 427 'forced course language', VALUE_OPTIONAL), 428 'forcetheme' => new external_value(PARAM_PLUGIN, 429 'name of the force theme', VALUE_OPTIONAL), 430 'courseformatoptions' => new external_multiple_structure( 431 new external_single_structure( 432 array('name' => new external_value(PARAM_ALPHANUMEXT, 'course format option name'), 433 'value' => new external_value(PARAM_RAW, 'course format option value') 434 )), 435 'additional options for particular course format', VALUE_OPTIONAL 436 ), 437 ), 'course' 438 ) 439 ); 440 } 441 442 /** 443 * Returns description of method parameters 444 * 445 * @return external_function_parameters 446 * @since Moodle 2.2 447 */ 448 public static function create_courses_parameters() { 449 $courseconfig = get_config('moodlecourse'); //needed for many default values 450 return new external_function_parameters( 451 array( 452 'courses' => new external_multiple_structure( 453 new external_single_structure( 454 array( 455 'fullname' => new external_value(PARAM_TEXT, 'full name'), 456 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 457 'categoryid' => new external_value(PARAM_INT, 'category id'), 458 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 459 'summary' => new external_value(PARAM_RAW, 'summary', VALUE_OPTIONAL), 460 'summaryformat' => new external_format_value('summary', VALUE_DEFAULT), 461 'format' => new external_value(PARAM_PLUGIN, 462 'course format: weeks, topics, social, site,..', 463 VALUE_DEFAULT, $courseconfig->format), 464 'showgrades' => new external_value(PARAM_INT, 465 '1 if grades are shown, otherwise 0', VALUE_DEFAULT, 466 $courseconfig->showgrades), 467 'newsitems' => new external_value(PARAM_INT, 468 'number of recent items appearing on the course page', 469 VALUE_DEFAULT, $courseconfig->newsitems), 470 'startdate' => new external_value(PARAM_INT, 471 'timestamp when the course start', VALUE_OPTIONAL), 472 'numsections' => new external_value(PARAM_INT, 473 '(deprecated, use courseformatoptions) number of weeks/topics', 474 VALUE_OPTIONAL), 475 'maxbytes' => new external_value(PARAM_INT, 476 'largest size of file that can be uploaded into the course', 477 VALUE_DEFAULT, $courseconfig->maxbytes), 478 'showreports' => new external_value(PARAM_INT, 479 'are activity report shown (yes = 1, no =0)', VALUE_DEFAULT, 480 $courseconfig->showreports), 481 'visible' => new external_value(PARAM_INT, 482 '1: available to student, 0:not available', VALUE_OPTIONAL), 483 'hiddensections' => new external_value(PARAM_INT, 484 '(deprecated, use courseformatoptions) How the hidden sections in the course are displayed to students', 485 VALUE_OPTIONAL), 486 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', 487 VALUE_DEFAULT, $courseconfig->groupmode), 488 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', 489 VALUE_DEFAULT, $courseconfig->groupmodeforce), 490 'defaultgroupingid' => new external_value(PARAM_INT, 'default grouping id', 491 VALUE_DEFAULT, 0), 492 'enablecompletion' => new external_value(PARAM_INT, 493 'Enabled, control via completion and activity settings. Disabled, 494 not shown in activity settings.', 495 VALUE_OPTIONAL), 496 'completionnotify' => new external_value(PARAM_INT, 497 '1: yes 0: no', VALUE_OPTIONAL), 498 'lang' => new external_value(PARAM_SAFEDIR, 499 'forced course language', VALUE_OPTIONAL), 500 'forcetheme' => new external_value(PARAM_PLUGIN, 501 'name of the force theme', VALUE_OPTIONAL), 502 'courseformatoptions' => new external_multiple_structure( 503 new external_single_structure( 504 array('name' => new external_value(PARAM_ALPHANUMEXT, 'course format option name'), 505 'value' => new external_value(PARAM_RAW, 'course format option value') 506 )), 507 'additional options for particular course format', VALUE_OPTIONAL), 508 ) 509 ), 'courses to create' 510 ) 511 ) 512 ); 513 } 514 515 /** 516 * Create courses 517 * 518 * @param array $courses 519 * @return array courses (id and shortname only) 520 * @since Moodle 2.2 521 */ 522 public static function create_courses($courses) { 523 global $CFG, $DB; 524 require_once($CFG->dirroot . "/course/lib.php"); 525 require_once($CFG->libdir . '/completionlib.php'); 526 527 $params = self::validate_parameters(self::create_courses_parameters(), 528 array('courses' => $courses)); 529 530 $availablethemes = core_component::get_plugin_list('theme'); 531 $availablelangs = get_string_manager()->get_list_of_translations(); 532 533 $transaction = $DB->start_delegated_transaction(); 534 535 foreach ($params['courses'] as $course) { 536 537 // Ensure the current user is allowed to run this function 538 $context = context_coursecat::instance($course['categoryid'], IGNORE_MISSING); 539 try { 540 self::validate_context($context); 541 } catch (Exception $e) { 542 $exceptionparam = new stdClass(); 543 $exceptionparam->message = $e->getMessage(); 544 $exceptionparam->catid = $course['categoryid']; 545 throw new moodle_exception('errorcatcontextnotvalid', 'webservice', '', $exceptionparam); 546 } 547 require_capability('moodle/course:create', $context); 548 549 // Make sure lang is valid 550 if (array_key_exists('lang', $course) and empty($availablelangs[$course['lang']])) { 551 throw new moodle_exception('errorinvalidparam', 'webservice', '', 'lang'); 552 } 553 554 // Make sure theme is valid 555 if (array_key_exists('forcetheme', $course)) { 556 if (!empty($CFG->allowcoursethemes)) { 557 if (empty($availablethemes[$course['forcetheme']])) { 558 throw new moodle_exception('errorinvalidparam', 'webservice', '', 'forcetheme'); 559 } else { 560 $course['theme'] = $course['forcetheme']; 561 } 562 } 563 } 564 565 //force visibility if ws user doesn't have the permission to set it 566 $category = $DB->get_record('course_categories', array('id' => $course['categoryid'])); 567 if (!has_capability('moodle/course:visibility', $context)) { 568 $course['visible'] = $category->visible; 569 } 570 571 //set default value for completion 572 $courseconfig = get_config('moodlecourse'); 573 if (completion_info::is_enabled_for_site()) { 574 if (!array_key_exists('enablecompletion', $course)) { 575 $course['enablecompletion'] = $courseconfig->enablecompletion; 576 } 577 } else { 578 $course['enablecompletion'] = 0; 579 } 580 581 $course['category'] = $course['categoryid']; 582 583 // Summary format. 584 $course['summaryformat'] = external_validate_format($course['summaryformat']); 585 586 if (!empty($course['courseformatoptions'])) { 587 foreach ($course['courseformatoptions'] as $option) { 588 $course[$option['name']] = $option['value']; 589 } 590 } 591 592 //Note: create_course() core function check shortname, idnumber, category 593 $course['id'] = create_course((object) $course)->id; 594 595 $resultcourses[] = array('id' => $course['id'], 'shortname' => $course['shortname']); 596 } 597 598 $transaction->allow_commit(); 599 600 return $resultcourses; 601 } 602 603 /** 604 * Returns description of method result value 605 * 606 * @return external_description 607 * @since Moodle 2.2 608 */ 609 public static function create_courses_returns() { 610 return new external_multiple_structure( 611 new external_single_structure( 612 array( 613 'id' => new external_value(PARAM_INT, 'course id'), 614 'shortname' => new external_value(PARAM_TEXT, 'short name'), 615 ) 616 ) 617 ); 618 } 619 620 /** 621 * Update courses 622 * 623 * @return external_function_parameters 624 * @since Moodle 2.5 625 */ 626 public static function update_courses_parameters() { 627 return new external_function_parameters( 628 array( 629 'courses' => new external_multiple_structure( 630 new external_single_structure( 631 array( 632 'id' => new external_value(PARAM_INT, 'ID of the course'), 633 'fullname' => new external_value(PARAM_TEXT, 'full name', VALUE_OPTIONAL), 634 'shortname' => new external_value(PARAM_TEXT, 'course short name', VALUE_OPTIONAL), 635 'categoryid' => new external_value(PARAM_INT, 'category id', VALUE_OPTIONAL), 636 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 637 'summary' => new external_value(PARAM_RAW, 'summary', VALUE_OPTIONAL), 638 'summaryformat' => new external_format_value('summary', VALUE_OPTIONAL), 639 'format' => new external_value(PARAM_PLUGIN, 640 'course format: weeks, topics, social, site,..', VALUE_OPTIONAL), 641 'showgrades' => new external_value(PARAM_INT, 642 '1 if grades are shown, otherwise 0', VALUE_OPTIONAL), 643 'newsitems' => new external_value(PARAM_INT, 644 'number of recent items appearing on the course page', VALUE_OPTIONAL), 645 'startdate' => new external_value(PARAM_INT, 646 'timestamp when the course start', VALUE_OPTIONAL), 647 'numsections' => new external_value(PARAM_INT, 648 '(deprecated, use courseformatoptions) number of weeks/topics', VALUE_OPTIONAL), 649 'maxbytes' => new external_value(PARAM_INT, 650 'largest size of file that can be uploaded into the course', VALUE_OPTIONAL), 651 'showreports' => new external_value(PARAM_INT, 652 'are activity report shown (yes = 1, no =0)', VALUE_OPTIONAL), 653 'visible' => new external_value(PARAM_INT, 654 '1: available to student, 0:not available', VALUE_OPTIONAL), 655 'hiddensections' => new external_value(PARAM_INT, 656 '(deprecated, use courseformatoptions) How the hidden sections in the course are 657 displayed to students', VALUE_OPTIONAL), 658 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', VALUE_OPTIONAL), 659 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', VALUE_OPTIONAL), 660 'defaultgroupingid' => new external_value(PARAM_INT, 'default grouping id', VALUE_OPTIONAL), 661 'enablecompletion' => new external_value(PARAM_INT, 662 'Enabled, control via completion and activity settings. Disabled, 663 not shown in activity settings.', VALUE_OPTIONAL), 664 'completionnotify' => new external_value(PARAM_INT, '1: yes 0: no', VALUE_OPTIONAL), 665 'lang' => new external_value(PARAM_SAFEDIR, 'forced course language', VALUE_OPTIONAL), 666 'forcetheme' => new external_value(PARAM_PLUGIN, 'name of the force theme', VALUE_OPTIONAL), 667 'courseformatoptions' => new external_multiple_structure( 668 new external_single_structure( 669 array('name' => new external_value(PARAM_ALPHANUMEXT, 'course format option name'), 670 'value' => new external_value(PARAM_RAW, 'course format option value') 671 )), 672 'additional options for particular course format', VALUE_OPTIONAL), 673 ) 674 ), 'courses to update' 675 ) 676 ) 677 ); 678 } 679 680 /** 681 * Update courses 682 * 683 * @param array $courses 684 * @since Moodle 2.5 685 */ 686 public static function update_courses($courses) { 687 global $CFG, $DB; 688 require_once($CFG->dirroot . "/course/lib.php"); 689 $warnings = array(); 690 691 $params = self::validate_parameters(self::update_courses_parameters(), 692 array('courses' => $courses)); 693 694 $availablethemes = core_component::get_plugin_list('theme'); 695 $availablelangs = get_string_manager()->get_list_of_translations(); 696 697 foreach ($params['courses'] as $course) { 698 // Catch any exception while updating course and return as warning to user. 699 try { 700 // Ensure the current user is allowed to run this function. 701 $context = context_course::instance($course['id'], MUST_EXIST); 702 self::validate_context($context); 703 704 $oldcourse = course_get_format($course['id'])->get_course(); 705 706 require_capability('moodle/course:update', $context); 707 708 // Check if user can change category. 709 if (array_key_exists('categoryid', $course) && ($oldcourse->category != $course['categoryid'])) { 710 require_capability('moodle/course:changecategory', $context); 711 $course['category'] = $course['categoryid']; 712 } 713 714 // Check if the user can change fullname. 715 if (array_key_exists('fullname', $course) && ($oldcourse->fullname != $course['fullname'])) { 716 require_capability('moodle/course:changefullname', $context); 717 } 718 719 // Check if the user can change shortname. 720 if (array_key_exists('shortname', $course) && ($oldcourse->shortname != $course['shortname'])) { 721 require_capability('moodle/course:changeshortname', $context); 722 } 723 724 // Check if the user can change the idnumber. 725 if (array_key_exists('idnumber', $course) && ($oldcourse->idnumber != $course['idnumber'])) { 726 require_capability('moodle/course:changeidnumber', $context); 727 } 728 729 // Check if user can change summary. 730 if (array_key_exists('summary', $course) && ($oldcourse->summary != $course['summary'])) { 731 require_capability('moodle/course:changesummary', $context); 732 } 733 734 // Summary format. 735 if (array_key_exists('summaryformat', $course) && ($oldcourse->summaryformat != $course['summaryformat'])) { 736 require_capability('moodle/course:changesummary', $context); 737 $course['summaryformat'] = external_validate_format($course['summaryformat']); 738 } 739 740 // Check if user can change visibility. 741 if (array_key_exists('visible', $course) && ($oldcourse->visible != $course['visible'])) { 742 require_capability('moodle/course:visibility', $context); 743 } 744 745 // Make sure lang is valid. 746 if (array_key_exists('lang', $course) && empty($availablelangs[$course['lang']])) { 747 throw new moodle_exception('errorinvalidparam', 'webservice', '', 'lang'); 748 } 749 750 // Make sure theme is valid. 751 if (array_key_exists('forcetheme', $course)) { 752 if (!empty($CFG->allowcoursethemes)) { 753 if (empty($availablethemes[$course['forcetheme']])) { 754 throw new moodle_exception('errorinvalidparam', 'webservice', '', 'forcetheme'); 755 } else { 756 $course['theme'] = $course['forcetheme']; 757 } 758 } 759 } 760 761 // Make sure completion is enabled before setting it. 762 if (array_key_exists('enabledcompletion', $course) && !completion_info::is_enabled_for_site()) { 763 $course['enabledcompletion'] = 0; 764 } 765 766 // Make sure maxbytes are less then CFG->maxbytes. 767 if (array_key_exists('maxbytes', $course)) { 768 $course['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $course['maxbytes']); 769 } 770 771 if (!empty($course['courseformatoptions'])) { 772 foreach ($course['courseformatoptions'] as $option) { 773 if (isset($option['name']) && isset($option['value'])) { 774 $course[$option['name']] = $option['value']; 775 } 776 } 777 } 778 779 // Update course if user has all required capabilities. 780 update_course((object) $course); 781 } catch (Exception $e) { 782 $warning = array(); 783 $warning['item'] = 'course'; 784 $warning['itemid'] = $course['id']; 785 if ($e instanceof moodle_exception) { 786 $warning['warningcode'] = $e->errorcode; 787 } else { 788 $warning['warningcode'] = $e->getCode(); 789 } 790 $warning['message'] = $e->getMessage(); 791 $warnings[] = $warning; 792 } 793 } 794 795 $result = array(); 796 $result['warnings'] = $warnings; 797 return $result; 798 } 799 800 /** 801 * Returns description of method result value 802 * 803 * @return external_description 804 * @since Moodle 2.5 805 */ 806 public static function update_courses_returns() { 807 return new external_single_structure( 808 array( 809 'warnings' => new external_warnings() 810 ) 811 ); 812 } 813 814 /** 815 * Returns description of method parameters 816 * 817 * @return external_function_parameters 818 * @since Moodle 2.2 819 */ 820 public static function delete_courses_parameters() { 821 return new external_function_parameters( 822 array( 823 'courseids' => new external_multiple_structure(new external_value(PARAM_INT, 'course ID')), 824 ) 825 ); 826 } 827 828 /** 829 * Delete courses 830 * 831 * @param array $courseids A list of course ids 832 * @since Moodle 2.2 833 */ 834 public static function delete_courses($courseids) { 835 global $CFG, $DB; 836 require_once($CFG->dirroot."/course/lib.php"); 837 838 // Parameter validation. 839 $params = self::validate_parameters(self::delete_courses_parameters(), array('courseids'=>$courseids)); 840 841 $transaction = $DB->start_delegated_transaction(); 842 843 foreach ($params['courseids'] as $courseid) { 844 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); 845 846 // Check if the context is valid. 847 $coursecontext = context_course::instance($course->id); 848 self::validate_context($coursecontext); 849 850 // Check if the current user has enought permissions. 851 if (!can_delete_course($courseid)) { 852 throw new moodle_exception('cannotdeletecategorycourse', 'error', 853 '', format_string($course->fullname)." (id: $courseid)"); 854 } 855 856 delete_course($course, false); 857 } 858 859 $transaction->allow_commit(); 860 861 return null; 862 } 863 864 /** 865 * Returns description of method result value 866 * 867 * @return external_description 868 * @since Moodle 2.2 869 */ 870 public static function delete_courses_returns() { 871 return null; 872 } 873 874 /** 875 * Returns description of method parameters 876 * 877 * @return external_function_parameters 878 * @since Moodle 2.3 879 */ 880 public static function duplicate_course_parameters() { 881 return new external_function_parameters( 882 array( 883 'courseid' => new external_value(PARAM_INT, 'course to duplicate id'), 884 'fullname' => new external_value(PARAM_TEXT, 'duplicated course full name'), 885 'shortname' => new external_value(PARAM_TEXT, 'duplicated course short name'), 886 'categoryid' => new external_value(PARAM_INT, 'duplicated course category parent'), 887 'visible' => new external_value(PARAM_INT, 'duplicated course visible, default to yes', VALUE_DEFAULT, 1), 888 'options' => new external_multiple_structure( 889 new external_single_structure( 890 array( 891 'name' => new external_value(PARAM_ALPHAEXT, 'The backup option name: 892 "activities" (int) Include course activites (default to 1 that is equal to yes), 893 "blocks" (int) Include course blocks (default to 1 that is equal to yes), 894 "filters" (int) Include course filters (default to 1 that is equal to yes), 895 "users" (int) Include users (default to 0 that is equal to no), 896 "role_assignments" (int) Include role assignments (default to 0 that is equal to no), 897 "comments" (int) Include user comments (default to 0 that is equal to no), 898 "userscompletion" (int) Include user course completion information (default to 0 that is equal to no), 899 "logs" (int) Include course logs (default to 0 that is equal to no), 900 "grade_histories" (int) Include histories (default to 0 that is equal to no)' 901 ), 902 'value' => new external_value(PARAM_RAW, 'the value for the option 1 (yes) or 0 (no)' 903 ) 904 ) 905 ), VALUE_DEFAULT, array() 906 ), 907 ) 908 ); 909 } 910 911 /** 912 * Duplicate a course 913 * 914 * @param int $courseid 915 * @param string $fullname Duplicated course fullname 916 * @param string $shortname Duplicated course shortname 917 * @param int $categoryid Duplicated course parent category id 918 * @param int $visible Duplicated course availability 919 * @param array $options List of backup options 920 * @return array New course info 921 * @since Moodle 2.3 922 */ 923 public static function duplicate_course($courseid, $fullname, $shortname, $categoryid, $visible = 1, $options = array()) { 924 global $CFG, $USER, $DB; 925 require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php'); 926 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); 927 928 // Parameter validation. 929 $params = self::validate_parameters( 930 self::duplicate_course_parameters(), 931 array( 932 'courseid' => $courseid, 933 'fullname' => $fullname, 934 'shortname' => $shortname, 935 'categoryid' => $categoryid, 936 'visible' => $visible, 937 'options' => $options 938 ) 939 ); 940 941 // Context validation. 942 943 if (! ($course = $DB->get_record('course', array('id'=>$params['courseid'])))) { 944 throw new moodle_exception('invalidcourseid', 'error'); 945 } 946 947 // Category where duplicated course is going to be created. 948 $categorycontext = context_coursecat::instance($params['categoryid']); 949 self::validate_context($categorycontext); 950 951 // Course to be duplicated. 952 $coursecontext = context_course::instance($course->id); 953 self::validate_context($coursecontext); 954 955 $backupdefaults = array( 956 'activities' => 1, 957 'blocks' => 1, 958 'filters' => 1, 959 'users' => 0, 960 'role_assignments' => 0, 961 'comments' => 0, 962 'userscompletion' => 0, 963 'logs' => 0, 964 'grade_histories' => 0 965 ); 966 967 $backupsettings = array(); 968 // Check for backup and restore options. 969 if (!empty($params['options'])) { 970 foreach ($params['options'] as $option) { 971 972 // Strict check for a correct value (allways 1 or 0, true or false). 973 $value = clean_param($option['value'], PARAM_INT); 974 975 if ($value !== 0 and $value !== 1) { 976 throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); 977 } 978 979 if (!isset($backupdefaults[$option['name']])) { 980 throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); 981 } 982 983 $backupsettings[$option['name']] = $value; 984 } 985 } 986 987 // Capability checking. 988 989 // The backup controller check for this currently, this may be redundant. 990 require_capability('moodle/course:create', $categorycontext); 991 require_capability('moodle/restore:restorecourse', $categorycontext); 992 require_capability('moodle/backup:backupcourse', $coursecontext); 993 994 if (!empty($backupsettings['users'])) { 995 require_capability('moodle/backup:userinfo', $coursecontext); 996 require_capability('moodle/restore:userinfo', $categorycontext); 997 } 998 999 // Check if the shortname is used. 1000 if ($foundcourses = $DB->get_records('course', array('shortname'=>$shortname))) { 1001 foreach ($foundcourses as $foundcourse) { 1002 $foundcoursenames[] = $foundcourse->fullname; 1003 } 1004 1005 $foundcoursenamestring = implode(',', $foundcoursenames); 1006 throw new moodle_exception('shortnametaken', '', '', $foundcoursenamestring); 1007 } 1008 1009 // Backup the course. 1010 1011 $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, 1012 backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $USER->id); 1013 1014 foreach ($backupsettings as $name => $value) { 1015 $bc->get_plan()->get_setting($name)->set_value($value); 1016 } 1017 1018 $backupid = $bc->get_backupid(); 1019 $backupbasepath = $bc->get_plan()->get_basepath(); 1020 1021 $bc->execute_plan(); 1022 $results = $bc->get_results(); 1023 $file = $results['backup_destination']; 1024 1025 $bc->destroy(); 1026 1027 // Restore the backup immediately. 1028 1029 // Check if we need to unzip the file because the backup temp dir does not contains backup files. 1030 if (!file_exists($backupbasepath . "/moodle_backup.xml")) { 1031 $file->extract_to_pathname(get_file_packer(), $backupbasepath); 1032 } 1033 1034 // Create new course. 1035 $newcourseid = restore_dbops::create_new_course($params['fullname'], $params['shortname'], $params['categoryid']); 1036 1037 $rc = new restore_controller($backupid, $newcourseid, 1038 backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $USER->id, backup::TARGET_NEW_COURSE); 1039 1040 foreach ($backupsettings as $name => $value) { 1041 $setting = $rc->get_plan()->get_setting($name); 1042 if ($setting->get_status() == backup_setting::NOT_LOCKED) { 1043 $setting->set_value($value); 1044 } 1045 } 1046 1047 if (!$rc->execute_precheck()) { 1048 $precheckresults = $rc->get_precheck_results(); 1049 if (is_array($precheckresults) && !empty($precheckresults['errors'])) { 1050 if (empty($CFG->keeptempdirectoriesonbackup)) { 1051 fulldelete($backupbasepath); 1052 } 1053 1054 $errorinfo = ''; 1055 1056 foreach ($precheckresults['errors'] as $error) { 1057 $errorinfo .= $error; 1058 } 1059 1060 if (array_key_exists('warnings', $precheckresults)) { 1061 foreach ($precheckresults['warnings'] as $warning) { 1062 $errorinfo .= $warning; 1063 } 1064 } 1065 1066 throw new moodle_exception('backupprecheckerrors', 'webservice', '', $errorinfo); 1067 } 1068 } 1069 1070 $rc->execute_plan(); 1071 $rc->destroy(); 1072 1073 $course = $DB->get_record('course', array('id' => $newcourseid), '*', MUST_EXIST); 1074 $course->fullname = $params['fullname']; 1075 $course->shortname = $params['shortname']; 1076 $course->visible = $params['visible']; 1077 1078 // Set shortname and fullname back. 1079 $DB->update_record('course', $course); 1080 1081 if (empty($CFG->keeptempdirectoriesonbackup)) { 1082 fulldelete($backupbasepath); 1083 } 1084 1085 // Delete the course backup file created by this WebService. Originally located in the course backups area. 1086 $file->delete(); 1087 1088 return array('id' => $course->id, 'shortname' => $course->shortname); 1089 } 1090 1091 /** 1092 * Returns description of method result value 1093 * 1094 * @return external_description 1095 * @since Moodle 2.3 1096 */ 1097 public static function duplicate_course_returns() { 1098 return new external_single_structure( 1099 array( 1100 'id' => new external_value(PARAM_INT, 'course id'), 1101 'shortname' => new external_value(PARAM_TEXT, 'short name'), 1102 ) 1103 ); 1104 } 1105 1106 /** 1107 * Returns description of method parameters for import_course 1108 * 1109 * @return external_function_parameters 1110 * @since Moodle 2.4 1111 */ 1112 public static function import_course_parameters() { 1113 return new external_function_parameters( 1114 array( 1115 'importfrom' => new external_value(PARAM_INT, 'the id of the course we are importing from'), 1116 'importto' => new external_value(PARAM_INT, 'the id of the course we are importing to'), 1117 'deletecontent' => new external_value(PARAM_INT, 'whether to delete the course content where we are importing to (default to 0 = No)', VALUE_DEFAULT, 0), 1118 'options' => new external_multiple_structure( 1119 new external_single_structure( 1120 array( 1121 'name' => new external_value(PARAM_ALPHA, 'The backup option name: 1122 "activities" (int) Include course activites (default to 1 that is equal to yes), 1123 "blocks" (int) Include course blocks (default to 1 that is equal to yes), 1124 "filters" (int) Include course filters (default to 1 that is equal to yes)' 1125 ), 1126 'value' => new external_value(PARAM_RAW, 'the value for the option 1 (yes) or 0 (no)' 1127 ) 1128 ) 1129 ), VALUE_DEFAULT, array() 1130 ), 1131 ) 1132 ); 1133 } 1134 1135 /** 1136 * Imports a course 1137 * 1138 * @param int $importfrom The id of the course we are importing from 1139 * @param int $importto The id of the course we are importing to 1140 * @param bool $deletecontent Whether to delete the course we are importing to content 1141 * @param array $options List of backup options 1142 * @return null 1143 * @since Moodle 2.4 1144 */ 1145 public static function import_course($importfrom, $importto, $deletecontent = 0, $options = array()) { 1146 global $CFG, $USER, $DB; 1147 require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php'); 1148 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); 1149 1150 // Parameter validation. 1151 $params = self::validate_parameters( 1152 self::import_course_parameters(), 1153 array( 1154 'importfrom' => $importfrom, 1155 'importto' => $importto, 1156 'deletecontent' => $deletecontent, 1157 'options' => $options 1158 ) 1159 ); 1160 1161 if ($params['deletecontent'] !== 0 and $params['deletecontent'] !== 1) { 1162 throw new moodle_exception('invalidextparam', 'webservice', '', $params['deletecontent']); 1163 } 1164 1165 // Context validation. 1166 1167 if (! ($importfrom = $DB->get_record('course', array('id'=>$params['importfrom'])))) { 1168 throw new moodle_exception('invalidcourseid', 'error'); 1169 } 1170 1171 if (! ($importto = $DB->get_record('course', array('id'=>$params['importto'])))) { 1172 throw new moodle_exception('invalidcourseid', 'error'); 1173 } 1174 1175 $importfromcontext = context_course::instance($importfrom->id); 1176 self::validate_context($importfromcontext); 1177 1178 $importtocontext = context_course::instance($importto->id); 1179 self::validate_context($importtocontext); 1180 1181 $backupdefaults = array( 1182 'activities' => 1, 1183 'blocks' => 1, 1184 'filters' => 1 1185 ); 1186 1187 $backupsettings = array(); 1188 1189 // Check for backup and restore options. 1190 if (!empty($params['options'])) { 1191 foreach ($params['options'] as $option) { 1192 1193 // Strict check for a correct value (allways 1 or 0, true or false). 1194 $value = clean_param($option['value'], PARAM_INT); 1195 1196 if ($value !== 0 and $value !== 1) { 1197 throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); 1198 } 1199 1200 if (!isset($backupdefaults[$option['name']])) { 1201 throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); 1202 } 1203 1204 $backupsettings[$option['name']] = $value; 1205 } 1206 } 1207 1208 // Capability checking. 1209 1210 require_capability('moodle/backup:backuptargetimport', $importfromcontext); 1211 require_capability('moodle/restore:restoretargetimport', $importtocontext); 1212 1213 $bc = new backup_controller(backup::TYPE_1COURSE, $importfrom->id, backup::FORMAT_MOODLE, 1214 backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); 1215 1216 foreach ($backupsettings as $name => $value) { 1217 $bc->get_plan()->get_setting($name)->set_value($value); 1218 } 1219 1220 $backupid = $bc->get_backupid(); 1221 $backupbasepath = $bc->get_plan()->get_basepath(); 1222 1223 $bc->execute_plan(); 1224 $bc->destroy(); 1225 1226 // Restore the backup immediately. 1227 1228 // Check if we must delete the contents of the destination course. 1229 if ($params['deletecontent']) { 1230 $restoretarget = backup::TARGET_EXISTING_DELETING; 1231 } else { 1232 $restoretarget = backup::TARGET_EXISTING_ADDING; 1233 } 1234 1235 $rc = new restore_controller($backupid, $importto->id, 1236 backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, $restoretarget); 1237 1238 foreach ($backupsettings as $name => $value) { 1239 $rc->get_plan()->get_setting($name)->set_value($value); 1240 } 1241 1242 if (!$rc->execute_precheck()) { 1243 $precheckresults = $rc->get_precheck_results(); 1244 if (is_array($precheckresults) && !empty($precheckresults['errors'])) { 1245 if (empty($CFG->keeptempdirectoriesonbackup)) { 1246 fulldelete($backupbasepath); 1247 } 1248 1249 $errorinfo = ''; 1250 1251 foreach ($precheckresults['errors'] as $error) { 1252 $errorinfo .= $error; 1253 } 1254 1255 if (array_key_exists('warnings', $precheckresults)) { 1256 foreach ($precheckresults['warnings'] as $warning) { 1257 $errorinfo .= $warning; 1258 } 1259 } 1260 1261 throw new moodle_exception('backupprecheckerrors', 'webservice', '', $errorinfo); 1262 } 1263 } else { 1264 if ($restoretarget == backup::TARGET_EXISTING_DELETING) { 1265 restore_dbops::delete_course_content($importto->id); 1266 } 1267 } 1268 1269 $rc->execute_plan(); 1270 $rc->destroy(); 1271 1272 if (empty($CFG->keeptempdirectoriesonbackup)) { 1273 fulldelete($backupbasepath); 1274 } 1275 1276 return null; 1277 } 1278 1279 /** 1280 * Returns description of method result value 1281 * 1282 * @return external_description 1283 * @since Moodle 2.4 1284 */ 1285 public static function import_course_returns() { 1286 return null; 1287 } 1288 1289 /** 1290 * Returns description of method parameters 1291 * 1292 * @return external_function_parameters 1293 * @since Moodle 2.3 1294 */ 1295 public static function get_categories_parameters() { 1296 return new external_function_parameters( 1297 array( 1298 'criteria' => new external_multiple_structure( 1299 new external_single_structure( 1300 array( 1301 'key' => new external_value(PARAM_ALPHA, 1302 'The category column to search, expected keys (value format) are:'. 1303 '"id" (int) the category id,'. 1304 '"name" (string) the category name,'. 1305 '"parent" (int) the parent category id,'. 1306 '"idnumber" (string) category idnumber'. 1307 ' - user must have \'moodle/category:manage\' to search on idnumber,'. 1308 '"visible" (int) whether the returned categories must be visible or hidden. If the key is not passed, 1309 then the function return all categories that the user can see.'. 1310 ' - user must have \'moodle/category:manage\' or \'moodle/category:viewhiddencategories\' to search on visible,'. 1311 '"theme" (string) only return the categories having this theme'. 1312 ' - user must have \'moodle/category:manage\' to search on theme'), 1313 'value' => new external_value(PARAM_RAW, 'the value to match') 1314 ) 1315 ), 'criteria', VALUE_DEFAULT, array() 1316 ), 1317 'addsubcategories' => new external_value(PARAM_BOOL, 'return the sub categories infos 1318 (1 - default) otherwise only the category info (0)', VALUE_DEFAULT, 1) 1319 ) 1320 ); 1321 } 1322 1323 /** 1324 * Get categories 1325 * 1326 * @param array $criteria Criteria to match the results 1327 * @param booln $addsubcategories obtain only the category (false) or its subcategories (true - default) 1328 * @return array list of categories 1329 * @since Moodle 2.3 1330 */ 1331 public static function get_categories($criteria = array(), $addsubcategories = true) { 1332 global $CFG, $DB; 1333 require_once($CFG->dirroot . "/course/lib.php"); 1334 1335 // Validate parameters. 1336 $params = self::validate_parameters(self::get_categories_parameters(), 1337 array('criteria' => $criteria, 'addsubcategories' => $addsubcategories)); 1338 1339 // Retrieve the categories. 1340 $categories = array(); 1341 if (!empty($params['criteria'])) { 1342 1343 $conditions = array(); 1344 $wheres = array(); 1345 foreach ($params['criteria'] as $crit) { 1346 $key = trim($crit['key']); 1347 1348 // Trying to avoid duplicate keys. 1349 if (!isset($conditions[$key])) { 1350 1351 $context = context_system::instance(); 1352 $value = null; 1353 switch ($key) { 1354 case 'id': 1355 $value = clean_param($crit['value'], PARAM_INT); 1356 break; 1357 1358 case 'idnumber': 1359 if (has_capability('moodle/category:manage', $context)) { 1360 $value = clean_param($crit['value'], PARAM_RAW); 1361 } else { 1362 // We must throw an exception. 1363 // Otherwise the dev client would think no idnumber exists. 1364 throw new moodle_exception('criteriaerror', 1365 'webservice', '', null, 1366 'You don\'t have the permissions to search on the "idnumber" field.'); 1367 } 1368 break; 1369 1370 case 'name': 1371 $value = clean_param($crit['value'], PARAM_TEXT); 1372 break; 1373 1374 case 'parent': 1375 $value = clean_param($crit['value'], PARAM_INT); 1376 break; 1377 1378 case 'visible': 1379 if (has_capability('moodle/category:manage', $context) 1380 or has_capability('moodle/category:viewhiddencategories', 1381 context_system::instance())) { 1382 $value = clean_param($crit['value'], PARAM_INT); 1383 } else { 1384 throw new moodle_exception('criteriaerror', 1385 'webservice', '', null, 1386 'You don\'t have the permissions to search on the "visible" field.'); 1387 } 1388 break; 1389 1390 case 'theme': 1391 if (has_capability('moodle/category:manage', $context)) { 1392 $value = clean_param($crit['value'], PARAM_THEME); 1393 } else { 1394 throw new moodle_exception('criteriaerror', 1395 'webservice', '', null, 1396 'You don\'t have the permissions to search on the "theme" field.'); 1397 } 1398 break; 1399 1400 default: 1401 throw new moodle_exception('criteriaerror', 1402 'webservice', '', null, 1403 'You can not search on this criteria: ' . $key); 1404 } 1405 1406 if (isset($value)) { 1407 $conditions[$key] = $crit['value']; 1408 $wheres[] = $key . " = :" . $key; 1409 } 1410 } 1411 } 1412 1413 if (!empty($wheres)) { 1414 $wheres = implode(" AND ", $wheres); 1415 1416 $categories = $DB->get_records_select('course_categories', $wheres, $conditions); 1417 1418 // Retrieve its sub subcategories (all levels). 1419 if ($categories and !empty($params['addsubcategories'])) { 1420 $newcategories = array(); 1421 1422 // Check if we required visible/theme checks. 1423 $additionalselect = ''; 1424 $additionalparams = array(); 1425 if (isset($conditions['visible'])) { 1426 $additionalselect .= ' AND visible = :visible'; 1427 $additionalparams['visible'] = $conditions['visible']; 1428 } 1429 if (isset($conditions['theme'])) { 1430 $additionalselect .= ' AND theme= :theme'; 1431 $additionalparams['theme'] = $conditions['theme']; 1432 } 1433 1434 foreach ($categories as $category) { 1435 $sqlselect = $DB->sql_like('path', ':path') . $additionalselect; 1436 $sqlparams = array('path' => $category->path.'/%') + $additionalparams; // It will NOT include the specified category. 1437 $subcategories = $DB->get_records_select('course_categories', $sqlselect, $sqlparams); 1438 $newcategories = $newcategories + $subcategories; // Both arrays have integer as keys. 1439 } 1440 $categories = $categories + $newcategories; 1441 } 1442 } 1443 1444 } else { 1445 // Retrieve all categories in the database. 1446 $categories = $DB->get_records('course_categories'); 1447 } 1448 1449 // The not returned categories. key => category id, value => reason of exclusion. 1450 $excludedcats = array(); 1451 1452 // The returned categories. 1453 $categoriesinfo = array(); 1454 1455 // We need to sort the categories by path. 1456 // The parent cats need to be checked by the algo first. 1457 usort($categories, "core_course_external::compare_categories_by_path"); 1458 1459 foreach ($categories as $category) { 1460 1461 // Check if the category is a child of an excluded category, if yes exclude it too (excluded => do not return). 1462 $parents = explode('/', $category->path); 1463 unset($parents[0]); // First key is always empty because path start with / => /1/2/4. 1464 foreach ($parents as $parentid) { 1465 // Note: when the parent exclusion was due to the context, 1466 // the sub category could still be returned. 1467 if (isset($excludedcats[$parentid]) and $excludedcats[$parentid] != 'context') { 1468 $excludedcats[$category->id] = 'parent'; 1469 } 1470 } 1471 1472 // Check category depth is <= maxdepth (do not check for user who can manage categories). 1473 if ((!empty($CFG->maxcategorydepth) && count($parents) > $CFG->maxcategorydepth) 1474 and !has_capability('moodle/category:manage', $context)) { 1475 $excludedcats[$category->id] = 'depth'; 1476 } 1477 1478 // Check the user can use the category context. 1479 $context = context_coursecat::instance($category->id); 1480 try { 1481 self::validate_context($context); 1482 } catch (Exception $e) { 1483 $excludedcats[$category->id] = 'context'; 1484 1485 // If it was the requested category then throw an exception. 1486 if (isset($params['categoryid']) && $category->id == $params['categoryid']) { 1487 $exceptionparam = new stdClass(); 1488 $exceptionparam->message = $e->getMessage(); 1489 $exceptionparam->catid = $category->id; 1490 throw new moodle_exception('errorcatcontextnotvalid', 'webservice', '', $exceptionparam); 1491 } 1492 } 1493 1494 // Return the category information. 1495 if (!isset($excludedcats[$category->id])) { 1496 1497 // Final check to see if the category is visible to the user. 1498 if ($category->visible 1499 or has_capability('moodle/category:viewhiddencategories', context_system::instance()) 1500 or has_capability('moodle/category:manage', $context)) { 1501 1502 $categoryinfo = array(); 1503 $categoryinfo['id'] = $category->id; 1504 $categoryinfo['name'] = $category->name; 1505 list($categoryinfo['description'], $categoryinfo['descriptionformat']) = 1506 external_format_text($category->description, $category->descriptionformat, 1507 $context->id, 'coursecat', 'description', null); 1508 $categoryinfo['parent'] = $category->parent; 1509 $categoryinfo['sortorder'] = $category->sortorder; 1510 $categoryinfo['coursecount'] = $category->coursecount; 1511 $categoryinfo['depth'] = $category->depth; 1512 $categoryinfo['path'] = $category->path; 1513 1514 // Some fields only returned for admin. 1515 if (has_capability('moodle/category:manage', $context)) { 1516 $categoryinfo['idnumber'] = $category->idnumber; 1517 $categoryinfo['visible'] = $category->visible; 1518 $categoryinfo['visibleold'] = $category->visibleold; 1519 $categoryinfo['timemodified'] = $category->timemodified; 1520 $categoryinfo['theme'] = $category->theme; 1521 } 1522 1523 $categoriesinfo[] = $categoryinfo; 1524 } else { 1525 $excludedcats[$category->id] = 'visibility'; 1526 } 1527 } 1528 } 1529 1530 // Sorting the resulting array so it looks a bit better for the client developer. 1531 usort($categoriesinfo, "core_course_external::compare_categories_by_sortorder"); 1532 1533 return $categoriesinfo; 1534 } 1535 1536 /** 1537 * Sort categories array by path 1538 * private function: only used by get_categories 1539 * 1540 * @param array $category1 1541 * @param array $category2 1542 * @return int result of strcmp 1543 * @since Moodle 2.3 1544 */ 1545 private static function compare_categories_by_path($category1, $category2) { 1546 return strcmp($category1->path, $category2->path); 1547 } 1548 1549 /** 1550 * Sort categories array by sortorder 1551 * private function: only used by get_categories 1552 * 1553 * @param array $category1 1554 * @param array $category2 1555 * @return int result of strcmp 1556 * @since Moodle 2.3 1557 */ 1558 private static function compare_categories_by_sortorder($category1, $category2) { 1559 return strcmp($category1['sortorder'], $category2['sortorder']); 1560 } 1561 1562 /** 1563 * Returns description of method result value 1564 * 1565 * @return external_description 1566 * @since Moodle 2.3 1567 */ 1568 public static function get_categories_returns() { 1569 return new external_multiple_structure( 1570 new external_single_structure( 1571 array( 1572 'id' => new external_value(PARAM_INT, 'category id'), 1573 'name' => new external_value(PARAM_TEXT, 'category name'), 1574 'idnumber' => new external_value(PARAM_RAW, 'category id number', VALUE_OPTIONAL), 1575 'description' => new external_value(PARAM_RAW, 'category description'), 1576 'descriptionformat' => new external_format_value('description'), 1577 'parent' => new external_value(PARAM_INT, 'parent category id'), 1578 'sortorder' => new external_value(PARAM_INT, 'category sorting order'), 1579 'coursecount' => new external_value(PARAM_INT, 'number of courses in this category'), 1580 'visible' => new external_value(PARAM_INT, '1: available, 0:not available', VALUE_OPTIONAL), 1581 'visibleold' => new external_value(PARAM_INT, '1: available, 0:not available', VALUE_OPTIONAL), 1582 'timemodified' => new external_value(PARAM_INT, 'timestamp', VALUE_OPTIONAL), 1583 'depth' => new external_value(PARAM_INT, 'category depth'), 1584 'path' => new external_value(PARAM_TEXT, 'category path'), 1585 'theme' => new external_value(PARAM_THEME, 'category theme', VALUE_OPTIONAL), 1586 ), 'List of categories' 1587 ) 1588 ); 1589 } 1590 1591 /** 1592 * Returns description of method parameters 1593 * 1594 * @return external_function_parameters 1595 * @since Moodle 2.3 1596 */ 1597 public static function create_categories_parameters() { 1598 return new external_function_parameters( 1599 array( 1600 'categories' => new external_multiple_structure( 1601 new external_single_structure( 1602 array( 1603 'name' => new external_value(PARAM_TEXT, 'new category name'), 1604 'parent' => new external_value(PARAM_INT, 1605 'the parent category id inside which the new category will be created 1606 - set to 0 for a root category', 1607 VALUE_DEFAULT, 0), 1608 'idnumber' => new external_value(PARAM_RAW, 1609 'the new category idnumber', VALUE_OPTIONAL), 1610 'description' => new external_value(PARAM_RAW, 1611 'the new category description', VALUE_OPTIONAL), 1612 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 1613 'theme' => new external_value(PARAM_THEME, 1614 'the new category theme. This option must be enabled on moodle', 1615 VALUE_OPTIONAL), 1616 ) 1617 ) 1618 ) 1619 ) 1620 ); 1621 } 1622 1623 /** 1624 * Create categories 1625 * 1626 * @param array $categories - see create_categories_parameters() for the array structure 1627 * @return array - see create_categories_returns() for the array structure 1628 * @since Moodle 2.3 1629 */ 1630 public static function create_categories($categories) { 1631 global $CFG, $DB; 1632 require_once($CFG->libdir . "/coursecatlib.php"); 1633 1634 $params = self::validate_parameters(self::create_categories_parameters(), 1635 array('categories' => $categories)); 1636 1637 $transaction = $DB->start_delegated_transaction(); 1638 1639 $createdcategories = array(); 1640 foreach ($params['categories'] as $category) { 1641 if ($category['parent']) { 1642 if (!$DB->record_exists('course_categories', array('id' => $category['parent']))) { 1643 throw new moodle_exception('unknowcategory'); 1644 } 1645 $context = context_coursecat::instance($category['parent']); 1646 } else { 1647 $context = context_system::instance(); 1648 } 1649 self::validate_context($context); 1650 require_capability('moodle/category:manage', $context); 1651 1652 // this will validate format and throw an exception if there are errors 1653 external_validate_format($category['descriptionformat']); 1654 1655 $newcategory = coursecat::create($category); 1656 1657 $createdcategories[] = array('id' => $newcategory->id, 'name' => $newcategory->name); 1658 } 1659 1660 $transaction->allow_commit(); 1661 1662 return $createdcategories; 1663 } 1664 1665 /** 1666 * Returns description of method parameters 1667 * 1668 * @return external_function_parameters 1669 * @since Moodle 2.3 1670 */ 1671 public static function create_categories_returns() { 1672 return new external_multiple_structure( 1673 new external_single_structure( 1674 array( 1675 'id' => new external_value(PARAM_INT, 'new category id'), 1676 'name' => new external_value(PARAM_TEXT, 'new category name'), 1677 ) 1678 ) 1679 ); 1680 } 1681 1682 /** 1683 * Returns description of method parameters 1684 * 1685 * @return external_function_parameters 1686 * @since Moodle 2.3 1687 */ 1688 public static function update_categories_parameters() { 1689 return new external_function_parameters( 1690 array( 1691 'categories' => new external_multiple_structure( 1692 new external_single_structure( 1693 array( 1694 'id' => new external_value(PARAM_INT, 'course id'), 1695 'name' => new external_value(PARAM_TEXT, 'category name', VALUE_OPTIONAL), 1696 'idnumber' => new external_value(PARAM_RAW, 'category id number', VALUE_OPTIONAL), 1697 'parent' => new external_value(PARAM_INT, 'parent category id', VALUE_OPTIONAL), 1698 'description' => new external_value(PARAM_RAW, 'category description', VALUE_OPTIONAL), 1699 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 1700 'theme' => new external_value(PARAM_THEME, 1701 'the category theme. This option must be enabled on moodle', VALUE_OPTIONAL), 1702 ) 1703 ) 1704 ) 1705 ) 1706 ); 1707 } 1708 1709 /** 1710 * Update categories 1711 * 1712 * @param array $categories The list of categories to update 1713 * @return null 1714 * @since Moodle 2.3 1715 */ 1716 public static function update_categories($categories) { 1717 global $CFG, $DB; 1718 require_once($CFG->libdir . "/coursecatlib.php"); 1719 1720 // Validate parameters. 1721 $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories)); 1722 1723 $transaction = $DB->start_delegated_transaction(); 1724 1725 foreach ($params['categories'] as $cat) { 1726 $category = coursecat::get($cat['id']); 1727 1728 $categorycontext = context_coursecat::instance($cat['id']); 1729 self::validate_context($categorycontext); 1730 require_capability('moodle/category:manage', $categorycontext); 1731 1732 // this will throw an exception if descriptionformat is not valid 1733 external_validate_format($cat['descriptionformat']); 1734 1735 $category->update($cat); 1736 } 1737 1738 $transaction->allow_commit(); 1739 } 1740 1741 /** 1742 * Returns description of method result value 1743 * 1744 * @return external_description 1745 * @since Moodle 2.3 1746 */ 1747 public static function update_categories_returns() { 1748 return null; 1749 } 1750 1751 /** 1752 * Returns description of method parameters 1753 * 1754 * @return external_function_parameters 1755 * @since Moodle 2.3 1756 */ 1757 public static function delete_categories_parameters() { 1758 return new external_function_parameters( 1759 array( 1760 'categories' => new external_multiple_structure( 1761 new external_single_structure( 1762 array( 1763 'id' => new external_value(PARAM_INT, 'category id to delete'), 1764 'newparent' => new external_value(PARAM_INT, 1765 'the parent category to move the contents to, if specified', VALUE_OPTIONAL), 1766 'recursive' => new external_value(PARAM_BOOL, '1: recursively delete all contents inside this 1767 category, 0 (default): move contents to newparent or current parent category (except if parent is root)', VALUE_DEFAULT, 0) 1768 ) 1769 ) 1770 ) 1771 ) 1772 ); 1773 } 1774 1775 /** 1776 * Delete categories 1777 * 1778 * @param array $categories A list of category ids 1779 * @return array 1780 * @since Moodle 2.3 1781 */ 1782 public static function delete_categories($categories) { 1783 global $CFG, $DB; 1784 require_once($CFG->dirroot . "/course/lib.php"); 1785 require_once($CFG->libdir . "/coursecatlib.php"); 1786 1787 // Validate parameters. 1788 $params = self::validate_parameters(self::delete_categories_parameters(), array('categories' => $categories)); 1789 1790 $transaction = $DB->start_delegated_transaction(); 1791 1792 foreach ($params['categories'] as $category) { 1793 $deletecat = coursecat::get($category['id'], MUST_EXIST); 1794 $context = context_coursecat::instance($deletecat->id); 1795 require_capability('moodle/category:manage', $context); 1796 self::validate_context($context); 1797 self::validate_context(get_category_or_system_context($deletecat->parent)); 1798 1799 if ($category['recursive']) { 1800 // If recursive was specified, then we recursively delete the category's contents. 1801 if ($deletecat->can_delete_full()) { 1802 $deletecat->delete_full(false); 1803 } else { 1804 throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name()); 1805 } 1806 } else { 1807 // In this situation, we don't delete the category's contents, we either move it to newparent or parent. 1808 // If the parent is the root, moving is not supported (because a course must always be inside a category). 1809 // We must move to an existing category. 1810 if (!empty($category['newparent'])) { 1811 $newparentcat = coursecat::get($category['newparent']); 1812 } else { 1813 $newparentcat = coursecat::get($deletecat->parent); 1814 } 1815 1816 // This operation is not allowed. We must move contents to an existing category. 1817 if (!$newparentcat->id) { 1818 throw new moodle_exception('movecatcontentstoroot'); 1819 } 1820 1821 self::validate_context(context_coursecat::instance($newparentcat->id)); 1822 if ($deletecat->can_move_content_to($newparentcat->id)) { 1823 $deletecat->delete_move($newparentcat->id, false); 1824 } else { 1825 throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name()); 1826 } 1827 } 1828 } 1829 1830 $transaction->allow_commit(); 1831 } 1832 1833 /** 1834 * Returns description of method parameters 1835 * 1836 * @return external_function_parameters 1837 * @since Moodle 2.3 1838 */ 1839 public static function delete_categories_returns() { 1840 return null; 1841 } 1842 1843 /** 1844 * Describes the parameters for delete_modules. 1845 * 1846 * @return external_external_function_parameters 1847 * @since Moodle 2.5 1848 */ 1849 public static function delete_modules_parameters() { 1850 return new external_function_parameters ( 1851 array( 1852 'cmids' => new external_multiple_structure(new external_value(PARAM_INT, 'course module ID', 1853 VALUE_REQUIRED, '', NULL_NOT_ALLOWED), 'Array of course module IDs'), 1854 ) 1855 ); 1856 } 1857 1858 /** 1859 * Deletes a list of provided module instances. 1860 * 1861 * @param array $cmids the course module ids 1862 * @since Moodle 2.5 1863 */ 1864 public static function delete_modules($cmids) { 1865 global $CFG, $DB; 1866 1867 // Require course file containing the course delete module function. 1868 require_once($CFG->dirroot . "/course/lib.php"); 1869 1870 // Clean the parameters. 1871 $params = self::validate_parameters(self::delete_modules_parameters(), array('cmids' => $cmids)); 1872 1873 // Keep track of the course ids we have performed a capability check on to avoid repeating. 1874 $arrcourseschecked = array(); 1875 1876 foreach ($params['cmids'] as $cmid) { 1877 // Get the course module. 1878 $cm = $DB->get_record('course_modules', array('id' => $cmid), '*', MUST_EXIST); 1879 1880 // Check if we have not yet confirmed they have permission in this course. 1881 if (!in_array($cm->course, $arrcourseschecked)) { 1882 // Ensure the current user has required permission in this course. 1883 $context = context_course::instance($cm->course); 1884 self::validate_context($context); 1885 // Add to the array. 1886 $arrcourseschecked[] = $cm->course; 1887 } 1888 1889 // Ensure they can delete this module. 1890 $modcontext = context_module::instance($cm->id); 1891 require_capability('moodle/course:manageactivities', $modcontext); 1892 1893 // Delete the module. 1894 course_delete_module($cm->id); 1895 } 1896 } 1897 1898 /** 1899 * Describes the delete_modules return value. 1900 * 1901 * @return external_single_structure 1902 * @since Moodle 2.5 1903 */ 1904 public static function delete_modules_returns() { 1905 return null; 1906 } 1907 } 1908 1909 /** 1910 * Deprecated course external functions 1911 * 1912 * @package core_course 1913 * @copyright 2009 Petr Skodak 1914 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 1915 * @since Moodle 2.0 1916 * @deprecated Moodle 2.2 MDL-29106 - Please do not use this class any more. 1917 * @see core_course_external 1918 */ 1919 class moodle_course_external extends external_api { 1920 1921 /** 1922 * Returns description of method parameters 1923 * 1924 * @return external_function_parameters 1925 * @since Moodle 2.0 1926 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1927 * @see core_course_external::get_courses_parameters() 1928 */ 1929 public static function get_courses_parameters() { 1930 return core_course_external::get_courses_parameters(); 1931 } 1932 1933 /** 1934 * Get courses 1935 * 1936 * @param array $options 1937 * @return array 1938 * @since Moodle 2.0 1939 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1940 * @see core_course_external::get_courses() 1941 */ 1942 public static function get_courses($options) { 1943 return core_course_external::get_courses($options); 1944 } 1945 1946 /** 1947 * Returns description of method result value 1948 * 1949 * @return external_description 1950 * @since Moodle 2.0 1951 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1952 * @see core_course_external::get_courses_returns() 1953 */ 1954 public static function get_courses_returns() { 1955 return core_course_external::get_courses_returns(); 1956 } 1957 1958 /** 1959 * Returns description of method parameters 1960 * 1961 * @return external_function_parameters 1962 * @since Moodle 2.0 1963 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1964 * @see core_course_external::create_courses_parameters() 1965 */ 1966 public static function create_courses_parameters() { 1967 return core_course_external::create_courses_parameters(); 1968 } 1969 1970 /** 1971 * Create courses 1972 * 1973 * @param array $courses 1974 * @return array courses (id and shortname only) 1975 * @since Moodle 2.0 1976 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1977 * @see core_course_external::create_courses() 1978 */ 1979 public static function create_courses($courses) { 1980 return core_course_external::create_courses($courses); 1981 } 1982 1983 /** 1984 * Returns description of method result value 1985 * 1986 * @return external_description 1987 * @since Moodle 2.0 1988 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. 1989 * @see core_course_external::create_courses_returns() 1990 */ 1991 public static function create_courses_returns() { 1992 return core_course_external::create_courses_returns(); 1993 } 1994 1995 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |