Переглянути джерело

Register grades into gradebook
- If gradebook field value is yes on submission form now registers grades on gradebook
- Updated install.xml to add necessary fields

- Remove deprecated fields on install.xml
- Changed description and description format to moodle standard intro and introformat on install.xml
- Reorganized fields order to improve readability

**********
Needs to reinstall to apply changes to DB

Bernardo 2 роки тому
батько
коміт
818dd61055

+ 40 - 67
db/install.xml

@@ -4,50 +4,38 @@
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
   <TABLES>
-    <TABLE NAME="gradeimporter" COMMENT="gradeimporter instance table, this table links the submissions to the course." NEXT="grade_importer_submission">
+    <TABLE NAME="gradeimporter" COMMENT="gradeimporter instance table, this table links the submissions to the course." >
       <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" COMMENT="primary key" NEXT="course"/>
-        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The id of the course this instance is placed on"
-                  PREVIOUS="id" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="256" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Instance name" PREVIOUS="course" NEXT="intro"/>
-        <FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Description of the grades that are going to be available on the module"
-              PREVIOUS="NAME" NEXT="timecreated"/>
-        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Time stamp from when the instance was first created"
-              PREVIOUS="intro" NEXT="timemodified"/>
-        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Last time the instance was modified"
-                PREVIOUS="timecreated" NEXT="usermodified"/>
-        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timemodified"/>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" COMMENT="primary key" />
+        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The id of the course this instance is placed on" />
+        <FIELD NAME="name" TYPE="char" LENGTH="256" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Instance name" />
+        <FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Description of the grades that are going to be available on the module" />
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="text format of intro field" />
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Time stamp from when the instance was first created" />
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Last time the instance was modified" />
+        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
         <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
       </KEYS>
     </TABLE>
