diff --git a/README.md b/README.md
index 3f1a6d5..ed36dde 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,8 @@
+Archived
+======================================================================
+Visit UCL Repo for latest commits
+https://github.com/ucl-isd/moodle-mod_coursework
+
Coursework Activity
======================================================================
Copyright University of London.
diff --git a/actions/ajax/datatable/grading.php b/actions/ajax/datatable/grading.php
new file mode 100644
index 0000000..a3875c1
--- /dev/null
+++ b/actions/ajax/datatable/grading.php
@@ -0,0 +1,39 @@
+set_context(context_system::instance());
+
+$group = required_param('group', PARAM_INT);
+$perpage = required_param('perpage', PARAM_INT);
+$sortby = required_param('sortby', PARAM_ALPHA);
+$sorthow = required_param('sorthow', PARAM_ALPHA);
+$courseworkid = required_param('courseworkid', PARAM_INT);
+$unallocated = optional_param('unallocated', false, PARAM_BOOL);
+
+// Grading report display options.
+$report_options = array();
+if ($unallocated) {
+ $report_options['unallocated'] = true;
+}
+
+$report_options['group'] = $group;
+$report_options['perpage'] = $perpage;
+$report_options['sortby'] = $sortby;
+$report_options['sorthow'] = $sorthow;
+$report_options['showsubmissiongrade'] = false;
+$report_options['showgradinggrade'] = false;
+$report_options['courseworkid'] = $courseworkid;
+$report_options['mode'] = \mod_coursework\grading_report::$MODE_GET_REMAIN_RECORDS;
+
+//$controller = new mod_coursework\controllers\grading_controller(['courseworkid' => $report_options, 'allocatableid' => $USER->id, 'allocatabletype' => $USER->id]);
+$controller = new mod_coursework\controllers\grading_controller([]);
+sleep(10);
+$table_html = $controller->get_remain_rows_grading_table($report_options);
+if (ob_get_contents()) {
+ ob_end_clean();
+}
+
+echo $table_html;
diff --git a/actions/ajax/deadline_extension/edit.php b/actions/ajax/deadline_extension/edit.php
new file mode 100644
index 0000000..34a70bb
--- /dev/null
+++ b/actions/ajax/deadline_extension/edit.php
@@ -0,0 +1,32 @@
+id, PARAM_INT);
+$allocatabletype = optional_param('allocatabletype', $USER->id, PARAM_ALPHANUMEXT);
+$requesttype = optional_param('requesttype', 'new', PARAM_ALPHANUMEXT);
+$id = optional_param('id', 0, PARAM_INT);
+$extra_information_text = optional_param('text', '', PARAM_RAW);
+$extra_information_format = optional_param('format', 1, PARAM_ALPHANUMEXT);
+$extended_deadline = optional_param('extended_deadline', 0, PARAM_ALPHANUMEXT);
+$pre_defined_reason = optional_param('pre_defined_reason', null, PARAM_ALPHANUMEXT);
+$submissionid = optional_param('submissionid', 0, PARAM_INT);
+$name = optional_param('name', 0, PARAM_ALPHANUMEXT);
+$params = array(
+ 'courseworkid' => $courseworkid,
+ 'allocatableid' => $allocatableid,
+ 'allocatabletype' => $allocatabletype,
+);
+$controller = new mod_coursework\controllers\deadline_extensions_controller($params);
+
+$params['id'] = $id;
+$params['extra_information_text'] = $extra_information_text;
+$params['extra_information_format'] = $extra_information_format;
+$params['extended_deadline'] = strtotime($extended_deadline);
+$params['pre_defined_reason'] = $pre_defined_reason;
+$params['submissionid'] = $submissionid;
+$params['name'] = $name;
+
+$controller->ajax_edit_mitigation($params);
\ No newline at end of file
diff --git a/actions/ajax/deadline_extension/new.php b/actions/ajax/deadline_extension/new.php
new file mode 100644
index 0000000..59b9ac9
--- /dev/null
+++ b/actions/ajax/deadline_extension/new.php
@@ -0,0 +1,32 @@
+id, PARAM_INT);
+$allocatabletype = optional_param('allocatabletype', $USER->id, PARAM_ALPHANUMEXT);
+$requesttype = optional_param('requesttype', 'new', PARAM_ALPHANUMEXT);
+$id = optional_param('id', 0, PARAM_INT);
+$extra_information_text = optional_param('text', '', PARAM_RAW);
+$extra_information_format = optional_param('format', 1, PARAM_ALPHANUMEXT);
+$extended_deadline = optional_param('extended_deadline', 0, PARAM_ALPHANUMEXT);
+$pre_defined_reason = optional_param('pre_defined_reason', null, PARAM_ALPHANUMEXT);
+$submissionid = optional_param('submissionid', 0, PARAM_INT);
+$name = optional_param('name', 0, PARAM_ALPHANUMEXT);
+$params = array(
+ 'courseworkid' => $courseworkid,
+ 'allocatableid' => $allocatableid,
+ 'allocatabletype' => $allocatabletype,
+);
+$controller = new mod_coursework\controllers\deadline_extensions_controller($params);
+
+$params['id'] = $id;
+$params['extra_information_text'] = $extra_information_text;
+$params['extra_information_format'] = $extra_information_format;
+$params['extended_deadline'] = strtotime($extended_deadline);
+$params['pre_defined_reason'] = $pre_defined_reason;
+$params['submissionid'] = $submissionid;
+$params['name'] = $name;
+
+$controller->ajax_new_mitigation($params);
\ No newline at end of file
diff --git a/actions/ajax/deadline_extension/submit.php b/actions/ajax/deadline_extension/submit.php
new file mode 100644
index 0000000..2e46b34
--- /dev/null
+++ b/actions/ajax/deadline_extension/submit.php
@@ -0,0 +1,33 @@
+id, PARAM_INT);
+$allocatabletype = optional_param('allocatabletype', $USER->id, PARAM_ALPHANUMEXT);
+$requesttype = optional_param('requesttype', 'new', PARAM_ALPHANUMEXT);
+$id = optional_param('id', 0, PARAM_INT);
+$extra_information_text = optional_param('text', '', PARAM_RAW);
+$extra_information_format = optional_param('format', 1, PARAM_ALPHANUMEXT);
+$extended_deadline = optional_param('extended_deadline', 0, PARAM_ALPHANUMEXT);
+$pre_defined_reason = optional_param('pre_defined_reason', null, PARAM_ALPHANUMEXT);
+$submissionid = optional_param('submissionid', 0, PARAM_INT);
+$name = optional_param('name', 0, PARAM_ALPHANUMEXT);
+$params = array(
+ 'courseworkid' => $courseworkid,
+ 'allocatableid' => $allocatableid,
+ 'allocatabletype' => $allocatabletype,
+);
+$controller = new mod_coursework\controllers\deadline_extensions_controller($params);
+
+$params['id'] = $id;
+$params['extra_information_text'] = $extra_information_text;
+$params['extra_information_format'] = $extra_information_format;
+$params['extended_deadline'] = strtotime($extended_deadline);
+$params['pre_defined_reason'] = $pre_defined_reason;
+$params['submissionid'] = $submissionid;
+$params['name'] = $name;
+
+$controller->ajax_submit_mitigation($params);
+
diff --git a/actions/feedbacks/create.php b/actions/feedbacks/create.php
index 303f572..a7ab4ff 100644
--- a/actions/feedbacks/create.php
+++ b/actions/feedbacks/create.php
@@ -14,6 +14,7 @@
$assessorid = optional_param('assessorid', $USER->id, PARAM_INT);
$stage_identifier = optional_param('stage_identifier', '', PARAM_ALPHANUMEXT);
$finalised = !!optional_param('submitbutton', 0, PARAM_TEXT);
+$ajax = optional_param('ajax', 0, PARAM_INT);
$params = array(
'submissionid' => $submissionid,
@@ -21,6 +22,12 @@
'assessorid' => $assessorid,
'stage_identifier' => $stage_identifier,
'finalised' => $finalised,
+ 'ajax' => $ajax,
);
+
+if ($ajax) {
+ $params['cell_type'] = required_param('cell_type', PARAM_TEXT);
+}
+
$controller = new mod_coursework\controllers\feedback_controller($params);
$controller->create_feedback();
\ No newline at end of file
diff --git a/actions/feedbacks/edit.php b/actions/feedbacks/edit.php
index a16b1a8..ee01b23 100644
--- a/actions/feedbacks/edit.php
+++ b/actions/feedbacks/edit.php
@@ -27,9 +27,11 @@
$feedbackid = optional_param('feedbackid', 0, PARAM_INT);
+$ajax = optional_param('ajax', 0, PARAM_INT);
$params = array(
'feedbackid' => $feedbackid,
+ 'ajax' => $ajax
);
$controller = new mod_coursework\controllers\feedback_controller($params);
$controller->edit_feedback();
\ No newline at end of file
diff --git a/actions/feedbacks/new.php b/actions/feedbacks/new.php
index d0baad5..d68afdf 100644
--- a/actions/feedbacks/new.php
+++ b/actions/feedbacks/new.php
@@ -30,6 +30,7 @@
$feedbackid = optional_param('feedbackid', 0, PARAM_INT);
$assessorid = optional_param('assessorid', $USER->id, PARAM_INT);
$stage_identifier = optional_param('stage_identifier', 'uh-oh', PARAM_RAW);
+$ajax = optional_param('ajax', 0, PARAM_INT);
$params = array(
'submissionid' => $submissionid,
@@ -37,6 +38,7 @@
'feedbackid' => $feedbackid,
'assessorid' => $assessorid,
'stage_identifier' => $stage_identifier,
+ 'ajax' => $ajax,
);
$controller = new mod_coursework\controllers\feedback_controller($params);
-$controller->new_feedback();
\ No newline at end of file
+$controller->new_feedback();
diff --git a/actions/feedbacks/show.php b/actions/feedbacks/show.php
index 7eea80d..47d822c 100644
--- a/actions/feedbacks/show.php
+++ b/actions/feedbacks/show.php
@@ -26,9 +26,12 @@
global $CFG, $USER;
$feedbackid = optional_param('feedbackid', 0, PARAM_INT);
+$ajax = optional_param('ajax', 0, PARAM_INT);
$params = array(
'feedbackid' => $feedbackid,
+ 'ajax' => $ajax
+
);
$controller = new mod_coursework\controllers\feedback_controller($params);
$controller->show_feedback();
\ No newline at end of file
diff --git a/actions/feedbacks/update.php b/actions/feedbacks/update.php
index 95e15ba..d0fe764 100644
--- a/actions/feedbacks/update.php
+++ b/actions/feedbacks/update.php
@@ -11,10 +11,21 @@
$feedbackid = required_param('feedbackid', PARAM_INT);
$finalised = !!optional_param('submitbutton', 0, PARAM_TEXT);
+$ajax = optional_param('ajax', 0, PARAM_INT);
+$remove = !!optional_param('removefeedbackbutton', 0, PARAM_TEXT);
+$confirm = optional_param('confirm', 0, PARAM_INT);
$params = array(
'feedbackid' => $feedbackid,
'finalised' => $finalised,
+ 'remove' => $remove,
+ 'confirm' => $confirm,
+ 'ajax' => $ajax
);
+
+if ($ajax) {
+ $params['cell_type'] = required_param('cell_type', PARAM_TEXT);
+}
+
$controller = new mod_coursework\controllers\feedback_controller($params);
$controller->update_feedback();
\ No newline at end of file
diff --git a/actions/personal_deadline.php b/actions/personal_deadline.php
index c8b5850..baf5be4 100644
--- a/actions/personal_deadline.php
+++ b/actions/personal_deadline.php
@@ -2,7 +2,9 @@
require_once(dirname(__FILE__) . '/../../../config.php');
-global $CFG, $USER;
+global $CFG, $USER, $PAGE, $DB;
+
+
$courseworkid = required_param('courseworkid', PARAM_INT);
$allocatableid_arr = optional_param_array('allocatableid_arr', false, PARAM_RAW);
@@ -10,10 +12,18 @@
$allocatabletype = optional_param('allocatabletype', $USER->id, PARAM_ALPHANUMEXT);
$setpersonaldeadlinespage = optional_param('setpersonaldeadlinespage', 0, PARAM_INT);
$multipleuserdeadlines = optional_param('multipleuserdeadlines', 0, PARAM_INT);
-
+$selectedtype = optional_param('selectedtype','date', PARAM_RAW);
+$personal_deadline_time = optional_param('personal_deadline_time',null,PARAM_RAW);
$allocatableid = (!empty($allocatableid_arr)) ? $allocatableid_arr : $allocatableid ;
+
+$coursework_db = $DB->get_record('coursework',array('id'=>$courseworkid));
+
+$coursework = \mod_coursework\models\coursework::find($coursework_db);
+
+require_login($coursework->get_course(),false,$coursework->get_course_module());
+
$params = array(
'courseworkid' => $courseworkid,
'allocatableid' => $allocatableid,
@@ -21,5 +31,23 @@
'setpersonaldeadlinespage' => $setpersonaldeadlinespage,
'multipleuserdeadlines' => $multipleuserdeadlines
);
-$controller = new mod_coursework\controllers\personal_deadlines_controller($params);
-$controller->new_personal_deadline();
+
+if ($selectedtype != 'unfinalise') {
+ $controller = new mod_coursework\controllers\personal_deadlines_controller($params);
+
+ if(!empty($personal_deadline_time)) {
+ $result = $controller->insert_update($personal_deadline_time);
+ echo json_encode($result);
+ } else {
+ $controller->new_personal_deadline();
+ }
+} else {
+
+ if (!has_capability('mod/coursework:revertfinalised', $PAGE->context)) {
+ $message = 'You do not have permission to revert submissions';
+ redirect($url, $message);
+ }
+
+ $controller = new mod_coursework\controllers\submissions_controller($params);
+ $controller->unfinalise_submission();
+}
diff --git a/actions/upload_allocations.php b/actions/upload_allocations.php
index 5893cff..145c34f 100644
--- a/actions/upload_allocations.php
+++ b/actions/upload_allocations.php
@@ -81,6 +81,9 @@
$page_renderer = $PAGE->get_renderer('mod_coursework', 'page');
echo $page_renderer->process_csv_upload($procsessingresults, $content, $csvtype);
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework->id]);
+ $cache->purge();
+
} else {
$page_renderer = $PAGE->get_renderer('mod_coursework', 'page');
echo $page_renderer->csv_upload($allocationsuploadform, $csvtype);
diff --git a/backup/moodle2/backup_coursework_stepslib.php b/backup/moodle2/backup_coursework_stepslib.php
index 44c6126..e092e90 100644
--- a/backup/moodle2/backup_coursework_stepslib.php
+++ b/backup/moodle2/backup_coursework_stepslib.php
@@ -5,7 +5,7 @@ class backup_coursework_activity_structure_step extends backup_activity_structur
protected function define_structure()
{
global $DB;
-
+
foreach(array('coursework_submissions',
'coursework_allocation_pairs',
'coursework_mod_set_members',
@@ -13,13 +13,13 @@ protected function define_structure()
'coursework_extensions',
'coursework_person_deadlines') as $tablename)
{
- $DB->execute("update {{$tablename}} set `allocatableuser`=0, `allocatablegroup`=0");
- $DB->execute("update {{$tablename}} set `allocatableuser`=`allocatableid` where allocatabletype='user'");
- $DB->execute("update {{$tablename}} set `allocatablegroup`=`allocatableid` where allocatabletype='group'");
+ $DB->execute("update {{$tablename}} set allocatableuser=0, allocatablegroup=0");
+ $DB->execute("update {{$tablename}} set allocatableuser=allocatableid where allocatabletype='user'");
+ $DB->execute("update {{$tablename}} set allocatablegroup=allocatableid where allocatabletype='group'");
}
-
+
$userinfo = $this->get_setting_value('userinfo');
-
+
$coursework=new backup_nested_element('coursework',array('id'),
array('formid',
'course',
@@ -72,6 +72,7 @@ protected function define_structure()
'automaticagreement',
'automaticagreementrange',
'automaticagreementstrategy',
+ 'averagerounding',
'feedbackreleaseemail',
'gradeeditingtime',
'markingdeadlineenabled',
@@ -316,7 +317,7 @@ protected function define_structure()
$coursework->add_child($allocation_configs);
//And sample members
$coursework->add_child($sample_members);
-
+
//And submissions are made up from individual submission instances
$submissions->add_child($submission);
//Submissions have multiple feedback items
@@ -377,30 +378,30 @@ protected function define_structure()
$allocation_config->set_source_table('coursework_allocation_config',
array('courseworkid'=>backup::VAR_PARENTID));
-
+
//Mark important foreign keys
$feedback->annotate_ids('user','assessorid');
$feedback->annotate_ids('user','lasteditedbyuser');
$feedback->annotate_ids('user','markernumber');
-
+
$submission->annotate_ids('user','userid');
$submission->annotate_ids('user','createdby');
$submission->annotate_ids('user','lastupdatedby');
- $submission->annotate_ids('user','allocatableuser');
+ $submission->annotate_ids('user','allocatableuser');
$submission->annotate_ids('group','allocatablegroup');
$reminder->annotate_ids('user','userid');
$pair->annotate_ids('user','assessorid');
- $pair->annotate_ids('user','allocatableuser');
+ $pair->annotate_ids('user','allocatableuser');
$pair->annotate_ids('group','allocatablegroup');
-
+
$allocation_config->annotate_ids('user','assessorid');
- $modsetmember->annotate_ids('user','allocatableuser');
+ $modsetmember->annotate_ids('user','allocatableuser');
$modsetmember->annotate_ids('group','allocatablegroup');
- $extension->annotate_ids('user','allocatableuser');
+ $extension->annotate_ids('user','allocatableuser');
$extension->annotate_ids('group','allocatablegroup');
$personal_deadline->annotate_ids('user','allocatableuser');
@@ -423,8 +424,8 @@ protected function define_structure()
$coursework->annotate_ids('grouping','grouping_id');
$coursework->set_source_table('coursework',array('id'=>backup::VAR_ACTIVITYID));
-
- return $this->prepare_activity_structure($coursework);
-
+
+ return $this->prepare_activity_structure($coursework);
+
}
}
\ No newline at end of file
diff --git a/backup/moodle2/restore_coursework_stepslib.php b/backup/moodle2/restore_coursework_stepslib.php
index 08bf3ea..0a5d6ec 100644
--- a/backup/moodle2/restore_coursework_stepslib.php
+++ b/backup/moodle2/restore_coursework_stepslib.php
@@ -448,6 +448,7 @@ protected function process_coursework($data)
'automaticagreement'=>0,
'automaticagreementrange'=>0,
'automaticagreementstrategy'=>'',
+ 'averagerounding'=>'mid',
'feedbackreleaseemail'=>0,
'gradeeditingtime'=>0,
'markingdeadlineenabled'=>0,
diff --git a/classes/ability.php b/classes/ability.php
index 169fd1b..b45aa04 100644
--- a/classes/ability.php
+++ b/classes/ability.php
@@ -532,7 +532,7 @@ protected function prevent_revert_submission_when_deadline_passed_and_no_extensi
$this->prevent('revert',
'mod_coursework\models\submission',
function (submission $submission) {
- return $submission->get_coursework()->deadline_has_passed() && !$submission->has_extension()
+ return $submission->get_coursework()->deadline_has_passed() && (!$submission->has_extension() || $submission->extension_deadline() < time())
&& !$submission->get_coursework()->allow_late_submissions();
});
}
diff --git a/classes/allocation/auto_allocator.php b/classes/allocation/auto_allocator.php
index d6e197c..4caa89a 100644
--- a/classes/allocation/auto_allocator.php
+++ b/classes/allocation/auto_allocator.php
@@ -42,6 +42,8 @@ public function process_allocations() {
$this->process_marking_stage($stage);
}
}
+ allocation::remove_cache($this->coursework->id);
+ allocation::fill_pool_coursework($this->coursework->id);
}
/**
diff --git a/classes/allocation/table/cell/builder.php b/classes/allocation/table/cell/builder.php
index 8ec4a36..cd86737 100644
--- a/classes/allocation/table/cell/builder.php
+++ b/classes/allocation/table/cell/builder.php
@@ -3,6 +3,7 @@
namespace mod_coursework\allocation\table\cell;
use mod_coursework\models\allocation;
use mod_coursework\models\coursework;
+use mod_coursework\models\feedback;
use mod_coursework\stages\base as stage_base;
use mod_coursework\allocation\allocatable;
use mod_coursework\models\submission;
@@ -422,32 +423,37 @@ private function get_automatically_in_sample_label() {
/**
* @return bool
*/
- private function has_final_feedback(){
- global $DB;
-
- $sql = "SELECT *
- FROM {coursework_submissions} s
- JOIN {coursework_feedbacks} f
- ON f.submissionid = s.id
- WHERE s.courseworkid = :courseworkid
- AND s.allocatableid = :allocatableid
- AND s.allocatabletype = :allocatabletype
- AND f.stage_identifier = 'final_agreed_1'";
-
- return $DB->record_exists_sql($sql, array('courseworkid'=>$this->coursework->id,
- 'allocatableid'=>$this->allocatable->id(),
- 'allocatabletype'=>$this->allocatable->type()));
+ private function has_final_feedback() {
+ submission::fill_pool_coursework($this->coursework->id);
+ feedback::fill_pool_coursework($this->coursework->id);
+ $submission = submission::get_object(
+ $this->coursework->id,
+ 'allocatableid-allocatabletype',
+ [$this->allocatable->id(), $this->allocatable->type()]
+ );
+ if($submission){
+ $feedbacks = isset(feedback::$pool[$this->coursework->id]['submissionid'][$submission->id]) ?
+ feedback::$pool[$this->coursework->id]['submissionid'][$submission->id] : [];
+
+ foreach ($feedbacks as $feedback) {
+ if ($feedback->stage_identifier == 'final_agreed_1') {
+ return true;
+ }
+ }
+ }
+ return false;
}
/**
* @return static
*/
- private function get_submission(){
-
- $submission_params = array('courseworkid' => $this->coursework->id,
- 'allocatableid' => $this->allocatable->id(),
- 'allocatabletype' => $this->allocatable->type());
-
- return submission::find($submission_params);
+ private function get_submission() {
+ submission::fill_pool_coursework($this->coursework->id);
+ $submission = submission::get_object(
+ $this->coursework->id,
+ 'allocatableid-allocatabletype',
+ [$this->allocatable->id(), $this->allocatable->type()]
+ );
+ return $submission;
}
}
\ No newline at end of file
diff --git a/classes/allocation/table/row/builder.php b/classes/allocation/table/row/builder.php
index 6c21e1e..35db042 100644
--- a/classes/allocation/table/row/builder.php
+++ b/classes/allocation/table/row/builder.php
@@ -140,5 +140,36 @@ public function get_student_lastname() {
return $this->get_allocatable()->lastname;
}
-
+ /**
+ * @return string
+ */
+ public function get_idnumber() {
+
+ global $DB;
+
+ $allocatable = $this->get_allocatable();
+ if (empty($allocatable->idnumber)) {
+ $this->allocatable = user::find($allocatable);
+ }
+
+ return $this->get_allocatable()->idnumber;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function get_email() {
+
+ global $DB;
+
+ $allocatable = $this->get_allocatable();
+ if (empty($allocatable->email)) {
+ $this->allocatable = user::find($allocatable);
+ }
+
+ return $this->get_allocatable()->email;
+ }
+
+
}
diff --git a/classes/allocation/upload.php b/classes/allocation/upload.php
index 4042090..d2b03c8 100644
--- a/classes/allocation/upload.php
+++ b/classes/allocation/upload.php
@@ -47,7 +47,9 @@ public function __construct($coursework) {
* @throws \moodle_exception
*/
public function validate_csv($content,$encoding,$delimeter){
- global $DB;
+ global $CFG, $DB;
+
+ $assessor_identifier = $CFG->coursework_allocation_identifier;
$iid = \csv_import_reader::get_new_iid('courseworkallocationsdata');
$csvreader = new \csv_import_reader($iid, 'courseworkallocationsdata');
@@ -102,7 +104,7 @@ public function validate_csv($content,$encoding,$delimeter){
if ($allocatabletype == 'user'){
// get user id
- $suballocatable = $DB->get_record('user', array('username'=>$value));
+ $suballocatable = $DB->get_record('user', array($assessor_identifier=>$value));
$allocatable = ($suballocatable)? \mod_coursework\models\user::find($suballocatable->id): '';
} else {
// get group id
@@ -125,7 +127,7 @@ public function validate_csv($content,$encoding,$delimeter){
// skip empty assessors fields
if(empty($value)){ continue;}
- $assessor = $DB->get_record('user', array('username'=>$value));
+ $assessor = $DB->get_record('user', array($assessor_identifier=>$value));
if(!$assessor ||!in_array($assessor->id, $assessors)){$errors[$s] = get_string('assessornotincoursework', 'coursework', $keynum ); continue;}
@@ -159,7 +161,9 @@ public function validate_csv($content,$encoding,$delimeter){
*/
public function process_csv($content, $encoding, $delimiter, $processingresults){
- global $DB, $PAGE;
+ global $CFG, $DB, $PAGE;
+
+ $assessor_identifier = $CFG->coursework_allocation_identifier;
$iid = \csv_import_reader::get_new_iid('courseworkallocationsdata');
$csvreader = new \csv_import_reader($iid, 'courseworkallocationsdata');
@@ -211,7 +215,7 @@ public function process_csv($content, $encoding, $delimiter, $processingresults)
if ($cells[$keynum] == 'allocatable') {
if ($allocatabletype == 'user'){
// get user id
- $suballocatable = $DB->get_record('user', array('username'=>$value));
+ $suballocatable = $DB->get_record('user', array($assessor_identifier=>$value));
$allocatable = ($suballocatable)? \mod_coursework\models\user::find($suballocatable->id): '';
} else {
// get group id
@@ -222,7 +226,7 @@ public function process_csv($content, $encoding, $delimiter, $processingresults)
}
if (substr($cells[$keynum],0,8) == 'assessor' && !(empty($value))){
- $assessor = $DB->get_record('user', array('username'=>$value));
+ $assessor = $DB->get_record('user', array($assessor_identifier=>$value));
$params = array('courseworkid' => $this->coursework->id,
'allocatableid' => $allocatable->id,
diff --git a/classes/auto_grader/auto_grader.php b/classes/auto_grader/auto_grader.php
index 5038c15..08f2a84 100644
--- a/classes/auto_grader/auto_grader.php
+++ b/classes/auto_grader/auto_grader.php
@@ -7,7 +7,7 @@
*/
interface auto_grader {
- public function __construct($coursework, $allocatable, $percentage);
+ public function __construct($coursework, $allocatable);
public function create_auto_grade_if_rules_match();
}
\ No newline at end of file
diff --git a/classes/auto_grader/average_grade.php b/classes/auto_grader/average_grade.php
new file mode 100644
index 0000000..e74faae
--- /dev/null
+++ b/classes/auto_grader/average_grade.php
@@ -0,0 +1,159 @@
+coursework = $coursework;
+ $this->roundingrule = $this->coursework->roundingrule;
+ $this->allocatable = $allocatable;
+ }
+
+ /**
+ * This will test whether there is a grade already present, test whether the rules for this class match the
+ * state of the initial assessor grades and make an automatic grade if they do.
+ *
+ */
+ public function create_auto_grade_if_rules_match(){
+
+ // bounce out if conditions are not right/
+ if (!$this->get_allocatable()->has_all_initial_feedbacks($this->get_coursework())) {
+ return;
+ }
+ if ($this->get_coursework()->numberofmarkers == 1) {
+ return;
+ }
+
+
+
+ if (!$this->get_allocatable()->has_agreed_feedback($this->get_coursework())) {
+ $this->create_final_feedback();
+ } else {
+ // update only if AgreedGrade has been automatic
+ $agreed_feedback = $this->get_allocatable()->get_agreed_feedback($this->get_coursework());
+ if ($agreed_feedback->timecreated == $agreed_feedback->timemodified || $agreed_feedback->lasteditedbyuser == 0) {
+ $this->update_final_feedback($agreed_feedback);
+ }
+ }
+
+
+
+ // trigger events?
+
+ }
+
+ /**
+ * @return coursework
+ */
+ private function get_coursework()
+ {
+ return $this->coursework;
+ }
+
+ /**
+ * @return int
+ */
+ private function automatic_grade(){
+
+ $grades = $this->grades_as_percentages();
+
+ // calculate average
+ $avggrade = array_sum($grades) / count($grades);
+
+ // round it according to the chosen rule
+ switch ($this->roundingrule) {
+ case 'mid':
+ $avggrade = round($avggrade);
+ break;
+ case 'up':
+ $avggrade = ceil($avggrade);
+ break;
+ case 'down':
+ $avggrade = floor($avggrade);
+ break;
+ }
+
+
+ return $avggrade;
+ }
+
+
+ /**
+ * @return allocatable
+ */
+ private function get_allocatable(){
+ return $this->allocatable;
+ }
+
+ /**
+ *
+ */
+ private function create_final_feedback() {
+ feedback::create(array(
+ 'stage_identifier' => 'final_agreed_1',
+ 'submissionid' => $this->get_allocatable()->get_submission($this->get_coursework())->id(),
+ 'grade' => $this->automatic_grade()
+
+ ));
+ }
+
+
+ /**
+ *
+ */
+ private function update_final_feedback($feedback){
+ global $DB;
+
+ $updated_feedback = new \stdClass();
+ $updated_feedback->id = $feedback->id;
+ $updated_feedback->grade = $this->automatic_grade();
+ $updated_feedback->lasteditedbyuser = 0;
+
+ $DB->update_record('coursework_feedbacks', $updated_feedback);
+
+ }
+
+
+ /**
+ * @return array
+ */
+ private function grades_as_percentages() {
+ $initial_feedbacks = $this->get_allocatable()->get_initial_feedbacks($this->get_coursework());
+ $grades = array_map(function ($feedback) {
+ return ($feedback->get_grade() / $this->get_coursework()->get_max_grade()) * 100;
+ },
+ $initial_feedbacks);
+ return $grades;
+ }
+}
\ No newline at end of file
diff --git a/classes/auto_grader/none.php b/classes/auto_grader/none.php
index e94e6c6..13383bd 100644
--- a/classes/auto_grader/none.php
+++ b/classes/auto_grader/none.php
@@ -14,7 +14,7 @@ class none implements auto_grader {
* @param $allocatable
* @param $percentage
*/
- public function __construct($coursework, $allocatable, $percentage) {
+ public function __construct($coursework, $allocatable) {
}
public function create_auto_grade_if_rules_match() {
diff --git a/classes/auto_grader/percentage_distance.php b/classes/auto_grader/percentage_distance.php
index 750fa29..055880d 100644
--- a/classes/auto_grader/percentage_distance.php
+++ b/classes/auto_grader/percentage_distance.php
@@ -34,9 +34,9 @@ class percentage_distance implements auto_grader {
* @param allocatable $allocatable
* @param int $percentage
*/
- public function __construct($coursework, $allocatable, $percentage) {
+ public function __construct($coursework, $allocatable) {
$this->coursework = $coursework;
- $this->percentage = (int)$percentage;
+ $this->percentage = (int)$this->coursework->automaticagreementrange;
$this->allocatable = $allocatable;
}
diff --git a/classes/controllers/deadline_extensions_controller.php b/classes/controllers/deadline_extensions_controller.php
index 2bf788d..7fbc230 100644
--- a/classes/controllers/deadline_extensions_controller.php
+++ b/classes/controllers/deadline_extensions_controller.php
@@ -3,8 +3,11 @@
namespace mod_coursework\controllers;
use mod_coursework\ability;
use mod_coursework\allocation\allocatable;
+use mod_coursework\decorators\coursework_groups_decorator;
use mod_coursework\forms\deadline_extension_form;
+use mod_coursework\models\coursework;
use mod_coursework\models\deadline_extension;
+use mod_coursework\models\group;
use mod_coursework\models\user;
/**
@@ -155,4 +158,229 @@ protected function set_default_current_deadline()
}
+
+ /**
+ * Begin Ajax functions
+ */
+ public function ajax_submit_mitigation($data_params)
+ {
+ global $USER, $OUTPUT;
+ $extended_deadline = false;
+ $response = [];
+ $this->coursework = coursework::find(['id' => $this->params['courseworkid']]);
+ require_login($this->coursework->course);
+ $params = $this->set_default_current_deadline();
+ $ability = new ability(user::find($USER), $this->coursework);
+ $errors = $this->validation($data_params);
+ $data = (object) $data_params;
+ if (!$errors) {
+ if ($data->id > 0) {
+ $this->deadline_extension = deadline_extension::find(['id' => $data->id]);
+ $ability->require_can('edit', $this->deadline_extension);
+ $data->createdbyid = $USER->id;
+ $this->deadline_extension->update_attributes($data);
+ } else {
+ $this->deadline_extension = deadline_extension::build($data);
+ $ability->require_can('new', $this->deadline_extension);
+ $this->deadline_extension->save();
+ $data_params['id'] = $this->deadline_extension->id;
+ }
+
+ $content = $this->table_cell_response($data_params);
+
+ $response = [
+ 'error' => 0,
+ 'data' => $data_params,
+ 'content' => $content
+ ];
+ echo json_encode($response);
+ } else {
+ $response = [
+ 'error' => 1,
+ 'messages' => $errors
+ ];
+
+ echo json_encode($response);
+ }
+ }
+
+ public function validation($data){
+ global $CFG;
+ $max_deadline = $CFG->coursework_max_extension_deadline;
+
+
+ if ($this->coursework->personaldeadlineenabled && $personal_deadline = $this->personal_deadline()) {
+ $deadline = $personal_deadline->personal_deadline;
+ } else {
+ $deadline = $this->coursework->deadline;
+ }
+
+
+ if ( $data['extended_deadline'] <= $deadline) {
+ return $errors = 'The new deadline must be later than the current deadline';
+ }
+
+ return false;
+ }
+
+ public function submission_exists($data){
+ global $DB;
+
+ return $DB->record_exists('coursework_submissions', array(
+ 'courseworkid' => $data['courseworkid'],
+ 'allocatableid' => $data['allocatableid'],
+ 'allocatabletype' => $data['allocatabletype']
+ ));
+ }
+
+ public function personal_deadline(){
+ global $DB;
+
+ $extensionid = optional_param('id', 0, PARAM_INT);
+
+ if ($extensionid != 0) {
+ $ext = $DB->get_record('coursework_extensions', array('id' => $extensionid));
+ $allocatableid = $ext->allocatableid;
+ $allocatabletype = $ext->allocatabletype;
+ $courseworkid = $ext->courseworkid;
+ } else {
+
+ $allocatableid = required_param('allocatableid', PARAM_INT);
+ $allocatabletype = required_param('allocatabletype', PARAM_ALPHANUMEXT);
+ $courseworkid = required_param('courseworkid', PARAM_INT);
+ }
+
+ $params = array(
+ 'allocatableid' => $allocatableid ?? 0,
+ 'allocatabletype' => $allocatabletype ?? 0,
+ 'courseworkid' => $courseworkid ?? 0,
+ );
+
+ return $personal_deadline = $DB->get_record('coursework_person_deadlines', $params);
+ }
+
+ public function ajax_edit_mitigation($data_params) {
+ global $USER;
+ $response = [];
+ if ($data_params['id'] > 0) {
+ $this->coursework = coursework::find(['id' => $this->params['courseworkid']]);
+ require_login($this->coursework->course);
+
+ $ability = new ability(user::find($USER), $this->coursework);
+ $deadline_extension = deadline_extension::find(['id' => $data_params['id']]);
+ if (empty($deadline_extension)) {
+ $response = [
+ 'error' => 1,
+ 'message' => 'This Deadline Extension does not exist!',
+ ];
+ } else {
+ $ability->require_can('edit', $deadline_extension);
+ $time_content = '';
+ $time = '';
+ if ($this->coursework->personaldeadlineenabled && $personal_deadline = $this->personal_deadline()) {
+ $time_content = 'Personal deadline: ' . userdate($personal_deadline->personal_deadline);
+ $time = date('d-m-Y H:i', $personal_deadline->personal_deadline);
+ } else if ($this->coursework->deadline) {
+ // Current deadline for comparison
+ $time_content = 'Default deadline: ' . userdate($this->coursework->deadline);
+ $time = date('d-m-Y H:i', $this->coursework->deadline);
+ }
+
+ if(!empty($deadline_extension->extended_deadline) && $deadline_extension->extended_deadline > 0) {
+ $time = date('d-m-Y H:i', $deadline_extension->extended_deadline);
+ }
+
+ $deadline_extension_transform = [
+ 'time_content' => $time_content,
+ 'time' => $time,
+ 'text' => $deadline_extension->extra_information_text,
+ 'allocatableid' => $deadline_extension->allocatableid,
+ 'allocatabletype' => $deadline_extension->allocatabletype,
+ 'courseworkid' => $deadline_extension->courseworkid,
+ 'id' => $deadline_extension->id,
+ 'pre_defined_reason' => $deadline_extension->pre_defined_reason,
+ ];
+ $response = [
+ 'error' => 0,
+ 'data' => $deadline_extension_transform
+ ];
+ }
+ } else {
+ $response = [
+ 'error' => 1,
+ 'message' => 'ID can not be lower than 1!'
+ ];
+ }
+ echo json_encode($response);
+ }
+
+ public function ajax_new_mitigation($data_params){
+ global $USER, $DB;
+ $response = [];
+ $this->coursework = coursework::find(['id' => $this->params['courseworkid']]);
+ require_login($this->coursework->course);
+
+ $params = array(
+ 'allocatableid' => $this->params['allocatableid'],
+ 'allocatabletype' => $this->params['allocatabletype'],
+ 'courseworkid' => $this->params['courseworkid'],
+ );
+
+ $ability = new ability(user::find($USER), $this->coursework);
+ $deadline_extension= deadline_extension::build($params);
+ $ability->require_can('new', $deadline_extension);
+ $time_content = '';
+ $time = '';
+ if ($this->coursework->deadline){
+ $personal_deadline = $DB->get_record('coursework_person_deadlines', $params);
+ if ($personal_deadline) {
+ $time_content = 'Personal deadline: ' . userdate($personal_deadline->personal_deadline);
+ // $this->coursework->deadline = $personal_deadline->personal_deadline;
+ $time = date('d-m-Y H:i', $personal_deadline->personal_deadline);
+ } else {
+ $time_content = 'Default deadline: ' . userdate($this->coursework->deadline);
+ $time = date('d-m-Y H:i', $this->coursework->deadline);
+ }
+ }
+
+ $deadline_extension_transform = [
+ 'time_content' => $time_content,
+ 'time' => $time,
+ ];
+
+ $response = [
+ 'error' => 0,
+ 'data' => $deadline_extension_transform
+ ];
+
+ echo json_encode($response);
+ }
+
+
+ /**
+ * function table_cell_response
+ * @param array $data_params
+ *
+ * Generate html cell base on time_submitted_cell
+ * @return html_string $content
+ *
+ */
+
+ public function table_cell_response($data_params) {
+ $participant = ($data_params['allocatabletype'] && $data_params['allocatabletype'] == 'group') ? group::find($data_params['allocatableid']) : user::find($data_params['allocatableid']);
+ $coursework = ($this->coursework instanceof coursework_groups_decorator) ? $this->coursework->wrapped_object() : $this->coursework;
+ if ($this->coursework->has_multiple_markers()) {
+ $row_object = new \mod_coursework\grading_table_row_multi($coursework, $participant);
+ } else {
+ $row_object = new \mod_coursework\grading_table_row_single($coursework, $participant);
+ }
+
+ $time_submitted_cell = new \mod_coursework\render_helpers\grading_report\cells\time_submitted_cell(array('coursework'=>$this->coursework));
+
+ $content = $time_submitted_cell->prepare_content_cell($row_object);
+
+ return $content;
+ }
+
+
}
\ No newline at end of file
diff --git a/classes/controllers/feedback_controller.php b/classes/controllers/feedback_controller.php
index 8d77c03..54cd504 100644
--- a/classes/controllers/feedback_controller.php
+++ b/classes/controllers/feedback_controller.php
@@ -10,6 +10,17 @@
use mod_coursework\models\feedback;
use mod_coursework\models\submission;
use mod_coursework\models\user;
+use mod_coursework\models\group;
+use mod_coursework\models\coursework;
+use mod_coursework\assessor_feedback_row;
+use mod_coursework\decorators\coursework_groups_decorator;
+use mod_coursework\grading_table_row_multi;
+use mod_coursework\grading_table_row_single;
+use mod_coursework\render_helpers\grading_report\cells\grade_for_gradebook_cell;
+use mod_coursework\render_helpers\grading_report\cells\multiple_agreed_grade_cell;
+use mod_coursework\render_helpers\grading_report\cells\single_assessor_feedback_cell;
+use mod_coursework\render_helpers\grading_report\sub_rows\multi_marker_feedback_sub_rows;
+use mod_coursework\stages\assessor;
use moodle_exception;
use stdClass;
@@ -39,6 +50,7 @@ protected function show_feedback() {
$urlparams = array('feedbackid' => $this->params['feedbackid']);
$PAGE->set_url('/mod/coursework/actions/feedbacks/show.php', $urlparams);
+ $ajax = (isset($this->params['ajax'])) ? $this->params['ajax'] : 0;
$teacherfeedback = new feedback($this->params['feedbackid']);
@@ -46,7 +58,15 @@ protected function show_feedback() {
$ability->require_can('show', $teacherfeedback);
$renderer = $this->get_page_renderer();
- $renderer->show_feedback_page($teacherfeedback);
+ $html = $renderer->show_feedback_page($teacherfeedback,$ajax);
+
+
+
+ if (empty($ajax)) {
+ echo $html;
+ } else {
+ echo json_encode(['success' => true, 'formhtml' => $html]);
+ }
}
/**
@@ -88,7 +108,7 @@ protected function new_feedback() {
$PAGE->set_url('/mod/coursework/actions/feedbacks/new.php', $urlparams);
$renderer = $this->get_page_renderer();
- $renderer->new_feedback_page($teacherfeedback);
+ $renderer->new_feedback_page($teacherfeedback, $this->params['ajax']);
}
@@ -119,7 +139,7 @@ protected function edit_feedback() {
}
$renderer = $this->get_page_renderer();
- $renderer->edit_feedback_page($teacherfeedback, $assessor, $editor);
+ $renderer->edit_feedback_page($teacherfeedback, $assessor, $editor, $this->params['ajax']);
}
/**
@@ -145,6 +165,7 @@ protected function create_feedback() {
'submission' => $submission,
'assessor' => \core_user::get_user($this->params['assessorid']),
'stage' => $teacherfeedback->get_stage(),
+
);
$url = $this->get_router()->get_path('new feedback', $path_params, true);
$PAGE->set_url($url);
@@ -172,9 +193,10 @@ protected function create_feedback() {
redirect($coursework_page_url);
}
+ $ajax = !empty($this->params['ajax']);
$data = $form->get_data();
- if ($data) {
+ if ($data && $form->validate_grade($data)) {
$teacherfeedback->save(); // Need an id so we can save the advanced grading here.
$teacherfeedback = $form->process_data($teacherfeedback);
@@ -199,11 +221,87 @@ protected function create_feedback() {
if (empty($gradeeditingtime) || time() > $teacherfeedback->timecreated + $gradeeditingtime) {
$this->try_auto_feedback_creation($teacherfeedback->get_submission());
}
+ if ($ajax) {
+ $coursework = $teacherfeedback->get_coursework();
+ $coursework->clear_stage($teacherfeedback->stage_identifier);
+ if ($coursework instanceof coursework_groups_decorator) {
+ $coursework = $coursework->wrapped_object();
+ }
+ //feedback::$pool[$coursework->id] = null;
+ $participant = $submission->get_allocatable();
+ $cell_class = $this->params['cell_type'];
+ $stage = new assessor($coursework, $teacherfeedback->stage_identifier);
+ $provisional = new grade_for_gradebook_cell(array('coursework'=>$coursework));
- redirect($coursework_page_url);
+ $jsonarray = array('success' => true);
+
+ if (strpos($cell_class, 'multi_marker_feedback_sub_rows') !== false) {
+ $feedback_row = new assessor_feedback_row($stage, $participant, $this->coursework);
+ $cell_object = new $cell_class($coursework, $participant);
+ $html = $cell_object->get_grade_cell_content($feedback_row, $this->coursework);
+
+ if ($teacherfeedback->stage_identifier == 'assessor_1' || $teacherfeedback->stage_identifier == 'assessor_2') {
+
+ $jsonarray['assessorname'] = (empty($feedback_row->get_assessor()->id()) && $coursework->allocation_enabled()) ?
+ get_string('assessornotallocated','mod_coursework') : $cell_object->profile_link($feedback_row);
+ $jsonarray['assessdate'] = $cell_object->date_for_column($feedback_row);
+
+ if ($teacherfeedback->stage_identifier == 'assessor_1') {
+ $ability = new ability(user::find($USER, false), $coursework);
+ $stage = new assessor($coursework, 'assessor_2');
+ $assessor_feedback_row = new assessor_feedback_row($stage, $feedback_row->get_allocatable(), $coursework);
+
+ $assessortwocell = $cell_object->get_grade_cell_content($assessor_feedback_row,$coursework,$ability);
+ //$jsonarray['assessortwo'] =$assessortwocell;
+ if (strpos($assessortwocell, 'new_feedback') !== false) $jsonarray['assessortwo'] = $assessortwocell;
+
+ }
+
+ $finalfeedback = $feedback_row->get_submission()->get_final_feedback();
+ $finalsubmission = $feedback_row->get_submission();
+
+
+ if ($coursework->automaticagreementrange != 'none' && !empty($finalfeedback) && $finalsubmission->all_inital_graded()) {
+ $finalstage = new assessor($coursework, "final_agreed_1");
+ $finalfeedback_row = new assessor_feedback_row($finalstage, $participant, $coursework);
+ $agreed_grade_object = new multiple_agreed_grade_cell(array('coursework'=>$coursework,'stage'=>$finalstage));
+ $jsonarray['finalhtml'] = $agreed_grade_object->get_table_cell($finalfeedback_row);
+ $jsonarray['allocatableid'] = $submission->get_allocatable()->id();
+ }
+
+ } else {
+
+ $jsonarray['extrahtml'] = $provisional->get_table_cell($feedback_row);
+
+ }
+
+ } else {
+ $row_class = $coursework->has_multiple_markers() ?
+ '\\mod_coursework\\grading_table_row_multi' : '\\mod_coursework\\grading_table_row_single';
+ $row_object = new $row_class($coursework, $participant);
+ $cell_object = new $cell_class(['coursework' => $coursework, 'stage' => $stage]);
+ $html = $cell_object->get_content($row_object);
+ $jsonarray['extrahtml'] = $provisional->get_table_cell($row_object);
+
+
+
+
+
+ }
+
+ $jsonarray['html'] = $html;
+
+ echo json_encode($jsonarray);
+ } else {
+ redirect($coursework_page_url);
+ }
} else {
- $renderer = $this->get_page_renderer();
- $renderer->new_feedback_page($teacherfeedback);
+ if ($ajax) {
+ echo json_encode(['success' => false, 'message' => get_string('guidenotcompleted', 'gradingform_guide')]);
+ } else {
+ $renderer = $this->get_page_renderer();
+ $renderer->new_feedback_page($teacherfeedback);
+ }
}
@@ -222,6 +320,75 @@ protected function update_feedback() {
$ability = new ability(user::find($USER), $this->coursework);
$ability->require_can('update', $teacherfeedback);
+ $coursework_page_url = $this->get_path('coursework', array('coursework' => $teacherfeedback->get_coursework()));
+
+ // remove feedback comments and associated feedback files if 'Remove feedback' button pressed
+ if($this->params['remove']){
+ if (!$this->params['confirm']) {
+
+ $urlparams = array('confirm'=>$this->params['confirm'],
+ 'remove'=>$this->params['remove'],'feedbackid'=>$this->params['feedbackid'],'finalised'=>$this->params['finalised']);
+
+ $PAGE->set_url('/mod/coursework/actions/feedbacks/edit.php', $urlparams);
+
+ // Ask the user for confirmation.
+ $confirmurl = new \moodle_url('/mod/coursework/actions/feedbacks/update.php');
+ $confirmurl->param('confirm', 1);
+ $confirmurl->param('removefeedbackbutton', 1);
+ $confirmurl->param('feedbackid',$this->params['feedbackid']);
+ $confirmurl->param('finalised',$this->params['finalised']);
+
+ $cancelurl = clone $PAGE->url;
+ $cancelurl->param('removefeedbackbutton', 0);
+ $cancelurl->param('feedbackid',$this->params['feedbackid']);
+ $cancelurl->param('finalised',$this->params['finalised']);
+ $renderer = $this->get_page_renderer();
+ return $renderer->confirm_feedback_removal_page($teacherfeedback,$confirmurl,$cancelurl);
+
+ //$OUTPUT->confirm(get_string('confirmremovefeedback', 'mod_coursework'), $confirmurl, $PAGE->url);
+
+ } else {
+ $teacherfeedback->destroy();
+ //remove associated files
+ $fs = get_file_storage();
+ $fs->delete_area_files($teacherfeedback->get_coursework()->get_context()->id, 'mod_coursework', 'feedback', $teacherfeedback->id());
+
+
+ $ajax = !empty($this->params['ajax']);
+ if ($ajax) {
+
+ $coursework = $teacherfeedback->get_coursework();
+ $coursework->clear_stage($teacherfeedback->stage_identifier);
+ if ($coursework instanceof coursework_groups_decorator) {
+ $coursework = $coursework->wrapped_object();
+ }
+ //feedback::$pool[$coursework->id] = null;
+ $submission = $teacherfeedback->get_submission();
+ $participant = $submission->get_allocatable();
+ $cell_class = $this->params['cell_type'];
+ $stage = new assessor($coursework, $teacherfeedback->stage_identifier);
+ if (strpos($cell_class, 'multi_marker_feedback_sub_rows') !== false) {
+ $feedback_row = new assessor_feedback_row($stage, $participant, $coursework);
+ $cell_object = new $cell_class($coursework, $participant);
+ $html = $cell_object->get_grade_cell_content($feedback_row, $coursework);
+ } else {
+ $row_class = $coursework->has_multiple_markers() ?
+ '\\mod_coursework\\grading_table_row_multi' : '\\mod_coursework\\grading_table_row_single';
+ $row_object = new $row_class($coursework, $participant);
+ $cell_object = new $cell_class(['coursework' => $coursework, 'stage' => $stage]);
+ $html = $cell_object->get_content($row_object);
+
+ $finalfeedback = $row_object->get_submission()->get_final_feedback();
+
+ }
+
+ echo json_encode(['success' => true, 'html' => $html]);
+ exit;
+ } else {
+ redirect($coursework_page_url);
+ }
+ }
+ }
$this->check_stage_permissions($teacherfeedback->stage_identifier);
@@ -235,12 +402,9 @@ protected function update_feedback() {
$teacherfeedback = $form->process_data($teacherfeedback);
$teacherfeedback->save();
-
$form->save_feedback_files($teacherfeedback);
- //only implement auto feedback (automatic agreement) if the settings is set to disabled otherwise
- //we will do this in the cron
- $gradeeditingtime = $teacherfeedback->get_coursework()->get_grade_editing_time();
+
if (empty($gradeeditingtime) || time() > $teacherfeedback->timecreated + $gradeeditingtime) {
$this->try_auto_feedback_creation($teacherfeedback->get_submission());
@@ -251,7 +415,73 @@ protected function update_feedback() {
$teacherfeedback->get_submission()->publish();
}
- redirect($coursework_page_url);
+ $ajax = !empty($this->params['ajax']);
+ if ($ajax) {
+ $coursework = $teacherfeedback->get_coursework();
+ $coursework->clear_stage($teacherfeedback->stage_identifier);
+ if ($coursework instanceof coursework_groups_decorator) {
+ $coursework = $coursework->wrapped_object();
+ }
+ //feedback::$pool[$coursework->id] = null;
+ $submission = $teacherfeedback->get_submission();
+ $participant = $submission->get_allocatable();
+ $cell_class = $this->params['cell_type'];
+ $stage = new assessor($coursework, $teacherfeedback->stage_identifier);
+ $provisional = new grade_for_gradebook_cell(array('coursework'=>$coursework));
+ $jsonarray = array('success' => true);
+
+ if (strpos($cell_class, 'multi_marker_feedback_sub_rows') !== false) {
+ $feedback_row = new assessor_feedback_row($stage, $participant, $coursework);
+ $cell_object = new $cell_class($coursework, $participant);
+ $html = $cell_object->get_grade_cell_content($feedback_row, $coursework);
+
+ if ($teacherfeedback->stage_identifier == 'assessor_1' || $teacherfeedback->stage_identifier == 'assessor_2') {
+ $jsonarray['assessorname'] = (empty($feedback_row->get_assessor()->id()) && $coursework->allocation_enabled()) ?
+ get_string('assessornotallocated','mod_coursework') : $cell_object->profile_link($feedback_row);
+ $jsonarray['assessdate'] = $cell_object->date_for_column($feedback_row);
+
+ if ($teacherfeedback->stage_identifier == 'assessor_1') {
+ $ability = new ability(user::find($USER, false), $coursework);
+ $stage = new assessor($coursework, 'assessor_2');
+ $assessor_feedback_row = new assessor_feedback_row($stage, $feedback_row->get_allocatable(), $coursework);
+
+ $assessortwocell = $cell_object->get_grade_cell_content($assessor_feedback_row,$coursework,$ability);
+ //$jsonarray['assessortwo'] =$assessortwocell;
+ if (strpos($assessortwocell, 'new_feedback') !== false) $jsonarray['assessortwo'] = $assessortwocell;
+
+ }
+
+ $finalfeedback = $submission->get_final_feedback();
+
+ if ($coursework->automaticagreementrange != 'none' && !empty($finalfeedback)) {
+ $finalstage = new assessor($coursework, "final_agreed_1");
+
+ $finalfeedbackrow_object = new \mod_coursework\grading_table_row_multi($coursework, $participant);
+
+ $agreed_grade_cell = new multiple_agreed_grade_cell(['coursework' => $coursework, 'stage' => $finalstage]);
+ $jsonarray['finalhtml'] = $agreed_grade_cell->get_content($finalfeedbackrow_object);
+ $jsonarray['allocatableid'] = $submission->get_allocatable()->id();
+ }
+
+ } else {
+ $jsonarray['extrahtml'] = strip_tags($provisional->get_table_cell($feedback_row));
+ }
+
+ } else {
+ $row_class = $coursework->has_multiple_markers() ?
+ '\\mod_coursework\\grading_table_row_multi' : '\\mod_coursework\\grading_table_row_single';
+ $row_object = new $row_class($coursework, $participant);
+ $cell_object = new $cell_class(['coursework' => $coursework, 'stage' => $stage]);
+ $html = $cell_object->get_content($row_object);
+ $jsonarray['extrahtml'] = strip_tags($provisional->get_table_cell($row_object));
+ }
+
+ $jsonarray['html'] = $html;
+
+ echo json_encode($jsonarray);
+ } else {
+ redirect($coursework_page_url);
+ }
}
/**
@@ -361,8 +591,7 @@ protected function try_auto_feedback_creation($submission) {
* @var auto_grader $auto_grader
*/
$auto_grader = new $auto_feedback_classname($this->coursework,
- $submission->get_allocatable(),
- $this->coursework->automaticagreementrange);
+ $submission->get_allocatable());
$auto_grader->create_auto_grade_if_rules_match();
}
-}
\ No newline at end of file
+}
diff --git a/classes/controllers/grading_controller.php b/classes/controllers/grading_controller.php
new file mode 100644
index 0000000..1881ce1
--- /dev/null
+++ b/classes/controllers/grading_controller.php
@@ -0,0 +1,33 @@
+get_record('coursework', array('id' => $options['courseworkid']), '*', MUST_EXIST);
+ //$coursework = mod_coursework\models\coursework::find($coursework_record);
+ $coursework = coursework::find($coursework_record, false);
+ require_login($coursework->course);
+
+ $coursework->coursemodule = get_coursemodule_from_instance('coursework', $coursework->id, $coursework->course, false, MUST_EXIST);
+ $grading_report = $coursework->renderable_grading_report_factory($options);
+
+ $tablerows = $grading_report->get_table_rows_for_page();
+ $cell_helpers = $grading_report->get_cells_helpers();
+ $sub_row_helper = $grading_report->get_sub_row_helper();
+
+ $grading_report_renderer = $PAGE->get_renderer('mod_coursework', 'grading_report');
+ $table_html = $grading_report_renderer->make_rows($tablerows, $cell_helpers, $sub_row_helper, $coursework->has_multiple_markers());
+ return $table_html;
+ }
+
+}
\ No newline at end of file
diff --git a/classes/controllers/personal_deadlines_controller.php b/classes/controllers/personal_deadlines_controller.php
index a0946c0..160e05f 100644
--- a/classes/controllers/personal_deadlines_controller.php
+++ b/classes/controllers/personal_deadlines_controller.php
@@ -4,6 +4,7 @@
use mod_coursework\ability;
use mod_coursework\allocation\allocatable;
use mod_coursework\forms\personal_deadline_form;
+use mod_coursework\models\coursework;
use mod_coursework\models\personal_deadline;
use mod_coursework\models\user;
@@ -158,5 +159,93 @@ protected function get_personal_deadline(){
return $DB->get_record('coursework_person_deadlines', $params);
}
+
+ /**
+ * @param $time
+ * @return array
+ * @throws \coding_exception
+ * @throws \mod_coursework\exceptions\access_denied
+ * @throws \moodle_exception
+ * @throws \require_login_exception
+ */
+ public function insert_update($time){
+ global $USER;
+ if (!$this->validated($time)) {
+ return [
+ 'error' => 1,
+ 'message' => 'The new deadline you chose has already passed. Please select appropriate deadline'
+ ];
+ }
+ $this->coursework = coursework::find(['id'=>$this->params['courseworkid']]);
+ require_login($this->coursework->course);
+ $params = $this->set_default_current_deadline();
+
+ $ability = new ability(user::find($USER), $this->coursework);
+ $ability->require_can('edit', $this->personal_deadline);
+ $params['allocatableid'] = (!is_array($params['allocatableid'])) ? $params['allocatableid']
+ : serialize($params['allocatableid']) ;
+
+ $data = (object) $this->params;
+ if (empty($data->multipleuserdeadlines)) {
+ if (!$this->get_personal_deadline()) { // personal deadline doesnt exist
+ // add new
+ $data->createdbyid = $USER->id;
+ $data->personal_deadline = strtotime($time);
+ $this->personal_deadline = personal_deadline::build($data);
+ $this->personal_deadline->save();
+ } else {
+ // update
+ $data->lastmodifiedbyid = $USER->id;
+ $data->personal_deadline = strtotime($time);
+ $data->timemodified = time();
+ $this->personal_deadline->update_attributes($data);
+ }
+ } else {
+ $allocatables = unserialize($data->allocatableid);
+
+ foreach ($allocatables as $allocatableid) {
+ $data->allocatableid = $allocatableid;
+ $data->id = '';
+ //$data->id = '';
+ $findparams = array(
+ 'allocatableid' => $allocatableid,
+ 'allocatabletype' => $data->allocatabletype,
+ 'courseworkid' => $data->courseworkid,
+ );
+ $this->personal_deadline = personal_deadline::find_or_build($findparams);
+
+ if (empty($this->personal_deadline->personal_deadline)) { // personal deadline doesnt exist
+ // add new
+ $data->createdbyid = $USER->id;
+ $this->personal_deadline = personal_deadline::build($data);
+ $this->personal_deadline->save();
+ } else {
+ // update
+ $data->id = $this->personal_deadline->id;
+ $data->lastmodifiedbyid = $USER->id;
+ $data->timemodified = time();
+ $this->personal_deadline->update_attributes($data);
+ }
+ }
+ }
+ $timestamp = $this->personal_deadline->personal_deadline;
+ $date = userdate($timestamp, '%a, %d %b %Y, %H:%M');
+ return [
+ 'error' => 0,
+ 'time' => $date,
+ 'timestamp' => $timestamp
+ ];
+ }
+
+ /**
+ * @param $time
+ * @return bool
+ */
+ protected function validated($time) {
+ if(strtotime($time) <= time()) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/classes/controllers/submissions_controller.php b/classes/controllers/submissions_controller.php
index 0c3b545..ec6eea5 100644
--- a/classes/controllers/submissions_controller.php
+++ b/classes/controllers/submissions_controller.php
@@ -151,10 +151,11 @@ protected function create_submission() {
if ($submission->finalised) {
if (!$submission->get_coursework()->has_deadline()) {
- $userids = explode(',',$submission->get_coursework()->get_submission_notification_users());
+ $useridcommaseparatedlist = $submission->get_coursework()->get_submission_notification_users();
- if (!empty($userids)) {
- foreach($userids as $u) {
+ if (!empty($useridcommaseparatedlist)) {
+ $userids = explode(',', $useridcommaseparatedlist);
+ foreach($userids as $u) {
$notifyuser = $DB->get_record('user',array('id'=>trim($u)));
if (!empty($notifyuser)) $mailer->send_submission_notification($notifyuser);
@@ -308,6 +309,50 @@ protected function finalise_submission() {
redirect($coursework_page_url);
}
+
+ protected function unfinalise_submission() {
+
+ global $USER, $DB;
+
+
+
+ $allocatableids = (!is_array($this->params['allocatableid'])) ? array($this->params['allocatableid']) : $this->params['allocatableid'] ;
+
+ $personaldeadline_page_url = new \moodle_url('/mod/coursework/actions/personal_deadline.php',
+ array('id'=>$this->coursework->get_coursemodule_id(),'multipleuserdeadlines'=>1,'setpersonaldeadlinespage'=>1,
+ 'courseworkid'=>$this->params['courseworkid'],'allocatabletype'=>$this->params['allocatabletype']));
+
+ $changedeadlines = false;
+
+ foreach($allocatableids as $aid) {
+
+ $submission_db = $DB->get_record('coursework_submissions',
+ array('courseworkid' => $this->params['courseworkid'], 'allocatableid' => $aid, 'allocatabletype' => $this->params['allocatabletype']));
+ if (!empty($submission_db)) {
+ $submission = \mod_coursework\models\submission::find($submission_db);
+
+ if ($submission->can_be_unfinalised()) {
+ $submission->finalised = 0;
+ $submission->save();
+ $personaldeadline_page_url->param("allocatableid_arr[$aid]",$aid);
+ $changedeadlines = true;
+ }
+ }
+
+ }
+
+
+
+ if (!empty($changedeadlines)) {
+ redirect($personaldeadline_page_url, get_string('unfinalisedchangesubmissiondate', 'mod_coursework'));
+ } else {
+ $setpersonaldeadline_page_url = new \moodle_url('/mod/coursework/actions/set_personal_deadlines.php',
+ array('id'=>$this->coursework->get_coursemodule_id()));
+ redirect($setpersonaldeadline_page_url);
+ }
+
+ }
+
protected function prepare_environment() {
if (!empty($this->params['submissionid'])) {
diff --git a/classes/cron.php b/classes/cron.php
index c870dd1..7cb4159 100644
--- a/classes/cron.php
+++ b/classes/cron.php
@@ -62,7 +62,10 @@ private static function send_reminders_to_students() {
* @var coursework $coursework
*/
$coursework = coursework::find($raw_coursework);
-
+ if (!$coursework || !$coursework->is_coursework_visible()) {// check if coursework exists and is not hidden
+ continue;
+ }
+
// if cw doesn't have personal deadlines and deadline passed and cw doesnt have any individual extensions
if (!$coursework->personal_deadlines_enabled() && (!$coursework->has_deadline()
|| $coursework->deadline_has_passed() && !$coursework->extension_exists())) {
@@ -335,7 +338,7 @@ private static function finalise_any_submissions_where_the_deadline_has_passed()
// done. Would not want them to check straight away and then find they could still
// edit it.
$submission->update_attribute('finalised', 1);
-
+ submission::remove_cache($submission->courseworkid);
// Slightly wasteful to keep re-fetching the coursework :-/
$mailer = new mailer($submission->get_coursework());
foreach ($submission->get_students() as $student) {
diff --git a/classes/export/csv.php b/classes/export/csv.php
index d191a17..d1fa51d 100644
--- a/classes/export/csv.php
+++ b/classes/export/csv.php
@@ -210,16 +210,24 @@ private function add_data_to_csv($csv_data) {
}
/**
+ * @param null $groupid
+ * @param string $selected_submission_ids
* @return array
* @throws \coding_exception
*/
- public function get_submissions(){
-
- $params = array(
- 'courseworkid' => $this->coursework->id
- );
- return submission::find_all($params);
-
+ public function get_submissions($groupid = null, $selected_submission_ids = '') {
+
+ $submissions = submission::$pool[$this->coursework->id]['id'] ?? submission::find_all(['courseworkid' => $this->coursework->id]);
+ if ($selected_submission_ids && $selected_submission_ids = json_decode($selected_submission_ids)) {
+ $result = array_flip($selected_submission_ids);
+ foreach ($submissions as $submission) {
+ if (array_key_exists($submission->id, $result)) {
+ $result[$submission->id] = $submission;
+ }
+ }
+ $submissions = $result;
+ }
+ return $submissions;
}
/**
@@ -243,10 +251,25 @@ public function add_csv_data($submission){
public function other_assessors_cells(){
$cells = 0;
- for ($i = 1; $i < $this->coursework->get_max_markers() ; $i++) {
- $cells = $cells + 2; // one for grade, one for feedback
+ if ($this->coursework->is_using_rubric()) {
+ $criterias = $this->coursework->get_rubric_criteria();
+ //we will increment by the number of criterias plus 1 for feedback
+ $increment = (count($criterias) * 2) +1;
+
+ } else {
+ $increment = 2;
}
+
+ for ($i = 1; $i < $this->coursework->get_max_markers(); $i++) {
+ $cells = $cells + $increment; // one for grade, one for feedback
+ }
+
+
+
+
+
+
return $cells;
diff --git a/classes/export/csv/cells/agreedgrade_cell.php b/classes/export/csv/cells/agreedgrade_cell.php
index 2e73e9f..2cc45c1 100644
--- a/classes/export/csv/cells/agreedgrade_cell.php
+++ b/classes/export/csv/cells/agreedgrade_cell.php
@@ -22,7 +22,7 @@ class agreedgrade_cell extends cell_base{
public function get_cell($submission, $student, $stage_identifier){
$agreedgrade = $submission->get_agreed_grade();
- if($this->coursework->is_using_rubric()){
+ if($this->coursework->is_using_rubric() && $this->coursework->finalstagegrading != 1){
$gradedata = array();
$this->get_rubric_scores_gradedata($agreedgrade, $gradedata); // multiple parts are handled here
} else {
@@ -39,7 +39,7 @@ public function get_cell($submission, $student, $stage_identifier){
*/
public function get_header($stage){
- if ($this->coursework->is_using_rubric()) {
+ if ($this->coursework->is_using_rubric() && $this->coursework->finalstagegrading != 1) {
$strings = array();
$criterias = $this->coursework->get_rubric_criteria();
foreach ($criterias as $criteria) { // rubrics can have multiple parts, so let's create header for each of it
@@ -68,7 +68,7 @@ public function validate_cell($value,$submissionid,$stage_identifier='', $upload
$errormsg = '';
- if (!$this->coursework->is_using_rubric()) {
+ if (!$this->coursework->is_using_rubric() || ($this->coursework->is_using_rubric() && $this->coursework->finalstagegrading == 1)) {
$gradejudge = new grade_judge($this->coursework);
if (!$gradejudge->grade_in_scale($value)){
$errormsg = get_string('valuenotincourseworkscale', 'coursework');
@@ -224,7 +224,7 @@ function value_in_rubric($criteria, $value) {
function get_rubrics($coursework,$csv_cells) {
- if ($coursework->is_using_rubric()) {
+ if ($coursework->is_using_rubric() && $this->coursework->finalstagegrading != 1) {
$rubricheaders = array();
diff --git a/classes/export/csv/cells/assessorgrade_cell.php b/classes/export/csv/cells/assessorgrade_cell.php
index d3fd196..8abf1a2 100644
--- a/classes/export/csv/cells/assessorgrade_cell.php
+++ b/classes/export/csv/cells/assessorgrade_cell.php
@@ -69,7 +69,7 @@ public function get_cell($submission, $student, $stage_identifier){
*/
public function get_header($stage){
- if ($this->coursework->is_using_rubric()) {
+ if ($this->coursework->is_using_rubric() ) {
$strings = array();
$criterias = $this->coursework->get_rubric_criteria();
foreach ($criterias as $criteria) { // rubrics can have multiple parts, so let's create header for each of it
diff --git a/classes/export/csv/cells/email_cell.php b/classes/export/csv/cells/email_cell.php
new file mode 100644
index 0000000..d073488
--- /dev/null
+++ b/classes/export/csv/cells/email_cell.php
@@ -0,0 +1,37 @@
+can_view_hidden() || $submission->is_published()){
+ $name = $student->email;
+ } else {
+ $name = get_string('hidden', 'coursework');
+ }
+
+ return $name;
+ }
+
+ /**
+ * @param $stage
+ * @return string
+ * @throws \coding_exception
+ */
+ public function get_header($stage){
+ return get_string('email');
+ }
+}
\ No newline at end of file
diff --git a/classes/export/csv/cells/idnumber_cell.php b/classes/export/csv/cells/idnumber_cell.php
new file mode 100644
index 0000000..ac72c00
--- /dev/null
+++ b/classes/export/csv/cells/idnumber_cell.php
@@ -0,0 +1,37 @@
+can_view_hidden() || $submission->is_published()){
+ $name = $student->idnumber;
+ } else {
+ $name = get_string('hidden', 'coursework');
+ }
+
+ return $name;
+ }
+
+ /**
+ * @param $stage
+ * @return string
+ * @throws \coding_exception
+ */
+ public function get_header($stage){
+ return get_string('idnumber');
+ }
+}
\ No newline at end of file
diff --git a/classes/export/csv/cells/name_cell.php b/classes/export/csv/cells/name_cell.php
index b1e2f6b..da45f97 100644
--- a/classes/export/csv/cells/name_cell.php
+++ b/classes/export/csv/cells/name_cell.php
@@ -1,6 +1,7 @@
can_view_hidden()){
+ if ($this->can_view_hidden() || $submission->is_published()){
$name = $student->lastname . ' ' . $student->firstname;
} else {
$name = get_string('hidden', 'coursework');
diff --git a/classes/export/csv/cells/otherassessors_cell.php b/classes/export/csv/cells/otherassessors_cell.php
index e9c84cd..2594d06 100644
--- a/classes/export/csv/cells/otherassessors_cell.php
+++ b/classes/export/csv/cells/otherassessors_cell.php
@@ -48,10 +48,10 @@ public function get_cell($submission, $student, $stage_identifier){
if ($grade){
// skip if you are allocated but someone else graded it
$allocation = $submission->get_assessor_allocation_by_stage($feedback->stage_identifier);
- if ($allocation->assessorid == $USER->id) continue;
+ if ($allocation && $allocation->assessorid == $USER->id) continue;
$ability = new ability(user::find($USER), $this->coursework);
if ((($ability->can('show', $feedback) || has_capability('mod/coursework:addallocatedagreedgrade', $submission->get_coursework()->get_context())) &&
- !$submission->any_editable_feedback_exists()) || is_siteadmin($USER->id)) {
+ (!$submission->any_editable_feedback_exists() && count($submission->get_assessor_feedbacks()) <= $submission->max_number_of_feedbacks())) || is_siteadmin($USER->id)) {
if($this->coursework->is_using_rubric()){
$this->get_rubric_scores_gradedata($grade, $gradedata); // multiple parts are handled here
@@ -83,6 +83,28 @@ public function get_cell($submission, $student, $stage_identifier){
}
+ $numothereassessorfeedbacks = $submission->max_number_of_feedbacks() -1;
+
+ if ($numothereassessorfeedbacks - count($feedbacks) != 0 ) {
+
+ $blankcolumns = $numothereassessorfeedbacks - count($feedbacks);
+
+ for($i = 0; $i < $blankcolumns; $i++) {
+ if ($this->coursework->is_using_rubric()) {
+ $criterias = $this->coursework->get_rubric_criteria();
+ foreach ($criterias as $criteria) { // rubrics can have multiple parts, so let's create header for each of it
+ $gradedata['assessor' . $stage_identifier.$i. '_' . $criteria['id']] = '';
+ $gradedata['assessor' . $stage_identifier.$i. '_' . $criteria['id'] . 'comment'] = '';
+ }
+ } else {
+ $gradedata[] = '';
+ }
+ $gradedata[] = '';
+
+ }
+
+ }
+
return $gradedata;
}
@@ -99,8 +121,8 @@ public function get_header($stage){
if ($this->coursework->is_using_rubric()) {
$criterias = $this->coursework->get_rubric_criteria();
foreach ($criterias as $criteria) { // rubrics can have multiple parts, so let's create header for each of it
- $fields['otherassessorgrade'.$stage.'_'.$criteria['id']] = 'Other assessor ('.$i.') - '.$criteria['description'];
- $fields['otherassessorgrade'.$stage.'_'.$criteria['id'] . 'comment'] = 'Comment for: Other assessor ('.$i.') - '.$criteria['description'];
+ $fields['otherassessorgrade'.$i.$stage.'_'.$criteria['id']] = 'Other assessor ('.$i.') - '.$criteria['description'];
+ $fields['otherassessorgrade'.$i.$stage.'_'.$criteria['id'] . 'comment'] = 'Comment for: Other assessor ('.$i.') - '.$criteria['description'];
}
} else {
$fields['otherassessorgrade' . $i] = get_string('otherassessorgrade', 'coursework', $i);
diff --git a/classes/export/csv/cells/username_cell.php b/classes/export/csv/cells/username_cell.php
index 925245a..9869cd4 100644
--- a/classes/export/csv/cells/username_cell.php
+++ b/classes/export/csv/cells/username_cell.php
@@ -1,6 +1,7 @@
can_view_hidden()){
+ if ($this->can_view_hidden() || $submission->is_published()){
$username = $student->username;
} else {
$username = get_string('hidden', 'coursework');
diff --git a/classes/export/grading_sheet.php b/classes/export/grading_sheet.php
index bfce0af..d520d2c 100644
--- a/classes/export/grading_sheet.php
+++ b/classes/export/grading_sheet.php
@@ -26,7 +26,7 @@ class grading_sheet extends csv{
- public function get_submissions(){
+ public function get_submissions($groupid = null, $selected_submission_ids = ''){
global $PAGE, $USER;
$params = array(
'courseworkid' => $this->coursework->id
@@ -157,6 +157,8 @@ public static function cells_array($coursework){
} else {
$csv_cells[] = 'name';
$csv_cells[] = 'username';
+ $csv_cells[] = 'idnumber';
+ $csv_cells[] = 'email';
}
$csv_cells[] = 'submissiontime';
diff --git a/classes/export/import.php b/classes/export/import.php
index a81d577..b79aeb6 100644
--- a/classes/export/import.php
+++ b/classes/export/import.php
@@ -115,7 +115,8 @@ public function validate_csv($content,$encoding,$delimeter,$csv_cells) {
//offsets the position of that we extract the data from $line based on data that has been extracted before
- if (($cells[$i] == "singlegrade" || $cells[$i] == "assessorgrade" || $cells[$i] == "agreedgrade") && $this->coursework->is_using_rubric()) {
+ if (($cells[$i] == "singlegrade" || $cells[$i] == "assessorgrade" || $cells[$i] == "agreedgrade")
+ && $this->coursework->is_using_rubric() && !($cells[$i] == "agreedgrade" && $this->coursework->finalstagegrading == 1)) {
//get the headers that would contain the rubric grade data
$rubricheaders = $cell->get_header(null);
@@ -159,7 +160,9 @@ function rubric_count_correct($csvheader,$linefromimportedcsv) {
// get criteria of rubrics and match it to grade cells
if ($this->coursework->is_using_rubric()) {
- $types = array("singlegrade","assessorgrade","agreedgrade");
+ $types = array("singlegrade","assessorgrade");
+
+ if ($this->coursework->finalstagegrading == 0 ) $types[] = "agreedgrade";
foreach($types as $type) {
@@ -185,7 +188,7 @@ function rubric_count_correct($csvheader,$linefromimportedcsv) {
if(!empty($typefound)) {
- //this var is need to provide an offset so the positions in the array we are looking for
+ //this var is needed to provide an offset so the positions in the array we are looking for
//are correct even after a splice and add is carried out
$offset = 0;
@@ -195,13 +198,17 @@ function rubric_count_correct($csvheader,$linefromimportedcsv) {
$cell = new $class($this->coursework);
$headers = $cell->get_header(null);
- unset($csvheader[$position+$offset]);
- unset($linefromimportedcsv[$position+$offset]);
- array_splice($csvheader, $position+$offset, 0, array_keys($headers));
- array_splice($linefromimportedcsv, $position+$offset, 0, array(''));
- $offset = $offset + count($headers)-1;
- $expectedsize = (int)sizeof($csvheader);
- $actualsize = (int)sizeof($linefromimportedcsv);
+
+ unset($csvheader[$position + $offset]);
+ unset($linefromimportedcsv[$position + $offset]);
+// if ($type == 'agreedgrade' && $this->coursework->finalstagegrading == 0) {
+ array_splice($csvheader, $position + $offset, 0, array_keys($headers));
+ array_splice($linefromimportedcsv, $position + $offset, 0, array(''));
+// }
+ $offset = $offset + count($headers) - 1;
+ $expectedsize = (int)sizeof($csvheader);
+ $actualsize = (int)sizeof($linefromimportedcsv);
+
}
@@ -400,14 +407,12 @@ public function process_csv($content, $encoding, $delimiter, $csv_cells, $proces
}
//we need to carry out a further check to see if the coursework is using advanced grades.
- //if yes then we may need to genenrate the grade for the grade pointer as
- // dont have grades
-
+ //if yes then we may need to generate the grade for the grade pointer as
+ //they dont have grades
- if ($coursework->is_using_rubric()) {
-
+ if ($coursework->is_using_rubric() && !($stage == 'final_agreed_1' && $this->coursework->finalstagegrading == 1)) {
//array that will hold the advanced grade data
@@ -434,10 +439,18 @@ public function process_csv($content, $encoding, $delimiter, $csv_cells, $proces
if ($coursework->allocation_enabled()) $rubricoffset += 1;
$rubricdata = array_slice($line, $rubricoffset, $numberofrubrics);
+ $feedbackdata = array_slice($line, $rubricoffset+$numberofrubrics, 1);
+
+ $csvline[$feedbackpointer] = $feedbackdata[0];
+
} else {
$rubricdata = array_slice($line, $rubricoffset, $numberofrubrics);
+ $feedbackdata = array_slice($line, $rubricoffset+$numberofrubrics, 1);
+
+ $csvline[$feedbackpointer] = $feedbackdata[0];
+
$rubricoffset = $rubricoffset + $numberofrubrics + 1;
}
@@ -483,17 +496,47 @@ public function process_csv($content, $encoding, $delimiter, $csv_cells, $proces
+ } else if ($coursework->is_using_rubric() && ($stage == 'final_agreed_1' && $this->coursework->finalstagegrading == 1)) {
+
+
+ if (!isset($numberofrubrics)) {
+
+ $criterias = $this->coursework->get_rubric_criteria();
+
+ $numberofrubrics = count($criterias) * 2;
+
+ }
+
+ $stagemultiplier = $numberofstages -1;
+
+ //the calculation below finds the position of the agreed grades in the uploaded csv
+
+
+ $rubricoffset = $rubricoffsetstart + $stagemultiplier + ($numberofrubrics * $stagemultiplier);
+
+
+ if ($coursework->allocation_enabled()) $rubricoffset += 1;
+
+ $gradearrvalue = array_slice($line, $rubricoffset, 2);
+
+ $csvline[$gradepointer] = $gradearrvalue[0];
+ $csvline[$feedbackpointer] = $gradearrvalue[1];
+
}
// don't create/update feedback if grade is empty
if (!empty($csvline[$gradepointer])) {
+
+ $stageusesrubric = ($this->coursework->is_using_rubric()
+ && !($stage == 'final_agreed_1' && $this->coursework->finalstagegrading)) ? true : false;
+
if (empty($grade)) {
- $cwfeedbackid = $this->add_grade($csvline['submissionid'], $csvline[$k], $csvline[$feedbackpointer], $stage,$this->coursework->is_using_rubric());
+ $cwfeedbackid = $this->add_grade($csvline['submissionid'], $csvline[$k], $csvline[$feedbackpointer], $stage,$stageusesrubric);
} else {
$cwfeedbackid = $this->get_coursework_feedback_id($csvline['submissionid'], $stage);
- $this->edit_grade($cwfeedbackid, $csvline[$k], $csvline[$feedbackpointer], $this->coursework->is_using_rubric());
+ $this->edit_grade($cwfeedbackid, $csvline[$k], $csvline[$feedbackpointer], $stageusesrubric);
}
// if feedback created and coursework has automatic grading enabled update agreedgrade
if ($cwfeedbackid && $this->coursework->automaticagreement_enabled()) {
@@ -803,8 +846,19 @@ public function remove_other_assessors_grade($csv_cells, &$line){
$key = array_search('otherassessors', $csv_cells);
unset($csv_cells[$key]);
$othercells = $this->other_assessors_cells();
+ if ($this->coursework->is_using_rubric()) {
+
+ $singlegradeposition = array_search('singlegrade', $csv_cells);
+
+ $criterias = $this->coursework->get_rubric_criteria();
+
+ $startposition = $singlegradeposition+ ((count($criterias) *2) +1);
+
+ } else {
+ $startposition = array_search('otherassessors', $csv_cells);
+ }
- for ($i = $key; $i < $key+$othercells ; $i++) {
+ for ($i = $startposition; $i < $startposition+$othercells ; $i++) {
unset($line[$i]);
}
$csv_cells =array_values($csv_cells);
diff --git a/classes/forms/advance_plugins_form.php b/classes/forms/advance_plugins_form.php
new file mode 100644
index 0000000..919519c
--- /dev/null
+++ b/classes/forms/advance_plugins_form.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * Creates an mform for final grade
+ *
+ * @package mod
+ * @subpackage coursework
+ * @copyright 2012 University of London Computer Centre {@link ulcc.ac.uk}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace mod_coursework\forms;
+
+global $CFG;
+
+use coding_exception;
+use gradingform_rubric_instance;
+use mod_coursework\models\feedback;
+use moodleform;
+use stdClass;
+
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Simple form providing a grade and comment area that will feed straight into the feedback table so
+ * that the final comment for the gradebook can be added.
+ */
+class advance_plugins_form extends moodleform {
+
+ /**
+ * Makes the form elements.
+ */
+ public function definition() {
+
+ $mform =& $this->_form;
+
+ $mform->addElement('editor', 'text_element', get_string('comment', 'mod_coursework'), array());
+ $mform->setType('editor', PARAM_RAW);
+
+ $file_manager_options = array(
+ 'subdirs' => false,
+ 'accepted_types' => '*',
+ 'return_types' => FILE_INTERNAL
+ );
+ $this->_form->addElement('filemanager',
+ 'file_element',
+ '',
+ null,
+ $file_manager_options);
+
+ }
+}
+
diff --git a/classes/forms/assessor_feedback_mform.php b/classes/forms/assessor_feedback_mform.php
index 9184a8c..4fd1b88 100644
--- a/classes/forms/assessor_feedback_mform.php
+++ b/classes/forms/assessor_feedback_mform.php
@@ -30,7 +30,9 @@
use coding_exception;
use gradingform_rubric_instance;
use mod_coursework\models\feedback;
+use mod_coursework\utils\cs_editor;
use moodleform;
+use stdClass;
require_once($CFG->libdir.'/formslib.php');
@@ -50,6 +52,10 @@ class assessor_feedback_mform extends moodleform {
*/
public $assessorid;
+ private $_grading_controller;
+
+ private $_grading_instance;
+
/**
* Makes the form elements.
*/
@@ -63,34 +69,34 @@ public function definition() {
$feedback = $this->_customdata['feedback'];
$coursework = $feedback->get_coursework();
- $mform->addElement('hidden', 'submissionid', $feedback->submissionid);
+ $mform->addElement('hidden', 'submissionid', $feedback->submissionid ?? 0);
$mform->setType('submissionid', PARAM_INT);
- $mform->addElement('hidden', 'isfinalgrade', $feedback->isfinalgrade);
+ $mform->addElement('hidden', 'isfinalgrade', $feedback->isfinalgrade ?? 0);
$mform->setType('isfinalgrade', PARAM_INT);
- $mform->addElement('hidden', 'ismoderation', $feedback->ismoderation);
+ $mform->addElement('hidden', 'ismoderation', $feedback->ismoderation ?? 0);
$mform->setType('ismoderation', PARAM_INT);
- $mform->addElement('hidden', 'assessorid', $feedback->assessorid);
+ $mform->addElement('hidden', 'assessorid', $feedback->assessorid ?? 0);
$mform->setType('assessorid', PARAM_INT);
- $mform->addElement('hidden', 'feedbackid', $feedback->id);
+ $mform->addElement('hidden', 'feedbackid', $feedback->id ?? 0);
$mform->setType('feedbackid', PARAM_INT);
- $mform->addElement('hidden', 'stage_identifier', $feedback->stage_identifier);
+ $mform->addElement('hidden', 'stage_identifier', $feedback->stage_identifier ?? '');
$mform->setType('stage_identifier', PARAM_ALPHANUMEXT);
$grademenu = make_grades_menu($coursework->grade);
- if ($coursework->is_using_advanced_grading()) {
- $controller = $coursework->get_advanced_grading_active_controller();
- $gradinginstance = $controller->get_or_create_instance(0, $feedback->assessorid, $feedback->id);
- $mform->addElement('grading', 'advancedgrading', get_string('grade'), array('gradinginstance' => $gradinginstance));
+ if (($coursework->is_using_advanced_grading() && $coursework->finalstagegrading ==0 ) || ($coursework->is_using_advanced_grading() && $coursework->finalstagegrading == 1 && $feedback->stage_identifier != 'final_agreed_1')) {
+ $this->_grading_controller = $coursework->get_advanced_grading_active_controller();
+ $this->_grading_instance = $this->_grading_controller->get_or_create_instance(0, $feedback->assessorid, $feedback->id);
+ $mform->addElement('grading', 'advancedgrading', get_string('grade', 'mod_coursework'), array('gradinginstance' => $this->_grading_instance));
} else {
$mform->addElement('select',
'grade',
- get_string('grade'),
+ get_string('grade', 'mod_coursework'),
$grademenu,
array('id' => 'feedback_grade'));
}
@@ -114,14 +120,22 @@ public function definition() {
$file_manager_options);
- $this->add_submit_buttons($coursework->draft_feedback_enabled());
+ $this->add_submit_buttons($coursework->draft_feedback_enabled(), $feedback->id);
}
+ /**
+ *
+ * @return mixed
+ */
+ public function get_grading_controller() {
+ return $this->_grading_controller;
+ }
+
/**
* @param $draftenabled
*/
- public function add_submit_buttons($draftenabled){
+ public function add_submit_buttons($draftenabled, $feedbackid){
$button_array = array();
@@ -133,12 +147,33 @@ public function add_submit_buttons($draftenabled){
$button_array[] =
$this->_form->createElement('submit', 'submitbutton', get_string('saveandfinalise', 'coursework'));
+ $feedback = $this->_customdata['feedback'];
+
+
+ $is_published = $feedback->get_submission()->is_published();
+
+ if ($feedbackid && !$is_published) {
+ $button_array[] = $this->_form->createElement('submit', 'removefeedbackbutton', get_string('removefeedback', 'coursework'));
+ }
$button_array[] = $this->_form->createElement('cancel');
$this->_form->addGroup($button_array, 'buttonar', '', array(' '), false);
$this->_form->closeHeaderBefore('buttonar');
}
+ /**
+ *
+ * @param $data
+ * @return bool
+ */
+ public function validate_grade($data){
+ $result = true;
+ if (!empty($this->_grading_instance) && property_exists($data, 'advancedgrading')) {
+ $result = $this->_grading_instance->validate_grading_element($data->advancedgrading);
+ }
+ return $result;
+ }
+
/**
* This is just to grab the data and add it to the feedback object.
*
@@ -148,9 +183,9 @@ public function add_submit_buttons($draftenabled){
public function process_data(feedback $feedback) {
$formdata = $this->get_data();
+ $coursework = $feedback->get_coursework();
- if ($feedback->get_coursework()->is_using_advanced_grading()) {
- $coursework = $feedback->get_coursework();
+ if (($coursework->is_using_advanced_grading() && $coursework->finalstagegrading == 0 ) || ($coursework->is_using_advanced_grading() && $coursework->finalstagegrading == 1 && $feedback->stage_identifier != 'final_agreed_1')) {
$controller = $coursework->get_advanced_grading_active_controller();
$gradinginstance = $controller->get_or_create_instance(0, $feedback->assessorid, $feedback->id);
/**
@@ -190,6 +225,38 @@ public function save_feedback_files(feedback $feedback) {
$feedback->id);
}
+ /**
+ *
+ * @return stdClass|null
+ */
+ public function get_file_options() {
+ global $PAGE, $CFG;
+ require_once("$CFG->dirroot/lib/form/filemanager.php");
+ $options = null;
+ $filemanager = $this->_form->getElement('feedback_manager');
+ if ($filemanager) {
+ $params = (object) [
+ 'maxfiles' => $filemanager->getMaxfiles(),
+ 'subdirs' => $filemanager->getSubdirs(),
+ 'areamaxbytes' => $filemanager->getAreamaxbytes(),
+ 'target' => 'id_' . $filemanager->getName(),
+ 'context' => $PAGE->context,
+ 'itemid' => $filemanager->getValue()
+ ];
+ $fm = new \form_filemanager($params);
+ $options = $fm->options;
+ }
+ return $options;
+ }
+ /**
+ *
+ * @return stdClass|null
+ */
+ public function get_editor_options() {
+ $editor = new cs_editor();
+ $options = $editor->get_options('feedback_comment');
+ return $options;
+ }
}
diff --git a/classes/forms/choose_student_for_submission_mform.php b/classes/forms/choose_student_for_submission_mform.php
index 9f31b8f..ee7855d 100644
--- a/classes/forms/choose_student_for_submission_mform.php
+++ b/classes/forms/choose_student_for_submission_mform.php
@@ -55,7 +55,7 @@ protected function definition() {
}
$options = array();
- $allnames = get_all_user_name_fields();
+ $allnames = \core_user\fields::get_name_fields();
foreach ($students as $student) {
diff --git a/classes/forms/student_submission_form.php b/classes/forms/student_submission_form.php
index 8c6dc04..1a2c03d 100644
--- a/classes/forms/student_submission_form.php
+++ b/classes/forms/student_submission_form.php
@@ -176,9 +176,10 @@ public function handle() {
if (!$submission->get_coursework()->has_deadline()) {
- $userids = explode(',',$submission->get_coursework()->get_submission_notification_users());
+ $useridcommaseparatedlist = $submission->get_coursework()->get_submission_notification_users();
- if (!empty($userids)) {
+ if (!empty($useridcommaseparatedlist)) {
+ $userids = explode(',', $useridcommaseparatedlist);
foreach($userids as $u) {
$notifyuser = $DB->get_record('user',array('id'=>trim($u)));
$mailer = new mailer($coursework);
@@ -370,7 +371,7 @@ protected function add_instructions_to_form() {
$file_manager_options = $this->get_file_manager_options();
$usernamehash = $this->get_coursework()->get_username_hash($this->get_submission()->userid);
- $filerenamestring = get_string('file_rename', 'coursework', $usernamehash);
+ $filerenamestring = ($this->get_coursework()->renamefiles == 1)? get_string('file_rename', 'coursework', $usernamehash) : "";
$filerenamestring .= $this->make_plagiarism_instructions();
$filerenamestring .= html_writer::empty_tag('br');
if ($file_manager_options['accepted_types'] != '*') {
@@ -387,11 +388,12 @@ protected function add_instructions_to_form() {
*/
protected function add_header_to_form() {
$file_manager_options = $this->get_file_manager_options();
-
- $files_string = ($file_manager_options['maxfiles'] == 1) ? 'yoursubmissionfile_upload'
+ $files_string = ($file_manager_options['maxfiles'] == 1) ? 'yoursubmissionfile'
: 'yoursubmissionfiles';
+ $renamed = ($this->get_coursework()->renamefiles == 1)?get_string('yoursubmissionfile_renamed', 'coursework') : "";
+
+ $this->_form->addElement('header', 'submitform', get_string($files_string, 'coursework'). $renamed);
- $this->_form->addElement('header', 'submitform', get_string($files_string, 'coursework'));
}
/**
diff --git a/classes/framework/decorator.php b/classes/framework/decorator.php
index 1115235..57d988a 100644
--- a/classes/framework/decorator.php
+++ b/classes/framework/decorator.php
@@ -61,6 +61,6 @@ public function __set($name, $value) {
* @return mixed
*/
public function wrapped_object() {
- return $this->wrapped_object();
+ return $this->wrapped_object;
}
}
\ No newline at end of file
diff --git a/classes/framework/table_base.php b/classes/framework/table_base.php
index 5a1d2c8..cdf0520 100644
--- a/classes/framework/table_base.php
+++ b/classes/framework/table_base.php
@@ -57,9 +57,12 @@ abstract class table_base {
* Makes a new instance. Can be overridden to provide a factory
*
* @param \stdClass|int|array $db_record
- * @return static
+ * @param bool $reload
+ * @return bool
+ * @throws \coding_exception
+ * @throws \dml_exception
*/
- public static function find($db_record) {
+ public static function find($db_record, $reload = true) {
global $DB;
@@ -91,7 +94,9 @@ public static function find($db_record) {
if ($db_record) {
$record = new $klass($db_record);
- $record->reload();
+ if ($reload) {
+ $record->reload();
+ }
return $record;
}
@@ -610,4 +615,47 @@ public function id() {
}
return $this->id;
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @throws \dml_exception
+ */
+ public static function fill_pool_coursework($coursework_id) {
+ if (isset(static::$pool[$coursework_id])) {
+ return;
+ }
+ $key = static::$table_name;
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework_id]);
+
+ $data = $cache->get($key);
+ if ($data === false) {
+ // no cache found
+ $data = static::get_cache_array($coursework_id);
+ $cache->set($key, $data);
+ }
+
+ static::$pool[$coursework_id] = $data;
+ }
+
+ /**
+ * @param $coursework_id
+ */
+ public static function remove_cache($coursework_id) {
+ global $SESSION;
+ if (!empty($SESSION->keep_cache_data)) {
+ return;
+ }
+ static::$pool[$coursework_id] = null;
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework_id]);
+ $cache->delete(static::$table_name);
+ }
+
}
diff --git a/classes/grade_judge.php b/classes/grade_judge.php
index ebbc77a..c218c0c 100644
--- a/classes/grade_judge.php
+++ b/classes/grade_judge.php
@@ -146,13 +146,12 @@ public function is_feedback_that_is_promoted_to_gradebook(feedback $feedback) {
* @param allocatable $allocatable
* @return bool
*/
- private function allocatable_needs_more_than_one_feedback ($allocatable){
+ public function allocatable_needs_more_than_one_feedback ($allocatable){
- if ($this->coursework->sampling_enabled()){
- $parameters = array('courseworkid' => $this->coursework->id,
- 'allocatableid' => $allocatable->id(),
- 'allocatabletype' => $allocatable->type());
- return assessment_set_membership::exists($parameters);
+ if ($this->coursework->sampling_enabled()) {
+ assessment_set_membership::fill_pool_coursework($this->coursework->id);
+ $record = assessment_set_membership::get_object($this->coursework->id, 'allocatableid-allocatabletype', [$allocatable->id(), $allocatable->type()]);
+ return !empty($record);
} else {
return $this->coursework->has_multiple_markers();
}
diff --git a/classes/grades/gradeitems.php b/classes/grades/gradeitems.php
new file mode 100644
index 0000000..63e7a50
--- /dev/null
+++ b/classes/grades/gradeitems.php
@@ -0,0 +1,61 @@
+.
+
+/**
+ * Grade item mappings for the activity.
+ *
+ * @package mod_coursework
+ */
+
+declare(strict_types = 1);
+
+namespace mod_coursework\grades;
+
+use \core_grades\local\gradeitem\itemnumber_mapping;
+use \core_grades\local\gradeitem\advancedgrading_mapping;
+
+/**
+ * Grade item mappings for the activity.
+ *
+ * @package mod_coursework
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class gradeitems implements itemnumber_mapping, advancedgrading_mapping {
+
+ /**
+ * Return the list of grade item mappings for the assign.
+ *
+ * @return array
+ */
+ public static function get_itemname_mapping_for_component(): array {
+ return [
+ 0 => 'submissions',
+ ];
+ }
+
+ /**
+ * Get the list of advanced grading item names for this component.
+ *
+ * @return array
+ */
+ public static function get_advancedgrading_itemnames(): array {
+ return [
+ 'submissions',
+ ];
+ }
+}
+
+
diff --git a/classes/grading_report.php b/classes/grading_report.php
index 78dcbea..ace35c2 100644
--- a/classes/grading_report.php
+++ b/classes/grading_report.php
@@ -16,7 +16,12 @@
namespace mod_coursework;
+use mod_coursework\models\allocation;
+use mod_coursework\models\course_module;
use mod_coursework\models\coursework;
+use mod_coursework\models\feedback;
+use mod_coursework\models\module;
+use mod_coursework\models\submission;
use mod_coursework\models\user;
use mod_coursework\render_helpers\grading_report\cells\cell_interface;
use mod_coursework\render_helpers\grading_report\sub_rows\sub_rows_interface;
@@ -28,6 +33,11 @@
*/
class grading_report {
+ //added static vars to determine in what manner the report is loaded
+ public static $MODE_GET_ALL = 1;
+ public static $MODE_GET_FIRST_RECORDS = 2;
+ public static $MODE_GET_REMAIN_RECORDS = 3;
+
/**
* @var array rendering options
*/
@@ -49,6 +59,11 @@ class grading_report {
*/
private $totalrows;
+ /**
+ * @var int The real total number of rows the user could see on all pages.
+ */
+ public $realtotalrows;
+
/**
* @var
*/
@@ -67,8 +82,27 @@ class grading_report {
* @param coursework $coursework
*/
public function __construct(array $options, $coursework) {
+
+ $options['courseworkid'] = $coursework->id;
+
$this->options = $options;
$this->coursework = $coursework;
+ $this->fill_pool();
+ }
+
+ /**
+ * Cache data for later use
+ */
+ protected function fill_pool() {
+ global $DB;
+
+ $coursework_id = $this->coursework->id;
+ submission::fill_pool_coursework($coursework_id);
+ coursework::fill_pool([$this->coursework]);
+ course_module::fill_pool([$this->coursework->get_course_module()]);
+ module::fill_pool($DB->get_records('modules', ['name' => 'coursework']));
+ feedback::fill_pool_submissions($coursework_id, array_keys(submission::$pool[$coursework_id]['id']));
+ allocation::fill_pool_coursework($coursework_id);
}
/**
@@ -306,7 +340,7 @@ public function get_participant_count() {
*
* @return grading_table_row_base[] row objects
*/
- public function get_table_rows_for_page() {
+ public function get_table_rows_for_page($rowcount=false) {
global $USER;
@@ -317,70 +351,68 @@ public function get_table_rows_for_page() {
// Make tablerow objects so we can use the methods to check permissions and set things.
$rows = array();
- foreach ($participants as $participant) {
+ $row_class = $this->coursework->has_multiple_markers() ? 'mod_coursework\grading_table_row_multi' : 'mod_coursework\grading_table_row_single';
+ $ability = new ability(user::find($USER, false), $this->get_coursework());
+
+ $participantsfound = 0;
+
+ foreach ($participants as $key => $participant) {
// handle 'Group mode' - unset groups/individuals thaat are not in the chosen group
- if(!empty($options['group']) && $options['group'] != -1){
- if ($this->coursework->is_configured_to_have_group_submissions()){
- if($options['group'] != $participant->id) continue;
- } else {
- if(!$this->coursework->student_in_group($participant->id, $options['group']))continue;
- }
- }
-
- if ($this->coursework->has_multiple_markers()) {
- $row = new grading_table_row_multi($this->coursework, $participant);
- $rows[$participant->id()] = $row;
- } else {
- $row = new grading_table_row_single($this->coursework, $participant);
- $rows[$participant->id()] = $row;
+ if(!empty($options['group']) && $options['group'] != -1){
+ if ($this->coursework->is_configured_to_have_group_submissions()){
+ if($options['group'] != $participant->id) continue;
+ } else {
+ if(!$this->coursework->student_in_group($participant->id, $options['group']))continue;
+ }
}
- }
- // Sort the rows.
- $method_name = 'sort_by_' . $options['sortby'];
- if (method_exists($this, $method_name)) {
- usort($rows,
- array($this,
- $method_name));
- }
+ $row = new $row_class($this->coursework, $participant);
- $ability = new ability(user::find($USER), $this->get_coursework());
-
- // Now, we remove the ones who should not be visible on this page. Must happen AFTER the sort!
- // Rather than sort in SQL, we sort here so we can use complex permissions stuff.
- // Page starts at 0!
- $start = ($options['page']) * $options['perpage']; // Will start at 0.
- $end = ($options['page'] + 1) * $options['perpage']; // Take care of overlap: 0-10, 10-20, 20-30.
- $counter = 0; // Begin from the first one that the user could see.
- foreach ($rows as $allocatable_id => $row) {
- /**
- * @var grading_table_row_base $row
- */
- // Some the user should not even know are there. Important that we only increment the counter after
- // this point.
- if (!$ability->can('show', $row) && !isset($options['unallocated'])) {
- unset($rows[$allocatable_id]);
+ // Now, we skip the ones who should not be visible on this page.
+ $can_show = $ability->can('show', $row);
+ if (!$can_show && !isset($options['unallocated'])) {
+ unset($participants[$key]);
continue;
}
-
- if ($ability->can('show', $row) && isset($options['unallocated'])) {
- unset($rows[$allocatable_id]);
+ if ($can_show && isset($options['unallocated'])) {
+ unset($participants[$key]);
continue;
}
- $counter++;
+ $rows[$participant->id()] = $row;
+ $participantsfound++;
+ if (!empty($rowcount) && $participantsfound >= $rowcount) break;
- if ($counter <= $start || $counter > $end) { // Taking care not to include the same ones in two pages.
- unset($rows[$allocatable_id]);
- }
+ }
+
+ // Sort the rows.
+ $method_name = 'sort_by_' . $options['sortby'];
+ if (method_exists($this, $method_name)) {
+ usort($rows,
+ array($this,
+ $method_name));
}
// Some will have submissions and therefore data fields. Others will have those fields null.
/* @var grading_table_row_base[] $tablerows */
+ $counter = count($rows);
+ $this->realtotalrows = $counter;
+ $mode = empty($this->options['mode']) ? self::$MODE_GET_ALL : $this->options['mode'];
+ if ($mode != self::$MODE_GET_ALL) {
+ $perpage = $this->options['perpage'] ?? 10;
+ if ($counter > $perpage) {
+ if ($mode == self::$MODE_GET_FIRST_RECORDS) {
+ $rows = array_slice($rows, 0, $perpage);
+ } else if ($mode == self::$MODE_GET_REMAIN_RECORDS) {
+ $rows = array_slice($rows, $perpage);
+ }
+ }
+ }
+
$this->tablerows = $rows;
- $this->totalrows = $counter;
+ $this->totalrows = count($rows);
}
return $this->tablerows;
diff --git a/classes/grading_table_row_base.php b/classes/grading_table_row_base.php
index e95163d..9359326 100644
--- a/classes/grading_table_row_base.php
+++ b/classes/grading_table_row_base.php
@@ -117,6 +117,42 @@ public function get_user_name($link = false) {
}
}
+ /**
+ * Will return the idnumber if permissions allow, otherwise, an anonymous placeholder.
+ *
+ * @throws \coding_exception
+ * @return string
+ */
+ public function get_idnumber() {
+ global $DB;
+
+ $viewanonymous = has_capability('mod/coursework:viewanonymous', $this->get_coursework()->get_context());
+ if (!$this->get_coursework()->blindmarking || $viewanonymous || $this->is_published()) {
+ $user = $DB->get_record('user', array('id' => $this->get_allocatable_id()));
+ return $user->idnumber;
+ } else {
+ return get_string('hidden', 'mod_coursework');
+ }
+ }
+
+ /**
+ * Will return the email if permissions allow, otherwise, an anonymous placeholder.
+ *
+ * @throws \coding_exception
+ * @return string
+ */
+ public function get_email() {
+ global $DB;
+
+ $viewanonymous = has_capability('mod/coursework:viewanonymous', $this->get_coursework()->get_context());
+ if (!$this->get_coursework()->blindmarking || $viewanonymous || $this->is_published()) {
+ $user = $DB->get_record('user', array('id' => $this->get_allocatable_id()));
+ return $user->email;
+ } else {
+ return '';
+ }
+ }
+
/**
* Returns the id of the student who's submission this is
*
@@ -202,13 +238,10 @@ public function get_coursework() {
public function get_submission() {
if (!isset($this->submission)) {
-
- $params = array(
- 'courseworkid' => $this->get_coursework_id(),
- 'allocatableid' => $this->get_allocatable()->id(),
- 'allocatabletype' => $this->get_allocatable()->type(),
- );
- $this->submission = submission::find($params);
+ $allocatableid = $this->get_allocatable()->id();
+ $allocatabletype = $this->get_allocatable()->type();
+ $params = [$allocatableid, $allocatabletype];
+ $this->submission = submission::get_object($this->get_coursework_id(), 'allocatableid-allocatabletype', $params);
}
return $this->submission;
@@ -361,4 +394,64 @@ public function get_single_feedback(){
return $this->get_submission()->get_assessor_feedback_by_stage('assessor_1');
}
+
+ /**
+ * Check if the extension is given to this row
+ *
+ * @return bool
+ */
+
+ public function has_extension() {
+
+ global $DB;
+ return $DB->record_exists('coursework_extensions', array('courseworkid' => $this->get_coursework()->id,
+ 'allocatableid' => $this->get_allocatable()->id(),
+ 'allocatabletype'=> $this->get_allocatable()->type()));
+
+ }
+
+
+ /**
+ * Getter for row extension
+ *
+ * @return mixed
+
+ */
+ public function get_extension() {
+ global $DB;
+ return $DB->get_record('coursework_extensions', array('courseworkid' => $this->get_coursework()->id,
+ 'allocatableid' => $this->get_allocatable()->id(),
+ 'allocatabletype'=> $this->get_allocatable()->type()));
+ }
+
+ public function get_user_firstname() {
+ /**
+ * @var user $user
+ */
+ $user = $this->get_allocatable();
+
+ $viewanonymous = has_capability('mod/coursework:viewanonymous', $this->get_coursework()->get_context());
+ if (!$this->get_coursework()->blindmarking || $viewanonymous || $this->is_published() ) {
+ return $user->firstname;
+ }
+ else {
+ return get_string('hidden', 'mod_coursework');
+ }
+ }
+
+ public function get_user_lastname() {
+ /**
+ * @var user $user
+ */
+ $user = $this->get_allocatable();
+
+ $viewanonymous = has_capability('mod/coursework:viewanonymous', $this->get_coursework()->get_context());
+ if (!$this->get_coursework()->blindmarking || $viewanonymous || $this->is_published()) {
+ return $user->lastname;
+ }
+ else {
+ return get_string('hidden', 'mod_coursework');
+ }
+ }
+
}
diff --git a/classes/mailer.php b/classes/mailer.php
index 7e7a840..99ab0ed 100644
--- a/classes/mailer.php
+++ b/classes/mailer.php
@@ -37,39 +37,42 @@ public function send_submission_receipt($user, $finalised = false) {
$submission = $this->coursework->get_user_submission($user);
- $email_data = new \stdClass();
- $email_data->name = $user->name();
- $dateformat = '%a, %d %b %Y, %H:%M';
- $email_data->submittedtime = userdate($submission->time_submitted(), $dateformat);
- $email_data->coursework_name = $this->coursework->name;
- $email_data->submissionid = $submission->id;
- if ($finalised) {
- $email_data->finalised = get_string('save_email_finalised', 'coursework');
- } else {
- $email_data->finalised = '';
- }
+ if ($this->coursework && $this->coursework->is_coursework_visible()) {// check if coursework exists and is not hidden
+
+ $email_data = new \stdClass();
+ $email_data->name = $user->name();
+ $dateformat = '%a, %d %b %Y, %H:%M';
+ $email_data->submittedtime = userdate($submission->time_submitted(), $dateformat);
+ $email_data->coursework_name = $this->coursework->name;
+ $email_data->submissionid = $submission->id;
+ if ($finalised) {
+ $email_data->finalised = get_string('save_email_finalised', 'coursework');
+ } else {
+ $email_data->finalised = '';
+ }
+
+ $subject = get_string('save_email_subject', 'coursework');
+ $text_body = get_string('save_email_text', 'coursework', $email_data);
+ $html_body = get_string('save_email_html', 'coursework', $email_data);
- $subject = get_string('save_email_subject', 'coursework');
- $text_body = get_string('save_email_text', 'coursework', $email_data);
- $html_body = get_string('save_email_html', 'coursework', $email_data);
-
- // New approach.
- $eventdata = new \core\message\message();
- $eventdata->component = 'mod_coursework';
- $eventdata->name = 'submission_receipt';
- $eventdata->userfrom = \core_user::get_noreply_user();
- $eventdata->userto = $user->get_raw_record();
- $eventdata->subject = $subject;
- $eventdata->fullmessage = $text_body;
- $eventdata->fullmessageformat = FORMAT_PLAIN;
- $eventdata->fullmessagehtml = $html_body;
- $eventdata->smallmessage = $text_body;
- $eventdata->notification = 1;
- $eventdata->contexturl = $CFG->wwwroot.'/mod/coursework/view.php?id='.$submission->get_coursework()->get_coursemodule_id();
- $eventdata->contexturlname = 'View your submission here';
- $eventdata->courseid = $this->coursework->course;
+ // New approach.
+ $eventdata = new \core\message\message();
+ $eventdata->component = 'mod_coursework';
+ $eventdata->name = 'submission_receipt';
+ $eventdata->userfrom = \core_user::get_noreply_user();
+ $eventdata->userto = $user->get_raw_record();
+ $eventdata->subject = $subject;
+ $eventdata->fullmessage = $text_body;
+ $eventdata->fullmessageformat = FORMAT_PLAIN;
+ $eventdata->fullmessagehtml = $html_body;
+ $eventdata->smallmessage = $text_body;
+ $eventdata->notification = 1;
+ $eventdata->contexturl = $CFG->wwwroot . '/mod/coursework/view.php?id=' . $submission->get_coursework()->get_coursemodule_id();
+ $eventdata->contexturlname = 'View your submission here';
+ $eventdata->courseid = $this->coursework->course;
- message_send($eventdata);
+ message_send($eventdata);
+ }
}
@@ -117,37 +120,40 @@ public function send_late_submission_notification($submission) {
public function send_feedback_notification($submission) {
global $CFG;
- $email_data = new \stdClass();
- $email_data->coursework_name = $this->coursework->name;
+ if ($this->coursework && $this->coursework->is_coursework_visible()) {// check if coursework exists and is not hidden
- $subject = get_string('feedback_released_email_subject', 'coursework');
+ $email_data = new \stdClass();
+ $email_data->coursework_name = $this->coursework->name;
- // get a student or all students from a group
- $students = $submission->students_for_gradebook();
+ $subject = get_string('feedback_released_email_subject', 'coursework');
- foreach ($students as $student) {
- $student = \mod_coursework\models\user::find($student);
+ // get a student or all students from a group
+ $students = $submission->students_for_gradebook();
- $email_data->name = $student->name();
- $text_body = get_string('feedback_released_email_text', 'coursework', $email_data);
- $html_body = get_string('feedback_released_email_html', 'coursework', $email_data);
+ foreach ($students as $student) {
+ $student = \mod_coursework\models\user::find($student);
- $eventdata = new \core\message\message();
- $eventdata->component = 'mod_coursework';
- $eventdata->name = 'feedback_released';
- $eventdata->userfrom = \core_user::get_noreply_user();
- $eventdata->userto = $student->get_raw_record();
- $eventdata->subject = $subject;
- $eventdata->fullmessage = $text_body;
- $eventdata->fullmessageformat = FORMAT_PLAIN;
- $eventdata->fullmessagehtml = $html_body;
- $eventdata->smallmessage = $text_body;
- $eventdata->notification = 1;
- $eventdata->contexturl = $CFG->wwwroot . '/mod/coursework/view.php?id=' . $submission->get_coursework()->get_coursemodule_id();
- $eventdata->contexturlname = 'View your submission here';
- $eventdata->courseid = $this->coursework->course;
+ $email_data->name = $student->name();
+ $text_body = get_string('feedback_released_email_text', 'coursework', $email_data);
+ $html_body = get_string('feedback_released_email_html', 'coursework', $email_data);
- message_send($eventdata);
+ $eventdata = new \core\message\message();
+ $eventdata->component = 'mod_coursework';
+ $eventdata->name = 'feedback_released';
+ $eventdata->userfrom = \core_user::get_noreply_user();
+ $eventdata->userto = $student->get_raw_record();
+ $eventdata->subject = $subject;
+ $eventdata->fullmessage = $text_body;
+ $eventdata->fullmessageformat = FORMAT_PLAIN;
+ $eventdata->fullmessagehtml = $html_body;
+ $eventdata->smallmessage = $text_body;
+ $eventdata->notification = 1;
+ $eventdata->contexturl = $CFG->wwwroot . '/mod/coursework/view.php?id=' . $submission->get_coursework()->get_coursemodule_id();
+ $eventdata->contexturlname = 'View your submission here';
+ $eventdata->courseid = $this->coursework->course;
+
+ message_send($eventdata);
+ }
}
}
@@ -162,6 +168,9 @@ public function send_student_deadline_reminder($user) {
global $CFG;
+ if (!$this->coursework || !$this->coursework->is_coursework_visible()) {// check if coursework exists and is not hidden
+ return false;
+ }
$email_data = new \stdClass();
$email_data->coursework_name = $this->coursework->name;
$email_data->coursework_name_with_link = \html_writer::link($CFG->wwwroot . '/mod/coursework/view.php?id=' . $this->coursework->get_coursemodule_id(), $this->coursework->name);
@@ -210,33 +219,36 @@ public function send_submission_notification($userstonotify) {
global $CFG;
- $email_data = new \stdClass();
- $email_data->coursework_name = $this->coursework->name;
+ if ($this->coursework && $this->coursework->is_coursework_visible()) {// check if coursework exists and is not hidden
- $subject = get_string('submission_notification_subject', 'coursework',$email_data->coursework_name);
+ $email_data = new \stdClass();
+ $email_data->coursework_name = $this->coursework->name;
- $userstonotify = \mod_coursework\models\user::find($userstonotify);
+ $subject = get_string('submission_notification_subject', 'coursework', $email_data->coursework_name);
- $email_data->name = $userstonotify->name();
- $text_body = get_string('submission_notification_text', 'coursework', $email_data);
- $html_body = get_string('submission_notification_html', 'coursework', $email_data);
+ $userstonotify = \mod_coursework\models\user::find($userstonotify);
- $eventdata = new \core\message\message();
- $eventdata->component = 'mod_coursework';
- $eventdata->name = 'coursework_submission';
- $eventdata->userfrom = \core_user::get_noreply_user();
- $eventdata->userto = $userstonotify->get_raw_record();
- $eventdata->subject = $subject;
- $eventdata->fullmessage = $text_body;
- $eventdata->fullmessageformat = FORMAT_PLAIN;
- $eventdata->fullmessagehtml = $html_body;
- $eventdata->smallmessage = $text_body;
- $eventdata->notification = 1;
- $eventdata->contexturl = $CFG->wwwroot . '/mod/coursework/view.php?id=' . $this->coursework->id();
- $eventdata->contexturlname = 'coursework submission';
- $eventdata->courseid = $this->coursework->course;
+ $email_data->name = $userstonotify->name();
+ $text_body = get_string('submission_notification_text', 'coursework', $email_data);
+ $html_body = get_string('submission_notification_html', 'coursework', $email_data);
- message_send($eventdata);
+ $eventdata = new \core\message\message();
+ $eventdata->component = 'mod_coursework';
+ $eventdata->name = 'coursework_submission';
+ $eventdata->userfrom = \core_user::get_noreply_user();
+ $eventdata->userto = $userstonotify->get_raw_record();
+ $eventdata->subject = $subject;
+ $eventdata->fullmessage = $text_body;
+ $eventdata->fullmessageformat = FORMAT_PLAIN;
+ $eventdata->fullmessagehtml = $html_body;
+ $eventdata->smallmessage = $text_body;
+ $eventdata->notification = 1;
+ $eventdata->contexturl = $CFG->wwwroot . '/mod/coursework/view.php?id=' . $this->coursework->id();
+ $eventdata->contexturlname = 'coursework submission';
+ $eventdata->courseid = $this->coursework->course;
+
+ message_send($eventdata);
+ }
}
diff --git a/classes/models/allocation.php b/classes/models/allocation.php
index 229674e..73b50b5 100644
--- a/classes/models/allocation.php
+++ b/classes/models/allocation.php
@@ -100,7 +100,7 @@ public function get_coursework() {
* @return user|bool
*/
public function assessor() {
- return user::find($this->assessorid);
+ return user::get_object($this->assessorid);
}
/**
@@ -141,4 +141,69 @@ public function unpin() {
$this->update_attribute('manual', 0);
}
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(static::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'id' => [],
+ 'stage_identifier' => [],
+ 'allocatableid-allocatabletype-stage_identifier' => [],
+ 'allocatableid-allocatabletype-assessorid' => [],
+ 'assessorid-allocatabletype' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['id'][$record->id] = $object;
+ $result['stage_identifier'][$record->stage_identifier][] = $object;
+ $result['allocatableid-allocatabletype-stage_identifier'][$record->allocatableid . '-' . $record->allocatabletype . '-' . $record->stage_identifier][] = $object;
+ $result['allocatableid-allocatabletype-assessorid'][$record->allocatableid . '-' . $record->allocatabletype . '-' . $record->assessorid][] = $object;
+ $result['assessorid-allocatabletype'][$record->assessorid . '-' . $record->allocatabletype][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
diff --git a/classes/models/assessment_set_membership.php b/classes/models/assessment_set_membership.php
index c427660..5482ab9 100644
--- a/classes/models/assessment_set_membership.php
+++ b/classes/models/assessment_set_membership.php
@@ -20,9 +20,69 @@
*/
class assessment_set_membership extends table_base implements moderatable {
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
/**
* @var string
*/
protected static $table_name = 'coursework_sample_set_mbrs';
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(self::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'allocatableid-allocatabletype' => [],
+ 'allocatableid-allocatabletype-stage_identifier' => [],
+ 'allocatableid-stage_identifier-selectiontype' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['allocatableid-allocatabletype'][$record->allocatableid . '-' . $record->allocatabletype][] = $object;
+ $result['allocatableid-allocatabletype-stage_identifier'][$record->allocatableid . '-' . $record->allocatabletype . '-' . $record->stage_identifier][] = $object;
+ $result['allocatableid-stage_identifier-selectiontype'][$record->allocatableid . '-' . $record->stage_identifier . '-' . $record->selectiontype][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
\ No newline at end of file
diff --git a/classes/models/course_module.php b/classes/models/course_module.php
new file mode 100644
index 0000000..2674272
--- /dev/null
+++ b/classes/models/course_module.php
@@ -0,0 +1,61 @@
+.
+
+namespace mod_coursework\models;
+
+use mod_coursework\framework\table_base;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Represents a row in the course_modules table.
+ */
+class course_module extends table_base {
+
+ /**
+ * @var string
+ */
+ protected static $table_name = 'course_modules';
+
+ /**
+ * @var int
+ */
+ public $id;
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ * Fill pool to cache for later use
+ *
+ * @param $array
+ */
+ public static function fill_pool($array) {
+ self::$pool = [
+ 'id' => [],
+ 'course-module-instance' => []
+ ];
+ foreach ($array as $record) {
+ $object = new self($record);
+ self::$pool['id'][$record->id] = $object;
+ self::$pool['course-module-instance'][$record->course][$record->module][$record->instance] = $object;
+ }
+ }
+}
diff --git a/classes/models/coursework.php b/classes/models/coursework.php
index a787737..fe942c5 100644
--- a/classes/models/coursework.php
+++ b/classes/models/coursework.php
@@ -41,7 +41,11 @@
use mod_coursework\decorators\coursework_groups_decorator;
use mod_coursework\grade_judge;
use mod_coursework\grading_report;
+use mod_coursework\render_helpers\grading_report\cells\first_name_cell;
use mod_coursework\render_helpers\grading_report\cells\grade_for_gradebook_cell;
+use mod_coursework\render_helpers\grading_report\cells\last_name_cell;
+use mod_coursework\render_helpers\grading_report\cells\email_cell;
+use mod_coursework\render_helpers\grading_report\cells\idnumber_cell;
use mod_coursework\render_helpers\grading_report\cells\moderation_agreement_cell;
use mod_coursework\render_helpers\grading_report\cells\single_assessor_feedback_cell;
use mod_coursework\render_helpers\grading_report\cells\filename_hash_cell;
@@ -147,6 +151,11 @@ class coursework extends table_base {
*/
public $numberofmarkers;
+ /**
+ * @var int
+ */
+ public $finalstagegrading;
+
/**
* @var int 0 or 1
*/
@@ -331,6 +340,11 @@ class coursework extends table_base {
*/
public $maxfiles;
+ /**
+ * @var int
+ */
+ public $renamefiles;
+
/**
* @var string
*/
@@ -398,7 +412,7 @@ class coursework extends table_base {
* @param int|\stdClass $db_record
* @return mixed|\mod_coursework_coursework
*/
- public static function find($db_record) {
+ public static function find($db_record, $reload = true) {
$coursework_object = parent::find($db_record);
if ($coursework_object && $coursework_object->is_configured_to_have_group_submissions()) {
@@ -433,11 +447,14 @@ public function get_course_module() {
if (empty($this->id)) {
throw new moodle_exception('Trying to get course module for a coursework that has not yet been saved');
}
- $module_id = $DB->get_field('modules', 'id', array('name' => 'coursework'));
- $this->coursemodule = $DB->get_record('course_modules',
- array('course' => $this->get_course_id(),
- 'module' => $module_id,
- 'instance' => $this->id), '*', MUST_EXIST);
+ $module_record = module::$pool['name']['coursework'] ?? $DB->get_record('modules', ['name' => 'coursework']);
+ $module_id = $module_record->id;
+ $course_id = $this->get_course_id();
+ if (!isset(course_module::$pool['course-module-instance'][$course_id][$module_id][$this->id]->id)) {
+ $this->coursemodule = course_module::$pool['course-module-instance'][$course_id][$module_id][$this->id] =
+ $DB->get_record('course_modules', ['course' => $course_id, 'module' => $module_id, 'instance' => $this->id], '*', MUST_EXIST);
+ }
+ $this->coursemodule = course_module::$pool['course-module-instance'][$course_id][$module_id][$this->id];
}
return $this->coursemodule;
@@ -478,6 +495,7 @@ public function get_coursemodule_idnumber() {
return (int)$coursemodule->idnumber;
}
+
/**
* Getter function for the coursework's course object.
*
@@ -527,17 +545,8 @@ public function set_course_id($courseid) {
* @return array
*/
public function get_all_raw_feedbacks() {
-
- global $DB;
-
- $sql = "SELECT f.*
- FROM {coursework_feedbacks} f
- INNER JOIN {coursework_submissions} s
- ON s.id = f.submissionid
- WHERE s.courseworkid = :courseworkid ";
-
- $params['courseworkid'] = $this->id;
- $feedbacks = $DB->get_records_sql($sql, $params);
+ feedback::fill_pool_coursework($this->id);
+ $feedbacks = feedback::$pool[$this->id]['id'];
return $feedbacks;
}
@@ -553,14 +562,13 @@ public function get_ungraded_assessments_number($can_grade) {
return 0;
}
// Count submitted work that this person has not graded.
- $submissions = $DB->get_records('coursework_submissions',
- array('courseworkid' => $this->id), '', 'id');
+ submission::fill_pool_coursework($this->id);
+ feedback::fill_pool_coursework($this->id);
+ $submissions = submission::$pool[$this->id]['id'];
$count = 0;
foreach ($submissions as $s) {
- $feedbacks = $DB->count_records('coursework_feedbacks',
- array('submissionid' => $s->id,
- 'assessorid' => $USER->id));
- if ($feedbacks < 1) {
+ $feedback = feedback::get_object($this->id, 'submissionid-assessorid', [$s->id, $USER->id]);
+ if (empty($feedback)) {
$count++;
}
}
@@ -689,7 +697,7 @@ public function get_file_options() {
$turnitinenabled = $this->tii_enabled();
// Turn it in only allows one file.
- $max_files = $turnitinenabled ? 1 : $this->maxfiles;
+ $max_files = $this->maxfiles;
// Turn it in only likes some file types.
/* DOC, DOCX, Corel
@@ -969,10 +977,31 @@ public function pack_files() {
$files = $fs->get_area_files($context->id, 'mod_coursework', 'submission',
$submission->id, "id", false);
foreach ($files as $f) {
+
+ $filename = basename($f->get_filename());
+
+ $foldername = '';
+
+ if($this->blindmarking == 0 || has_capability('mod/coursework:viewanonymous',$this->get_context())) {
+ $submissionuser = $submission->get_allocatable();
+ if ($this->is_configured_to_have_group_submissions() && $submissionuser->name) {
+ $foldername = $submissionuser->name . '_';
+ } elseif(!$this->is_configured_to_have_group_submissions()) {
+ $foldername = $submissionuser->firstname . ' ' . $submissionuser->lastname . '_';
+ }
+ }
+
+ $foldername .= $this->get_username_hash($submission->get_allocatable()->id());
+
+ $filename = $foldername.'/'.$filename;
+
/* @var $f stored_file */
- $files_for_zipping[$f->get_filename()] = $f;
+ $files_for_zipping[$filename] = $f;
}
}
+
+
+
// Create path for new zip file.
$temp_zip = tempnam($CFG->dataroot.'/temp/', 'ocm_');
// Zip files.
@@ -1216,28 +1245,21 @@ public function assessor_has_any_allocation_for_student($allocatable, $userid=fa
*/
public function assessor_has_allocation_for_student_not_in_current_stage($allocatable, $userid, $stage) {
- global $DB, $USER;
-
- if (!$userid){
+ global $USER;
+ if (!$userid) {
$userid = $USER->id;
}
- $params = array(
- 'courseworkid' => $this->id,
- 'assessorid' => $userid,
- 'allocatableid' => $allocatable->id(),
- 'allocatabletype' => $allocatable->type(),
- 'stage' => $stage );
-
- $sql = "SELECT *
- FROM {coursework_allocation_pairs}
- WHERE courseworkid = :courseworkid
- AND assessorid = :assessorid
- AND allocatableid = :allocatableid
- AND allocatabletype = :allocatabletype
- AND stage_identifier <> :stage";
+ allocation::fill_pool_coursework($this->id);
+ $records = isset(allocation::$pool[$this->id]['allocatableid-allocatabletype-assessorid'][$allocatable->id() . '-' . $allocatable->type() . "-$userid"]) ?
+ allocation::$pool[$this->id]['allocatableid-allocatabletype-assessorid'][$allocatable->id() . '-' . $allocatable->type() . "-$userid"] : [];
+ foreach ($records as $record) {
+ if ($record->stage_identifier != $stage) {
+ return true;
+ }
+ }
- return $DB->record_exists_sql($sql, $params);
+ return false;
}
@@ -1268,18 +1290,114 @@ public function current_user_is_moderator_for_student($allocatable) {
* @return submission[]
*/
public function get_all_submissions() {
+ submission::fill_pool_coursework($this->id);
+ $submissions = submission::$pool[$this->id]['id'];
+
+ return $submissions;
+ }
+
+ /**
+ * Get submissions that need grading, either in initial or final stage
+ * For multiple marker coursework if final grade is not given it is assumed that submission may need grading in
+ * either initial, final or both stages
+ *
+ * @throws \dml_exception
+ * @throws \dml_missing_record_exception
+ * @throws \dml_multiple_records_exception
+ */
+ public function get_submissions_needing_grading(){
+
+ $needsgrading = array();
+ $submissions = $this->get_finalised_submissions();
+
+ foreach ($submissions as $submission) {
+
+ $stage_identifier = ($this->has_multiple_markers())? 'final_agreed_1': 'assessor_1';
+ $submission = submission::find($submission);
+ if (!$feedback = $submission->get_assessor_feedback_by_stage($stage_identifier)){
+ $needsgrading[] = $submission;
+ }
+
+ }
+
+
+ return $needsgrading;
+
+ }
+
+ /**
+ * Get all graded submissions for the specified marking stage
+ *
+ * @param $stage_identifier
+ * @return array
+ * @throws \dml_missing_record_exception
+ * @throws \dml_multiple_records_exception
+ */
+ public function get_graded_submissions_by_stage($stage_identifier){
+
+ $graded = array();
+ $submissions = $this->get_finalised_submissions();
+
+ foreach ($submissions as $submission) {
+ $submission = submission::find($submission);
+ if ($feedback = $submission->get_assessor_feedback_by_stage($stage_identifier)){
+ $graded[$submission->id] = $submission;
+ }
+ }
+ return $graded;
+ }
+ /**
+ * Function to get all assessor's graded submissions within the specified coursework
+ *
+ * @param $assessorid
+ * @return array
+ * @throws \dml_exception
+ */
+ public function get_assessor_graded_submissions($assessorid){
global $DB;
- $submissions = $DB->get_records('coursework_submissions', array('courseworkid' => $this->id));
+ $graded = array();
+ $params = array('courseworkid' => $this->id, 'assessorid' => $assessorid);
+ $sql = "SELECT cs.id
+ FROM {coursework_feedbacks} cf
+ JOIN {coursework_submissions} cs
+ ON cs.id = cf.submissionid
+ WHERE cs.courseworkid = :courseworkid
+ AND assessorid = :assessorid";
+ $submissions = $DB->get_records_sql($sql, $params);
- foreach ($submissions as &$submission) {
+ foreach ($submissions as $submission) {
$submission = submission::find($submission);
+ $graded[$submission->id] = $submission;
}
+ return $graded;
+ }
+
+
+ /**
+ * Get all published submissions in the coursework
+ *
+ * @return array
+ * @throws \dml_exception
+ */
+ public function get_published_submissions(){
+ global $DB;
+
+ $sql = "SELECT *
+ FROM {coursework_submissions}
+ WHERE courseworkid = :courseworkid
+ AND firstpublished IS NOT NULL";
+
+ $submissions = $DB->get_records_sql($sql, array('courseworkid' => $this->id));
+ foreach ($submissions as &$submission) {
+ $submission = submission::find($submission);
+ }
return $submissions;
}
+
/**
* Returns a hash of this user's id. Not username as this would be non-unique across
* different courseworks, compromising anonymity.
@@ -1425,21 +1543,11 @@ public function get_student_feedback_release_date() {
*/
public function get_unfinalised_students($fields = 'u.id, u.firstname, u.lastname') {
- global $DB;
-
$students = get_enrolled_users(context_course::instance($this->get_course_id()), 'mod/coursework:submit', 0, $fields);
-
- $sql = "
- SELECT submissions.userid
- FROM {coursework_submissions} submissions
- WHERE submissions.courseworkid = :courseworkid
- AND submissions.finalised = 1
- ";
- $params = array('courseworkid' => $this->id);
- $alreadyfinalised = $DB->get_records_sql($sql, $params);
-
- foreach ($alreadyfinalised as $studentid => $studentrecord) {
- unset ($students[$studentid]);
+ submission::fill_pool_coursework($this->id);
+ $alreadyfinalised = isset(submission::$pool[$this->id]['finalised'][1]) ? submission::$pool[$this->id]['finalised'][1] : [];
+ foreach ($alreadyfinalised as $submission) {
+ unset ($students[$submission->userid]);
}
return $students;
@@ -1742,7 +1850,11 @@ public function renderable_grading_report_factory($report_options) {
if ($this->is_configured_to_have_group_submissions()) {
$report->add_cell(new group_cell($cell_items));
} else {
+ $report->add_cell(new first_name_cell($cell_items));
+ $report->add_cell(new last_name_cell($cell_items));
+ $report->add_cell(new email_cell($cell_items));
$report->add_cell(new user_cell($cell_items));
+ $report->add_cell(new idnumber_cell($cell_items));
}
if ($this->personal_deadlines_enabled()) {
@@ -2330,6 +2442,10 @@ public function get_finalised_submissions(){
$submissions = $DB->get_records('coursework_submissions',
array('courseworkid' => $this->id, 'finalised'=>1), '', 'id');
+ foreach ($submissions as &$submission) {
+ $submission = submission::find($submission);
+ }
+
return $submissions;
}
@@ -2413,10 +2529,11 @@ public function extensions_enabled() {
return (bool)$this->extensionsenabled;
}
- /** Let us know if any extension was granted in the coursework
- * @return bool
- */
+ /*
+* @return bool
+*/
public function extension_exists(){
+
global $DB;
return $DB->record_exists('coursework_extensions',array('courseworkid'=>$this->id));
}
@@ -2513,33 +2630,38 @@ public function get_allocatables_with_feedback($stage, $random = false) {
*
*/
public function create_automatic_feedback() {
+ global $SESSION;
- global $DB;
-
- $module = $DB->get_record('modules',array('name'=>'coursework'));
-
-
- //get all submissions that could need automatic agreement
- $sql = "SELECT DISTINCT(cs.id)
- FROM {coursework} c,
- {coursework_submissions} cs,
- {coursework_feedbacks} cf
- WHERE c.id = cs.courseworkid
- AND cs.id = cf.submissionid
- AND c.numberofmarkers > 1
- AND cs.finalised = 1
- AND cf.stage_identifier NOT LIKE 'final_agreed%'
- AND c.id = :courseworkid
- AND c.automaticagreementstrategy != 'null'
- AND (c.gradeeditingtime = 0 OR c.gradeeditingtime != 0 AND cf.timecreated + c.gradeeditingtime <= :currenttime) ";
-
- $submissionids = $DB->get_records_sql($sql,array('courseworkid'=>$this->id,'currenttime'=>time()));
-
- foreach($submissionids as $s) {
-
- $submission = submission::find(array('id'=>$s->id));
- //check if any feedback for this submission are editable
+ if ($this->numberofmarkers <= 1 || $this->automaticagreementstrategy == 'null') {
+ return;
+ }
+ submission::fill_pool_coursework($this->id);
+ feedback::fill_pool_coursework($this->id);
+ $submissions = isset(submission::$pool[$this->id]['finalised'][1]) ? submission::$pool[$this->id]['finalised'][1] : [];
+ if (empty($submissions)) {
+ return;
+ }
+ $current = time();
+ $gradeeditingtime = $this->gradeeditingtime;
+ $SESSION->keep_cache_data = 1;
+ foreach ($submissions as $submission) {
+ if ($gradeeditingtime != 0) {
+ // initial feedbacks - other feedbacks than final
+ $initial_feedbacks = isset(feedback::$pool[$this->id]['submissionid-stage_identifier_index'][$submission->id . '-others']) ?
+ feedback::$pool[$this->id]['submissionid-stage_identifier_index'][$submission->id . '-others'] : [];
+ $valid_fb = false;
+ foreach ($initial_feedbacks as $feedback) {
+ if ($feedback->timecreated + $gradeeditingtime <= $current) {
+ $valid_fb = true;
+ break;
+ }
+ }
+ if (!$valid_fb) {
+ continue;
+ }
+ }
if (!$submission->editable_feedbacks_exist()) {
+ // this submission needs automatic agreement
$auto_feedback_classname = '\mod_coursework\auto_grader\\' . $submission->get_coursework()->automaticagreementstrategy;
/**
* @var auto_grader $auto_grader
@@ -2551,36 +2673,45 @@ public function create_automatic_feedback() {
}
}
+ unset($SESSION->keep_cache_data);
+ feedback::remove_cache($this->id);
}
+
/** Function to check it Turnitin is enabled for the particular coursework
* @return bool
* @throws \dml_exception
*/
public function tii_enabled(){
- global $CFG, $DB;
- $turnitinenabled = false;
- if ($CFG->enableplagiarism) {
- $plagiarismsettings = (array)get_config('plagiarism');
- if (!empty($plagiarismsettings['turnitin_use'])) {
- $params = array(
- 'cm' => $this->get_coursemodule_id(),
- 'name' => 'use_turnitin',
- 'value' => 1
- );
- if ($DB->record_exists('plagiarism_turnitin_config', $params)) {
- $turnitinenabled = true;
+ if (!isset(self::$pool[$this->id]['tii_enabled'][$this->id])) {
+ global $CFG, $DB;
+ $turnitinenabled = false;
+ if ($CFG->enableplagiarism) {
+ $plagiarismsettings = (array)get_config('plagiarism');
+ if (!empty($plagiarismsettings['turnitin_use'])) {
+ $params = array(
+ 'cm' => $this->get_coursemodule_id(),
+ 'name' => 'use_turnitin',
+ 'value' => 1
+ );
+ if ($DB->record_exists('plagiarism_turnitin_config', $params)) {
+ $turnitinenabled = true;
+ }
}
}
+ self::$pool[$this->id]['tii_enabled'][$this->id] = $turnitinenabled;
}
- return $turnitinenabled;
+ return self::$pool[$this->id]['tii_enabled'][$this->id];
}
+
+
+
/**
* Lets us know if personal deadlines are enabled in the coursework.
* @return bool
@@ -2631,7 +2762,8 @@ private function get_allocatable_personal_deadline($allocatable) {
$allocatable->coursework_id = $this->id;
if ($this->personal_deadlines_enabled()) {
- $deadlinerecord = $DB->get_record('coursework_person_deadlines', array('courseworkid' => $this->id, 'allocatableid' => $allocatable->id));
+ personal_deadline::fill_pool_coursework($this->id);
+ $deadlinerecord = personal_deadline::get_object($this->id, 'allocatableid-allocatabletype', [$allocatable->id, $allocatable->type()]);
if (!empty($deadlinerecord)) {
$allocatable->deadline = $deadlinerecord->personal_deadline;
@@ -2686,7 +2818,6 @@ public function marking_deadline_enabled(){
return (bool)$this->markingdeadlineenabled ;
}
-
/**
* Function to check if a given individual is in the given group
*
@@ -2696,9 +2827,7 @@ public function marking_deadline_enabled(){
* @throws \dml_exception
*/
public function student_in_group($studentid, $groupid){
-
global $DB;
-
$sql = "SELECT groups.*
FROM {groups} groups
INNER JOIN {groups_members} gm
@@ -2706,34 +2835,28 @@ public function student_in_group($studentid, $groupid){
WHERE gm.userid = :userid
AND groups.courseid = :courseid
AND groups.id = :groupid";
-
$params = array('userid' => $studentid,
- 'courseid' => $this->get_course()->id,
- 'groupid' => $groupid);
-
+ 'courseid' => $this->get_course()->id,
+ 'groupid' => $groupid);
return $DB->record_exists_sql($sql, $params);
}
-
/**
* Function to retrieve all submissions by coursework
*
* @return submissions
*/
- function retrieve_submissions_by_coursework() {
+ function retrieve_submissions_by_coursework(){
global $DB;
-
return $DB->get_records('coursework_submissions', ['courseworkid' => $this->id, 'allocatabletype' => 'user']);
}
-
/**
* Function to retrieve all submissions submitted by a user
*
* @param $user_id
* @return submissions
*/
- public function retrieve_submissions_by_user($user_id) {
+ public function retrieve_submissions_by_user($user_id){
global $DB;
-
return $DB->get_records('coursework_submissions', ['courseworkid' => $this->id, 'authorid' => $user_id, 'allocatabletype' => 'user']);
}
@@ -2744,44 +2867,28 @@ public function retrieve_submissions_by_user($user_id) {
* @return feedbacks
*/
public function retrieve_feedbacks_by_submission($submission_id) {
- global $DB;
-
- return $DB->get_records('coursework_feedbacks', ['submissionid' => $submission_id]);
+ feedback::fill_pool_coursework($this->id);
+ $result = isset(feedback::$pool[$this->id][submissionid]) ? feedback::$pool[$this->id][submissionid] : [];
+ return $result;
}
-
/**
* Function to remove all submissions submitted by a user
*
* @param $user_id
*/
- public function remove_submissions_by_user($user_id) {
+ public function remove_submissions_by_user($user_id){
global $DB;
-
$DB->delete_records('coursework_submissions', ['courseworkid' => $this->id, 'authorid' => $user_id, 'allocatabletype' => 'user']);
}
-
/**
* Function to remove all submissions by this coursework
*
* @return submissions
*/
- public function remove_submissions_by_coursework() {
+ public function remove_submissions_by_coursework(){
global $DB;
-
$DB->delete_records('coursework_submissions', ['courseworkid' => $this->id, 'allocatabletype' => 'user']);
}
-
- /**
- * Function to Remove all plagiarisms by a submission
- *
- * @param $submission_id
- */
- public function remove_plagiarisms_by_submission($submission_id) {
- global $DB;
-
- $DB->delete_records('coursework_plagiarism_flags', ['submissionid' => $submission_id]);
- }
-
/**
* Function to Remove the corresponding file by context, item-id and fielarea
*
@@ -2789,76 +2896,258 @@ public function remove_plagiarisms_by_submission($submission_id) {
* @param $item_id
* @param $filearea
*/
- public function remove_corresponding_file($context_id, $item_id, $filearea) {
+ public function remove_corresponding_file($context_id, $item_id, $filearea){
global $DB;
-
- $component = 'mod_coursework';
-
+ $component = 'mod_coursework';
$fs = get_file_storage();
$fs->delete_area_files($context_id, $component, $filearea, $item_id);
}
-
/**
* Function to Remove all feedbacks by a submission
*
* @param $submission_id
*/
- public function remove_feedbacks_by_submission($submission_id) {
+ public function remove_feedbacks_by_submission($submission_id){
global $DB;
-
$DB->delete_records('coursework_feedbacks', ['submissionid' => $submission_id]);
}
-
/**
* Function to Remove all agreements by a feedback
*
* @param $feedback_id
*/
- public function remove_agreements_by_feedback($feedback_id) {
+ public function remove_agreements_by_feedback($feedback_id){
global $DB;
-
$DB->delete_records('coursework_mod_agreements', ['feedbackid' => $feedback_id]);
}
-
/**
* Function to Remove all deadline extensions by user
*
* @param $user_id
*/
- public function remove_deadline_extensions_by_user($user_id) {
+ public function remove_deadline_extensions_by_user($user_id){
global $DB;
-
$DB->execute('DELETE FROM {coursework_extensions} WHERE allocatabletype = ? AND (allocatableid = ? OR allocatableuser = ? ) ', array('user', $user_id, $user_id));
}
+ /**
+ * Function to Remove all personal deadlines by coursework
+ *
+ */
+ public function remove_personal_deadlines_by_coursework() {
+ global $DB;
+ $DB->execute('DELETE FROM {coursework_person_deadlines} WHERE allocatabletype = ? AND courseworkid = ? ', array('user', $this->id));
+ personal_deadline::remove_cache($this->id);
+ }
/**
- * Function to Remove all personal deadlines by user
+ * Function to Remove all deadline extensions by coursework
*
- * @param $user_id
*/
- public function remove_personal_deadlines_by_user($user_id) {
+ public function remove_deadline_extensions_by_coursework(){
+ global $DB;
+ $DB->execute('DELETE FROM {coursework_extensions} WHERE allocatabletype = ? AND courseworkid = ? ', array('user', $this->id));
+ }
+
+
+ /**
+ * Function to check if Coursework has any final feedback
+ *
+ * @return bool
+ * @throws \dml_exception
+ */
+ public function has_any_final_feedback(){
global $DB;
- $DB->execute('DELETE FROM {coursework_person_deadlines} WHERE allocatabletype = ? AND (allocatableid = ? OR allocatableuser = ? ) ', array('user', $user_id, $user_id));
+ $sql = "SELECT *
+ FROM {coursework_feedbacks} cf
+ JOIN {coursework_submissions} cs ON cs.id = cf.submissionid
+ WHERE cs.courseworkid = :courseworkid
+ AND cf.stage_identifier = 'final_agreed_1'";
+
+ return $DB->record_exists_sql($sql, array('courseworkid' => $this->id));
}
/**
- * Function to Remove all deadline extensions by coursework
+ * Tells us the deadline for a specific allocatable.
*
+ * @param int $allocatableid
+ * @return int
+ */
+ public function get_allocatable_deadline($allocatableid) {
+ $deadline = $this->deadline;
+
+ if($this->use_groups){
+ $allocatable = group::find($allocatableid);
+ } else {
+ $allocatable = user::find($allocatableid);
+ }
+
+
+ if ($this->personal_deadlines_enabled()){
+ // find personal deadline for a user if this option enabled
+ $personal = $this->get_allocatable_personal_deadline($allocatable);
+ if (!empty($personal)) {
+ $deadline = $personal->deadline;
+ }
+ }
+
+ if($this->extensions_enabled()){ // check if coursework allows extensions
+ // check if extension for this user exists
+ $extension = $this->get_allocatable_extension($allocatable);
+ if (!empty($extension)) {
+ $deadline = $extension;
+ }
+ }
+
+ return $deadline;
+ }
+
+ /**
+ * * This function returns allocatable extension if given
+ * @param $allocatable
+ * @return bool/int
*/
- public function remove_deadline_extensions_by_coursework() {
+ private function get_allocatable_extension($allocatable) {
+
+ global $DB;
+ $extension = false;
+
+
+ if ($this->extensions_enabled() ) {
+ $extensionrecord = $DB->get_record('coursework_extensions', array('courseworkid' => $this->id,'allocatableid' => $allocatable->id));
+
+ if (!empty($extensionrecord)) {
+ $extension = $extensionrecord->extended_deadline;
+ }
+ }
+
+ return $extension;
+ }
+
+
+ /**
+ * Function to Remove all plagiarisms by a submission
+ *
+ * @param $submission_id
+ */
+ public function remove_plagiarisms_by_submission($submission_id) {
global $DB;
- $DB->execute('DELETE FROM {coursework_extensions} WHERE allocatabletype = ? AND courseworkid = ? ', array('user', $this->id));
+ $DB->delete_records('coursework_plagiarism_flags', ['submissionid' => $submission_id]);
}
+
/**
- * Function to Remove all personal deadlines by coursework
+ * Function to check if Coursework has any submission
*
+ * @return bool
+ * @throws \dml_exception
*/
- public function remove_personal_deadlines_by_coursework() {
+ public function has_any_submission(){
global $DB;
- $DB->execute('DELETE FROM {coursework_person_deadlines} WHERE allocatabletype = ? AND courseworkid = ? ', array('user', $this->id));
+ $sql = "SELECT *
+ FROM {coursework_submissions} cs
+ WHERE cs.courseworkid = :courseworkid";
+
+ return $DB->record_exists_sql($sql, array('courseworkid' => $this->id));
+ }
+
+
+ /**
+ * Function to check if coursework or course that a coursework belongs to is hidden
+ *
+ * @return bool
+ * @throws moodle_exception
+ */
+ public function is_coursework_visible(){
+
+ $visible = true;
+ if ($this->get_course_module()->visible == 0 || $this->get_course()->visible == 0){
+ $visible = false;
+ }
+ return $visible;
+
+ }
+
+ /**
+ * @param null $stage_index
+ */
+ public function clear_stage($stage_index = null) {
+ if ($stage_index) {
+ if (isset($this->stages[$stage_index])) {
+ unset($this->stages[$stage_index]);
+ }
+ } else {
+ $this->stages = [];
+ }
+ }
+
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ * Fill pool to cache for later use
+ *
+ * @param $array
+ */
+ public static function fill_pool($array) {
+ self::$pool = [
+ 'id' => []
+ ];
+
+ foreach ($array as $record) {
+ $object = new self($record);
+ self::$pool['id'][$record->id] = $object;
+ }
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @throws \dml_exception
+ */
+ public static function fill_pool_coursework($coursework_id) {
+ global $DB;
+ if (empty(self::$pool['id'][$coursework_id])) {
+ $courseworks = $DB->get_records('coursework', ['id' => $coursework_id]);
+ self::fill_pool($courseworks);
+ }
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @return bool
+ */
+ public static function get_object($coursework_id) {
+ if (!isset(self::$pool['id'][$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ return self::$pool['id'][$coursework_id] ?? false;
+ }
+
+ /**
+ *
+ */
+ public function fill_cache() {
+ global $DB;
+ $coursework_id = $this->id;
+ submission::fill_pool_coursework($coursework_id);
+ coursework::fill_pool([$this]);
+ course_module::fill_pool([$this->get_course_module()]);
+ module::fill_pool($DB->get_records('modules', ['name' => 'coursework']));
+ feedback::fill_pool_submissions($coursework_id, array_keys(submission::$pool[$coursework_id]['id']));
+ allocation::fill_pool_coursework($coursework_id);
+ plagiarism_flag::fill_pool_coursework($coursework_id);
+ assessment_set_membership::fill_pool_coursework($coursework_id);
+ if (\core_plugin_manager::instance()->get_plugin_info('local_uolw_sits_data_import')) {
+ user::fill_candidate_number_data($this);
+ }
}
}
diff --git a/classes/models/deadline_extension.php b/classes/models/deadline_extension.php
index e12e127..465d9af 100644
--- a/classes/models/deadline_extension.php
+++ b/classes/models/deadline_extension.php
@@ -34,11 +34,9 @@ class deadline_extension extends table_base {
* @return bool
*/
public static function allocatable_extension_allows_submission($allocatable, $coursework) {
- $params = array('allocatabletype' => $allocatable->type(),
- 'allocatableid' => $allocatable->id(),
- 'courseworkid' => $coursework->id,
- );
- $extension = self::find($params);
+ self::fill_pool_coursework($coursework->id);
+ $extension = self::get_object($coursework->id, 'allocatableid-allocatabletype', [$allocatable->id(), $allocatable->type()]);
+
return !empty($extension) && $extension->extended_deadline > time();
}
@@ -54,10 +52,9 @@ public static function get_extension_for_student($student, $coursework) {
$allocatable = $student;
}
if ($allocatable) {
- return static::find(array('courseworkid' => $coursework->id,
- 'allocatableid' => $allocatable->id(),
- 'allocatabletype' => $allocatable->type(),
- ));
+ self::fill_pool_coursework($coursework->id);
+ $extension = self::get_object($coursework->id, 'allocatableid-allocatabletype', [$allocatable->id(), $allocatable->type()]);
+ return $extension;
}
}
@@ -66,7 +63,7 @@ public static function get_extension_for_student($student, $coursework) {
*/
public function get_coursework() {
if (!isset($this->coursework)) {
- $this->coursework = coursework::find($this->courseworkid);
+ $this->coursework = coursework::get_object($this->courseworkid);
}
return $this->coursework;
@@ -84,4 +81,61 @@ protected function pre_save_hook() {
$this->createdbyid = $USER->id;
}
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(static::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'allocatableid-allocatabletype' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['allocatableid-allocatabletype'][$record->allocatableid . '-' . $record->allocatabletype][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
\ No newline at end of file
diff --git a/classes/models/feedback.php b/classes/models/feedback.php
index 723bb4c..89d33b6 100644
--- a/classes/models/feedback.php
+++ b/classes/models/feedback.php
@@ -208,7 +208,8 @@ public function display_assessor_name(){
public function get_assesor_username() {
if (!$this->firstname && !empty($this->lasteditedbyuser)) {
- $this->assessor = core_user::get_user($this->lasteditedbyuser);
+ //$this->assessor = core_user::get_user($this->lasteditedbyuser);
+ $this->assessor = user::get_object($this->lasteditedbyuser);
}
return fullname($this->assessor);
@@ -472,7 +473,12 @@ protected function get_submission_state() {
public function get_submission() {
if (!isset($this->submission) && !empty($this->submissionid)) {
- $this->submission = submission::find($this->submissionid);
+ global $DB;
+ $coursework_id = $this->courseworkid ?? $DB->get_field(submission::$table_name, 'courseworkid', ['id' => $this->submissionid], MUST_EXIST);
+ if (!isset(submission::$pool[$coursework_id])) {
+ submission::fill_pool_coursework($coursework_id);
+ }
+ $this->submission = submission::$pool[$coursework_id]['id'][$this->submissionid] ?? false;
}
return $this->submission;
@@ -546,7 +552,7 @@ public function is_allowed_to_show_comment() {
* @return user
*/
public function assessor() {
- return user::find($this->assessorid);
+ return user::get_object($this->assessorid);
}
/**
@@ -566,5 +572,107 @@ public function get_allocatable() {
public function is_assessor_anonymity_enabled(){
return $this->get_coursework()->assessoranonymity;
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @throws \dml_exception
+ */
+ public static function fill_pool_coursework($coursework_id) {
+ global $DB;
+ if (isset(self::$pool[$coursework_id])) {
+ return;
+ }
+ if (submission::$pool[$coursework_id]) {
+ $submission_ids = submission::$pool[$coursework_id]['id'];
+ } else {
+ $submission_ids = $DB->get_records(submission::$table_name, ['courseworkid' => $coursework_id], '', 'id');
+ }
+ self::fill_pool_submissions($coursework_id, array_keys($submission_ids));
+ }
+
+ /**
+ * @param $coursework_id
+ * @param $submission_ids
+ */
+ public static function fill_pool_submissions($coursework_id, $submission_ids) {
+ global $DB;
+
+ if (isset(self::$pool[$coursework_id])) {
+ return;
+ }
+
+ $key = self::$table_name;
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework_id]);
+
+ $data = $cache->get($key);
+ if ($data === false) {
+ $data = [
+ 'id' => [],
+ 'submissionid-stage_identifier' => [],
+ 'submissionid-stage_identifier_index' => [],
+ 'submissionid-finalised' => [],
+ 'submissionid-ismoderation-isfinalgrade-stage_identifier' => [],
+ 'submissionid-assessorid' => [],
+ 'submissionid' => []
+ ];
+ if ($submission_ids) {
+ list($submission_id_sql, $submission_id_params) = $DB->get_in_or_equal($submission_ids, SQL_PARAMS_NAMED);
+ $feedbacks = $DB->get_records_sql("SELECT * FROM {coursework_feedbacks} WHERE submissionid $submission_id_sql", $submission_id_params);
+ foreach ($feedbacks as $record) {
+ $object = new self($record);
+ $stage_identifier = $record->stage_identifier;
+ $stage_identifier_index = ($stage_identifier == 'final_agreed_1') ? $stage_identifier : 'others';
+ $data['id'][$record->id] = $object;
+ $data['submissionid-stage_identifier'][$record->submissionid . '-' . $stage_identifier][] = $object;
+ $data['submissionid-stage_identifier_index'][$record->submissionid . '-' . $stage_identifier_index][] = $object;
+ $data['submissionid-finalised'][$record->submissionid . '-' . $record->finalised][] = $object;
+ $data['submissionid-ismoderation-isfinalgrade-stage_identifier'][$record->submissionid . '-' . $record->ismoderation . '-' . $record->isfinalgrade . '-' . $stage_identifier][] = $object;
+ $data['submissionid-assessorid'][$record->submissionid . '-' . $record->assessorid][] = $object;
+ $data['submissionid'][$record->submissionid][] = $object;
+ }
+ }
+ $cache->set($key, $data);
+ }
+ self::$pool[$coursework_id] = $data;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ $courseworkid = $this->get_submission()->courseworkid;
+ self::remove_cache($courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ $courseworkid = $this->get_submission()->courseworkid;
+ self::remove_cache($courseworkid);
+ }
}
diff --git a/classes/models/group.php b/classes/models/group.php
index 745936d..e75fc93 100644
--- a/classes/models/group.php
+++ b/classes/models/group.php
@@ -91,4 +91,36 @@ public function profile_link($with_picture = false) {
public function is_valid_for_course($course) {
return $this->courseid == $course->id;
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ * Fill pool to cache for later use
+ *
+ * @param $array
+ */
+ public static function fill_pool($array) {
+ foreach ($array as $record) {
+ $object = new self($record);
+ self::$pool['id'][$record->id] = $object;
+ }
+ }
+
+ /**
+ * @param $id
+ * @return mixed
+ */
+ public static function get_object($id) {
+ if (!isset(self::$pool['id'][$id])) {
+ global $DB;
+ $user = $DB->get_record(self::$table_name, ['id' => $id]);
+ self::$pool['id'][$id] = new self($user);
+ }
+ return self::$pool['id'][$id];
+ }
}
\ No newline at end of file
diff --git a/classes/models/moderation.php b/classes/models/moderation.php
index 1645c3b..2a9debb 100644
--- a/classes/models/moderation.php
+++ b/classes/models/moderation.php
@@ -125,7 +125,7 @@ public function get_submission() {
* @return user
*/
public function moderator() {
- return user::find($this->moderatorid);
+ return user::get_object($this->moderatorid);
}
/**
diff --git a/classes/models/module.php b/classes/models/module.php
new file mode 100644
index 0000000..57739a7
--- /dev/null
+++ b/classes/models/module.php
@@ -0,0 +1,61 @@
+.
+
+namespace mod_coursework\models;
+
+use mod_coursework\framework\table_base;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Represents a row in the modules table.
+ */
+class module extends table_base {
+
+ /**
+ * @var string
+ */
+ protected static $table_name = 'modules';
+
+ /**
+ * @var int
+ */
+ public $id;
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ * Fill pool to cache for later use
+ *
+ * @param $array
+ */
+ public static function fill_pool($array) {
+ self::$pool = [
+ 'id' => [],
+ 'name' => []
+ ];
+ foreach ($array as $record) {
+ $object = new self($record);
+ self::$pool['id'][$record->id] = $object;
+ self::$pool['name'][$record->name] = $object;
+ }
+ }
+}
diff --git a/classes/models/outstanding_marking.php b/classes/models/outstanding_marking.php
index f9e44d6..582b4a8 100644
--- a/classes/models/outstanding_marking.php
+++ b/classes/models/outstanding_marking.php
@@ -120,26 +120,26 @@ private function get_multiple_to_mark_sampled_initial_grade_submissions($coursew
global $DB;
- $sql = " SELECT *,
- IF (a.id IS NULL , 0, COUNT(a.id))+1 AS count_samples,
+ $countsamples = 'CASE WHEN a.id = NULL THEN 0 ELSE COUNT(a.id)+1 END';
+ $sql = " SELECT *,
+ $countsamples AS count_samples,
COUNT(a.id) AS ssmID FROM(
- SELECT cs.id AS csid, f.id AS fid, cs.allocatableid ,ssm.id, COUNT(f.id) AS count_feedback,
+ SELECT cs.id AS csid, f.id AS fid, cs.allocatableid ,ssm.id, COUNT(f.id) AS count_feedback,
cs.courseworkid
FROM {coursework_submissions} cs LEFT JOIN
- {coursework_feedbacks} f ON f.submissionid= cs.id
- LEFT JOIN {coursework_sample_set_mbrs} ssm
- ON cs.courseworkid = ssm.courseworkid AND cs.allocatableid =ssm.allocatableid
+ {coursework_feedbacks} f ON f.submissionid= cs.id
+ LEFT JOIN {coursework_sample_set_mbrs} ssm
+ ON cs.courseworkid = ssm.courseworkid AND cs.allocatableid =ssm.allocatableid
WHERE cs.courseworkid = :courseworkid
-
- AND cs.id NOT IN (SELECT sub.id
- FROM {coursework_feedbacks} feed
- JOIN {coursework_submissions} sub ON sub.id = feed.submissionid
- WHERE assessorid = :subassessorid AND sub.courseworkid= :subcourseworkid)
- GROUP BY cs.allocatableid, ssm.stage_identifier
- ) a
- GROUP BY a.allocatableid
- HAVING (count_feedback < count_samples )";
+ AND cs.id NOT IN (SELECT sub.id
+ FROM {coursework_feedbacks} feed
+ JOIN {coursework_submissions} sub ON sub.id = feed.submissionid
+ WHERE assessorid = :subassessorid AND sub.courseworkid= :subcourseworkid)
+ GROUP BY cs.allocatableid, ssm.stage_identifier, f.id, cs.id, ssm.id
+ ) a
+ GROUP BY a.allocatableid, a.csid, a.fid, a.id, a.count_feedback, a.courseworkid
+ HAVING (count_feedback < $countsamples )";
$sqlparams = array();
$sqlparams['subassessorid'] = $userid;
@@ -192,8 +192,8 @@ private function get_multiple_to_mark_initial_grade_submissions($courseworkid,$u
{coursework_feedbacks} feed JOIN
{coursework_submissions} sub ON sub.id = feed.submissionid
WHERE assessorid = :subassessorid AND sub.courseworkid= :subcourseworkid)
- GROUP BY cs.id
- HAVING (count_feedback < :numofmarkers)";
+ GROUP BY cs.id, f.id
+ HAVING (COUNT(f.id) < :numofmarkers)";
$sqlparams['subassessorid'] = $userid;
@@ -223,7 +223,7 @@ private function get_to_grade_agreed_grade_submissions($courseworkid,$numberofma
AND cs.finalised = 1
AND cs.courseworkid = :courseworkid
GROUP BY cs.id
- HAVING (count_feedback = :numofmarkers)";
+ HAVING (COUNT(cs.id) = :numofmarkers)";
$sqlparams['numofmarkers'] = $numberofmarkers;
@@ -242,21 +242,21 @@ private function get_to_grade_agreed_grade_sampled_submissions($courseworkid) {
global $DB;
- $sql = "SELECT *,
- IF (a.id IS NULL , 0, COUNT(a.id))+1 AS count_samples,
+ $countsamples = 'CASE WHEN a.id = NULL THEN 0 ELSE COUNT(a.id)+1 END';
+ $sql = "SELECT *,
+ $countsamples AS count_samples,
COUNT(a.id) AS ssmID FROM(
- SELECT f.id AS fid, cs.id AS csid, cs.allocatableid ,ssm.id, COUNT(f.id) AS count_feedback,
+ SELECT f.id AS fid, cs.id AS csid, cs.allocatableid ,ssm.id, COUNT(f.id) AS count_feedback,
cs.courseworkid
- FROM mdl_coursework_submissions cs LEFT JOIN
- mdl_coursework_feedbacks f ON f.submissionid= cs.id
- LEFT JOIN `mdl_coursework_sample_set_mbrs` ssm
- ON cs.courseworkid = ssm.courseworkid AND cs.allocatableid =ssm.allocatableid
+ FROM {coursework_submissions} cs LEFT JOIN
+ {coursework_feedbacks} f ON f.submissionid= cs.id
+ LEFT JOIN {coursework_sample_set_mbrs} ssm
+ ON cs.courseworkid = ssm.courseworkid AND cs.allocatableid =ssm.allocatableid
WHERE cs.courseworkid = :courseworkid
- GROUP BY cs.allocatableid, ssm.stage_identifier
+ GROUP BY cs.allocatableid, ssm.stage_identifier, f.id, cs.id, ssm.id
) a
- GROUP BY a.allocatableid
- HAVING (count_feedback = count_samples AND count_samples > 1 );";
-
+ GROUP BY a.allocatableid, a.csid, a.fid, a.id, a.count_feedback, a.courseworkid
+ HAVING (count_feedback = $countsamples AND $countsamples > 1 );";
$sqlparams['courseworkid'] = $courseworkid;
@@ -320,4 +320,4 @@ private function should_get_to_mark_agreed_grade_info($courseworkid,$userid)
return $user_has_agreed_grade_capability;
}
-}
\ No newline at end of file
+}
diff --git a/classes/models/personal_deadline.php b/classes/models/personal_deadline.php
index 120bd3f..c8349b1 100644
--- a/classes/models/personal_deadline.php
+++ b/classes/models/personal_deadline.php
@@ -31,7 +31,8 @@ class personal_deadline extends table_base {
*/
public function get_coursework() {
if (!isset($this->coursework)) {
- $this->coursework = coursework::find($this->courseworkid);
+ coursework::fill_pool_coursework($this->courseworkid);
+ $this->coursework = coursework::get_object($this->courseworkid);
}
return $this->coursework;
@@ -75,4 +76,61 @@ public static function get_personal_deadline_for_student($student, $coursework)
}
}
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(static::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'allocatableid-allocatabletype' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['allocatableid-allocatabletype'][$record->allocatableid . '-' . $record->allocatabletype][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
\ No newline at end of file
diff --git a/classes/models/plagiarism_flag.php b/classes/models/plagiarism_flag.php
index 0d3a4ca..d5e5bf1 100644
--- a/classes/models/plagiarism_flag.php
+++ b/classes/models/plagiarism_flag.php
@@ -39,7 +39,8 @@ class plagiarism_flag extends table_base {
*/
public function get_coursework() {
if (!isset($this->coursework)) {
- $this->coursework = coursework::find($this->courseworkid);
+ coursework::fill_pool_coursework($this->courseworkid);
+ $this->coursework = coursework::get_object($this->courseworkid);
}
return $this->coursework;
@@ -52,7 +53,9 @@ public function get_coursework() {
*/
public function get_submission() {
if (!isset($this->submission) && !empty($this->submissionid)) {
- $this->submission = submission::find($this->submissionid);
+ submission::fill_pool_coursework($this->courseworkid);
+ $this->submission = isset(submission::$pool[$this->courseworkid]['id'][$this->submissionid]) ?
+ submission::$pool[$this->courseworkid]['id'][$this->submissionid] : null;
}
return $this->submission;
@@ -62,8 +65,10 @@ public function get_submission() {
* @param $submission
* @return static
*/
- public static function get_plagiarism_flag($submission){
- return static::find(array('submissionid' => $submission->id));
+ public static function get_plagiarism_flag($submission) {
+ self::fill_pool_coursework($submission->courseworkid);
+ $result = self::get_object($submission->courseworkid, 'submissionid', [$submission->id]);
+ return $result;
}
@@ -86,5 +91,61 @@ public function can_release_grades(){
}
}
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(self::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'submissionid' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['submissionid'][$record->submissionid][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
\ No newline at end of file
diff --git a/classes/models/submission.php b/classes/models/submission.php
index 2829d47..37029ef 100644
--- a/classes/models/submission.php
+++ b/classes/models/submission.php
@@ -50,7 +50,7 @@ class submission extends table_base implements \renderable {
/**
* @var string
*/
- protected static $table_name = 'coursework_submissions';
+ public static $table_name = 'coursework_submissions';
/**
* @var int
@@ -221,7 +221,7 @@ public function __construct($db_record = null) {
// Get the real first and last name from the user table. We use fullname($this), which needs it,
// so we can't lazy-load.
$user = $DB->get_record('user', array('id' => $this->userid));
- $allnames = get_all_user_name_fields();
+ $allnames = \core_user\fields::get_name_fields();
foreach ($allnames as $namefield) {
$this->$namefield = $user->$namefield;
}
@@ -286,7 +286,7 @@ public function has_feedback() {
*/
public function has_disability() {
global $DB;
- $user = $DB->get_record('user', array('id' => $this->userid));
+ $user = user::get_object($this->userid);
return (!empty($user)) ? has_disability($user->username) : false;
}
@@ -428,16 +428,12 @@ public function get_context() {
* @return feedback[] array of raw db records
*/
public function get_feedbacks() {
-
- global $DB;
-
if (!is_array($this->feedbacks)) {
- $conditions = array('submissionid' => $this->id);
// Sort here is on ID so that if there's any need to get the first one chronologically, we can use reset().
- $this->feedbacks = $DB->get_records('coursework_feedbacks', $conditions, 'id');
- foreach ($this->feedbacks as &$feedback) {
- $feedback = new feedback($feedback, $this);
- }
+
+ feedback::fill_pool_coursework($this->courseworkid);
+ $this->feedbacks = isset(feedback::$pool[$this->courseworkid]['submissionid'][$this->id]) ?
+ feedback::$pool[$this->courseworkid]['submissionid'][$this->id] : [];
}
return $this->feedbacks;
@@ -459,40 +455,18 @@ public function get_first_feedback() {
* @return feedback[]
*/
public function get_assessor_feedbacks() {
-
- global $DB;
-
if (!$this->id) {
// No submission - empty placeholder.
return array();
}
- $params = array(
- 'submissionid' => $this->id,
- 'ismoderation' => 0,
- 'isfinalgrade' => 0,
- 'stageidentifier' => 'final_agreed_1'
- );
-
-
- $sql = "SELECT * FROM {coursework_feedbacks}
- WHERE submissionid = :submissionid
- AND ismoderation = :ismoderation
- AND isfinalgrade = :isfinalgrade
- AND stage_identifier <> :stageidentifier
- ORDER BY stage_identifier";
-
- $feedbacks = $DB->get_records_sql($sql, $params);
-
- if (!$feedbacks) {
- $feedbacks = array(); // In case of loops, we want to avoid returning false.
- }
-
- foreach ($feedbacks as &$feedback) {
- $feedback = new feedback($feedback, $this);
+ if (!isset(feedback::$pool[$this->courseworkid]['submissionid-stage_identifier_index'])) {
+ feedback::fill_pool_coursework($this->courseworkid);
}
-
- return $feedbacks;
+ // Get all other feedbacks whose stage_identifier is not "final_agreed_1"
+ // In case of loops, we would like empty array instead of false.
+ $res = feedback::$pool[$this->courseworkid]['submissionid-stage_identifier_index']["$this->id-others"] ?? [];
+ return $res;
}
/**
@@ -502,26 +476,15 @@ public function get_assessor_feedbacks() {
* @throws \dml_multiple_records_exception
*/
public function get_assessor_feedback_by_stage($stage_identifier) {
-
- global $DB;
-
- $params = array(
+ $params = [
'submissionid' => $this->id,
'ismoderation' => 0,
'isfinalgrade' => 0,
- 'stageidentifier' => $stage_identifier
- );
-
-
- $sql = "SELECT * FROM {coursework_feedbacks}
- WHERE submissionid = :submissionid
- AND ismoderation = :ismoderation
- AND isfinalgrade = :isfinalgrade
- AND stage_identifier = :stageidentifier";
-
- $feedback = $DB->get_record_sql($sql, $params);
+ 'stage_identifier' => $stage_identifier
+ ];
+ feedback::fill_pool_coursework($this->courseworkid);
+ $feedback = feedback::get_object($this->courseworkid, 'submissionid-ismoderation-isfinalgrade-stage_identifier', $params);
return $feedback;
-
}
/**
@@ -532,23 +495,12 @@ public function get_assessor_feedback_by_stage($stage_identifier) {
*/
public function get_assessor_allocation_by_stage($stage_identifier) {
- global $DB;
-
- $params = array(
- 'courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->get_allocatable()->id(),
- 'allocatabletype' => $this->get_allocatable()->type(),
- 'stageidentifier' => $stage_identifier
- );
-
-
- $sql = "SELECT * FROM {coursework_allocation_pairs}
- WHERE courseworkid = :courseworkid
- AND allocatableid = :allocatableid
- AND allocatabletype = :allocatabletype
- AND stage_identifier = :stageidentifier";
-
- $allocation = $DB->get_record_sql($sql, $params);
+ $courseworkid = $this->get_coursework()->id;
+ allocation::fill_pool_coursework($courseworkid);
+ $allocation = allocation::get_object(
+ $courseworkid,
+ 'allocatableid-allocatabletype-stage_identifier',
+ [$this->get_allocatable()->id(), $this->get_allocatable()->type(), $stage_identifier]);
return $allocation;
}
@@ -567,26 +519,14 @@ public function get_agreed_grade(){
return array();
}
- $params = array(
+ $params = [
'submissionid' => $this->id,
'ismoderation' => 0,
'isfinalgrade' => 0,
- 'stageidentifier' => 'final_agreed_1'
- );
-
-
- $sql = "SELECT * FROM {coursework_feedbacks}
- WHERE submissionid = :submissionid
- AND ismoderation = :ismoderation
- AND isfinalgrade = :isfinalgrade
- AND stage_identifier = :stageidentifier";
-
- $feedback = $DB->get_record_sql($sql, $params);
- if ($feedback){
- $feedback = new feedback($feedback, $this);
- } else {
- $feedback = false;
- }
+ 'stage_identifier' => 'final_agreed_1'
+ ];
+ feedback::fill_pool_coursework($this->courseworkid);
+ $feedback = feedback::get_object($this->courseworkid, 'submissionid-ismoderation-isfinalgrade-stage_identifier', $params);
return $feedback;
}
@@ -741,7 +681,7 @@ public function get_allocatable_name($as_link = false) {
* @return mixed
*/
public function get_last_updated_by_user() {
- return user::find($this->lastupdatedby);
+ return user::get_object($this->lastupdatedby);
}
/**
@@ -772,7 +712,10 @@ public function is_published() {
public function get_coursework() {
if (empty($this->coursework)) {
- $this->coursework = coursework::find($this->courseworkid);
+ if (!isset(coursework::$pool['id'][$this->courseworkid])) {
+ coursework::fill_pool_coursework($this->courseworkid);
+ }
+ $this->coursework = coursework::$pool['id'][$this->courseworkid];
if (!$this->coursework) {
throw new \coding_exception('Could not find the coursework for submission id '. $this->id);
}
@@ -804,12 +747,16 @@ public function user_has_submitted_feedback($userid = 0) {
$userid = $USER->id;
}
- $params = array('submissionid' => $this->id,
- 'assessorid' => $userid,
- 'isfinalgrade' => 0,
- 'ismoderation' => 0);
- return $DB->record_exists('coursework_feedbacks', $params);
-
+ $params = [
+ 'submissionid' => $this->id,
+ 'assessorid' => $userid
+ ];
+ feedback::fill_pool_coursework($this->courseworkid);
+ $feedback = feedback::get_object($this->courseworkid, 'submissionid-assessorid', $params);
+ if ($feedback && $feedback->isfinalgrade == 0 && $feedback->ismoderation == 0) {
+ return true;
+ }
+ return false;
}
@@ -967,6 +914,10 @@ public function all_inital_graded() {
return $this->get_state() >= submission::FULLY_GRADED;
}
+ public function is_finalised() {
+ return $this->get_state() == submission::FINALISED;
+ }
+
/**
* @return bool
@@ -983,7 +934,7 @@ public function get_allocatable() {
* @var table_base $classname
*/
$classname = "\\mod_coursework\\models\\".$this->allocatabletype;
- return $classname::find($this->allocatableid);
+ return $classname::get_object($this->allocatableid);
}
/**
@@ -1013,7 +964,8 @@ public function ready_to_publish() {
if ($this->get_coursework()->plagiarism_flagging_enbled()) {
// check if not stopped by plagiarism flag
- $plagiarism = plagiarism_flag::find(array('submissionid' => $this->id));
+ plagiarism_flag::fill_pool_coursework($this->courseworkid);
+ $plagiarism = plagiarism_flag::get_object($this->courseworkid, 'submissionid', [$this->id]);
if ($plagiarism && !$plagiarism->can_release_grades()) {
return false;
}
@@ -1091,7 +1043,7 @@ private function get_grades_to_update() {
* @return user|false
*/
public function get_last_submitter() {
- return user::find($this->lastupdatedby);
+ return user::get_object($this->lastupdatedby);
}
/**
@@ -1121,7 +1073,9 @@ public function save_files($files_id) {
$this->id,
$this->coursework->get_file_options());
- $this->rename_files();
+ if (!empty($this->coursework->renamefiles)) {
+ $this->rename_files();
+ }
}
/**
@@ -1193,7 +1147,7 @@ public function time_submitted() {
public function sampled_feedback_exists(){
global $DB;
- return $DB->record_exists('coursework_sample_set_mbrs', array('courseworkid' => $this->coursework->id,
+ return $DB->record_exists('coursework_sample_set_mbrs', array('courseworkid' => $this->courseworkid,
'allocatableid' => $this->get_allocatable()->id(),
'allocatabletype' => $this->get_allocatable()->type()));
@@ -1269,12 +1223,11 @@ private function is_submission_on_behalf(){
* @throws \coding_exception
*/
- public function get_submissions_in_sample(){
- global $DB;
- return $DB->get_records('coursework_sample_set_mbrs', array('courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->allocatableid,
- 'allocatabletype' => $this->allocatabletype));
-
+ public function get_submissions_in_sample() {
+ assessment_set_membership::fill_pool_coursework($this->courseworkid);
+ $records = isset(assessment_set_membership::$pool[$this->courseworkid]['allocatableid-allocatabletype'][$allocatable->id . '-' . $allocatable->type()]) ?
+ assessment_set_membership::$pool[$this->courseworkid]['allocatableid-allocatabletype'][$allocatable->id . '-' . $allocatable->type()] : [];
+ return $records;
}
@@ -1284,14 +1237,14 @@ public function get_submissions_in_sample(){
* @throws \coding_exception
*/
- public function get_submissions_in_sample_by_stage($stage_identifier){
- global $DB;
- return $DB->get_record('coursework_sample_set_mbrs',
- array('courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->allocatableid,
- 'allocatabletype' => $this->allocatabletype,
- 'stage_identifier'=> $stage_identifier));
-
+ public function get_submissions_in_sample_by_stage($stage_identifier) {
+ assessment_set_membership::fill_pool_coursework($this->courseworkid);
+ $record = assessment_set_membership::get_object(
+ $this->courseworkid,
+ 'allocatableid-allocatabletype-stage_identifier',
+ [$this->allocatableid, $this->allocatabletype, $stage_identifier]
+ );
+ return $record;
}
@@ -1301,12 +1254,10 @@ public function get_submissions_in_sample_by_stage($stage_identifier){
* @return bool
* @throws \coding_exception
*/
- public function has_extension(){
- global $DB;
- return $DB->record_exists('coursework_extensions', array('courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->get_allocatable()->id(),
- 'allocatabletype'=> $this->get_allocatable()->type()));
-
+ public function has_extension() {
+ deadline_extension::fill_pool_coursework($this->courseworkid);
+ $extension = deadline_extension::get_object($this->courseworkid, 'allocatableid-allocatabletype', [$this->allocatableid, $this->allocatabletype]);
+ return !empty($extension);
}
/**
@@ -1315,14 +1266,12 @@ public function has_extension(){
* @return mixed
* @throws \coding_exception
*/
- public function submission_extension(){
- global $DB;
- return $DB->get_record('coursework_extensions', array('courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->get_allocatable()->id(),
- 'allocatabletype'=> $this->get_allocatable()->type()));
-
+ public function submission_extension() {
+ deadline_extension::fill_pool_coursework($this->courseworkid);
+ $extension = deadline_extension::get_object($this->courseworkid, 'allocatableid-allocatabletype', [$this->allocatableid, $this->allocatabletype]);
+ return $extension;
}
-
+
/**
* Retrieve details of submission's personal deadline, if not given, use corsework default
*
@@ -1330,18 +1279,17 @@ public function submission_extension(){
* @throws \coding_exception
*/
public function submission_personal_deadline(){
- global $DB;
- $personal_deadline = $DB->get_record('coursework_person_deadlines', array('courseworkid' => $this->get_coursework()->id,
- 'allocatableid' => $this->get_allocatable()->id(),
- 'allocatabletype'=> $this->get_allocatable()->type()));
+ $allocatableid = $this->get_allocatable()->id();
+ $allocatabletype = $this->get_allocatable()->type();
+ $personal_deadline = personal_deadline::get_object($this->courseworkid, 'allocatableid-allocatabletype', [$allocatableid, $allocatabletype]);
if ($personal_deadline){
- $personal_deadline = $personal_deadline->personal_deadline;
+ $personal_deadline = $personal_deadline->personal_deadline;
} else {
$personal_deadline = $this->get_coursework()->deadline;
}
- return $personal_deadline;
+ return $personal_deadline;
}
@@ -1363,25 +1311,22 @@ public function submitted_within_extension(){
public function extension_deadline(){
return $this->submission_extension()->extended_deadline;
}
-
+
/**
* Has assessor graded in any of the initial stages?
*/
- public function is_assessor_initial_grader(){
- global $DB, $USER;
-
-
- $params = array('submissionid' => $this->id,
- 'assessorid' => $USER->id,
- 'stage_identifier' => 'final_agreed_1');
-
- $sql = "SELECT id
- FROM {coursework_feedbacks}
- WHERE submissionid = :submissionid
- AND assessorid = :assessorid
- AND stage_identifier <> :stage_identifier";
+ public function is_assessor_initial_grader() {
+ global $USER;
- return $DB->record_exists_sql($sql, $params);
+ feedback::fill_pool_coursework($this->courseworkid);
+ $feedbacks = isset(feedback::$pool[$this->courseworkid]['submissionid-assessorid'][$this->id . '-' . $USER->id]) ?
+ feedback::$pool[$this->courseworkid]['submissionid-assessorid'][$this->id . '-' . $USER->id] : [];
+ foreach ($feedbacks as $feedback) {
+ if ($feedback->stage_identifier != 'final_agreed_1') {
+ return true;
+ }
+ }
+ return false;
}
@@ -1394,41 +1339,26 @@ public function is_assessor_initial_grader(){
*/
public function editable_feedbacks_exist() {
- global $DB;
-
- $this->get_coursework()->get_grade_editing_time();
- $params = array('submissionid'=>$this->id);
- $extrasql = "";
-
-
- if($this->get_coursework()->get_grade_editing_time() != 0){
- $extrasql = " AND (( cf.timecreated + c.gradeeditingtime > :time
- AND cf.finalised = 1) OR cf.finalised = 0)";
- $params['time'] = time();
- } else{
- $extrasql = " AND cf.finalised = 0";
+ $editablefeedbacks = [];
+ $coursework = $this->get_coursework();
+ if ($coursework->numberofmarkers > 1 && $this->finalised = 1) {
+ $this->get_coursework()->get_grade_editing_time();
+ $gradeeditingtime = $coursework->get_grade_editing_time();
+
+ $editablefeedbacks = isset(feedback::$pool[$coursework->id]['submissionid-finalised'][$this->id . '-0']) ?
+ feedback::$pool[$coursework->id]['submissionid-finalised'][$this->id . '-0'] : [];
+ if ($gradeeditingtime != 0) {
+ $time = time();
+ $finalized_feedbacks = isset(feedback::$pool[$coursework->id]['submissionid-finalised'][$this->id . '-1']) ?
+ feedback::$pool[$coursework->id]['submissionid-finalised'][$this->id . '-1']: [];
+ foreach ($finalized_feedbacks as $feedback) {
+ if ($feedback->timecreated + $gradeeditingtime > $time) {
+ $editablefeedbacks[] = $feedback;
+ }
+ }
+ }
}
-
- $sql = "
- SELECT *
- FROM {coursework} c,
- {coursework_submissions} cs,
- {coursework_feedbacks} cf
- WHERE c.id = cs.courseworkid
- AND cs.id = cf.submissionid
- AND c.numberofmarkers > 1
- AND cs.finalised = 1
- AND cf.stage_identifier NOT LIKE 'final_agreed%'
- AND cs.id = :submissionid
-
-
- $extrasql
-
- ";
-
- $editablefeedbacks = $DB->get_records_sql($sql, $params);
-
return (empty($editablefeedbacks)) ? false : $editablefeedbacks;
}
@@ -1438,44 +1368,25 @@ public function editable_feedbacks_exist() {
*
*/
public function editable_final_feedback_exist() {
-
- global $DB;
-
- $this->get_coursework()->get_grade_editing_time();
- $params = array('submissionid'=>$this->id);
- $extrasql = "";
-
-
- if($this->get_coursework()->get_grade_editing_time() != 0){
- $extrasql = " AND (( cf.timecreated + c.gradeeditingtime > :time
- AND cf.finalised = 1) OR cf.finalised = 0)";
- $params['time'] = time();
- } else {
- $extrasql = " AND cf.finalised = 0";
- }
- if (($this->get_coursework()->has_multiple_markers() && !$this->get_coursework()->sampling_enabled())
- || ($this->get_coursework()->sampling_enabled() && $this->sampled_feedback_exists())){
- $extrasql .= " AND cf.stage_identifier LIKE 'final_agreed%'";
+ if (!isset($this->editable_final_feedback)) {
+ $this->editable_final_feedback = false;
+ if ($this->finalised == 1) {
+
+ $coursework = $this->get_coursework();
+ $final_feedback = feedback::get_object($coursework->id, 'submissionid-stage_identifier', [$this->id, 'final_agreed_1']);
+ if ($final_feedback) {
+ $grade_editing_time = $coursework->get_grade_editing_time();
+ if ($grade_editing_time) {
+ if ($final_feedback->timecreated + $grade_editing_time > time()) {
+ $this->editable_final_feedback = true;
+ }
+ } elseif ($final_feedback->finalised == 0 && $final_feedback->assessorid <> 0) {
+ $this->editable_final_feedback = true;
+ }
+ }
+ }
}
-
-
- $sql = "
- SELECT *
- FROM {coursework} c,
- {coursework_submissions} cs,
- {coursework_feedbacks} cf
- WHERE c.id = cs.courseworkid
- AND cs.id = cf.submissionid
- AND cs.finalised = 1
- AND cs.id = :submissionid
-
- $extrasql
-
- ";
-
- $editablefinalfeedback = $DB->get_record_sql($sql, $params);
-
- return (empty($editablefinalfeedback)) ? false : $editablefinalfeedback;
+ return $this->editable_final_feedback;
}
/**
@@ -1539,13 +1450,8 @@ function any_editable_feedback_exists(){
* @return bool
*/
function has_valid_extension(){
- global $DB;
-
- $valid_extension = false;
- $extension = $DB->get_record('coursework_extensions',
- array('courseworkid' => $this->courseworkid,
- 'allocatableid' => $this->allocatableid,
- 'allocatabletype' => $this->allocatabletype));
+ deadline_extension::fill_pool_coursework($this->courseworkid);
+ $extension = deadline_extension::get_object($this->courseworkid, 'allocatableid-allocatabletype', [$this->allocatableid, $this->allocatabletype]);
if ($extension) {
if ($extension->extended_deadline > time()) {
@@ -1554,4 +1460,90 @@ function has_valid_extension(){
}
return $valid_extension;
}
+
+
+ function can_be_unfinalised() {
+ return ($this->get_state() == submission::FINALISED);
+ }
+
+ /**
+ * check if the feedback by provided assessor exists
+ *
+ * @param $assessorid
+ * @return bool|false|mixed|stdClass
+ * @throws \dml_exception
+ */
+ function has_specific_assessor_feedback($assessorid){
+ global $DB;
+
+ $feedback = $DB->get_record('coursework_feedbacks', array('submissionid'=>$this->id,
+ 'assessorid'=>$assessorid));
+
+ return (empty($feedback)) ? false : $feedback;
+ }
+
+ //caching
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @return array
+ */
+ protected static function get_cache_array($coursework_id) {
+ global $DB;
+ $records = $DB->get_records(static::$table_name, ['courseworkid' => $coursework_id]);
+ $result = [
+ 'id' => [],
+ 'allocatableid' => [],
+ 'finalised' => [],
+ 'allocatableid-allocatabletype' => []
+ ];
+ if ($records) {
+ foreach ($records as $record) {
+ $object = new self($record);
+ $result['id'][$record->id] = $object;
+ $result['allocatableid'][$record->allocatableid][] = $object;
+ $result['finalised'][$record->finalised][] = $object;
+ $result['allocatableid-allocatabletype'][$record->allocatableid . '-' . $record->allocatabletype][] = $object;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param $coursework_id
+ * @param $key
+ * @param $params
+ * @return bool
+ */
+ public static function get_object($coursework_id, $key, $params) {
+ if (!isset(self::$pool[$coursework_id])) {
+ self::fill_pool_coursework($coursework_id);
+ }
+ $value_key = implode('-', $params);
+ return self::$pool[$coursework_id][$key][$value_key][0] ?? false;
+ }
+
+ /**
+ *
+ */
+ protected function post_save_hook() {
+ self::remove_cache($this->courseworkid);
+ }
+
+ /**
+ *
+ */
+ protected function after_destroy() {
+ self::remove_cache($this->courseworkid);
+ }
+
}
diff --git a/classes/models/user.php b/classes/models/user.php
index adb2582..62705e6 100644
--- a/classes/models/user.php
+++ b/classes/models/user.php
@@ -30,7 +30,7 @@ class user extends table_base implements allocatable, moderatable {
* @param bool $data
*/
public function __construct($data = false) {
- $allnames = get_all_user_name_fields();
+ $allnames = \core_user\fields::get_name_fields();
foreach($allnames as $namefield) {
$this->$namefield = '';
}
@@ -112,4 +112,83 @@ public function __toString() {
}
+ /**
+ * cache array
+ *
+ * @var
+ */
+ //public static $pool;
+
+ /**
+ *
+ * @param $coursework_id
+ * @throws \dml_exception
+ */
+ /*
+ public static function fill_pool_coursework($coursework_id) {
+ if (isset(static::$pool[$coursework_id])) {
+ return;
+ }
+ $key = static::$table_name;
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework_id]);
+
+ $data = $cache->get($key);
+ if ($data === false) {
+ // no cache found
+ $data = static::get_cache_array($coursework_id);
+ $cache->set($key, $data);
+ }
+
+ static::$pool[$coursework_id] = $data;
+ }
+ */
+
+ /**
+ * @param $coursework_id
+ */
+ /*
+ public static function remove_cache($coursework_id) {
+ global $SESSION;
+ if (!empty($SESSION->keep_cache_data)) {
+ return;
+ }
+ static::$pool[$coursework_id] = null;
+ $cache = \cache::make('mod_coursework', 'courseworkdata', ['id' => $coursework_id]);
+ $cache->delete(static::$table_name);
+ }
+ */
+
+ /**
+ * cache array
+ *
+ * @var
+ */
+ public static $pool;
+
+ /**
+ * Fill pool to cache for later use
+ *
+ * @param $array
+ */
+ public static function fill_pool($array) {
+ foreach ($array as $record) {
+ $object = new self($record);
+ self::$pool['id'][$record->id] = $object;
+ }
+ }
+
+ /**
+ * @param $id
+ * @return mixed
+ */
+ public static function get_object($id) {
+ if (!isset(self::$pool['id'][$id])) {
+ global $DB;
+ $user = $DB->get_record(self::$table_name, ['id' => $id]);
+ self::$pool['id'][$id] = new self($user);
+ }
+ return self::$pool['id'][$id];
+ }
+
+
}
\ No newline at end of file
diff --git a/classes/observer.php b/classes/observer.php
index a4287fc..66cecc7 100644
--- a/classes/observer.php
+++ b/classes/observer.php
@@ -77,4 +77,23 @@ public static function process_allocations_when_group_member_added(\core\event\g
public static function process_allocations_when_group_member_removed(\core\event\group_member_removed $event){
course_group_member_removed($event);
}
+
+ /**
+ * @param \core\event\role_assigned $event
+ */
+ public static function add_teacher_to_dropdown_when_enrolled(core\event\role_assigned$event){
+ teacher_allocation_cache_purge($event);
+
+ }
+
+ /**
+ * @param \core\event\role_unassigned $event
+ */
+ public static function remove_teacher_from_dropdown_when_unenrolled(core\event\role_unassigned$event){
+ teacher_removed_allocated_not_graded($event);
+ teacher_allocation_cache_purge($event);
+
+ }
+
+
}
\ No newline at end of file
diff --git a/classes/personal_deadline/table/row/builder.php b/classes/personal_deadline/table/row/builder.php
index 7e0488d..0f9f3a8 100644
--- a/classes/personal_deadline/table/row/builder.php
+++ b/classes/personal_deadline/table/row/builder.php
@@ -142,6 +142,37 @@ public function get_student_lastname() {
return $this->get_allocatable()->lastname;
}
+ /**
+ * @return string
+ */
+ public function get_idnumber() {
+
+ global $DB;
+
+ $allocatable = $this->get_allocatable();
+ if (empty($allocatable->idnumber)) {
+ $this->allocatable = user::find($allocatable);
+ }
+
+ return $this->get_allocatable()->idnumber;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function get_email() {
+
+ global $DB;
+
+ $allocatable = $this->get_allocatable();
+ if (empty($allocatable->email)) {
+ $this->allocatable = user::find($allocatable);
+ }
+
+ return $this->get_allocatable()->email;
+ }
+
/**
* Getter for personal deadline time
*
@@ -168,6 +199,28 @@ public function get_personal_deadlines() {
return $personal_deadline;
}
+
+
+ public function get_submission_status() {
+ global $DB;
+
+ $submission_db = $DB->get_record('coursework_submissions',
+ array('courseworkid' => $this->get_coursework()->id,
+ 'allocatableid' => $this->allocatable->id(),
+ 'allocatabletype'=> $this->allocatable->type()));
+
+ $submission = \mod_coursework\models\submission::find($submission_db);
+
+ $statustext = get_string('statusnotsubmitted','mod_coursework');
+
+ if (!empty($submission) && $submission->is_finalised()) {
+ $statustext = get_string('finalisedsubmission','mod_coursework');
+ } else if (!empty($submission)) {
+ $statustext = $submission->get_status_text();
+ }
+
+ return $statustext;
+ }
}
diff --git a/classes/plagiarism_helpers/turnitin.php b/classes/plagiarism_helpers/turnitin.php
index e206670..ca03191 100644
--- a/classes/plagiarism_helpers/turnitin.php
+++ b/classes/plagiarism_helpers/turnitin.php
@@ -25,8 +25,8 @@ public function enabled() {
global $DB, $CFG;
if ($CFG->enableplagiarism) {
- $plagiarismsettings = (array)get_config('plagiarism');
- if (!empty($plagiarismsettings['turnitin_use'])) {
+ $plagiarismsettings = (array)get_config('plagiarism_turnitin');
+ if (!empty($plagiarismsettings['enabled'])) {
$params = array(
'cm' => $this->get_coursework()->get_course_module()->id,
'name' => 'use_turnitin',
diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php
index 20a7837..96537ec 100644
--- a/classes/privacy/provider.php
+++ b/classes/privacy/provider.php
@@ -13,11 +13,8 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see