/** * Prepares the data passed in $_POST: * - processes the pressed buttons 'addlevel', 'addcriterion', 'moveup', 'movedown', 'delete' (when JavaScript is disabled) * sets $this->nonjsbuttonpressed to true/false if such button was pressed * - if options not passed (i.e. we create a new rubric) fills the options array with the default values * - if options are passed completes the options array with unchecked checkboxes * - if $withvalidation is set, adds 'error_xxx' attributes to elements that contain errors and creates an error string * and stores it in $this->validationerrors * * @param array $value * @param boolean $withvalidation whether to enable data validation * @return array */ protected function prepare_data($value = null, $withvalidation = false) { if (null === $value) { $value = $this->getValue(); } if ($this->nonjsbuttonpressed === null) { $this->nonjsbuttonpressed = false; } $totalscore = 0; $errors = array(); $return = array('criteria' => array(), 'options' => gradingform_rubric_controller::get_default_options()); if (!isset($value['criteria'])) { $value['criteria'] = array(); $errors['err_nocriteria'] = 1; } // If options are present in $value, replace default values with submitted values if (!empty($value['options'])) { foreach (array_keys($return['options']) as $option) { // special treatment for checkboxes if (!empty($value['options'][$option])) { $return['options'][$option] = $value['options'][$option]; } else { $return['options'][$option] = null; } } } if (is_array($value)) { // for other array keys of $value no special treatmeant neeeded, copy them to return value as is foreach (array_keys($value) as $key) { if ($key != 'options' && $key != 'criteria') { $return[$key] = $value[$key]; } } } // iterate through criteria $lastaction = null; $lastid = null; foreach ($value['criteria'] as $id => $criterion) { if ($id == 'addcriterion') { $id = $this->get_next_id(array_keys($value['criteria'])); $criterion = array('description' => '', 'levels' => array()); $i = 0; // when adding new criterion copy the number of levels and their scores from the last criterion if (!empty($value['criteria'][$lastid]['levels'])) { foreach ($value['criteria'][$lastid]['levels'] as $lastlevel) { $criterion['levels']['NEWID' . $i++]['score'] = $lastlevel['score']; } } else { $criterion['levels']['NEWID' . $i++]['score'] = 0; } // add more levels so there are at least 3 in the new criterion. Increment by 1 the score for each next one for ($i = $i; $i < 3; $i++) { $criterion['levels']['NEWID' . $i]['score'] = $criterion['levels']['NEWID' . ($i - 1)]['score'] + 1; } // set other necessary fields (definition) for the levels in the new criterion foreach (array_keys($criterion['levels']) as $i) { $criterion['levels'][$i]['definition'] = ''; } $this->nonjsbuttonpressed = true; } $levels = array(); $maxscore = null; if (array_key_exists('levels', $criterion)) { foreach ($criterion['levels'] as $levelid => $level) { if ($levelid == 'addlevel') { $levelid = $this->get_next_id(array_keys($criterion['levels'])); $level = array('definition' => '', 'score' => 0); foreach ($criterion['levels'] as $lastlevel) { if (isset($lastlevel['score']) && $level['score'] < $lastlevel['score'] + 1) { $level['score'] = $lastlevel['score'] + 1; } } $this->nonjsbuttonpressed = true; } if (!array_key_exists('delete', $level)) { if ($withvalidation) { if (!strlen(trim($level['definition']))) { $errors['err_nodefinition'] = 1; $level['error_definition'] = true; } if (!preg_match('#^[\\+]?\\d*$#', trim($level['score'])) && !preg_match('#^[\\+]?\\d*[\\.,]\\d+$#', trim($level['score']))) { $errors['err_scoreformat'] = 1; $level['error_score'] = true; } } $levels[$levelid] = $level; if ($maxscore === null || (double) $level['score'] > $maxscore) { $maxscore = (double) $level['score']; } } else { $this->nonjsbuttonpressed = true; } } } $totalscore += (double) $maxscore; $criterion['levels'] = $levels; if ($withvalidation && !array_key_exists('delete', $criterion)) { if (count($levels) < 2) { $errors['err_mintwolevels'] = 1; $criterion['error_levels'] = true; } if (!strlen(trim($criterion['description']))) { $errors['err_nodescription'] = 1; $criterion['error_description'] = true; } } if (array_key_exists('moveup', $criterion) || $lastaction == 'movedown') { unset($criterion['moveup']); if ($lastid !== null) { $lastcriterion = $return['criteria'][$lastid]; unset($return['criteria'][$lastid]); $return['criteria'][$id] = $criterion; $return['criteria'][$lastid] = $lastcriterion; } else { $return['criteria'][$id] = $criterion; } $lastaction = null; $lastid = $id; $this->nonjsbuttonpressed = true; } else { if (array_key_exists('delete', $criterion)) { $this->nonjsbuttonpressed = true; } else { if (array_key_exists('movedown', $criterion)) { unset($criterion['movedown']); $lastaction = 'movedown'; $this->nonjsbuttonpressed = true; } $return['criteria'][$id] = $criterion; $lastid = $id; } } } if ($totalscore <= 0) { $errors['err_totalscore'] = 1; } // add sort order field to criteria $csortorder = 1; foreach (array_keys($return['criteria']) as $id) { $return['criteria'][$id]['sortorder'] = $csortorder++; } // create validation error string (if needed) if ($withvalidation) { if (count($errors)) { $rv = array(); foreach ($errors as $error => $v) { $rv[] = get_string($error, 'gradingform_rubric'); } $this->validationerrors = join('<br/ >', $rv); } else { $this->validationerrors = false; } $this->wasvalidated = true; } return $return; }
/** * Check if there are changes in the rubric and it is needed to ask user whether to * mark the current grades for re-grading. User may confirm re-grading and continue, * return to editing or cancel the changes * * @param gradingform_rubric_controller $controller */ public function need_confirm_regrading($controller) { $data = $this->get_data(); if (isset($data->rubric['regrade'])) { // we have already displayed the confirmation on the previous step return false; } if (!isset($data->saverubric) || !$data->saverubric) { // we only need confirmation when button 'Save rubric' is pressed return false; } if (!$controller->has_active_instances()) { // nothing to re-grade, confirmation not needed return false; } $changelevel = $controller->update_or_check_rubric($data); if ($changelevel == 0) { // no changes in the rubric, no confirmation needed return false; } // freeze form elements and pass the values in hidden fields // TODO MDL-29421 description_editor does not freeze the normal way, uncomment below when fixed $form = $this->_form; foreach (array('rubric', 'name') as $fieldname) { $el =& $form->getElement($fieldname); $el->freeze(); $el->setPersistantFreeze(true); if ($fieldname == 'rubric') { $el->add_regrade_confirmation($changelevel); } } // replace button text 'saverubric' and unfreeze 'Back to edit' button $this->findButton('saverubric')->setValue(get_string('continue')); $el =& $this->findButton('editrubric'); $el->setValue(get_string('backtoediting', 'gradingform_rubric')); $el->unfreeze(); return true; }