-    <TABLE NAME="gradeimporter_submission" COMMENT="submission table, relates the submission to the gradeimporter, feedback files and student." PREVIOUS="gradeimporter" NEXT="gradeimporter_submissiontype" >
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="gradeimporter"/>
-        <FIELD NAME="gradeimporterid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-              COMMENT="Which gradeimporter instance this submission is related to" PREVIOUS="id" NEXT="type"/>
-        <FIELD NAME="type" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Type of the submission (exam, exercise list,"
-                PREVIOUS="gradeimporter" NEXT="gradebook"/>
-        <FIELD NAME="gradebook" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="Register if the submission is going to the gradebook"
-                PREVIOUS="type" NEXT="timecreated"/>
-        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                PREVIOUS="gradebook" NEXT="timemodified"/>
-        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                PREVIOUS="timecreated" NEXT="usermodified"/>
-        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                PREVIOUS="timemodified" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="256" NOTNULL="true" SEQUENCE="false" COMMENT="submission name"
-                PREVIOUS="usermodified" NEXT="info"/>
-        <FIELD NAME="description" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Description of the submission type ex: exam 1 given on day YYYY/MM/DD"
-              PREVIOUS="name" NEXT="descriptionformat"/>
-        <FIELD NAME="descriptionformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="description" NEXT="position"/>
 
-        <FIELD NAME="position" TYPE="int" LENGTH="3" NOTNULL="true" SEQUENCE="false" COMMENT="Position relative to other submissions"
-                PREVIOUS="descriptionformat" NEXT="visibility"/>
-        <FIELD NAME="visibility" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="Registers if students can see this submission."
-                PREVIOUS="position"/>
+    <TABLE NAME="gradeimporter_submission" COMMENT="submission table, relates the submission to the gradeimporter, feedback files and student."  >
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
+        <FIELD NAME="gradeimporterid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Which gradeimporter instance this submission is related to" />
+        <FIELD NAME="name" TYPE="char" LENGTH="256" NOTNULL="true" SEQUENCE="false" COMMENT="submission name" />
+        <FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Description of the submission type ex: exam 1 given on day YYYY/MM/DD" />
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="type" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Type of the submission (exam, exercise list," />
+        <FIELD NAME="position" TYPE="int" LENGTH="3" NOTNULL="true" SEQUENCE="false" COMMENT="Position relative to other submissions" />
+        <FIELD NAME="visibility" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="Registers if students can see this submission." />
+        <FIELD NAME="gradebook" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="Register if the submission is going to the gradebook" />
+        <FIELD NAME="maxgrade" TYPE="int"  LENGTH="10" NOTNULL=false SEQUENCE="false" COMMENT="Max grade if going to gradebook" />
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
@@ -57,16 +45,13 @@
       </KEYS>
     </TABLE>
 
-    <TABLE NAME="gradeimporter_submissiontype" COMMENT="Submission types are recorded by this table, eg: exam, exercises list, etc." PREVIOUS="gradeimporter_submission" NEXT="gradeimporter_feedback">
+    <TABLE NAME="gradeimporter_submissiontype" COMMENT="Submission types are recorded by this table, eg: exam, exercises list, etc." >
       <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="gradeimporterid"/>
-        <FIELD NAME="gradeimporterid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Which gradeimporter instance this submission is related to" PREVIOUS="id" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="Type name (exam, exercises list, etc)."
-                    PREVIOUS="gradeimporterid" NEXT="info"/>
-
-        <FIELD NAME="description" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Submission type description. eg for exam type: exams given in class."
-                    PREVIOUS="name" NEXT="descriptionformat"/>
-        <FIELD NAME="descriptionformat" TYPE="char" LENGTH="10" NOTNULL="false" DEFAULT="plaintext" SEQUENCE="false" COMMENT="Type description format (html, plaintext, etc.)"/>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
+        <FIELD NAME="gradeimporterid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Which gradeimporter instance this submission is related to" />
+        <FIELD NAME="name" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="Type name (exam, exercises list, etc)."/>
+        <FIELD NAME="intro" TYPE="text" NOTNULL="false" COMMENT="Submission type description. eg for exam type: exams given in class."/>
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Type description format (html, plaintext, etc.)"/>
       </FIELDS>
 
       <KEYS>
@@ -75,29 +60,17 @@
       </KEYS>
     </TABLE>
 
-    <TABLE NAME="gradeimporter_feedback" COMMENT="This table is responsible to link the feedback files from a certain submission to the student" PREVIOUS="gradeimporter_submissiontype">
+    <TABLE NAME="gradeimporter_feedback" COMMENT="This table is responsible to link the feedback files from a certain submission to the student" >
       <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="submissionid"/>
-        <FIELD NAME="submissionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Which submission this feedback is related to"
-                    PREVIOUS="id" NEXT="student"/>
-        <FIELD NAME="studentid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Student moodle user id. Related the feedback files to the student"
-                    PREVIOUS="submissionid" NEXT="grade"/>
-        <FIELD NAME="grade" TYPE="number" LENGTH="4" NOTNULL="false" SEQUENCE="false" DECIMALS="2" COMMENT="Student grade on the submission"
-                    PREVIOUS="studentid" NEXT="comment"/>
-        <FIELD NAME="comment" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Teacher comment about the feedback"
-                    PREVIOUS="grade" NEXT="fileid"/>
-        <FIELD NAME="fileid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false" COMMENT="id from filesplugin, where the feedback files are recorded"
-                    PREVIOUS="comment" NEXT="usermodified"/>
-        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                    PREVIOUS="fileid" NEXT="timecreated"/>
-        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                    PREVIOUS="usermodified" NEXT="timemodified"/>
-        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                    PREVIOUS="timecreated" NEXT="contextid"/>
-        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
-                    PREVIOUS="timemodified" NEXT="filename"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" COMMENT="File name to fetch at pluginfile."
-                    PREVIOUS="contextid"/>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
+        <FIELD NAME="submissionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Which submission this feedback is related to" />
+        <FIELD NAME="studentid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Student moodle user id. Related the feedback files to the student" />
+        <FIELD NAME="grade" TYPE="number" LENGTH="4" NOTNULL="false" SEQUENCE="false" DECIMALS="2" COMMENT="Student grade on the submission" />
+        <FIELD NAME="comment" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Teacher comment about the feedback" />
+        <FIELD NAME="filename" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" COMMENT="File name to fetch at pluginfile." /><FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>

+ 21 - 2
forms/submission/submission_form_functions.php

@@ -79,8 +79,10 @@ function store_files ($context, $cm, $data) {
 function read_csv ($content, $context, $data, $zipfiles = null) {
 
   $csv = prepare_csv($content);
-  foreach ($csv as $feedback) {
+  foreach ($csv as $line => $feedback) {
+    $feedback = fix_feedback($feedback, $line); // Check if data is correct
     $feedbackid = store_feedback($feedback, $context->id, $data->id);
+    gradeimporter_update_grades($data, $feedback->id);
     if ($feedback['file'] != "") {
       // If feedback has associated file, insert it into pluginfile
       foreach ($zipfiles as $file) {
@@ -140,7 +142,6 @@ function store_feedback ($feedback, $contextid, $submissionid) {
   $entry->grade = $feedback['grade'];
   $entry->comment = $feedback['comment'];
   $entry->name = $feedback['file'];
-  $entry->fileid = 0; // To be removed fileid is now feedbackid
   $entry->usermodified = $USER->id;
 
   // If is not a new feedback update previous record and return id
@@ -233,3 +234,21 @@ function delete_feedback_files($feedback) {
     $file->delete();
   }
 }
+
+/**
+ * Checks if $feedback csv line is correct
+ * if id is missing throw error
+ * if grade is missing change it to 0
+ * @param array $feedback - line with feedback data for a student
+ * @param int $line - which line of the csv file the feedback is
+ * @return array $feedback - Either empty grade changed to 0 or the same as param
+ */
+function fix_feedback ($feedback, $line) {
+  if ($feedback['id'] == "") {
+    throw new moodle_exception(get_string('studentidmissing', 'gradeimporter'), $line);
+  }
+  if ($feedback['grade'] == "") {
+    $feedback['grade'] = 0;
+  }
+  return $feedback;
+}

+ 1 - 0
lang/en/forms_lang.php

@@ -28,3 +28,4 @@ $string['submissionfiles_help'] = 'Submit 1 file with all submissions inside it,
 $string['newtypebutton'] = 'New type';
   // Exceptions
   $string['invalidtype'] = "Submission type is invalid, must first create a type";
+  $string['studentidmissing'] = 'Student id missing in .csv at line {$a}';

+ 4 - 4
lang/en/gradeimporter.php

@@ -29,8 +29,8 @@ $string['displayingview'] = 'Posted Grades';
 
 // Submission.php
 $string['invalidgradeimporterid'] = 'Invalid Grade Importer ID';
-$string['submissionadded'] = "Submission added to DB";
-$string['newsubmission'] = "Add new submission";
+$string['submissionadded'] = 'Submission added to DB';
+$string['newsubmission'] = 'Add new submission';
 
 // FormStrings
 
@@ -104,7 +104,7 @@ $string['grade']        = 'Grade';
 $string['file']         = 'File';
 $string['nameCol']      = 'Name';
 $string['nameColTitle'] = 'Fullname of all students enrolled in this course';
-$string['editSub']      = "Edit this submission";
+$string['editSub']      = 'Edit submission {$a}';
 
 // Access Errors
-    $string['guestnoedit'] = "Guests can't edit forms";
+    $string['guestnoedit'] = 'Guests can\'t edit forms';

+ 76 - 0
lib.php

@@ -39,6 +39,10 @@ function gradeimporter_supports($feature) {
       return false;
     case FEATURE_BACKUP_MOODLE2:
       return true;
+    case FEATURE_GRADE_HAS_GRADE:
+      return true;
+    case FEATURE_GRADE_OUTCOMES:
+      return true;
     default:
       return null;
   }
@@ -161,3 +165,75 @@ function mod_gradeimporter_pluginfile($course, $cm, $context, $filearea, $args,
   // We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
   send_stored_file($file, 86400, 0, $forcedownload, $options);
 }
+
+function gradeimporter_grade_item_update ($submission, $grades = null) {
+  global $CFG, $COURSE;
+
+  require_once("{$CFG->libdir}/gradelib.php");
+
+  $params = array('itemname' => $submission->name, 'idnumber' => $submission->cmid);
+
+  if ($submission->gradebook == 0) {
+    $params['gradetype'] = GRADE_TYPE_NONE;
+  } else {
+    $params['gradetype'] = GRADE_TYPE_VALUE;
+    $params['grademax'] = 10;
+    $params['grademin'] = 0;
+  }
+
+  if ($grades == 'reset') {
+    $params['reset'] == true;
+    $grades = null;
+  }
+
+  return grade_update('mod/gradeimporter', $COURSE->id, 'mod', 'gradeimporter', $submission->gradeimporterid, 0, $grades, $params);
+}
+
+function gradeimporter_update_grades ($submission, $userid = 0, $nullifnone = true) {
+  global $CFG, $DB, $COURSE;
+
+  require_once("{$CFG->libdir}/gradelib.php");
+
+  if ($submission->gradebook == 0) {
+    gradeimporter_grade_item_update($submission);
+    return;
+  }
+
+  // If submission is gradeable (gradebook==1) then tries to submit the grades
+  if ($grades = gradeimporter_get_user_grades($submission, $userid)) {
+    // Gets student grade from gradeimporter_feedback table
+    gradeimporter_grade_item_update($submission, $grades);
+
+  } else if ($userid and $nullifnone) {
+    $grade = new stdClass();
+    $grade->userid = $userid;
+    $grade->rawgrade = null;
+    gradeimporter_grade_item_update($submission, $grade);
+
+  } else {
+    gradeimporter_grade_item_update($submission);
+  }
+}
+
+function gradeimporter_reset_gradebook ($courseid, $type = '') {
+  global $CFG, $DB;
+  // Select all grades on gradebook and reset them
+}
+
+function gradeimporter_get_user_grades($submission, $userid) {
+  global $DB;
+  $grade = new stdClass();
+  $grade->userid = $userid;
+
+  $feedback = $DB->get_record('gradeimporter_feedback',
+                                    ['submissionid' => $submission->id, 'studendit' => $userid],
+                                    ['grade']
+                                  );
+
+  if ($feedback) {
+    $grade->rawgrade = $feedback->grade;
+    return $grade;
+  }
+
+  return null;
+}

+ 9 - 4
libs/teacher_viewlib.php

@@ -228,10 +228,15 @@ class Teacherview {
                                                                                       'cmid' => $this->get_cmid(),
                                                                                       'subid' => $submission->id)
                                                                                     );
-    $editlinktitle = get_string('editSub', 'gradeimporter');
-    return "<a title=\"$submission->description\">$submission->name</a>
-            <a href=\"$url\" target=\"_blank\"><i class = \"icon fa fa-pencil fa-fw\" title=\"$editlinktitle\"
-              aria-label=\"$editlinktitle\"></i>";
+    $editlinktitle = get_string('editSub', 'gradeimporter', $submission->name);
+    return "<a title=\"$submission->description\">
+              $submission->name
+            </a>
+            <a href=\"$url\" target=\"_blank\">
+              <i class = \"icon fa fa-pencil fa-fw\" title=\"$editlinktitle\"
+              aria-label=\"$editlinktitle\">
+              </i>
+            </a>";
   }
 
 }