[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/form/ -> modgrade.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  /**
  19   * Drop down form element to select the grade
  20   *
  21   * Contains HTML class for a drop down element to select the grade for an activity,
  22   * used in mod update form
  23   *
  24   * @package   core_form
  25   * @copyright 2006 Jamie Pratt <[email protected]>
  26   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27   */
  28  
  29  global $CFG;
  30  require_once "$CFG->libdir/form/select.php";
  31  require_once("HTML/QuickForm/element.php");
  32  require_once($CFG->dirroot.'/lib/form/group.php');
  33  require_once($CFG->dirroot.'/lib/grade/grade_scale.php');
  34  
  35  /**
  36   * Drop down form element to select the grade
  37   *
  38   * HTML class for a drop down element to select the grade for an activity,
  39   * used in mod update form
  40   *
  41   * @package   core_form
  42   * @category  form
  43   * @copyright 2006 Jamie Pratt <[email protected]>
  44   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  45   */
  46  class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
  47  
  48      /**
  49       * Constructor
  50       *
  51       * @param string $elementname Element's name
  52       * @param mixed $elementlabel Label(s) for an element
  53       * @param array $options Options to control the element's display. Not used.
  54       * @param mixed $attributes Either a typical HTML attribute string or an associative array
  55       */
  56      public function MoodleQuickForm_modgrade($elementname = null, $elementlabel = null, $options = array(), $attributes = null) {
  57          $this->HTML_QuickForm_element($elementname, $elementlabel, $attributes);
  58          $this->_persistantFreeze = true;
  59          $this->_appendName = true;
  60          $this->_type = 'modgrade';
  61      }
  62  
  63      /**
  64       * Create elements for this group.
  65       */
  66      public function _createElements() {
  67          global $COURSE, $CFG;
  68          $attributes = $this->getAttributes();
  69          if (is_null($attributes)) {
  70              $attributes = array();
  71          }
  72  
  73          $this->_elements = array();
  74  
  75          // Create main elements
  76          // We have to create the scale and point elements first, as we need their IDs.
  77  
  78          // Grade scale select box.
  79          $scales = get_scales_menu($COURSE->id);
  80          $langscale = get_string('modgradetypescale', 'grades');
  81          $scaleselect = @MoodleQuickForm::createElement('select', 'modgrade_scale', $langscale, $scales, $attributes);
  82          $scaleselect->setHiddenLabel = false;
  83          $scaleselect->_generateId();
  84          $scaleselectid = $scaleselect->getAttribute('id');
  85  
  86          // Maximum grade textbox.
  87          $langmaxgrade = get_string('modgrademaxgrade', 'grades');
  88          $maxgrade = @MoodleQuickForm::createElement('text', 'modgrade_point', $langmaxgrade, array());
  89          $maxgrade->setHiddenLabel = false;
  90          $maxgrade->_generateId();
  91          $maxgradeid = $maxgrade->getAttribute('id');
  92  
  93          // Grade type select box.
  94          $gradetype = array(
  95              'none' => get_string('modgradetypenone', 'grades'),
  96              'scale' => get_string('modgradetypescale', 'grades'),
  97              'point' => get_string('modgradetypepoint', 'grades'),
  98          );
  99          $langtype = get_string('modgradetype', 'grades');
 100          $typeselect = @MoodleQuickForm::createElement('select', 'modgrade_type', $langtype, $gradetype, $attributes, true);
 101          $typeselect->setHiddenLabel = false;
 102          $typeselect->_generateId();
 103  
 104          // Add elements.
 105  
 106          // Grade type select box.
 107          $label = html_writer::tag('label', $typeselect->getLabel(), array('for' => $typeselect->getAttribute('id')));
 108          $this->_elements[] = @MoodleQuickForm::createElement('static', 'gradetypelabel', '', '&nbsp;'.$label);
 109          $this->_elements[] = $typeselect;
 110          $this->_elements[] = @MoodleQuickForm::createElement('static', 'gradetypespacer', '', '<br />');
 111  
 112          // Grade scale select box.
 113          $label = html_writer::tag('label', $scaleselect->getLabel(), array('for' => $scaleselectid));
 114          $this->_elements[] = @MoodleQuickForm::createElement('static', 'scalelabel', '', $label);
 115          $this->_elements[] = $scaleselect;
 116          $this->_elements[] = @MoodleQuickForm::createElement('static', 'scalespacer', '', '<br />');
 117  
 118          // Maximum grade textbox.
 119          $label = html_writer::tag('label', $maxgrade->getLabel(), array('for' => $maxgradeid));
 120          $this->_elements[] = @MoodleQuickForm::createElement('static', 'pointlabel', '', $label);
 121          $this->_elements[] = $maxgrade;
 122          $this->_elements[] = @MoodleQuickForm::createElement('static', 'pointspacer', '', '<br />');
 123      }
 124  
 125      /**
 126       * Calculate the output value for the element as a whole.
 127       *
 128       * @param array $submitvalues The incoming values from the form.
 129       * @param bool $notused Not used.
 130       * @return array Return value for the element, formatted like field name => value.
 131       */
 132      public function exportValue(&$submitvalues, $notused = false) {
 133          global $COURSE;
 134  
 135          // Get the values from all the child elements.
 136          $vals = array();
 137          foreach ($this->_elements as $element) {
 138              $thisexport = $element->exportValue($submitvalues[$this->getName()], true);
 139              if (!is_null($thisexport)) {
 140                  $vals += $thisexport;
 141              }
 142          }
 143  
 144          $type = (isset($vals['modgrade_type'])) ? $vals['modgrade_type'] : 'none';
 145          $point = (isset($vals['modgrade_point'])) ? $vals['modgrade_point'] : null;
 146          $scale = (isset($vals['modgrade_scale'])) ? $vals['modgrade_scale'] : null;
 147          $return = $this->process_value($type, $scale, $point);
 148          return array($this->getName() => $return);
 149      }
 150  
 151      /**
 152       * Process the value for the group based on the selected grade type, and the input for the scale and point elements.
 153       *
 154       * @param  string $type The value of the grade type select box. Can be 'none', 'scale', or 'point'
 155       * @param  string|int $scale The value of the scale select box.
 156       * @param  string|int $point The value of the point grade textbox.
 157       * @return int The resulting value
 158       */
 159      protected function process_value($type='none', $scale=null, $point=null) {
 160          global $COURSE;
 161          $val = 0;
 162          switch ($type) {
 163              case 'point':
 164                  if ($this->validate_point($point) === true) {
 165                      $val = (int)$point;
 166                  }
 167                  break;
 168  
 169              case 'scale':
 170                  if ($this->validate_scale($scale)) {
 171                      $val = (int)(-$scale);
 172                  }
 173                  break;
 174          }
 175          return $val;
 176      }
 177  
 178      /**
 179       * Determines whether a given value is a valid scale selection.
 180       *
 181       * @param string|int $val The value to test.
 182       * @return bool Valid or invalid
 183       */
 184      protected function validate_scale($val) {
 185          global $COURSE;
 186          $scales = get_scales_menu($COURSE->id);
 187          return (!empty($val) && isset($scales[(int)$val])) ? true : false;
 188      }
 189  
 190      /**
 191       * Determines whether a given value is a valid point selection.
 192       *
 193       * @param string|int $val The value to test.
 194       * @return bool Valid or invalid
 195       */
 196      protected function validate_point($val) {
 197          if (empty($val)) {
 198              return false;
 199          }
 200          $maxgrade = (int)get_config('core', 'gradepointmax');
 201          $isintlike = ((string)(int)$val === $val) ? true : false;
 202          return ($isintlike === true && $val > 0 && $val <= $maxgrade) ? true : false;
 203      }
 204  
 205      /**
 206       * Called by HTML_QuickForm whenever form event is made on this element.
 207       *
 208       * @param string $event Name of event
 209       * @param mixed $arg event arguments
 210       * @param moodleform $caller calling object
 211       * @return mixed
 212       */
 213      public function onQuickFormEvent($event, $arg, &$caller) {
 214          switch ($event) {
 215              case 'createElement':
 216                  // The first argument is the name.
 217                  $name = $arg[0];
 218  
 219                  // Set disable actions.
 220                  $caller->disabledIf($name.'[modgrade_scale]', $name.'[modgrade_type]', 'neq', 'scale');
 221                  $caller->disabledIf($name.'[modgrade_point]', $name.'[modgrade_type]', 'neq', 'point');
 222  
 223                  // Set validation rules for the sub-elements belonging to this element.
 224                  // A handy note: the parent scope of a closure is the function in which the closure was declared.
 225                  // Because of this using $this is safe despite the closures being called statically.
 226                  // A nasty magic hack!
 227                  $checkmaxgrade = function($val) {
 228                      // Closure to validate a max points value. See the note above about scope if this confuses you.
 229                      if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'point') {
 230                          if (!isset($val['modgrade_point'])) {
 231                              return false;
 232                          }
 233                          return $this->validate_point($val['modgrade_point']);
 234                      }
 235                      return true;
 236                  };
 237                  $checkvalidscale = function($val) {
 238                      // Closure to validate a scale value. See the note above about scope if this confuses you.
 239                      if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'scale') {
 240                          if (!isset($val['modgrade_scale'])) {
 241                              return false;
 242                          }
 243                          return $this->validate_scale($val['modgrade_scale']);
 244                      }
 245                      return true;
 246                  };
 247  
 248                  $maxgradeexceeded = get_string('modgradeerrorbadpoint', 'grades', get_config('core', 'gradepointmax'));
 249                  $invalidscale = get_string('modgradeerrorbadscale', 'grades');
 250                  // When creating the rules the sixth arg is $force, we set it to true because otherwise the form
 251                  // will attempt to validate the existence of the element, we don't want this because the element
 252                  // is being created right now and doesn't actually exist as a registered element yet.
 253                  $caller->addRule($name, $maxgradeexceeded, 'callback', $checkmaxgrade, 'server', false, true);
 254                  $caller->addRule($name, $invalidscale, 'callback', $checkvalidscale, 'server', false, true);
 255  
 256                  break;
 257  
 258              case 'updateValue':
 259                  // As this is a group element with no value of its own we are only interested in situations where the
 260                  // default value or a constant value are being provided to the actual element.
 261                  // In this case we expect an int that is going to translate to a scale if negative, or to max points
 262                  // if positive.
 263  
 264                  // A constant value should be given as an int.
 265                  // The default value should be an int and should really be $CFG->gradepointdefault.
 266                  $value = $this->_findValue($caller->_constantValues);
 267                  if (null === $value) {
 268                      if ($caller->isSubmitted()) {
 269                          break;
 270                      }
 271                      $value = $this->_findValue($caller->_defaultValues);
 272                  }
 273  
 274                  if (!is_null($value) && !is_scalar($value)) {
 275                      // Something unexpected (likely an array of subelement values) has been given - this will be dealt
 276                      // with somewhere else - where exactly... likely the subelements.
 277                      debugging('An invalid value (type '.gettype($value).') has arrived at '.__METHOD__, DEBUG_DEVELOPER);
 278                      break;
 279                  }
 280  
 281                  // Set element state for existing data.
 282                  // This is really a pretty hacky thing to do, when data is being set the group element is called
 283                  // with the data first and the subelements called afterwards.
 284                  // This means that the subelements data (inc const and default values) can be overridden by form code.
 285                  // So - when we call this code really we can't be sure that will be the end value for the element.
 286                  if (!empty($this->_elements)) {
 287                      if (!empty($value)) {
 288                          if ($value < 0) {
 289                              $this->_elements[1]->setValue('scale');
 290                              $this->_elements[4]->setValue(($value * -1));
 291                          } else if ($value > 0) {
 292                              $this->_elements[1]->setValue('point');
 293                              $this->_elements[7]->setValue($value);
 294                          }
 295                      } else {
 296                          $this->_elements[1]->setValue('none');
 297                          $this->_elements[7]->setValue('');
 298                      }
 299                  }
 300                  break;
 301          }
 302  
 303          // Always let the parent do its thing!
 304          return parent::onQuickFormEvent($event, $arg, $caller);
 305      }
 306  
 307  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1