/**
  *
  * @param mixed $row
  * @param mixed $col
  * @return type 
  */
 public function key($row, $col)
 {
     $row_id = is_object($row) ? $row->id : $row;
     $col_id = is_object($col) ? $col->id : $col;
     $multiple = $this->multiple;
     return qtype_matrix_grading::cell_name($row_id, $col_id, $multiple);
 }
 function set_data($question)
 {
     $is_new = empty($question->id) || empty($question->options->rows);
     if (!$is_new) {
         $options = $question->options;
         $question->multiple = $options->multiple ? '1' : '0';
         $question->grademethod = $options->grademethod;
         $question->rowshort = array();
         $question->rowlong = array();
         $question->rowfeedback = array();
         $question->rowid = array();
         foreach ($options->rows as $row) {
             $question->rowshort[] = $row->shorttext;
             $question->rowlong[] = $row->description;
             $question->rowfeedback[] = $row->feedback;
             $question->rowid[] = $row->id;
         }
         $question->colshort = array();
         $question->collong = array();
         $question->colid = array();
         foreach ($options->cols as $col) {
             $question->colshort[] = $col->shorttext;
             $question->collong[] = $col->description;
             $question->colid[] = $col->id;
         }
         //$question->matrix = array();
         $row_index = 0;
         foreach ($options->rows as $row) {
             $col_index = 0;
             foreach ($options->cols as $col) {
                 $cell_name = qtype_matrix_grading::cell_name($row_index, $col_index, $options->multiple);
                 $weight = $options->weights[$row->id][$col->id];
                 if ($options->multiple) {
                     $value = $weight > 0 ? 'on' : '';
                     $question->{$cell_name} = $value;
                 } else {
                     if ($weight > 0) {
                         $question->{$cell_name} = $col_index;
                         break;
                     }
                 }
                 $col_index++;
             }
             $row_index++;
         }
     }
     /* set data should be called on new questions to set up course id, etc
      * after setting up values for question
      */
     parent::set_data($question);
 }
 /**
  * Saves question-type specific options.
  * This is called by {@link save_question()} to save the question-type specific data.
  * 
  * @param object $question This holds the information from the editing form, it is not a standard question object.
  * @return object $result->error or $result->noticeyesno or $result->notice
  */
 function save_question_options($question)
 {
     global $DB;
     //parent::save_question_options($question);
     $question_id = isset($question->id) ? $question->id : false;
     if (empty($question->makecopy)) {
         $this->delete_question_options($question_id);
     }
     $transaction = $DB->start_delegated_transaction();
     $matrix = (object) array('questionid' => $question->id, 'multiple' => $question->multiple, 'grademethod' => $question->grademethod, 'renderer' => 'matrix');
     $matrix_id = $DB->insert_record('question_matrix', $matrix);
     // rows
     $rowids = array();
     //mapping for indexes to db ids.
     foreach ($question->rowshort as $i => $short) {
         if (empty($short)) {
             break;
         }
         $row = (object) array('matrixid' => $matrix_id, 'shorttext' => $question->rowshort[$i], 'description' => $question->rowlong[$i], 'feedback' => $question->rowfeedback[$i]);
         $newid = $DB->insert_record('question_matrix_rows', $row);
         $rowids[] = $newid;
     }
     // cols
     $colids = array();
     foreach ($question->colshort as $i => $short) {
         if (empty($short)) {
             break;
         }
         $col = (object) array('matrixid' => $matrix_id, 'shorttext' => $question->colshort[$i], 'description' => $question->collong[$i]);
         $newid = $DB->insert_record('question_matrix_cols', $col);
         $colids[] = $newid;
     }
     //wheights
     if ($question->multiple) {
         foreach ($rowids as $row_index => $row_id) {
             foreach ($colids as $col_index => $col_id) {
                 $key = qtype_matrix_grading::cell_name($row_index, $col_index, $question->multiple);
                 $value = isset($question->{$key}) ? $question->{$key} : 0;
                 if (!is_numeric($value)) {
                     $value = empty($value) ? 0 : 1;
                 }
                 $weight = (object) array('rowid' => $row_id, 'colid' => $col_id, 'weight' => $value);
                 $DB->insert_record('question_matrix_weights', $weight);
             }
         }
     } else {
         foreach ($rowids as $row_index => $row_id) {
             $key = qtype_matrix_grading::cell_name($row_index, 0, $question->multiple);
             $col_index = $question->{$key};
             $col_id = $colids[$col_index];
             $value = 1;
             $weight = (object) array('rowid' => $row_id, 'colid' => $col_id, 'weight' => $value);
             $DB->insert_record('question_matrix_weights', $weight);
         }
     }
     $transaction->allow_commit();
 }