Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Edit a calculated grade item
  19   *
  20   * @package   core_grades
  21   * @copyright 2007 Petr Skoda
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  require_once '../../../config.php';
  26  require_once $CFG->dirroot.'/grade/lib.php';
  27  require_once $CFG->libdir.'/mathslib.php';
  28  require_once  'calculation_form.php';
  29  
  30  $courseid  = required_param('courseid', PARAM_INT);
  31  $id        = required_param('id', PARAM_INT);
  32  $section   = optional_param('section', 'calculation', PARAM_ALPHA);
  33  $idnumbers = optional_param_array('idnumbers', null, PARAM_RAW);
  34  
  35  $url = new moodle_url('/grade/edit/tree/calculation.php', array('id'=>$id, 'courseid'=>$courseid));
  36  if ($section !== 'calculation') {
  37      $url->param('section', $section);
  38  }
  39  $PAGE->set_url($url);
  40  
  41  if (!$course = $DB->get_record('course', array('id' => $courseid))) {
  42      throw new \moodle_exception('invalidcourseid');
  43  }
  44  
  45  require_login($course);
  46  $context = context_course::instance($course->id);
  47  require_capability('moodle/grade:manage', $context);
  48  
  49  $PAGE->set_pagelayout('admin');
  50  navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
  51      array('id'=>$course->id)));
  52  
  53  // default return url
  54  $gpr = new grade_plugin_return();
  55  $returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report/index.php?id='.$course->id);
  56  
  57  if (!$grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
  58      throw new \moodle_exception('invaliditemid');
  59  }
  60  
  61  // activity items and items without grade can not have calculation
  62  if ($grade_item->is_external_item() or ($grade_item->gradetype != GRADE_TYPE_VALUE and $grade_item->gradetype != GRADE_TYPE_SCALE)) {
  63      redirect($returnurl, get_string('errornocalculationallowed', 'grades'));
  64  }
  65  
  66  $mform = new edit_calculation_form(null, array('gpr'=>$gpr, 'itemid' => $grade_item->id));
  67  
  68  if ($mform->is_cancelled()) {
  69      redirect($returnurl);
  70  
  71  }
  72  
  73  $calculation = calc_formula::localize($grade_item->calculation);
  74  $calculation = grade_item::denormalize_formula($calculation, $grade_item->courseid);
  75  $mform->set_data(array('courseid'=>$grade_item->courseid, 'calculation'=>$calculation, 'id'=>$grade_item->id, 'itemname'=>$grade_item->itemname));
  76  
  77  $errors = array();
  78  
  79  if ($data = $mform->get_data()) {
  80      $calculation = calc_formula::unlocalize($data->calculation);
  81      $grade_item->set_calculation($calculation);
  82  
  83      redirect($returnurl);
  84  
  85  } elseif (!empty($section) AND $section='idnumbers' AND !empty($idnumbers)) { // Handle idnumbers separately (non-mform)
  86      //first validate and store the new idnumbers
  87      foreach ($idnumbers as $giid => $value) {
  88          if ($gi = grade_item::fetch(array('id' => $giid))) {
  89              if ($gi->itemtype == 'mod') {
  90                  $cm = get_coursemodule_from_instance($gi->itemmodule, $gi->iteminstance, $gi->courseid);
  91              } else {
  92                  $cm = null;
  93              }
  94  
  95              if (!grade_verify_idnumber($value, $COURSE->id, $gi, $cm)) {
  96                  $errors[$giid] = get_string('idnumbertaken');
  97                  continue;
  98              }
  99  
 100              if (empty($gi->idnumber) and !$gi->add_idnumber($idnumbers[$gi->id])) {
 101                  $errors[$giid] = get_string('error');
 102                  continue;
 103              }
 104          } else {
 105              $errors[$giid] = 'Could not fetch the grade_item with id=' . $giid;
 106          }
 107      }
 108  }
 109  
 110  $gtree = new grade_tree($course->id, false, false);
 111  
 112  $strgrades          = get_string('grades');
 113  $strgraderreport    = get_string('graderreport', 'grades');
 114  $strcalculationedit = get_string('editcalculation', 'grades');
 115  
 116  $PAGE->navbar->add($strcalculationedit);
 117  print_grade_page_head($courseid, 'settings', null, $strcalculationedit, false, false, false);
 118  
 119  $mform->display();
 120  // Now show the gradetree with the idnumbers add/edit form
 121  echo '
 122  <form class="mform" id="mform2" method="post" action="' . $CFG->wwwroot . '/grade/edit/tree/calculation.php?courseid='.$courseid.'&amp;id='.$id.'">
 123      <div style="display: none;">
 124          <input type="hidden" value="'.$id.'" name="id"/>
 125          <input type="hidden" value="'.$courseid.'" name="courseid"/>
 126          <input type="hidden" value="'.$gpr->type.'" name="gpr_type"/>
 127          <input type="hidden" value="'.$gpr->plugin.'" name="gpr_plugin"/>
 128          <input type="hidden" value="'.$gpr->courseid.'" name="gpr_courseid"/>
 129          <input type="hidden" value="'.sesskey().'" name="sesskey"/>
 130          <input type="hidden" value="idnumbers" name="section"/>
 131      </div>
 132  
 133      <fieldset id="idnumbers" class="clearfix">
 134          <legend class="ftoggler">'.get_string('idnumbers', 'grades').'</legend>
 135          <div class="fcontainer clearfix">
 136              <ul>
 137              ' . get_grade_tree($gtree, $gtree->top_element, $id, $errors) . '
 138              </ul>
 139          </div>
 140      </fieldset>
 141      <div class="fitem" style="text-align: center;">
 142          <input id="id_addidnumbers" type="submit" class="btn btn-secondary" value="' . get_string('addidnumbers', 'grades') . '" name="addidnumbers" />
 143      </div>
 144  </form>';
 145  
 146  echo $OUTPUT->footer();
 147  die();
 148  
 149  
 150  /**
 151   * Simplified version of the print_grade_tree() recursive function found in grade/edit/tree/index.php
 152   * Only prints a tree with a basic icon for each element, and an edit field for
 153   * items without an idnumber.
 154   * @param object $gtree
 155   * @param object $element
 156   * @param int $current_itemid The itemid of this page: should be excluded from the tree
 157   * @param array $errors An array of idnumbers => error
 158   * @return string
 159   */
 160  function get_grade_tree(&$gtree, $element, $current_itemid=null, $errors=null) {
 161      global $CFG;
 162  
 163      $object     = $element['object'];
 164      $eid        = $element['eid'];
 165      $type       = $element['type'];
 166      $grade_item = $object->get_grade_item();
 167  
 168      $name = $object->get_name();
 169      $return_string = '';
 170  
 171      //TODO: improve outcome visualisation
 172      if ($type == 'item' and !empty($object->outcomeid)) {
 173          $name = $name.' ('.get_string('outcome', 'grades').')';
 174      }
 175  
 176      $idnumber = $object->get_idnumber();
 177  
 178      // Don't show idnumber or input field for current item if given to function. Highlight the item instead.
 179      if ($type != 'category') {
 180          if (is_null($current_itemid) OR $grade_item->id != $current_itemid) {
 181              if ($idnumber) {
 182                  $name .= ": [[$idnumber]]";
 183              } else {
 184                  $closingdiv = '';
 185                  if (!empty($errors[$grade_item->id])) {
 186                      $name .= '<div class="error"><span class="error">' . $errors[$grade_item->id].'</span><br />'."\n";
 187                      $closingdiv = "</div>\n";
 188                  }
 189                  $name .= '<label class="accesshide" for="id_idnumber_' . $grade_item->id . '">' . get_string('gradeitems', 'grades')  .'</label>';
 190                  $name .= '<input class="idnumber" id="id_idnumber_'.$grade_item->id.'" type="text" name="idnumbers['.$grade_item->id.']" />' . "\n";
 191                  $name .= $closingdiv;
 192              }
 193          } else {
 194              $name = "<strong>$name</strong>";
 195          }
 196      }
 197  
 198      $icon = $gtree->get_element_icon($element, true);
 199      $last = '';
 200      $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
 201  
 202      if ($type != 'category') {
 203          $return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n";
 204      } else {
 205          $return_string .= '<li class="'.$type.'">'.$icon.$name . "\n";
 206          $return_string .= '<ul class="catlevel'.$element['depth'].'">'."\n";
 207          $last = null;
 208          foreach($element['children'] as $child_el) {
 209              $return_string .= get_grade_tree($gtree, $child_el, $current_itemid, $errors);
 210          }
 211          if ($last) {
 212              $return_string .= get_grade_tree($gtree, $last, $current_itemid, $errors);
 213          }
 214          $return_string .= '</ul></li>'."\n";
 215      }
 216  
 217      return $return_string;
 218  }
 219  
 220