[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/course/ -> modlib.php (source)

   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   * Library of functions specific to course/modedit.php and course API functions.
  19   * The course API function calling them are course/lib.php:create_module() and update_module().
  20   * This file has been created has an alternative solution to a full refactor of course/modedit.php
  21   * in order to create the course API functions.
  22   *
  23   * @copyright 2013 Jerome Mouneyrac
  24   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   * @package core_course
  26   */
  27  
  28  defined('MOODLE_INTERNAL') || die;
  29  
  30  require_once($CFG->dirroot.'/course/lib.php');
  31  
  32  /**
  33   * Add course module.
  34   *
  35   * The function does not check user capabilities.
  36   * The function creates course module, module instance, add the module to the correct section.
  37   * It also trigger common action that need to be done after adding/updating a module.
  38   *
  39   * @param object $moduleinfo the moudle data
  40   * @param object $course the course of the module
  41   * @param object $mform this is required by an existing hack to deal with files during MODULENAME_add_instance()
  42   * @return object the updated module info
  43   */
  44  function add_moduleinfo($moduleinfo, $course, $mform = null) {
  45      global $DB, $CFG;
  46  
  47      // Attempt to include module library before we make any changes to DB.
  48      include_modulelib($moduleinfo->modulename);
  49  
  50      $moduleinfo->course = $course->id;
  51      $moduleinfo = set_moduleinfo_defaults($moduleinfo);
  52  
  53      if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) {
  54          $moduleinfo->groupmode = 0; // Do not set groupmode.
  55      }
  56  
  57      // First add course_module record because we need the context.
  58      $newcm = new stdClass();
  59      $newcm->course           = $course->id;
  60      $newcm->module           = $moduleinfo->module;
  61      $newcm->instance         = 0; // Not known yet, will be updated later (this is similar to restore code).
  62      $newcm->visible          = $moduleinfo->visible;
  63      $newcm->visibleold       = $moduleinfo->visible;
  64      if (isset($moduleinfo->cmidnumber)) {
  65          $newcm->idnumber         = $moduleinfo->cmidnumber;
  66      }
  67      $newcm->groupmode        = $moduleinfo->groupmode;
  68      $newcm->groupingid       = $moduleinfo->groupingid;
  69      $completion = new completion_info($course);
  70      if ($completion->is_enabled()) {
  71          $newcm->completion                = $moduleinfo->completion;
  72          $newcm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber;
  73          $newcm->completionview            = $moduleinfo->completionview;
  74          $newcm->completionexpected        = $moduleinfo->completionexpected;
  75      }
  76      if(!empty($CFG->enableavailability)) {
  77          // This code is used both when submitting the form, which uses a long
  78          // name to avoid clashes, and by unit test code which uses the real
  79          // name in the table.
  80          $newcm->availability = null;
  81          if (property_exists($moduleinfo, 'availabilityconditionsjson')) {
  82              if ($moduleinfo->availabilityconditionsjson !== '') {
  83                  $newcm->availability = $moduleinfo->availabilityconditionsjson;
  84              }
  85          } else if (property_exists($moduleinfo, 'availability')) {
  86              $newcm->availability = $moduleinfo->availability;
  87          }
  88          // If there is any availability data, verify it.
  89          if ($newcm->availability) {
  90              $tree = new \core_availability\tree(json_decode($newcm->availability));
  91              // Save time and database space by setting null if the only data
  92              // is an empty tree.
  93              if ($tree->is_empty()) {
  94                  $newcm->availability = null;
  95              }
  96          }
  97      }
  98      if (isset($moduleinfo->showdescription)) {
  99          $newcm->showdescription = $moduleinfo->showdescription;
 100      } else {
 101          $newcm->showdescription = 0;
 102      }
 103  
 104      // From this point we make database changes, so start transaction.
 105      $transaction = $DB->start_delegated_transaction();
 106  
 107      if (!$moduleinfo->coursemodule = add_course_module($newcm)) {
 108          print_error('cannotaddcoursemodule');
 109      }
 110  
 111      if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true) &&
 112              isset($moduleinfo->introeditor)) {
 113          $introeditor = $moduleinfo->introeditor;
 114          unset($moduleinfo->introeditor);
 115          $moduleinfo->intro       = $introeditor['text'];
 116          $moduleinfo->introformat = $introeditor['format'];
 117      }
 118  
 119      $addinstancefunction    = $moduleinfo->modulename."_add_instance";
 120      try {
 121          $returnfromfunc = $addinstancefunction($moduleinfo, $mform);
 122      } catch (moodle_exception $e) {
 123          $returnfromfunc = $e;
 124      }
 125      if (!$returnfromfunc or !is_number($returnfromfunc)) {
 126          // Undo everything we can. This is not necessary for databases which
 127          // support transactions, but improves consistency for other databases.
 128          $modcontext = context_module::instance($moduleinfo->coursemodule);
 129          context_helper::delete_instance(CONTEXT_MODULE, $moduleinfo->coursemodule);
 130          $DB->delete_records('course_modules', array('id'=>$moduleinfo->coursemodule));
 131  
 132          if ($e instanceof moodle_exception) {
 133              throw $e;
 134          } else if (!is_number($returnfromfunc)) {
 135              print_error('invalidfunction', '', course_get_url($course, $moduleinfo->section));
 136          } else {
 137              print_error('cannotaddnewmodule', '', course_get_url($course, $moduleinfo->section), $moduleinfo->modulename);
 138          }
 139      }
 140  
 141      $moduleinfo->instance = $returnfromfunc;
 142  
 143      $DB->set_field('course_modules', 'instance', $returnfromfunc, array('id'=>$moduleinfo->coursemodule));
 144  
 145      // Update embedded links and save files.
 146      $modcontext = context_module::instance($moduleinfo->coursemodule);
 147      if (!empty($introeditor)) {
 148          $moduleinfo->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id,
 149                                                        'mod_'.$moduleinfo->modulename, 'intro', 0,
 150                                                        array('subdirs'=>true), $introeditor['text']);
 151          $DB->set_field($moduleinfo->modulename, 'intro', $moduleinfo->intro, array('id'=>$moduleinfo->instance));
 152      }
 153  
 154      // Add module tags.
 155      if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) {
 156          core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags);
 157      }
 158  
 159      // Course_modules and course_sections each contain a reference to each other.
 160      // So we have to update one of them twice.
 161      $sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section);
 162  
 163      // Trigger event based on the action we did.
 164      // Api create_from_cm expects modname and id property, and we don't want to modify $moduleinfo since we are returning it.
 165      $eventdata = clone $moduleinfo;
 166      $eventdata->modname = $eventdata->modulename;
 167      $eventdata->id = $eventdata->coursemodule;
 168      $event = \core\event\course_module_created::create_from_cm($eventdata, $modcontext);
 169      $event->trigger();
 170  
 171      $moduleinfo = edit_module_post_actions($moduleinfo, $course);
 172      $transaction->allow_commit();
 173  
 174      return $moduleinfo;
 175  }
 176  
 177  /**
 178   * Hook for plugins to take action when a module is created or updated.
 179   *
 180   * @param stdClass $moduleinfo the module info
 181   * @param stdClass $course the course of the module
 182   *
 183   * @return stdClass moduleinfo updated by plugins.
 184   */
 185  function plugin_extend_coursemodule_edit_post_actions($moduleinfo, $course) {
 186      $callbacks = get_plugins_with_function('coursemodule_edit_post_actions', 'lib.php');
 187      foreach ($callbacks as $type => $plugins) {
 188          foreach ($plugins as $plugin => $pluginfunction) {
 189              $moduleinfo = $pluginfunction($moduleinfo, $course);
 190          }
 191      }
 192      return $moduleinfo;
 193  }
 194  
 195  /**
 196   * Common create/update module module actions that need to be processed as soon as a module is created/updaded.
 197   * For example:create grade parent category, add outcomes, rebuild caches, regrade, save plagiarism settings...
 198   * Please note this api does not trigger events as of MOODLE 2.6. Please trigger events before calling this api.
 199   *
 200   * @param object $moduleinfo the module info
 201   * @param object $course the course of the module
 202   *
 203   * @return object moduleinfo update with grading management info
 204   */
 205  function edit_module_post_actions($moduleinfo, $course) {
 206      global $CFG;
 207      require_once($CFG->libdir.'/gradelib.php');
 208  
 209      $modcontext = context_module::instance($moduleinfo->coursemodule);
 210      $hasgrades = plugin_supports('mod', $moduleinfo->modulename, FEATURE_GRADE_HAS_GRADE, false);
 211      $hasoutcomes = plugin_supports('mod', $moduleinfo->modulename, FEATURE_GRADE_OUTCOMES, true);
 212  
 213      // Sync idnumber with grade_item.
 214      if ($hasgrades && $grade_item = grade_item::fetch(array('itemtype'=>'mod', 'itemmodule'=>$moduleinfo->modulename,
 215                   'iteminstance'=>$moduleinfo->instance, 'itemnumber'=>0, 'courseid'=>$course->id))) {
 216          $gradeupdate = false;
 217          if ($grade_item->idnumber != $moduleinfo->cmidnumber) {
 218              $grade_item->idnumber = $moduleinfo->cmidnumber;
 219              $gradeupdate = true;
 220          }
 221          if (isset($moduleinfo->gradepass) && $grade_item->gradepass != $moduleinfo->gradepass) {
 222              $grade_item->gradepass = $moduleinfo->gradepass;
 223              $gradeupdate = true;
 224          }
 225          if ($gradeupdate) {
 226              $grade_item->update();
 227          }
 228      }
 229  
 230      if ($hasgrades) {
 231          $items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$moduleinfo->modulename,
 232                                           'iteminstance'=>$moduleinfo->instance, 'courseid'=>$course->id));
 233      } else {
 234          $items = array();
 235      }
 236  
 237      // Create parent category if requested and move to correct parent category.
 238      if ($items and isset($moduleinfo->gradecat)) {
 239          if ($moduleinfo->gradecat == -1) {
 240              $grade_category = new grade_category();
 241              $grade_category->courseid = $course->id;
 242              $grade_category->fullname = $moduleinfo->name;
 243              $grade_category->insert();
 244              if ($grade_item) {
 245                  $parent = $grade_item->get_parent_category();
 246                  $grade_category->set_parent($parent->id);
 247              }
 248              $moduleinfo->gradecat = $grade_category->id;
 249          }
 250  
 251          foreach ($items as $itemid=>$unused) {
 252              $items[$itemid]->set_parent($moduleinfo->gradecat);
 253              if ($itemid == $grade_item->id) {
 254                  // Use updated grade_item.
 255                  $grade_item = $items[$itemid];
 256              }
 257          }
 258      }
 259  
 260      require_once($CFG->libdir.'/grade/grade_outcome.php');
 261      // Add outcomes if requested.
 262      if ($hasoutcomes && $outcomes = grade_outcome::fetch_all_available($course->id)) {
 263          $grade_items = array();
 264  
 265          // Outcome grade_item.itemnumber start at 1000, there is nothing above outcomes.
 266          $max_itemnumber = 999;
 267          if ($items) {
 268              foreach($items as $item) {
 269                  if ($item->itemnumber > $max_itemnumber) {
 270                      $max_itemnumber = $item->itemnumber;
 271                  }
 272              }
 273          }
 274  
 275          foreach($outcomes as $outcome) {
 276              $elname = 'outcome_'.$outcome->id;
 277  
 278              if (property_exists($moduleinfo, $elname) and $moduleinfo->$elname) {
 279                  // So we have a request for new outcome grade item?
 280                  if ($items) {
 281                      $outcomeexists = false;
 282                      foreach($items as $item) {
 283                          if ($item->outcomeid == $outcome->id) {
 284                              $outcomeexists = true;
 285                              break;
 286                          }
 287                      }
 288                      if ($outcomeexists) {
 289                          continue;
 290                      }
 291                  }
 292  
 293                  $max_itemnumber++;
 294  
 295                  $outcome_item = new grade_item();
 296                  $outcome_item->courseid     = $course->id;
 297                  $outcome_item->itemtype     = 'mod';
 298                  $outcome_item->itemmodule   = $moduleinfo->modulename;
 299                  $outcome_item->iteminstance = $moduleinfo->instance;
 300                  $outcome_item->itemnumber   = $max_itemnumber;
 301                  $outcome_item->itemname     = $outcome->fullname;
 302                  $outcome_item->outcomeid    = $outcome->id;
 303                  $outcome_item->gradetype    = GRADE_TYPE_SCALE;
 304                  $outcome_item->scaleid      = $outcome->scaleid;
 305                  $outcome_item->insert();
 306  
 307                  // Move the new outcome into correct category and fix sortorder if needed.
 308                  if ($grade_item) {
 309                      $outcome_item->set_parent($grade_item->categoryid);
 310                      $outcome_item->move_after_sortorder($grade_item->sortorder);
 311  
 312                  } else if (isset($moduleinfo->gradecat)) {
 313                      $outcome_item->set_parent($moduleinfo->gradecat);
 314                  }
 315              }
 316          }
 317      }
 318  
 319      if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_ADVANCED_GRADING, false)
 320              and has_capability('moodle/grade:managegradingforms', $modcontext)) {
 321          require_once($CFG->dirroot.'/grade/grading/lib.php');
 322          $gradingman = get_grading_manager($modcontext, 'mod_'.$moduleinfo->modulename);
 323          $showgradingmanagement = false;
 324          foreach ($gradingman->get_available_areas() as $areaname => $aretitle) {
 325              $formfield = 'advancedgradingmethod_'.$areaname;
 326              if (isset($moduleinfo->{$formfield})) {
 327                  $gradingman->set_area($areaname);
 328                  $methodchanged = $gradingman->set_active_method($moduleinfo->{$formfield});
 329                  if (empty($moduleinfo->{$formfield})) {
 330                      // Going back to the simple direct grading is not a reason to open the management screen.
 331                      $methodchanged = false;
 332                  }
 333                  $showgradingmanagement = $showgradingmanagement || $methodchanged;
 334              }
 335          }
 336          // Update grading management information.
 337          $moduleinfo->gradingman = $gradingman;
 338          $moduleinfo->showgradingmanagement = $showgradingmanagement;
 339      }
 340  
 341      rebuild_course_cache($course->id, true);
 342      if ($hasgrades) {
 343          grade_regrade_final_grades($course->id);
 344      }
 345      require_once($CFG->libdir.'/plagiarismlib.php');
 346      plagiarism_save_form_elements($moduleinfo);
 347  
 348      // Allow plugins to extend the course module form.
 349      $moduleinfo = plugin_extend_coursemodule_edit_post_actions($moduleinfo, $course);
 350  
 351      return $moduleinfo;
 352  }
 353  
 354  
 355  /**
 356   * Set module info default values for the unset module attributs.
 357   *
 358   * @param object $moduleinfo the current known data of the module
 359   * @return object the completed module info
 360   */
 361  function set_moduleinfo_defaults($moduleinfo) {
 362  
 363      if (empty($moduleinfo->coursemodule)) {
 364          // Add.
 365          $cm = null;
 366          $moduleinfo->instance     = '';
 367          $moduleinfo->coursemodule = '';
 368      } else {
 369          // Update.
 370          $cm = get_coursemodule_from_id('', $moduleinfo->coursemodule, 0, false, MUST_EXIST);
 371          $moduleinfo->instance     = $cm->instance;
 372          $moduleinfo->coursemodule = $cm->id;
 373      }
 374      // For safety.
 375      $moduleinfo->modulename = clean_param($moduleinfo->modulename, PARAM_PLUGIN);
 376  
 377      if (!isset($moduleinfo->groupingid)) {
 378          $moduleinfo->groupingid = 0;
 379      }
 380  
 381      if (!isset($moduleinfo->name)) { // Label.
 382          $moduleinfo->name = $moduleinfo->modulename;
 383      }
 384  
 385      if (!isset($moduleinfo->completion)) {
 386          $moduleinfo->completion = COMPLETION_DISABLED;
 387      }
 388      if (!isset($moduleinfo->completionview)) {
 389          $moduleinfo->completionview = COMPLETION_VIEW_NOT_REQUIRED;
 390      }
 391      if (!isset($moduleinfo->completionexpected)) {
 392          $moduleinfo->completionexpected = 0;
 393      }
 394  
 395      // Convert the 'use grade' checkbox into a grade-item number: 0 if checked, null if not.
 396      if (isset($moduleinfo->completionusegrade) && $moduleinfo->completionusegrade) {
 397          $moduleinfo->completiongradeitemnumber = 0;
 398      } else {
 399          $moduleinfo->completiongradeitemnumber = null;
 400      }
 401  
 402      if (!isset($moduleinfo->conditiongradegroup)) {
 403          $moduleinfo->conditiongradegroup = array();
 404      }
 405      if (!isset($moduleinfo->conditionfieldgroup)) {
 406          $moduleinfo->conditionfieldgroup = array();
 407      }
 408  
 409      return $moduleinfo;
 410  }
 411  
 412  /**
 413   * Check that the user can add a module. Also returns some information like the module, context and course section info.
 414   * The fucntion create the course section if it doesn't exist.
 415   *
 416   * @param object $course the course of the module
 417   * @param object $modulename the module name
 418   * @param object $section the section of the module
 419   * @return array list containing module, context, course section.
 420   * @throws moodle_exception if user is not allowed to perform the action or module is not allowed in this course
 421   */
 422  function can_add_moduleinfo($course, $modulename, $section) {
 423      global $DB;
 424  
 425      $module = $DB->get_record('modules', array('name'=>$modulename), '*', MUST_EXIST);
 426  
 427      $context = context_course::instance($course->id);
 428      require_capability('moodle/course:manageactivities', $context);
 429  
 430      course_create_sections_if_missing($course, $section);
 431      $cw = get_fast_modinfo($course)->get_section_info($section);
 432  
 433      if (!course_allowed_module($course, $module->name)) {
 434          print_error('moduledisable');
 435      }
 436  
 437      return array($module, $context, $cw);
 438  }
 439  
 440  /**
 441   * Check if user is allowed to update module info and returns related item/data to the module.
 442   *
 443   * @param object $cm course module
 444   * @return array - list of course module, context, module, moduleinfo, and course section.
 445   * @throws moodle_exception if user is not allowed to perform the action
 446   */
 447  function can_update_moduleinfo($cm) {
 448      global $DB;
 449  
 450      // Check the $USER has the right capability.
 451      $context = context_module::instance($cm->id);
 452      require_capability('moodle/course:manageactivities', $context);
 453  
 454      // Check module exists.
 455      $module = $DB->get_record('modules', array('id'=>$cm->module), '*', MUST_EXIST);
 456  
 457      // Check the moduleinfo exists.
 458      $data = $DB->get_record($module->name, array('id'=>$cm->instance), '*', MUST_EXIST);
 459  
 460      // Check the course section exists.
 461      $cw = $DB->get_record('course_sections', array('id'=>$cm->section), '*', MUST_EXIST);
 462  
 463      return array($cm, $context, $module, $data, $cw);
 464  }
 465  
 466  
 467  /**
 468   * Update the module info.
 469   * This function doesn't check the user capabilities. It updates the course module and the module instance.
 470   * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...).
 471   *
 472   * @param object $cm course module
 473   * @param object $moduleinfo module info
 474   * @param object $course course of the module
 475   * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function.
 476   * @return array list of course module and module info.
 477   */
 478  function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
 479      global $DB, $CFG;
 480  
 481      $data = new stdClass();
 482      if ($mform) {
 483          $data = $mform->get_data();
 484      }
 485  
 486      // Attempt to include module library before we make any changes to DB.
 487      include_modulelib($moduleinfo->modulename);
 488  
 489      $moduleinfo->course = $course->id;
 490      $moduleinfo = set_moduleinfo_defaults($moduleinfo);
 491  
 492      if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) {
 493          $moduleinfo->groupmode = $cm->groupmode; // Keep original.
 494      }
 495  
 496      // Update course module first.
 497      $cm->groupmode = $moduleinfo->groupmode;
 498      if (isset($moduleinfo->groupingid)) {
 499          $cm->groupingid = $moduleinfo->groupingid;
 500      }
 501  
 502      $completion = new completion_info($course);
 503      if ($completion->is_enabled()) {
 504          // Completion settings that would affect users who have already completed
 505          // the activity may be locked; if so, these should not be updated.
 506          if (!empty($moduleinfo->completionunlocked)) {
 507              $cm->completion = $moduleinfo->completion;
 508              $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber;
 509              $cm->completionview = $moduleinfo->completionview;
 510          }
 511          // The expected date does not affect users who have completed the activity,
 512          // so it is safe to update it regardless of the lock status.
 513          $cm->completionexpected = $moduleinfo->completionexpected;
 514      }
 515      if (!empty($CFG->enableavailability)) {
 516          // This code is used both when submitting the form, which uses a long
 517          // name to avoid clashes, and by unit test code which uses the real
 518          // name in the table.
 519          if (property_exists($moduleinfo, 'availabilityconditionsjson')) {
 520              if ($moduleinfo->availabilityconditionsjson !== '') {
 521                  $cm->availability = $moduleinfo->availabilityconditionsjson;
 522              } else {
 523                  $cm->availability = null;
 524              }
 525          } else if (property_exists($moduleinfo, 'availability')) {
 526              $cm->availability = $moduleinfo->availability;
 527          }
 528          // If there is any availability data, verify it.
 529          if ($cm->availability) {
 530              $tree = new \core_availability\tree(json_decode($cm->availability));
 531              // Save time and database space by setting null if the only data
 532              // is an empty tree.
 533              if ($tree->is_empty()) {
 534                  $cm->availability = null;
 535              }
 536          }
 537      }
 538      if (isset($moduleinfo->showdescription)) {
 539          $cm->showdescription = $moduleinfo->showdescription;
 540      } else {
 541          $cm->showdescription = 0;
 542      }
 543  
 544      $DB->update_record('course_modules', $cm);
 545  
 546      $modcontext = context_module::instance($moduleinfo->coursemodule);
 547  
 548      // Update embedded links and save files.
 549      if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) {
 550          $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id,
 551                                                        'mod_'.$moduleinfo->modulename, 'intro', 0,
 552                                                        array('subdirs'=>true), $moduleinfo->introeditor['text']);
 553          $moduleinfo->introformat = $moduleinfo->introeditor['format'];
 554          unset($moduleinfo->introeditor);
 555      }
 556      // Get the a copy of the grade_item before it is modified incase we need to scale the grades.
 557      $oldgradeitem = null;
 558      $newgradeitem = null;
 559      if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
 560          // Fetch the grade item before it is updated.
 561          $oldgradeitem = grade_item::fetch(array('itemtype' => 'mod',
 562                                                  'itemmodule' => $moduleinfo->modulename,
 563                                                  'iteminstance' => $moduleinfo->instance,
 564                                                  'itemnumber' => 0,
 565                                                  'courseid' => $moduleinfo->course));
 566      }
 567  
 568      $updateinstancefunction = $moduleinfo->modulename."_update_instance";
 569      if (!$updateinstancefunction($moduleinfo, $mform)) {
 570          print_error('cannotupdatemod', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
 571      }
 572  
 573      // This needs to happen AFTER the grademin/grademax have already been updated.
 574      if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
 575          // Get the grade_item after the update call the activity to scale the grades.
 576          $newgradeitem = grade_item::fetch(array('itemtype' => 'mod',
 577                                                  'itemmodule' => $moduleinfo->modulename,
 578                                                  'iteminstance' => $moduleinfo->instance,
 579                                                  'itemnumber' => 0,
 580                                                  'courseid' => $moduleinfo->course));
 581          if ($newgradeitem && $oldgradeitem->gradetype == GRADE_TYPE_VALUE && $newgradeitem->gradetype == GRADE_TYPE_VALUE) {
 582              $params = array(
 583                  $course,
 584                  $cm,
 585                  $oldgradeitem->grademin,
 586                  $oldgradeitem->grademax,
 587                  $newgradeitem->grademin,
 588                  $newgradeitem->grademax
 589              );
 590              if (!component_callback('mod_' . $moduleinfo->modulename, 'rescale_activity_grades', $params)) {
 591                  print_error('cannotreprocessgrades', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
 592              }
 593          }
 594      }
 595  
 596      // Make sure visibility is set correctly (in particular in calendar).
 597      if (has_capability('moodle/course:activityvisibility', $modcontext)) {
 598          set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible);
 599      }
 600  
 601      if (isset($moduleinfo->cmidnumber)) { // Label.
 602          // Set cm idnumber - uniqueness is already verified by form validation.
 603          set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber);
 604      }
 605  
 606      // Update module tags.
 607      if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) {
 608          core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags);
 609      }
 610  
 611      // Now that module is fully updated, also update completion data if required.
 612      // (this will wipe all user completion data and recalculate it)
 613      if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) {
 614          $completion->reset_all_state($cm);
 615      }
 616      $cm->name = $moduleinfo->name;
 617      \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger();
 618  
 619      $moduleinfo = edit_module_post_actions($moduleinfo, $course);
 620  
 621      return array($cm, $moduleinfo);
 622  }
 623  
 624  /**
 625   * Include once the module lib file.
 626   *
 627   * @param string $modulename module name of the lib to include
 628   * @throws moodle_exception if lib.php file for the module does not exist
 629   */
 630  function include_modulelib($modulename) {
 631      global $CFG;
 632      $modlib = "$CFG->dirroot/mod/$modulename/lib.php";
 633      if (file_exists($modlib)) {
 634          include_once($modlib);
 635      } else {
 636          throw new moodle_exception('modulemissingcode', '', '', $modlib);
 637      }
 638  }
 639  


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1