diff --git a/admin/actions.php b/admin/actions.php
index 825874e655..9f68b42c9b 100644
--- a/admin/actions.php
+++ b/admin/actions.php
@@ -3,6 +3,7 @@
//(c) 2006 David Lippman
require("../init.php");
require_once("../includes/password.php");
+require_once("../includes/TeacherAuditLog.php");
//Look to see if a hook file is defined, and include if it is
if (isset($CFG['hooks']['admin/actions'])) {
@@ -662,13 +663,20 @@
}
if ($stm->rowCount()>0) {
+ $metadata = array();
if ($setdatesbylti==1) {
$stm = $DBH->prepare("UPDATE imas_assessments SET date_by_lti=1 WHERE date_by_lti=0 AND courseid=:cid");
$stm->execute(array(':cid'=>$_GET['id']));
+ if ($stm->rowCount()>0) {
+ $metadata['date_by_lti'] = 1;
+ }
} else {
//undo it - doesn't restore dates
$stm = $DBH->prepare("UPDATE imas_assessments SET date_by_lti=0 WHERE date_by_lti>0 AND courseid=:cid");
$stm->execute(array(':cid'=>$_GET['id']));
+ if ($stm->rowCount()>0) {
+ $metadata['date_by_lti'] = 0;
+ }
//remove is_lti from exceptions with latepasses
$query = "UPDATE imas_exceptions JOIN imas_assessments ";
$query .= "ON imas_exceptions.assessmentid=imas_assessments.id ";
@@ -676,12 +684,26 @@
$query .= "WHERE imas_exceptions.is_lti>0 AND imas_exceptions.islatepass>0 AND imas_assessments.courseid=:cid";
$stm = $DBH->prepare($query);
$stm->execute(array(':cid'=>$_GET['id']));
+ if ($stm->rowCount()>0) {
+ $metadata['imas_exceptions.is_lti'] = 0;
+ }
//delete any other is_lti exceptions
$query = "DELETE imas_exceptions FROM imas_exceptions JOIN imas_assessments ";
$query .= "ON imas_exceptions.assessmentid=imas_assessments.id ";
$query .= "WHERE imas_exceptions.is_lti>0 AND imas_exceptions.islatepass=0 AND imas_assessments.courseid=:cid";
$stm = $DBH->prepare($query);
$stm->execute(array(':cid'=>$_GET['id']));
+ if ($stm->rowCount()>0) {
+ $metadata['imas_exceptions.is_lti'] = 'deleted';
+ }
+ }
+ if (!empty($metadata)) {
+ $result = TeacherAuditLog::addTracking(
+ $cid,
+ "Mass Assessment Settings Change",
+ null,
+ $metadata
+ );
}
}
} else { //new course
@@ -881,6 +903,14 @@ function updateoutcomes(&$arr) {
if ($setdatesbylti==1) {
$stm = $DBH->prepare("UPDATE imas_assessments SET date_by_lti=1 WHERE date_by_lti=0 AND courseid=:cid");
$stm->execute(array(':cid'=>$cid));
+ if ($stm->rowCount()>0) {
+ $result = TeacherAuditLog::addTracking(
+ $cid,
+ "Mass Assessment Settings Change",
+ null,
+ ['date_by_lti'=>1]
+ );
+ }
}
/*
//add to top of course list (skip until we can do it consistently)
diff --git a/admin/teacherauditlog.php b/admin/teacherauditlog.php
new file mode 100644
index 0000000000..cbf6246fa2
--- /dev/null
+++ b/admin/teacherauditlog.php
@@ -0,0 +1,88 @@
+Admin > User Details ";
+$curBreadcrumb .= "> Teacher Audit Log\n";
+
+if (isset($_GET['id'])) {
+ $stm = $DBH->prepare("SELECT courseid FROM imas_assessments WHERE id=?");
+ $stm->execute(array(intval($_GET['id'])));
+ if ($stm->rowCount()==0 || $stm->fetchColumn(0) != $_GET['cid']) {
+ echo "Invalid ID";
+ exit;
+ }
+}
+
+if ($myrights <75) {
+ $overwriteBody=1;
+ $body = "You need to log in as an admin to access this page";
+} elseif (!(isset($_GET['cid']))) {
+ $overwriteBody=1;
+ $body = "You need to select the course";
+}
+function formatdate($date) {
+ return tzdate("M j, Y, g:i a",strtotime($date));
+}
+
+
+//BEGIN DISPLAY BLOCK
+
+ /******* begin html output ********/
+//$placeinhead = "";
+
+require("../header.php");
+
+if ($overwriteBody==1) {
+ echo $body;
+} else {
+ $stm = $DBH->prepare("SELECT ic.name,ic.ownerid,iu.groupid FROM imas_courses AS ic JOIN imas_users AS iu ON ic.ownerid=iu.id WHERE ic.id=?");
+ $stm->execute(array($cid));
+ list($coursename, $courseownerid, $coursegroupid) = $stm->fetch(PDO::FETCH_NUM);
+
+ echo '
', $curBreadcrumb, '
';
+ echo '';
+
+ $teacher_actions = TeacherAuditLog::findActionsByCourse($cid);
+ if (empty($teacher_actions)) {
+ echo "Nothing to report
";
+ } else {
+ $stm = $DBH->query("SELECT FirstName, LastName FROM imas_users WHERE id=" . $teacher_actions[0]['userid']);
+ list($first, $last) = $stm->fetch();
+ echo '';
+ echo 'Date/Time ';
+ echo 'Teacher ';
+ echo 'Action ';
+ echo 'ItemID ';
+ echo 'Details ';
+ echo ' ';
+
+ foreach ($teacher_actions as $action) {
+ echo '';
+ echo '' . formatdate($action['created_at']) . ' ';
+ echo "$first $last (" . Sanitize::onlyInt($action['userid']) . ') ';
+ echo '' . Sanitize::encodeStringForDisplay($action['action']) . ' ';
+ echo '' . Sanitize::onlyInt($action['itemid']) . ' ';
+ echo 'Details ';
+ echo ' ';
+ }
+ }
+}
+
+require("../footer.php");
\ No newline at end of file
diff --git a/admin/userdetails.php b/admin/userdetails.php
index cfec8cc932..9c2fcecc3e 100644
--- a/admin/userdetails.php
+++ b/admin/userdetails.php
@@ -392,7 +392,8 @@ function hidecourse(el) {
var cid = $(el).attr("data-cid");
var thishtml = html + \' '._('Return to home page course list').' \';
thishtml += \' '._('Hide from home page course list').' \';
-
+
+ thishtml += \' '._('Teacher Audit Log').' \';
thishtml += \' '._('Settings').' \';
thishtml += \' '._('Add/remove teachers').' \';
thishtml += \' '._('Transfer ownership').' \';
diff --git a/admin/userreportdetails.php b/admin/userreportdetails.php
index bf7a95265e..a611a972eb 100644
--- a/admin/userreportdetails.php
+++ b/admin/userreportdetails.php
@@ -516,6 +516,7 @@ function hidecourse(el) {
var thishtml = html + \' '._('Return to home page course list').' \';
thishtml += \' '._('Hide from home page course list').' \';
+ thishtml += \' '._('Teacher Audit Log').' \';
thishtml += \' '._('Settings').' \';
thishtml += \' '._('Add/remove teachers').' \';
thishtml += \' '._('Transfer ownership').' \';
diff --git a/assess2/AssessRecord.php b/assess2/AssessRecord.php
index 852268f879..4383f22962 100644
--- a/assess2/AssessRecord.php
+++ b/assess2/AssessRecord.php
@@ -11,6 +11,7 @@
require_once(__DIR__ . '/questions/models/ShowAnswer.php');
require_once(__DIR__ . '/questions/ScoreEngine.php');
require_once(__DIR__ . '/questions/models/ScoreQuestionParams.php');
+require_once(__DIR__ . '/../includes/TeacherAuditLog.php');
use IMathAS\assess2\questions\QuestionGenerator;
use IMathAS\assess2\questions\models\QuestionParams;
@@ -180,12 +181,45 @@ public function saveRecord() {
}
$stm = $this->DBH->prepare($query);
$stm->execute($qarr);
+ if ($stm->rowCount()>0 && isset( $qarr[':scoreddata'])) {
+ $this->assessRecord['scoreddata'] = json_decode(gzdecode($this->assessRecord['scoreddata']), true);
+ $qarr[':scoreddata'] = json_decode(gzdecode($qarr[':scoreddata']), true);
+ $override = $this->array_diff_assoc_recursive($this->assessRecord['scoreddata'],$qarr[':scoreddata']);
+ TeacherAuditLog::addTracking(
+ $this->assess_info->getCourseId(),
+ "Change Grades",
+ $this->curAid,
+ array(
+ 'Assessment Ver' => 2,
+ 'studentid' => $this->curUid,
+ 'override' => $override
+ )
+ );
+ }
$this->need_to_record = false;
}
}
+ private function array_diff_assoc_recursive($firstArray, $secondArray) {
+ $aReturn = array();
+ foreach ($firstArray as $mKey => $mValue) {
+ if (array_key_exists($mKey, $secondArray)) {
+ if (is_array($mValue)) {
+ $aRecursiveDiff = $this->array_diff_assoc_recursive($mValue, $secondArray[$mKey]);
+ if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; }
+ } else {
+ if ($mValue != $secondArray[$mKey]) {
+ $aReturn[$mKey] = $mValue;
+ }
+ }
+ } else {
+ $aReturn[$mKey] = $mValue;
+ }
+ }
+ return $aReturn;
+ }
- /**
+ /**
* Create a new record in the database. Call after loadRecord.
*
* @param array $users Array of users to create record for.
@@ -2942,6 +2976,18 @@ public function gbClearAttempts($type, $keepver, $av=0, $qn=0, $qv=0) {
$replacedDeleted = true;
}
$this->updateStatus();
+ $result = TeacherAuditLog::addTracking(
+ $this->assess_info->getCourseId(),
+ "Clear Attempts",
+
+ $this->curAid,
+ array(
+ 'Assessment Ver' => 2,
+ 'studentid' => $this->curUid,
+ 'type'=>$type,
+ 'keepver' => $this->assessRecord,
+ )
+ );
return $replacedDeleted;
}
diff --git a/assess2/gbclearattempt.php b/assess2/gbclearattempt.php
index 7e19299773..84306ddfb7 100644
--- a/assess2/gbclearattempt.php
+++ b/assess2/gbclearattempt.php
@@ -26,6 +26,7 @@
require_once("./AssessInfo.php");
require_once("./AssessRecord.php");
require_once('./AssessUtils.php');
+require_once("../includes/TeacherAuditLog.php");
header('Content-Type: application/json; charset=utf-8');
@@ -72,6 +73,14 @@
if ($type == 'all' && $keepver == 0) {
$stm = $DBH->prepare('DELETE FROM imas_assessment_records WHERE assessmentid=? AND userid=?');
$stm->execute(array($aid, $uid));
+ if ($stm->rowCount()>0) {
+ $result = TeacherAuditLog::addTracking(
+ $cid,
+ "Clear Attempts",
+ $aid,
+ array('grades'=>$assess_record->getGbScore())
+ );
+ }
// update LTI grade
$lti_sourcedid = $assess_record->getLTIsourcedId();
if (strlen($lti_sourcedid) > 1) {
diff --git a/assess2/vue-src/package-lock.json b/assess2/vue-src/package-lock.json
index 1909f1e018..16f857ecbf 100644
--- a/assess2/vue-src/package-lock.json
+++ b/assess2/vue-src/package-lock.json
@@ -2900,7 +2900,8 @@
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"coa": {
"version": "2.0.2",
@@ -5521,7 +5522,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -5542,12 +5544,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -5562,17 +5566,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -5689,7 +5696,8 @@
"inherits": {
"version": "2.0.4",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -5701,6 +5709,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -5715,6 +5724,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -5722,12 +5732,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -5746,6 +5758,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5835,7 +5848,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -5847,6 +5861,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -5932,7 +5947,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -5968,6 +5984,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -5987,6 +6004,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -6030,12 +6048,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -9953,7 +9973,8 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"rx-lite-aggregates": {
"version": "4.0.8",
diff --git a/assess2/vue-src/public/gbviewassess.html b/assess2/vue-src/public/gbviewassess.html
index b5a2b22d6d..9feb667b0c 100644
--- a/assess2/vue-src/public/gbviewassess.html
+++ b/assess2/vue-src/public/gbviewassess.html
@@ -4,39 +4,39 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
vue-demo
diff --git a/assess2/vue-src/public/index.html b/assess2/vue-src/public/index.html
index 0d75905af0..3238cf1d61 100644
--- a/assess2/vue-src/public/index.html
+++ b/assess2/vue-src/public/index.html
@@ -4,36 +4,36 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
vue-demo
diff --git a/assess2/vue/gbviewassess.html b/assess2/vue/gbviewassess.html
index 5b97bab76e..f1363fd508 100644
--- a/assess2/vue/gbviewassess.html
+++ b/assess2/vue/gbviewassess.html
@@ -1,8 +1,8 @@
-vue-demo We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to continue.
[more..]
\ No newline at end of file
+ var filePickerCallBackFunc = function() {};vue-demo We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to continue.
[more..]