function validation($data)
 {
     $errors = parent::validation($data, null);
     $colcount = matrix_qtype::count_form_rows_or_cols($data, false);
     $rowcount = matrix_qtype::count_form_rows_or_cols($data);
     if ($rowcount == 0) {
         $errors['rowshort[0]'] = get_string('mustdefine1by1', 'qtype_matrix');
     }
     if ($colcount == 0) {
         $errors['colshort[0]'] = get_string('mustdefine1by1', 'qtype_matrix');
     }
     if (array_key_exists('grademethod', $data)) {
         $grademethod = $data['grademethod'];
     } else {
         $grademethod = matrix_qtype::single_default_grademethod();
     }
     if ($grademethod == QTYPE_MATRIX_GRADING_WEIGHTED && empty($data['multiple'])) {
         $errors['multiple'] = get_string('weightednomultiple', 'qtype_matrix');
     }
     $gradeclass = matrix_qtype::grade_class($grademethod, $data['multiple']);
     $matrixerrors = $gradeclass->validate_defining_form_matrix($data);
     $errors = array_merge($errors, $matrixerrors);
     return $errors ? $errors : true;
 }
 function grade_responses(&$question, &$state, $cmoptions)
 {
     $gradeclass = matrix_qtype::grade_class($question->options->grademethod, $question->options->multiple);
     if ($gradeclass->is_manual_graded()) {
         $state->raw_grade = 0;
         $state->penalty = 0;
         return true;
     }
     $gradeclass->set_weights($question->options->weights);
     $subqs = $gradeclass->grade_matrix($state->responses);
     $state->raw_grade = $gradeclass->grade_question($subqs);
     //
     // Make sure we don't assign negative or too high marks.
     $state->raw_grade = min(max((double) $state->raw_grade, 0.0), 1.0) * $question->maxgrade;
     // Update the penalty.
     $state->penalty = $question->penalty * $question->maxgrade;
     // mark the state as graded
     $state->event = $state->event == QUESTION_EVENTCLOSE ? QUESTION_EVENTCLOSEANDGRADE : QUESTION_EVENTGRADE;
     return true;
 }
 static function load_all_data($questionid)
 {
     static $cache = array();
     if (array_key_exists($questionid, $cache)) {
         return $cache[$questionid];
     }
     if (!($matrix = get_record('question_matrix', 'questionid', $questionid))) {
         return false;
     }
     if (!($matrix->rows = get_records('question_matrix_rows', 'matrixid', $matrix->id))) {
         $matrix->rows = array();
         $rowsql = '';
     } else {
         $rowsql = 'rowid IN ( ' . implode(',', array_keys($matrix->rows)) . ')';
     }
     if (!($matrix->cols = get_records('question_matrix_cols', 'matrixid', $matrix->id))) {
         $matrix->cols = array();
         $colsql = '';
     } else {
         $colsql = 'colid IN ( ' . implode(',', array_keys($matrix->cols)) . ')';
     }
     $matrix->gradingmatrix = array();
     $matrix->fullmatrix = array();
     foreach ($matrix->rows as $r) {
         $matrix->rowshort[] = $r->shorttext;
         $matrix->rowlong[] = $r->description;
         $matrix->rowfeedback[] = $r->feedback;
         $matrix->fullmatrix[$r->id] = array();
     }
     foreach ($matrix->cols as $c) {
         $matrix->colshort[] = $c->shorttext;
         $matrix->collong[] = $c->description;
         // create an empty hole
         foreach ($matrix->fullmatrix as $r => $null) {
             $matrix->fullmatrix[$r][$c->id] = null;
         }
     }
     if (empty($rowsql) || empty($colsql)) {
         $cache[$questionid] = $matrix;
         return $matrix;
     }
     if (!($matrix->rawweights = get_records_select('question_matrix_weights', $rowsql . ' AND ' . $colsql))) {
         $matrix->rawweights = array();
     }
     foreach ($matrix->rawweights as $w) {
         $gradeclass = matrix_qtype::grade_class($matrix->grademethod, $matrix->multiple);
         $cellname = $gradeclass->cellname($w->rowid, $w->colid);
         if (!$matrix->multiple) {
             $matrix->gradingmatrix[$cellname] = $w->colid;
         } else {
             $matrix->gradingmatrix[$cellname] = $w->weight;
         }
         $matrix->fullmatrix[$w->rowid][$w->colid] = $w->weight;
     }
     $cache[$questionid] = $matrix;
     return $matrix;
 }