예제 #1
0
파일: lib.php 프로젝트: nicusX/moodle
 /**
  * Either saves the guide definition into the database or check if it has been changed.
  *
  * Returns the level of changes:
  * 0 - no changes
  * 1 - only texts or criteria sortorders are changed, students probably do not require re-grading
  * 2 - added levels but maximum score on guide is the same, students still may not require re-grading
  * 3 - removed criteria or changed number of points, students require re-grading but may be re-graded automatically
  * 4 - removed levels - students require re-grading and not all students may be re-graded automatically
  * 5 - added criteria - all students require manual re-grading
  *
  * @param stdClass $newdefinition guide definition data as coming from gradingform_guide_editguide::get_data()
  * @param int|null $usermodified optional userid of the author of the definition, defaults to the current user
  * @param bool $doupdate if true actually updates DB, otherwise performs a check
  * @return int
  */
 public function update_or_check_guide(stdClass $newdefinition, $usermodified = null, $doupdate = false)
 {
     global $DB;
     // Firstly update the common definition data in the {grading_definition} table.
     if ($this->definition === false) {
         if (!$doupdate) {
             // If we create the new definition there is no such thing as re-grading anyway.
             return 5;
         }
         // If definition does not exist yet, create a blank one
         // (we need id to save files embedded in description).
         parent::update_definition(new stdClass(), $usermodified);
         parent::load_definition();
     }
     if (!isset($newdefinition->guide['options'])) {
         $newdefinition->guide['options'] = self::get_default_options();
     }
     $newdefinition->options = json_encode($newdefinition->guide['options']);
     $editoroptions = self::description_form_field_options($this->get_context());
     $newdefinition = file_postupdate_standard_editor($newdefinition, 'description', $editoroptions, $this->get_context(), 'grading', 'description', $this->definition->id);
     // Reload the definition from the database.
     $currentdefinition = $this->get_definition(true);
     // Update guide data.
     $haschanges = array();
     if (empty($newdefinition->guide['criteria'])) {
         $newcriteria = array();
     } else {
         $newcriteria = $newdefinition->guide['criteria'];
         // New ones to be saved.
     }
     $currentcriteria = $currentdefinition->guide_criteria;
     $criteriafields = array('sortorder', 'description', 'descriptionformat', 'descriptionmarkers', 'descriptionmarkersformat', 'shortname', 'maxscore');
     foreach ($newcriteria as $id => $criterion) {
         if (preg_match('/^NEWID\\d+$/', $id)) {
             // Insert criterion into DB.
             $data = array('definitionid' => $this->definition->id, 'descriptionformat' => FORMAT_MOODLE, 'descriptionmarkersformat' => FORMAT_MOODLE);
             // TODO format is not supported yet.
             foreach ($criteriafields as $key) {
                 if (array_key_exists($key, $criterion)) {
                     $data[$key] = $criterion[$key];
                 }
             }
             if ($doupdate) {
                 $id = $DB->insert_record('gradingform_guide_criteria', $data);
             }
             $haschanges[5] = true;
         } else {
             // Update criterion in DB.
             $data = array();
             foreach ($criteriafields as $key) {
                 if (array_key_exists($key, $criterion) && $criterion[$key] != $currentcriteria[$id][$key]) {
                     $data[$key] = $criterion[$key];
                 }
             }
             if (!empty($data)) {
                 // Update only if something is changed.
                 $data['id'] = $id;
                 if ($doupdate) {
                     $DB->update_record('gradingform_guide_criteria', $data);
                 }
                 $haschanges[1] = true;
             }
         }
     }
     // Remove deleted criteria from DB.
     foreach (array_keys($currentcriteria) as $id) {
         if (!array_key_exists($id, $newcriteria)) {
             if ($doupdate) {
                 $DB->delete_records('gradingform_guide_criteria', array('id' => $id));
             }
             $haschanges[3] = true;
         }
     }
     // Now handle comments.
     if (empty($newdefinition->guide['comments'])) {
         $newcomment = array();
     } else {
         $newcomment = $newdefinition->guide['comments'];
         // New ones to be saved.
     }
     $currentcomments = $currentdefinition->guide_comment;
     $commentfields = array('sortorder', 'description');
     foreach ($newcomment as $id => $comment) {
         if (preg_match('/^NEWID\\d+$/', $id)) {
             // Insert criterion into DB.
             $data = array('definitionid' => $this->definition->id, 'descriptionformat' => FORMAT_MOODLE);
             foreach ($commentfields as $key) {
                 if (array_key_exists($key, $comment)) {
                     $data[$key] = $comment[$key];
                 }
             }
             if ($doupdate) {
                 $id = $DB->insert_record('gradingform_guide_comments', $data);
             }
         } else {
             // Update criterion in DB.
             $data = array();
             foreach ($commentfields as $key) {
                 if (array_key_exists($key, $comment) && $comment[$key] != $currentcomments[$id][$key]) {
                     $data[$key] = $comment[$key];
                 }
             }
             if (!empty($data)) {
                 // Update only if something is changed.
                 $data['id'] = $id;
                 if ($doupdate) {
                     $DB->update_record('gradingform_guide_comments', $data);
                 }
             }
         }
     }
     // Remove deleted criteria from DB.
     foreach (array_keys($currentcomments) as $id) {
         if (!array_key_exists($id, $newcomment)) {
             if ($doupdate) {
                 $DB->delete_records('gradingform_guide_comments', array('id' => $id));
             }
         }
     }
     // End comments handle.
     foreach (array('status', 'description', 'descriptionformat', 'name', 'options') as $key) {
         if (isset($newdefinition->{$key}) && $newdefinition->{$key} != $this->definition->{$key}) {
             $haschanges[1] = true;
         }
     }
     if ($usermodified && $usermodified != $this->definition->usermodified) {
         $haschanges[1] = true;
     }
     if (!count($haschanges)) {
         return 0;
     }
     if ($doupdate) {
         parent::update_definition($newdefinition, $usermodified);
         $this->load_definition();
     }
     // Return the maximum level of changes.
     $changelevels = array_keys($haschanges);
     sort($changelevels);
     return array_pop($changelevels);
 }
예제 #2
0
파일: lib.php 프로젝트: JP-Git/moodle
 /**
  * Either saves the rubric definition into the database or check if it has been changed.
  * Returns the level of changes:
  * 0 - no changes
  * 1 - only texts or criteria sortorders are changed, students probably do not require re-grading
  * 2 - added levels but maximum score on rubric is the same, students still may not require re-grading
  * 3 - removed criteria or added levels or changed number of points, students require re-grading but may be re-graded automatically
  * 4 - removed levels - students require re-grading and not all students may be re-graded automatically
  * 5 - added criteria - all students require manual re-grading
  *
  * @param stdClass $newdefinition rubric definition data as coming from gradingform_rubric_editrubric::get_data()
  * @param int|null $usermodified optional userid of the author of the definition, defaults to the current user
  * @param boolean $doupdate if true actually updates DB, otherwise performs a check
  *
  */
 public function update_or_check_rubric(stdClass $newdefinition, $usermodified = null, $doupdate = false)
 {
     global $DB;
     // firstly update the common definition data in the {grading_definition} table
     if ($this->definition === false) {
         if (!$doupdate) {
             // if we create the new definition there is no such thing as re-grading anyway
             return 5;
         }
         // if definition does not exist yet, create a blank one
         // (we need id to save files embedded in description)
         parent::update_definition(new stdClass(), $usermodified);
         parent::load_definition();
     }
     if (!isset($newdefinition->rubric['options'])) {
         $newdefinition->rubric['options'] = self::get_default_options();
     }
     $newdefinition->options = json_encode($newdefinition->rubric['options']);
     $editoroptions = self::description_form_field_options($this->get_context());
     $newdefinition = file_postupdate_standard_editor($newdefinition, 'description', $editoroptions, $this->get_context(), 'grading', 'description', $this->definition->id);
     // reload the definition from the database
     $currentdefinition = $this->get_definition(true);
     // update rubric data
     $haschanges = array();
     if (empty($newdefinition->rubric['criteria'])) {
         $newcriteria = array();
     } else {
         $newcriteria = $newdefinition->rubric['criteria'];
         // new ones to be saved
     }
     $currentcriteria = $currentdefinition->rubric_criteria;
     $criteriafields = array('sortorder', 'description', 'descriptionformat');
     $levelfields = array('score', 'definition', 'definitionformat');
     foreach ($newcriteria as $id => $criterion) {
         // get list of submitted levels
         $levelsdata = array();
         if (array_key_exists('levels', $criterion)) {
             $levelsdata = $criterion['levels'];
         }
         $criterionmaxscore = null;
         if (preg_match('/^NEWID\\d+$/', $id)) {
             // insert criterion into DB
             $data = array('definitionid' => $this->definition->id, 'descriptionformat' => FORMAT_MOODLE);
             // TODO format is not supported yet
             foreach ($criteriafields as $key) {
                 if (array_key_exists($key, $criterion)) {
                     $data[$key] = $criterion[$key];
                 }
             }
             if ($doupdate) {
                 $id = $DB->insert_record('gradingform_rubric_criteria', $data);
             }
             $haschanges[5] = true;
         } else {
             // update criterion in DB
             $data = array();
             foreach ($criteriafields as $key) {
                 if (array_key_exists($key, $criterion) && $criterion[$key] != $currentcriteria[$id][$key]) {
                     $data[$key] = $criterion[$key];
                 }
             }
             if (!empty($data)) {
                 // update only if something is changed
                 $data['id'] = $id;
                 if ($doupdate) {
                     $DB->update_record('gradingform_rubric_criteria', $data);
                 }
                 $haschanges[1] = true;
             }
             // remove deleted levels from DB and calculate the maximum score for this criteria
             foreach ($currentcriteria[$id]['levels'] as $levelid => $currentlevel) {
                 if ($criterionmaxscore === null || $criterionmaxscore < $currentlevel['score']) {
                     $criterionmaxscore = $currentlevel['score'];
                 }
                 if (!array_key_exists($levelid, $levelsdata)) {
                     if ($doupdate) {
                         $DB->delete_records('gradingform_rubric_levels', array('id' => $levelid));
                     }
                     $haschanges[4] = true;
                 }
             }
         }
         foreach ($levelsdata as $levelid => $level) {
             if (isset($level['score'])) {
                 $level['score'] = (double) $level['score'];
                 if ($level['score'] < 0) {
                     // TODO why we can't allow negative score for rubric?
                     $level['score'] = 0;
                 }
             }
             if (preg_match('/^NEWID\\d+$/', $levelid)) {
                 // insert level into DB
                 $data = array('criterionid' => $id, 'definitionformat' => FORMAT_MOODLE);
                 // TODO format is not supported yet
                 foreach ($levelfields as $key) {
                     if (array_key_exists($key, $level)) {
                         $data[$key] = $level[$key];
                     }
                 }
                 if ($doupdate) {
                     $levelid = $DB->insert_record('gradingform_rubric_levels', $data);
                 }
                 if ($criterionmaxscore !== null && $criterionmaxscore >= $level['score']) {
                     // new level is added but the maximum score for this criteria did not change, re-grading may not be necessary
                     $haschanges[2] = true;
                 } else {
                     $haschanges[3] = true;
                 }
             } else {
                 // update level in DB
                 $data = array();
                 foreach ($levelfields as $key) {
                     if (array_key_exists($key, $level) && $level[$key] != $currentcriteria[$id]['levels'][$levelid][$key]) {
                         $data[$key] = $level[$key];
                     }
                 }
                 if (!empty($data)) {
                     // update only if something is changed
                     $data['id'] = $levelid;
                     if ($doupdate) {
                         $DB->update_record('gradingform_rubric_levels', $data);
                     }
                     if (isset($data['score'])) {
                         $haschanges[3] = true;
                     }
                     $haschanges[1] = true;
                 }
             }
         }
     }
     // remove deleted criteria from DB
     foreach (array_keys($currentcriteria) as $id) {
         if (!array_key_exists($id, $newcriteria)) {
             if ($doupdate) {
                 $DB->delete_records('gradingform_rubric_criteria', array('id' => $id));
                 $DB->delete_records('gradingform_rubric_levels', array('criterionid' => $id));
             }
             $haschanges[3] = true;
         }
     }
     foreach (array('status', 'description', 'descriptionformat', 'name', 'options') as $key) {
         if (isset($newdefinition->{$key}) && $newdefinition->{$key} != $this->definition->{$key}) {
             $haschanges[1] = true;
         }
     }
     if ($usermodified && $usermodified != $this->definition->usermodified) {
         $haschanges[1] = true;
     }
     if (!count($haschanges)) {
         return 0;
     }
     if ($doupdate) {
         parent::update_definition($newdefinition, $usermodified);
         $this->load_definition();
     }
     // return the maximum level of changes
     $changelevels = array_keys($haschanges);
     sort($changelevels);
     return array_pop($changelevels);
 }
 /**
  * Either saves the enriched rubric definition into the database or check if it has been changed.
  * Returns the level of changes:
  * 0 - no changes
  * 1 - only texts or criteria sortorders are changed, students probably do not require re-grading
  * 2 - added levels but maximum score on enriched rubric is the same, students still may not require re-grading
  * 3 - removed criteria or added levels or changed number of points, students require re-grading but may be re-graded automatically
  * 4 - removed levels - students require re-grading and not all students may be re-graded automatically
  * 5 - added criteria or changed enriched criteria or changed enriched level values - all students require manual re-grading
  *
  * @param stdClass $newdefinition enriched rubric definition data as coming from gradingform_erubric_editrubric::get_data()
  * @param int|null $usermodified optional userid of the author of the definition, defaults to the current user
  * @param boolean $doupdate if true actually updates DB, otherwise performs a check
  *
  */
 public function update_or_check_erubric(stdClass $newdefinition, $usermodified = null, $doupdate = false)
 {
     global $DB;
     // Firstly update the common definition data in the {grading_definition} table.
     if ($this->definition === false) {
         if (!$doupdate) {
             // If we create the new definition there is no such thing as re-grading anyway.
             return 5;
         }
         // If definition does not exist yet, create a blank one
         // (we need id to save files embedded in description).
         parent::update_definition(new stdClass(), $usermodified);
         parent::load_definition();
     }
     if (!isset($newdefinition->erubric['options'])) {
         $newdefinition->erubric['options'] = self::get_default_options();
     }
     $newdefinition->options = json_encode($newdefinition->erubric['options']);
     $editoroptions = self::description_form_field_options($this->get_context());
     $newdefinition = file_postupdate_standard_editor($newdefinition, 'description', $editoroptions, $this->get_context(), 'grading', 'description', $this->definition->id);
     // Reload the definition from the database.
     $currentdefinition = $this->get_definition(true);
     // Update enriched rubric data.
     $haschanges = array();
     if (empty($newdefinition->erubric['criteria'])) {
         $newcriteria = array();
     } else {
         $newcriteria = $newdefinition->erubric['criteria'];
         // New ones to be saved...
     }
     $currentcriteria = $currentdefinition->erubric_criteria;
     // Create tables to use for evaluation of form data.
     $enrichedcriteriafields = array('sortorder', 'description', 'criteriontype', 'collaborationtype', 'operator', 'referencetype');
     $enrichedlevelfields = array('score', 'definition', 'definitionformat', 'enrichedvalue');
     foreach ($newcriteria as $id => $criterion) {
         // Get the list of submitted levels (if they exist).
         $levelsdata = array();
         if (array_key_exists('levels', $criterion)) {
             $levelsdata = $criterion['levels'];
         }
         $criterionmaxscore = null;
         if (preg_match('/^NEWID\\d+$/', $id)) {
             // Insert new criterion into DB.
             $data = array('definitionid' => $this->definition->id, 'descriptionformat' => FORMAT_MOODLE);
             foreach ($enrichedcriteriafields as $key) {
                 if (array_key_exists($key, $criterion)) {
                     $data[$key] = $criterion[$key] && (string) $criterion[$key] != '' ? $criterion[$key] : null;
                 }
             }
             // Handle course modules array (if exist), to store in database.
             if (array_key_exists('coursemodules', $criterion) && $criterion['coursemodules'] && is_array($criterion['coursemodules'])) {
                 // Check if user wants to publish the given form definition as a new template in the forms bank,
                 // or if he uses a template to create a new form.
                 $formshared = optional_param('shareform', '', PARAM_INT);
                 $pick = optional_param('pick', '', PARAM_INT);
                 if ($formshared || $pick) {
                     // Don't re-encode coursemodules table.
                     $dblbrackets = array('[[', ']]');
                     $snglbrackets = array('[', ']');
                     $data['coursemodules'] = str_replace($dblbrackets, $snglbrackets, json_encode($criterion['coursemodules']));
                 } else {
                     $data['coursemodules'] = json_encode($criterion['coursemodules']);
                 }
             } else {
                 $data['coursemodules'] = null;
             }
             if ($doupdate) {
                 $id = $DB->insert_record('gradingform_erubric_criteria', $data);
             }
             $haschanges[5] = true;
         } else {
             // Update criterion in DB.
             $data = array();
             // Set missing array elements to empty strings to avoid warnings.
             if (!array_key_exists('coursemodules', $criterion)) {
                 $criterion['coursemodules'] = '';
             }
             foreach ($enrichedcriteriafields as $key) {
                 if (array_key_exists($key, $criterion) && (string) $criterion[$key] != (string) $currentcriteria[$id][$key]) {
                     $data[$key] = $criterion[$key] && (string) $criterion[$key] != '' ? $criterion[$key] : null;
                 }
             }
             // Handle course modules array.
             if (is_array($criterion['coursemodules'])) {
                 // Check if coursemodules array already exist in current definition.
                 if (array_key_exists('coursemodules', $currentcriteria[$id]) && is_array($currentcriteria[$id]['coursemodules'])) {
                     // Something quick to accurate compare the modules array from the form, with the modules array to be updated.
                     $dblbrackets = array('[[', ']]');
                     $snglbrackets = array('[', ']');
                     $tempmodulescompstr1 = str_replace($dblbrackets, $snglbrackets, json_encode($currentcriteria[$id]['coursemodules']));
                     $tempmodulescompstr2 = json_encode($criterion['coursemodules']);
                 } else {
                     $tempmodulescompstr1 = 1;
                     // Dummy var
                     $tempmodulescompstr2 = 2;
                     // Dummy var
                 }
                 // If there is a change, update current data.
                 if ($tempmodulescompstr1 != $tempmodulescompstr2) {
                     $data['coursemodules'] = json_encode($criterion['coursemodules']);
                 }
             } else {
                 // In case we need to reset already stored course modules to null...
                 if (array_key_exists('coursemodules', $currentcriteria[$id])) {
                     $data['coursemodules'] = null;
                 }
             }
             if (!empty($data)) {
                 // Update only if something is changed...
                 $data['id'] = $id;
                 if ($doupdate) {
                     $DB->update_record('gradingform_erubric_criteria', $data);
                 }
                 // Check if there is a change in any of the enriched fields.
                 if (count($data) > 1 || count($data) == 2 && !isset($data['description'])) {
                     $haschanges[5] = true;
                     // Else, only the criterion description has changed.
                 } else {
                     $haschanges[1] = true;
                 }
             }
             // Remove deleted levels from DB and calculate the maximum score for this criteria.
             foreach ($currentcriteria[$id]['levels'] as $levelid => $currentlevel) {
                 if ($criterionmaxscore === null || $criterionmaxscore < $currentlevel['score']) {
                     $criterionmaxscore = $currentlevel['score'];
                 }
                 if (!array_key_exists($levelid, $levelsdata)) {
                     if ($doupdate) {
                         $DB->delete_records('gradingform_erubric_levels', array('id' => $levelid));
                     }
                     $haschanges[4] = true;
                 }
             }
         }
         foreach ($levelsdata as $levelid => $level) {
             if (isset($level['score'])) {
                 $level['score'] = (double) $level['score'];
                 if ($level['score'] < 0) {
                     $level['score'] = 0;
                 }
             }
             if (array_key_exists('enrichedvalue', $level) && !is_null($level['enrichedvalue']) && strlen(trim($level['enrichedvalue'])) > 0) {
                 $level['enrichedvalue'] = (double) $level['enrichedvalue'];
             } else {
                 $level['enrichedvalue'] = null;
             }
             if (preg_match('/^NEWID\\d+$/', $levelid)) {
                 // Insert level into DB.
                 $data = array('criterionid' => $id, 'definitionformat' => FORMAT_MOODLE);
                 foreach ($enrichedlevelfields as $key) {
                     if (array_key_exists($key, $level) && strlen(trim($level[$key])) > 0) {
                         $data[$key] = $level[$key];
                     }
                 }
                 if ($doupdate) {
                     $levelid = $DB->insert_record('gradingform_erubric_levels', $data);
                 }
                 if ($criterionmaxscore !== null && $criterionmaxscore >= $level['score']) {
                     // New level is added but the maximum score for this criteria did not change, re-grading may not be necessary.
                     $haschanges[2] = true;
                 } else {
                     $haschanges[3] = true;
                 }
                 // If there is a new enriched level value added, students must be re-graded.
                 if (count($data) > 1) {
                     $haschanges[5] = true;
                 }
             } else {
                 // Update level in DB.
                 $data = array();
                 foreach ($enrichedlevelfields as $key) {
                     if (array_key_exists($key, $level) && (string) $level[$key] != (string) $currentcriteria[$id]['levels'][$levelid][$key]) {
                         $data[$key] = $level[$key];
                     }
                 }
                 if (!empty($data)) {
                     // Update only if something has changed.
                     $data['id'] = $levelid;
                     if ($doupdate) {
                         $DB->update_record('gradingform_erubric_levels', $data);
                     }
                     if (isset($data['score'])) {
                         $haschanges[3] = true;
                     }
                     // Check if there is a change in any of the enriched fields.
                     if (count($data) > 1 || count($data) == 1 && !is_null($data['enrichedvalue'])) {
                         $haschanges[5] = true;
                         // Else, only the criterion description has changed.
                     } else {
                         $haschanges[1] = true;
                     }
                 }
             }
         }
     }
     // Rremove deleted criteria from DB.
     foreach (array_keys($currentcriteria) as $id) {
         if (!array_key_exists($id, $newcriteria)) {
             if ($doupdate) {
                 $DB->delete_records('gradingform_erubric_criteria', array('id' => $id));
                 $DB->delete_records('gradingform_erubric_levels', array('criterionid' => $id));
             }
             $haschanges[3] = true;
         }
     }
     foreach (array('status', 'description', 'descriptionformat', 'name', 'options') as $key) {
         if (isset($newdefinition->{$key}) && $newdefinition->{$key} != $this->definition->{$key}) {
             $haschanges[1] = true;
         }
     }
     if ($usermodified && $usermodified != $this->definition->usermodified) {
         $haschanges[1] = true;
     }
     if (!count($haschanges)) {
         return 0;
     }
     if ($doupdate) {
         parent::update_definition($newdefinition, $usermodified);
         $this->load_definition();
     }
     // Return the maximum level of changes.
     $changelevels = array_keys($haschanges);
     sort($changelevels);
     return array_pop($changelevels);
 }