/** * Default implementation of file_get_info for plugins. * This is used by the filebrowser to browse a plugins file areas. * * This implementation should work for most plugins but can be overridden if required. * @param file_browser $browser * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return file_info_stored */ public function get_file_info($browser, $filearea, $itemid, $filepath, $filename) { global $CFG, $DB, $USER; $urlbase = $CFG->wwwroot . '/pluginfile.php'; // Permission check on the itemid. if ($this->get_subtype() == 'assignsubmission') { if ($itemid) { $record = $DB->get_record('assign_submission', array('id' => $itemid), 'userid', IGNORE_MISSING); if (!$record) { return null; } if (!$this->assignment->can_view_submission($record->userid)) { return null; } } } else { // Not supported for feedback plugins. return null; } $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; if (!($storedfile = $fs->get_file($this->assignment->get_context()->id, $this->get_subtype() . '_' . $this->get_type(), $filearea, $itemid, $filepath, $filename))) { return null; } return new file_info_stored($browser, $this->assignment->get_context(), $storedfile, $urlbase, $filearea, $itemid, true, true, false); }
/** * list current marker * * @param stdClass $row - The row of data * @return id the user->id of the marker. */ public function col_allocatedmarker(stdClass $row) { static $markers = null; static $markerlist = array(); if ($markers === null) { $markers = get_users_by_capability($this->assignment->get_context(), 'mod/assign:grade'); $markerlist[0] = get_string('choosemarker', 'assign'); foreach ($markers as $marker) { $markerlist[$marker->id] = fullname($marker); } } if (empty($markerlist)) { // TODO: add some form of notification here that no markers are available. return ''; } if ($this->is_downloading()) { return $markers[$row->allocatedmarker]; } if ($this->quickgrading && has_capability('mod/assign:manageallocations', $this->assignment->get_context()) && (empty($row->workflowstate) || $row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_INMARKING || $row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED)) { $name = 'quickgrade_' . $row->id . '_allocatedmarker'; return html_writer::select($markerlist, $name, $row->allocatedmarker, false); } else if (!empty($row->allocatedmarker)) { $output = ''; if ($this->quickgrading) { // Add hidden field for quickgrading page. $name = 'quickgrade_' . $row->id . '_allocatedmarker'; $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$name, 'value'=>$row->allocatedmarker)); } $output .= $markerlist[$row->allocatedmarker]; return $output; } }
/** * Create instance of event. * * @param \assign $assign * @param \stdClass $submission * @return submission_viewed */ public static function create_from_submission(\assign $assign, \stdClass $submission) { $data = array('objectid' => $submission->id, 'relateduserid' => $submission->userid, 'context' => $assign->get_context(), 'other' => array('assignid' => $assign->get_instance()->id)); /** @var submission_viewed $event */ $event = self::create($data); $event->set_assign($assign); $event->add_record_snapshot('assign_submission', $submission); return $event; }
/** * Create instance of event. * * @param \assign $assign * @return batch_set_marker_allocation_viewed */ public static function create_from_assign(\assign $assign) { $data = array('context' => $assign->get_context(), 'other' => array('assignid' => $assign->get_instance()->id)); self::$preventcreatecall = false; /** @var batch_set_marker_allocation_viewed $event */ $event = self::create($data); self::$preventcreatecall = true; $event->set_assign($assign); return $event; }
/** * Create instance of event. * * @since Moodle 2.7 * * @param \assign $assign * @return all_submissions_downloaded */ public static function create_from_assign(\assign $assign) { $data = array('context' => $assign->get_context(), 'objectid' => $assign->get_instance()->id); self::$preventcreatecall = false; /** @var submission_graded $event */ $event = self::create($data); self::$preventcreatecall = true; $event->set_assign($assign); return $event; }
/** * Set assign instance for this event. * @param \assign $assign * @throws \coding_exception */ public function set_assign(\assign $assign) { if ($this->is_triggered()) { throw new \coding_exception('set_assign() must be done before triggerring of event'); } if ($assign->get_context()->id != $this->get_context()->id) { throw new \coding_exception('Invalid assign isntance supplied!'); } $this->assign = $assign; }
/** * Create instance of event. * * @since Moodle 2.7 * * @param \assign $assign * @param \stdClass $grade * @return submission_graded */ public static function create_from_grade(\assign $assign, \stdClass $grade) { $data = array('context' => $assign->get_context(), 'objectid' => $grade->id, 'relateduserid' => $grade->userid); self::$preventcreatecall = false; /** @var submission_graded $event */ $event = self::create($data); self::$preventcreatecall = true; $event->set_assign($assign); $event->add_record_snapshot('assign_grades', $grade); return $event; }
/** * Create instance of event. * * @since Moodle 2.7 * * @param \assign $assign * @param \stdClass $submission * @return statement_accepted */ public static function create_from_submission(\assign $assign, \stdClass $submission) { $data = array('context' => $assign->get_context(), 'objectid' => $submission->id); self::$preventcreatecall = false; /** @var statement_accepted $event */ $event = self::create($data); self::$preventcreatecall = true; $event->set_assign($assign); $event->add_record_snapshot('assign_submission', $submission); return $event; }
/** * Create instance of event. * * @since Moodle 2.7 * * @param \assign $assign * @param \stdClass $user * @return submission_locked */ public static function create_from_user(\assign $assign, \stdClass $user) { $data = array('context' => $assign->get_context(), 'objectid' => $assign->get_instance()->id, 'relateduserid' => $user->id); self::$preventcreatecall = false; /** @var submission_locked $event */ $event = self::create($data); self::$preventcreatecall = true; $event->set_assign($assign); $event->add_record_snapshot('user', $user); return $event; }
/** * Create instance of event. * * @since Moodle 2.7 * * @param \assign $assign * @param \stdClass $submission * @param bool $editable * @return assessable_submitted */ public static function create_from_submission(\assign $assign, \stdClass $submission, $editable) { global $USER; $data = array('context' => $assign->get_context(), 'objectid' => $submission->id, 'other' => array('submission_editable' => $editable)); if (!empty($submission->userid) && $submission->userid != $USER->id) { $data['relateduserid'] = $submission->userid; } /** @var assessable_submitted $event */ $event = self::create($data); $event->set_assign($assign); $event->add_record_snapshot('assign_submission', $submission); return $event; }
/** * File browsing support for assign module. * * @param file_browser $browser * @param object $areas * @param object $course * @param object $cm * @param object $context * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return object file_info instance or null if not found */ function assign_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG; require_once $CFG->dirroot . '/mod/assign/locallib.php'; if ($context->contextlevel != CONTEXT_MODULE) { return null; } $urlbase = $CFG->wwwroot . '/pluginfile.php'; $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; // Need to find where this belongs to. $assignment = new assign($context, $cm, $course); if ($filearea === ASSIGN_INTROATTACHMENT_FILEAREA) { if (!has_capability('moodle/course:managefiles', $context)) { // Students can not peak here! return null; } if (!($storedfile = $fs->get_file($assignment->get_context()->id, 'mod_assign', $filearea, 0, $filepath, $filename))) { return null; } return new file_info_stored($browser, $assignment->get_context(), $storedfile, $urlbase, $filearea, $itemid, true, true, false); } $pluginowner = null; foreach ($assignment->get_submission_plugins() as $plugin) { if ($plugin->is_visible()) { $pluginareas = $plugin->get_file_areas(); if (array_key_exists($filearea, $pluginareas)) { $pluginowner = $plugin; break; } } } if (!$pluginowner) { foreach ($assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible()) { $pluginareas = $plugin->get_file_areas(); if (array_key_exists($filearea, $pluginareas)) { $pluginowner = $plugin; break; } } } } if (!$pluginowner) { return null; } $result = $pluginowner->get_file_info($browser, $filearea, $itemid, $filepath, $filename); return $result; }
/** * This function copies annotations and comments from the source user * to the current group member being processed when using applytoall. * @param int|\assign $assignment * @param stdClass $grade * @param int $sourceuserid * @return bool */ public static function copy_drafts_from_to($assignment, $grade, $sourceuserid) { global $DB; // Delete any existing annotations and comments from current user. $DB->delete_records('assignfeedback_editpdf_annot', array('gradeid' => $grade->id)); $DB->delete_records('assignfeedback_editpdf_cmnt', array('gradeid' => $grade->id)); // Get gradeid, annotations and comments from sourceuserid. $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); // Add annotations and comments to current user to generate feedback file. foreach ($annotations as $annotation) { $annotation->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_annot', $annotation); } foreach ($comments as $comment) { $comment->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_cmnt', $comment); } // Delete the existing stamps and copy the source ones. $fs = get_file_storage(); $fs->delete_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $grade->id); if ($files = $fs->get_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $sourceusergrade->id, "filename", false)) { foreach ($files as $file) { $newrecord = new \stdClass(); $newrecord->contextid = $assignment->get_context()->id; $newrecord->itemid = $grade->id; $fs->create_file_from_storedfile($newrecord, $file); } } return true; }
function urkund_reset_file($id) { global $DB, $CFG; $plagiarismfile = $DB->get_record('plagiarism_urkund_files', array('id' => $id), '*', MUST_EXIST); if ($plagiarismfile->statuscode == 'Analyzed' || $plagiarismfile->statuscode == URKUND_STATUSCODE_ACCEPTED) { // Sanity Check. return true; } // Set some new values. $plagiarismfile->statuscode = 'pending'; $plagiarismfile->attempt = 0; $plagiarismfile->timesubmitted = time(); $cm = get_coursemodule_from_id('', $plagiarismfile->cm); $modulecontext = context_module::instance($plagiarismfile->cm); $fs = get_file_storage(); if ($cm->modname == 'assignment') { $submission = $DB->get_record('assignment_submissions', array('assignment' => $cm->instance, 'userid' => $plagiarismfile->userid)); $files = $fs->get_area_files($modulecontext->id, 'mod_assignment', 'submission', $submission->id); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { $DB->update_record('plagiarism_urkund_files', $plagiarismfile); // Update before trying to send again. return urkund_send_file($plagiarismfile->cm, $plagiarismfile->userid, $file, plagiarism_plugin_urkund::get_settings()); } } } else { if ($cm->modname == 'assign') { require_once $CFG->dirroot . '/mod/assign/locallib.php'; $assign = new assign($modulecontext, null, null); $submissionplugins = $assign->get_submission_plugins(); $dbparams = array('assignment' => $assign->get_instance()->id, 'userid' => $plagiarismfile->userid); $submissions = $DB->get_records('assign_submission', $dbparams); foreach ($submissions as $submission) { foreach ($submissionplugins as $submissionplugin) { $component = $submissionplugin->get_subtype() . '_' . $submissionplugin->get_type(); $fileareas = $submissionplugin->get_file_areas(); foreach ($fileareas as $filearea => $name) { $files = $fs->get_area_files($assign->get_context()->id, $component, $filearea, $submission->id, "timemodified", false); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { $DB->update_record('plagiarism_urkund_files', $plagiarismfile); // Update before trying to send again. return urkund_send_file($plagiarismfile->cm, $plagiarismfile->userid, $file, plagiarism_plugin_urkund::get_settings()); } } } } } } else { if ($cm->modname == 'workshop') { require_once $CFG->dirroot . '/mod/workshop/locallib.php'; $cm = get_coursemodule_from_id('workshop', $plagiarismfile->cm, 0, false, MUST_EXIST); $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $workshop = new workshop($workshop, $cm, $course); $submissions = $workshop->get_submissions($plagiarismfile->userid); foreach ($submissions as $submission) { $files = $fs->get_area_files($workshop->context->id, 'mod_workshop', 'submission_attachment', $submission->id); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { $DB->update_record('plagiarism_urkund_files', $plagiarismfile); // Update before trying to send again. return urkund_send_file($plagiarismfile->cm, $plagiarismfile->userid, $file, plagiarism_plugin_urkund::get_settings()); } } } } else { if ($cm->modname == 'forum') { require_once $CFG->dirroot . '/mod/forum/lib.php'; $cm = get_coursemodule_from_id('forum', $plagiarismfile->cm, 0, false, MUST_EXIST); $posts = forum_get_user_posts($cm->instance, $plagiarismfile->userid); foreach ($posts as $post) { $files = $fs->get_area_files($modulecontext->id, 'mod_forum', 'attachment', $post->id, "timemodified", false); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { $DB->update_record('plagiarism_urkund_files', $plagiarismfile); // Update before trying to send again. return urkund_send_file($plagiarismfile->cm, $plagiarismfile->userid, $file, plagiarism_plugin_urkund::get_settings()); } } } } } } } }
/** * This function converts all of the base settings for an instance of * the old assignment to the new format. Then it calls each of the plugins * to see if they can help upgrade this assignment. * @param int $oldassignmentid (don't rely on the old assignment type even being installed) * @param string $log This string gets appended to during the conversion process * @return bool true or false */ public function upgrade_assignment($oldassignmentid, &$log) { global $DB, $CFG, $USER; // Steps to upgrade an assignment. // Is the user the admin? admin check goes here. if (!is_siteadmin($USER->id)) { return false; } core_php_time_limit::raise(ASSIGN_MAX_UPGRADE_TIME_SECS); // Get the module details. $oldmodule = $DB->get_record('modules', array('name' => 'assignment'), '*', MUST_EXIST); $params = array('module' => $oldmodule->id, 'instance' => $oldassignmentid); $oldcoursemodule = $DB->get_record('course_modules', $params, '*', MUST_EXIST); $oldcontext = context_module::instance($oldcoursemodule->id); // First insert an assign instance to get the id. $oldassignment = $DB->get_record('assignment', array('id' => $oldassignmentid), '*', MUST_EXIST); $oldversion = get_config('assignment_' . $oldassignment->assignmenttype, 'version'); $data = new stdClass(); $data->course = $oldassignment->course; $data->name = $oldassignment->name; $data->intro = $oldassignment->intro; $data->introformat = $oldassignment->introformat; $data->alwaysshowdescription = 1; $data->sendnotifications = $oldassignment->emailteachers; $data->sendlatenotifications = $oldassignment->emailteachers; $data->duedate = $oldassignment->timedue; $data->allowsubmissionsfromdate = $oldassignment->timeavailable; $data->grade = $oldassignment->grade; $data->submissiondrafts = $oldassignment->resubmit; $data->requiresubmissionstatement = 0; $data->markingworkflow = 0; $data->markingallocation = 0; $data->cutoffdate = 0; // New way to specify no late submissions. if ($oldassignment->preventlate) { $data->cutoffdate = $data->duedate; } $data->teamsubmission = 0; $data->requireallteammemberssubmit = 0; $data->teamsubmissiongroupingid = 0; $data->blindmarking = 0; $data->attemptreopenmethod = 'none'; $data->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS; $newassignment = new assign(null, null, null); if (!$newassignment->add_instance($data, false)) { $log = get_string('couldnotcreatenewassignmentinstance', 'mod_assign'); return false; } // Now create a new coursemodule from the old one. $newmodule = $DB->get_record('modules', array('name' => 'assign'), '*', MUST_EXIST); $newcoursemodule = $this->duplicate_course_module($oldcoursemodule, $newmodule->id, $newassignment->get_instance()->id); if (!$newcoursemodule) { $log = get_string('couldnotcreatenewcoursemodule', 'mod_assign'); return false; } // Convert the base database tables (assignment, submission, grade). // These are used to store information in case a rollback is required. $gradingarea = null; $gradingdefinitions = null; $gradeidmap = array(); $completiondone = false; $gradesdone = false; // From this point we want to rollback on failure. $rollback = false; try { $newassignment->set_context(context_module::instance($newcoursemodule->id)); // The course module has now been created - time to update the core tables. // Copy intro files. $newassignment->copy_area_files_for_upgrade($oldcontext->id, 'mod_assignment', 'intro', 0, $newassignment->get_context()->id, 'mod_assign', 'intro', 0); // Get the plugins to do their bit. foreach ($newassignment->get_submission_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { $plugin->enable(); if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) { $rollback = true; } } else { $plugin->disable(); } } foreach ($newassignment->get_feedback_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { $plugin->enable(); if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) { $rollback = true; } } else { $plugin->disable(); } } // See if there is advanced grading upgrades required. $gradingarea = $DB->get_record('grading_areas', array('contextid' => $oldcontext->id, 'areaname' => 'submission'), '*', IGNORE_MISSING); if ($gradingarea) { $params = array('id' => $gradingarea->id, 'contextid' => $newassignment->get_context()->id, 'component' => 'mod_assign', 'areaname' => 'submissions'); $DB->update_record('grading_areas', $params); $gradingdefinitions = $DB->get_records('grading_definitions', array('areaid' => $gradingarea->id)); } // Upgrade availability data. \core_availability\info::update_dependency_id_across_course($newcoursemodule->course, 'course_modules', $oldcoursemodule->id, $newcoursemodule->id); // Upgrade completion data. $DB->set_field('course_modules_completion', 'coursemoduleid', $newcoursemodule->id, array('coursemoduleid' => $oldcoursemodule->id)); $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $oldcoursemodule->id)); foreach ($allcriteria as $criteria) { $criteria->module = 'assign'; $criteria->moduleinstance = $newcoursemodule->id; $DB->update_record('course_completion_criteria', $criteria); } $completiondone = true; // Migrate log entries so we don't lose them. $logparams = array('cmid' => $oldcoursemodule->id, 'course' => $oldcoursemodule->course); $DB->set_field('log', 'module', 'assign', $logparams); $DB->set_field('log', 'cmid', $newcoursemodule->id, $logparams); // Copy all the submission data (and get plugins to do their bit). $oldsubmissions = $DB->get_records('assignment_submissions', array('assignment' => $oldassignmentid)); foreach ($oldsubmissions as $oldsubmission) { $submission = new stdClass(); $submission->assignment = $newassignment->get_instance()->id; $submission->userid = $oldsubmission->userid; $submission->timecreated = $oldsubmission->timecreated; $submission->timemodified = $oldsubmission->timemodified; $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; $submission->id = $DB->insert_record('assign_submission', $submission); if (!$submission->id) { $log .= get_string('couldnotinsertsubmission', 'mod_assign', $submission->userid); $rollback = true; } foreach ($newassignment->get_submission_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { if (!$plugin->upgrade($oldcontext, $oldassignment, $oldsubmission, $submission, $log)) { $rollback = true; } } } if ($oldsubmission->timemarked) { // Submission has been graded - create a grade record. $grade = new stdClass(); $grade->assignment = $newassignment->get_instance()->id; $grade->userid = $oldsubmission->userid; $grade->grader = $oldsubmission->teacher; $grade->timemodified = $oldsubmission->timemarked; $grade->timecreated = $oldsubmission->timecreated; $grade->grade = $oldsubmission->grade; if ($oldsubmission->mailed) { // The mailed flag goes in the flags table. $flags = new stdClass(); $flags->userid = $oldsubmission->userid; $flags->assignment = $newassignment->get_instance()->id; $flags->mailed = 1; $DB->insert_record('assign_user_flags', $flags); } $grade->id = $DB->insert_record('assign_grades', $grade); if (!$grade->id) { $log .= get_string('couldnotinsertgrade', 'mod_assign', $grade->userid); $rollback = true; } // Copy any grading instances. if ($gradingarea) { $gradeidmap[$grade->id] = $oldsubmission->id; foreach ($gradingdefinitions as $definition) { $params = array('definitionid' => $definition->id, 'itemid' => $oldsubmission->id); $DB->set_field('grading_instances', 'itemid', $grade->id, $params); } } foreach ($newassignment->get_feedback_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { if (!$plugin->upgrade($oldcontext, $oldassignment, $oldsubmission, $grade, $log)) { $rollback = true; } } } } } $newassignment->update_calendar($newcoursemodule->id); // Reassociate grade_items from the old assignment instance to the new assign instance. // This includes outcome linked grade_items. $params = array('assign', $newassignment->get_instance()->id, 'assignment', $oldassignment->id); $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?'; $DB->execute($sql, $params); // Create a mapping record to map urls from the old to the new assignment. $mapping = new stdClass(); $mapping->oldcmid = $oldcoursemodule->id; $mapping->oldinstance = $oldassignment->id; $mapping->newcmid = $newcoursemodule->id; $mapping->newinstance = $newassignment->get_instance()->id; $mapping->timecreated = time(); $DB->insert_record('assignment_upgrade', $mapping); $gradesdone = true; } catch (Exception $exception) { $rollback = true; $log .= get_string('conversionexception', 'mod_assign', $exception->getMessage()); } if ($rollback) { // Roll back the grades changes. if ($gradesdone) { // Reassociate grade_items from the new assign instance to the old assignment instance. $params = array('assignment', $oldassignment->id, 'assign', $newassignment->get_instance()->id); $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?'; $DB->execute($sql, $params); } // Roll back the completion changes. if ($completiondone) { $DB->set_field('course_modules_completion', 'coursemoduleid', $oldcoursemodule->id, array('coursemoduleid' => $newcoursemodule->id)); $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $newcoursemodule->id)); foreach ($allcriteria as $criteria) { $criteria->module = 'assignment'; $criteria->moduleinstance = $oldcoursemodule->id; $DB->update_record('course_completion_criteria', $criteria); } } // Roll back the log changes. $logparams = array('cmid' => $newcoursemodule->id, 'course' => $newcoursemodule->course); $DB->set_field('log', 'module', 'assignment', $logparams); $DB->set_field('log', 'cmid', $oldcoursemodule->id, $logparams); // Roll back the advanced grading update. if ($gradingarea) { foreach ($gradeidmap as $newgradeid => $oldsubmissionid) { foreach ($gradingdefinitions as $definition) { $DB->set_field('grading_instances', 'itemid', $oldsubmissionid, array('definitionid' => $definition->id, 'itemid' => $newgradeid)); } } $params = array('id' => $gradingarea->id, 'contextid' => $oldcontext->id, 'component' => 'mod_assignment', 'areaname' => 'submission'); $DB->update_record('grading_areas', $params); } $newassignment->delete_instance(); return false; } // Delete the old assignment (use object delete). $cm = get_coursemodule_from_id('', $oldcoursemodule->id, $oldcoursemodule->course); if ($cm) { course_delete_module($cm->id); } rebuild_course_cache($oldcoursemodule->course); return true; }
/** * Process an uploaded zip file * * @param assign $assignment - The assignment instance * @param assign_feedback_file $fileplugin - The file feedback plugin * @return string - The html response */ public function import_zip_files($assignment, $fileplugin) { global $USER, $CFG, $PAGE, $DB; @set_time_limit(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); $packer = get_file_packer('application/zip'); $feedbackfilesupdated = 0; $feedbackfilesadded = 0; $userswithnewfeedback = array(); $contextid = $assignment->get_context()->id; $fs = get_file_storage(); $files = $fs->get_directory_files($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, $USER->id, '/import/'); $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); $allusers = $assignment->list_participants($currentgroup, false); $participants = array(); foreach ($allusers as $user) { $participants[$assignment->get_uniqueid_for_user($user->id)] = $user; } foreach ($files as $unzippedfile) { // Set the timeout for unzipping each file. $user = null; $plugin = null; $filename = ''; if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { $grade = $assignment->get_user_grade($user->id, true); if ($oldfile = $fs->get_file($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_FILEAREA, $grade->id, '/', $filename)) { // Update existing feedback file. $oldfile->replace_content_with($unzippedfile); $feedbackfilesupdated++; } else { // Create a new feedback file. $newfilerecord = new stdClass(); $newfilerecord->contextid = $contextid; $newfilerecord->component = 'assignfeedback_file'; $newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA; $newfilerecord->filename = $filename; $newfilerecord->filepath = '/'; $newfilerecord->itemid = $grade->id; $fs->create_file_from_storedfile($newfilerecord, $unzippedfile); $feedbackfilesadded++; } $userswithnewfeedback[$user->id] = 1; // Update the number of feedback files for this user. $fileplugin->update_file_count($grade); // Update the last modified time on the grade which will trigger student notifications. $assignment->notify_grade_modified($grade); } } } require_once($CFG->dirroot . '/mod/assign/feedback/file/renderable.php'); $importsummary = new assignfeedback_file_import_summary($assignment->get_course_module()->id, count($userswithnewfeedback), $feedbackfilesadded, $feedbackfilesupdated); $assignrenderer = $assignment->get_renderer(); $renderer = $PAGE->get_renderer('assignfeedback_file'); $o = ''; $o .= $assignrenderer->render(new assign_header($assignment->get_instance(), $assignment->get_context(), false, $assignment->get_course_module()->id, get_string('uploadzipsummary', 'assignfeedback_file'))); $o .= $renderer->render($importsummary); $o .= $assignrenderer->render_footer(); return $o; }
/** * Returns submissions for the requested assignment ids * * @param int[] $assignmentids * @param string $status only return submissions with this status * @param int $since only return submissions with timemodified >= since * @param int $before only return submissions with timemodified <= before * @return array of submissions for each requested assignment * @since Moodle 2.5 */ public static function get_submissions($assignmentids, $status = '', $since = 0, $before = 0) { global $DB, $CFG; require_once "{$CFG->dirroot}/mod/assign/locallib.php"; $params = self::validate_parameters(self::get_submissions_parameters(), array('assignmentids' => $assignmentids, 'status' => $status, 'since' => $since, 'before' => $before)); $warnings = array(); $assignments = array(); // Check the user is allowed to get the submissions for the assignments requested. $placeholders = array(); list($inorequalsql, $placeholders) = $DB->get_in_or_equal($params['assignmentids'], SQL_PARAMS_NAMED); $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module " . "WHERE md.name = :modname AND cm.instance " . $inorequalsql; $placeholders['modname'] = 'assign'; $cms = $DB->get_records_sql($sql, $placeholders); $assigns = array(); foreach ($cms as $cm) { try { $context = context_module::instance($cm->id); self::validate_context($context); require_capability('mod/assign:grade', $context); $assign = new assign($context, null, null); $assigns[] = $assign; } catch (Exception $e) { $warnings[] = array('item' => 'assignment', 'itemid' => $cm->instance, 'warningcode' => '1', 'message' => 'No access rights in module context'); } } foreach ($assigns as $assign) { $submissions = array(); $submissionplugins = $assign->get_submission_plugins(); $placeholders = array('assignid1' => $assign->get_instance()->id, 'assignid2' => $assign->get_instance()->id); $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt FROM {assign_submission} mxs WHERE mxs.assignment = :assignid1 GROUP BY mxs.userid'; $sql = "SELECT mas.id, mas.assignment,mas.userid," . "mas.timecreated,mas.timemodified,mas.status,mas.groupid,mas.attemptnumber " . "FROM {assign_submission} mas " . "JOIN ( " . $submissionmaxattempt . " ) smx ON mas.userid = smx.userid " . "WHERE mas.assignment = :assignid2 AND mas.attemptnumber = smx.maxattempt"; if (!empty($params['status'])) { $placeholders['status'] = $params['status']; $sql = $sql . " AND mas.status = :status"; } if (!empty($params['before'])) { $placeholders['since'] = $params['since']; $placeholders['before'] = $params['before']; $sql = $sql . " AND mas.timemodified BETWEEN :since AND :before"; } else { $placeholders['since'] = $params['since']; $sql = $sql . " AND mas.timemodified >= :since"; } $submissionrecords = $DB->get_records_sql($sql, $placeholders); if (!empty($submissionrecords)) { $fs = get_file_storage(); foreach ($submissionrecords as $submissionrecord) { $submission = array('id' => $submissionrecord->id, 'userid' => $submissionrecord->userid, 'timecreated' => $submissionrecord->timecreated, 'timemodified' => $submissionrecord->timemodified, 'status' => $submissionrecord->status, 'attemptnumber' => $submissionrecord->attemptnumber, 'groupid' => $submissionrecord->groupid); foreach ($submissionplugins as $submissionplugin) { $plugin = array('name' => $submissionplugin->get_name(), 'type' => $submissionplugin->get_type()); // Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'. $component = $submissionplugin->get_subtype() . '_' . $submissionplugin->get_type(); $fileareas = $submissionplugin->get_file_areas(); foreach ($fileareas as $filearea => $name) { $fileareainfo = array('area' => $filearea); $files = $fs->get_area_files($assign->get_context()->id, $component, $filearea, $submissionrecord->id, "timemodified", false); foreach ($files as $file) { $filepath = $file->get_filepath() . $file->get_filename(); $fileurl = file_encode_url($CFG->wwwroot . '/webservice/pluginfile.php', '/' . $assign->get_context()->id . '/' . $component . '/' . $filearea . '/' . $submissionrecord->id . $filepath); $fileinfo = array('filepath' => $filepath, 'fileurl' => $fileurl); $fileareainfo['files'][] = $fileinfo; } $plugin['fileareas'][] = $fileareainfo; } $editorfields = $submissionplugin->get_editor_fields(); foreach ($editorfields as $name => $description) { $editorfieldinfo = array('name' => $name, 'description' => $description, 'text' => $submissionplugin->get_editor_text($name, $submissionrecord->id), 'format' => $submissionplugin->get_editor_format($name, $submissionrecord->id)); $plugin['editorfields'][] = $editorfieldinfo; } $submission['plugins'][] = $plugin; } $submissions[] = $submission; } } else { $warnings[] = array('item' => 'module', 'itemid' => $assign->get_instance()->id, 'warningcode' => '3', 'message' => 'No submissions found'); } $assignments[] = array('assignmentid' => $assign->get_instance()->id, 'submissions' => $submissions); } $result = array('assignments' => $assignments, 'warnings' => $warnings); return $result; }
require_login($course, false, $cm); $context = context_module::instance($cm->id); // Add or edit an override. require_capability('mod/assign:manageoverrides', $context); if ($overrideid) { // Editing an override. $data = clone $override; } else { // Creating a new override. $data = new stdClass(); } // Merge assign defaults with data. $keys = array('duedate', 'cutoffdate', 'allowsubmissionsfromdate'); foreach ($keys as $key) { if (!isset($data->{$key}) || $reset) { $data->{$key} = $assign->get_context()->{$key}; } } // True if group-based override. $groupmode = !empty($data->groupid) || $action === 'addgroup' && empty($overrideid); // If we are duplicating an override, then clear the user/group and override id // since they will change. if ($action === 'duplicate') { $override->id = $data->id = null; $override->userid = $data->userid = null; $override->groupid = $data->groupid = null; $pagetitle = get_string('duplicateoverride', 'assign'); } $overridelisturl = new moodle_url('/mod/assign/overrides.php', array('cmid' => $cm->id)); if (!$groupmode) { $overridelisturl->param('mode', 'user');
/** * Process an uploaded zip file * * @param assign $assignment - The assignment instance * @param assign_feedback_file $fileplugin - The file feedback plugin * @return string - The html response */ public function import_zip_files($assignment, $fileplugin) { global $CFG, $PAGE, $DB; core_php_time_limit::raise(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); $packer = get_file_packer('application/zip'); $feedbackfilesupdated = 0; $feedbackfilesadded = 0; $userswithnewfeedback = array(); $contextid = $assignment->get_context()->id; $fs = get_file_storage(); $files = $this->get_import_files($contextid); $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); $allusers = $assignment->list_participants($currentgroup, false); $participants = array(); foreach ($allusers as $user) { $participants[$assignment->get_uniqueid_for_user($user->id)] = $user; } foreach ($files as $unzippedfile) { // Set the timeout for unzipping each file. $user = null; $plugin = null; $filename = ''; if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { $grade = $assignment->get_user_grade($user->id, true); // In 3.1 the default download structure of the submission files changed so that each student had their own // separate folder, the files were not renamed and the folder structure was kept. It is possible that // a user downloaded the submission files in 3.0 (or earlier) and edited the zip to add feedback or // changed the behavior back to the previous format, the following code means that we will still support the // old file structure. For more information please see - MDL-52489 / MDL-56022. $path = pathinfo($filename); if ($path['dirname'] == '.') { // Student submissions are not in separate folders. $basename = $filename; $dirname = "/"; $dirnamewslash = "/"; } else { $basename = $path['basename']; $dirname = $path['dirname']; $dirnamewslash = $dirname . "/"; } if ($oldfile = $fs->get_file($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_FILEAREA, $grade->id, $dirname, $basename)) { // Update existing feedback file. $oldfile->replace_file_with($unzippedfile); $feedbackfilesupdated++; } else { // Create a new feedback file. $newfilerecord = new stdClass(); $newfilerecord->contextid = $contextid; $newfilerecord->component = 'assignfeedback_file'; $newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA; $newfilerecord->filename = $basename; $newfilerecord->filepath = $dirnamewslash; $newfilerecord->itemid = $grade->id; $fs->create_file_from_storedfile($newfilerecord, $unzippedfile); $feedbackfilesadded++; } $userswithnewfeedback[$user->id] = 1; // Update the number of feedback files for this user. $fileplugin->update_file_count($grade); // Update the last modified time on the grade which will trigger student notifications. $assignment->notify_grade_modified($grade); } } } require_once $CFG->dirroot . '/mod/assign/feedback/file/renderable.php'; $importsummary = new assignfeedback_file_import_summary($assignment->get_course_module()->id, count($userswithnewfeedback), $feedbackfilesadded, $feedbackfilesupdated); $assignrenderer = $assignment->get_renderer(); $renderer = $PAGE->get_renderer('assignfeedback_file'); $o = ''; $o .= $assignrenderer->render(new assign_header($assignment->get_instance(), $assignment->get_context(), false, $assignment->get_course_module()->id, get_string('uploadzipsummary', 'assignfeedback_file'))); $o .= $renderer->render($importsummary); $o .= $assignrenderer->render_footer(); return $o; }
/** * Copy annotations, comments, pages, and other required content from the source user to the current group member * being procssed when using applytoall. * * @param int|\assign $assignment * @param stdClass $grade * @param int $sourceuserid * @return bool */ public static function copy_drafts_from_to($assignment, $grade, $sourceuserid) { global $DB; // Delete any existing annotations and comments from current user. $DB->delete_records('assignfeedback_editpdf_annot', array('gradeid' => $grade->id)); $DB->delete_records('assignfeedback_editpdf_cmnt', array('gradeid' => $grade->id)); // Get gradeid, annotations and comments from sourceuserid. $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $contextid = $assignment->get_context()->id; $sourceitemid = $sourceusergrade->id; // Add annotations and comments to current user to generate feedback file. foreach ($annotations as $annotation) { $annotation->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_annot', $annotation); } foreach ($comments as $comment) { $comment->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_cmnt', $comment); } $fs = get_file_storage(); // Copy the stamp files. self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::STAMPS_FILEAREA, true); // Copy the PAGE_IMAGE_FILEAREA files. self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::PAGE_IMAGE_FILEAREA); return true; }
/** * overridden constructor keeps a reference to the assignment class that is displaying this table * * @param assign $assignment The assignment class * @param int $perpage how many per page * @param string $filter The current filter * @param int $rowoffset For showing a subsequent page of results * @param bool $quickgrading Is this table wrapped in a quickgrading form? */ function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgrading) { global $CFG, $PAGE, $DB; parent::__construct('mod_assign_grading'); $this->assignment = $assignment; $this->perpage = $perpage; $this->quickgrading = $quickgrading; $this->output = $PAGE->get_renderer('mod_assign'); $this->define_baseurl(new moodle_url($CFG->wwwroot . '/mod/assign/view.php', array('action'=>'grading', 'id'=>$assignment->get_course_module()->id))); // do some business - then set the sql $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); if ($rowoffset) { $this->rownum = $rowoffset - 1; } $users = array_keys( $assignment->list_participants($currentgroup, true)); if (count($users) == 0) { // insert a record that will never match to the sql is still valid. $users[] = -1; } $params = array(); $params['assignmentid1'] = (int)$this->assignment->get_instance()->id; $params['assignmentid2'] = (int)$this->assignment->get_instance()->id; $extrauserfields = get_extra_user_fields($this->assignment->get_context()); $fields = user_picture::fields('u', $extrauserfields) . ', u.id as userid, '; $fields .= 's.status as status, s.id as submissionid, s.timecreated as firstsubmission, s.timemodified as timesubmitted, '; $fields .= 'g.id as gradeid, g.grade as grade, g.timemodified as timemarked, g.timecreated as firstmarked, g.mailed as mailed, g.locked as locked'; $from = '{user} u LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid1' . ' LEFT JOIN {assign_grades} g ON u.id = g.userid AND g.assignment = :assignmentid2'; $userparams = array(); $userindex = 0; list($userwhere, $userparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED, 'user'); $where = 'u.id ' . $userwhere; $params = array_merge($params, $userparams); // The filters do not make sense when there are no submissions, so do not apply them. if ($this->assignment->is_any_submission_plugin_enabled()) { if ($filter == ASSIGN_FILTER_SUBMITTED) { $where .= ' AND (s.timemodified IS NOT NULL AND s.status = :submitted) '; $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED; } else if ($filter == ASSIGN_FILTER_REQUIRE_GRADING) { $where .= ' AND (s.timemodified IS NOT NULL AND s.status = :submitted AND (s.timemodified > g.timemodified OR g.timemodified IS NULL))'; $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED; } else if (strpos($filter, ASSIGN_FILTER_SINGLE_USER) === 0) { $userfilter = (int) array_pop(explode('=', $filter)); $where .= ' AND (u.id = :userid)'; $params['userid'] = $userfilter; } } $this->set_sql($fields, $from, $where, $params); $columns = array(); $headers = array(); // Select if (!$this->is_downloading()) { $columns[] = 'select'; $headers[] = get_string('select') . '<div class="selectall"><input type="checkbox" name="selectall" title="' . get_string('selectall') . '"/></div>'; } // User picture $columns[] = 'picture'; $headers[] = get_string('pictureofuser'); // Fullname $columns[] = 'fullname'; $headers[] = get_string('fullname'); foreach ($extrauserfields as $extrafield) { $columns[] = $extrafield; $headers[] = get_user_field_name($extrafield); } // Submission status if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'status'; $headers[] = get_string('status'); } // Grade $columns[] = 'grade'; $headers[] = get_string('grade'); if (!$this->is_downloading()) { // We have to call this column userid so we can use userid as a default sortable column. $columns[] = 'userid'; $headers[] = get_string('edit'); } // Submission plugins if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'timesubmitted'; $headers[] = get_string('lastmodifiedsubmission', 'assign'); foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { $columns[] = 'assignsubmission_' . $plugin->get_type(); $headers[] = $plugin->get_name(); } } } // time marked $columns[] = 'timemarked'; $headers[] = get_string('lastmodifiedgrade', 'assign'); // Feedback plugins foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { $columns[] = 'assignfeedback_' . $plugin->get_type(); $headers[] = $plugin->get_name(); } } // final grade $columns[] = 'finalgrade'; $headers[] = get_string('finalgrade', 'grades'); // load the grading info for all users $this->gradinginfo = grade_get_grades($this->assignment->get_course()->id, 'mod', 'assign', $this->assignment->get_instance()->id, $users); if (!empty($CFG->enableoutcomes) && !empty($this->gradinginfo->outcomes)) { $columns[] = 'outcomes'; $headers[] = get_string('outcomes', 'grades'); } // set the columns $this->define_columns($columns); $this->define_headers($headers); foreach ($extrauserfields as $extrafield) { $this->column_class($extrafield, $extrafield); } // We require at least one unique column for the sort. $this->sortable(true, 'userid'); $this->no_sorting('finalgrade'); $this->no_sorting('userid'); $this->no_sorting('select'); $this->no_sorting('outcomes'); foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { $this->no_sorting('assignsubmission_' . $plugin->get_type()); } } foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { $this->no_sorting('assignfeedback_' . $plugin->get_type()); } } }
/** * Return information (files and text fields) for the given plugins in the assignment. * * @param assign $assign the assignment object * @param array $assignplugins array of assignment plugins (submission or feedback) * @param stdClass $item the item object (submission or grade) * @return array an array containing the plugins returned information */ private static function get_plugins_data($assign, $assignplugins, $item) { global $CFG; $plugins = array(); $fs = get_file_storage(); foreach ($assignplugins as $assignplugin) { if (!$assignplugin->is_enabled() or !$assignplugin->is_visible()) { continue; } $plugin = array('name' => $assignplugin->get_name(), 'type' => $assignplugin->get_type()); // Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'. $component = $assignplugin->get_subtype() . '_' . $assignplugin->get_type(); $fileareas = $assignplugin->get_file_areas(); foreach ($fileareas as $filearea => $name) { $fileareainfo = array('area' => $filearea); $fileareainfo['files'] = external_util::get_area_files($assign->get_context()->id, $component, $filearea, $item->id); $plugin['fileareas'][] = $fileareainfo; } $editorfields = $assignplugin->get_editor_fields(); foreach ($editorfields as $name => $description) { $editorfieldinfo = array('name' => $name, 'description' => $description, 'text' => $assignplugin->get_editor_text($name, $item->id), 'format' => $assignplugin->get_editor_format($name, $item->id)); // Now format the text. foreach ($fileareas as $filearea => $name) { list($editorfieldinfo['text'], $editorfieldinfo['format']) = external_format_text($editorfieldinfo['text'], $editorfieldinfo['format'], $assign->get_context()->id, $component, $filearea, $item->id); } $plugin['editorfields'][] = $editorfieldinfo; } $plugins[] = $plugin; } return $plugins; }
/** * Returns information about an assignment submission status for a given user. * * @param int $assignid assignment instance id * @param int $userid user id (empty for current user) * @return array of warnings and grading, status, feedback and previous attempts information * @since Moodle 3.1 * @throws required_capability_exception */ public static function get_submission_status($assignid, $userid = 0) { global $USER, $DB; $warnings = array(); $params = array('assignid' => $assignid, 'userid' => $userid); $params = self::validate_parameters(self::get_submission_status_parameters(), $params); // Request and permission validation. $assign = $DB->get_record('assign', array('id' => $params['assignid']), 'id', MUST_EXIST); list($course, $cm) = get_course_and_cm_from_instance($assign, 'assign'); $context = context_module::instance($cm->id); self::validate_context($context); $assign = new assign($context, $cm, $course); // Default value for userid. if (empty($params['userid'])) { $params['userid'] = $USER->id; } $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); if (!$assign->can_view_submission($user->id)) { throw new required_capability_exception($context, 'mod/assign:viewgrades', 'nopermission', ''); } $gradingsummary = $lastattempt = $feedback = $previousattempts = null; // Get the renderable since it contais all the info we need. if ($assign->can_view_grades()) { $gradingsummary = $assign->get_assign_grading_summary_renderable(); } // Retrieve the rest of the renderable objects. if (has_capability('mod/assign:submit', $assign->get_context(), $user)) { $lastattempt = $assign->get_assign_submission_status_renderable($user, true); } $feedback = $assign->get_assign_feedback_status_renderable($user); $previousattempts = $assign->get_assign_attempt_history_renderable($user); // Now, build the result. $result = array(); // First of all, grading summary, this is suitable for teachers/managers. if ($gradingsummary) { $result['gradingsummary'] = $gradingsummary; } // Did we submit anything? if ($lastattempt) { $submissionplugins = $assign->get_submission_plugins(); if (empty($lastattempt->submission)) { unset($lastattempt->submission); } else { $lastattempt->submission->plugins = self::get_plugins_data($assign, $submissionplugins, $lastattempt->submission); } if (empty($lastattempt->teamsubmission)) { unset($lastattempt->teamsubmission); } else { $lastattempt->teamsubmission->plugins = self::get_plugins_data($assign, $submissionplugins, $lastattempt->teamsubmission); } // We need to change the type of some of the structures retrieved from the renderable. if (!empty($lastattempt->submissiongroup)) { $lastattempt->submissiongroup = $lastattempt->submissiongroup->id; } else { unset($lastattempt->submissiongroup); } if (!empty($lastattempt->usergroups)) { $lastattempt->usergroups = array_keys($lastattempt->usergroups); } // We cannot use array_keys here. if (!empty($lastattempt->submissiongroupmemberswhoneedtosubmit)) { $lastattempt->submissiongroupmemberswhoneedtosubmit = array_map(function ($e) { return $e->id; }, $lastattempt->submissiongroupmemberswhoneedtosubmit); } $result['lastattempt'] = $lastattempt; } // The feedback for our latest submission. if ($feedback) { if ($feedback->grade) { $feedbackplugins = $assign->get_feedback_plugins(); $feedback->plugins = self::get_plugins_data($assign, $feedbackplugins, $feedback->grade); } else { unset($feedback->plugins); unset($feedback->grade); } $result['feedback'] = $feedback; } // Retrieve only previous attempts. if ($previousattempts and count($previousattempts->submissions) > 1) { // Don't show the last one because it is the current submission. array_pop($previousattempts->submissions); // Show newest to oldest. $previousattempts->submissions = array_reverse($previousattempts->submissions); foreach ($previousattempts->submissions as $i => $submission) { $attempt = array(); $grade = null; foreach ($previousattempts->grades as $onegrade) { if ($onegrade->attemptnumber == $submission->attemptnumber) { $grade = $onegrade; break; } } $attempt['attemptnumber'] = $submission->attemptnumber; if ($submission) { $submission->plugins = self::get_plugins_data($assign, $previousattempts->submissionplugins, $submission); $attempt['submission'] = $submission; } if ($grade) { // From object to id. $grade->grader = $grade->grader->id; $feedbackplugins = self::get_plugins_data($assign, $previousattempts->feedbackplugins, $grade); $attempt['grade'] = $grade; $attempt['feedbackplugins'] = $feedbackplugins; } $result['previousattempts'][] = $attempt; } } $result['warnings'] = $warnings; return $result; }
/** * overridden constructor keeps a reference to the assignment class that is displaying this table * * @param assign $assignment The assignment class * @param int $perpage how many per page * @param string $filter The current filter * @param int $rowoffset For showing a subsequent page of results * @param bool $quickgrading Is this table wrapped in a quickgrading form? */ public function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgrading, $downloadfilename = null) { global $CFG, $PAGE, $DB; parent::__construct('mod_assign_grading'); $this->assignment = $assignment; foreach ($assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_grading_batch_operations() as $action => $description) { if (empty($this->plugingradingbatchoperations)) { $this->plugingradingbatchoperations[$plugin->get_type()] = array(); } $this->plugingradingbatchoperations[$plugin->get_type()][$action] = $description; } } } $this->perpage = $perpage; $this->quickgrading = $quickgrading; $this->output = $PAGE->get_renderer('mod_assign'); $this->define_baseurl(new moodle_url($CFG->wwwroot . '/mod/assign/view.php', array('action' => 'grading', 'id' => $assignment->get_course_module()->id))); // do some business - then set the sql $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); if ($rowoffset) { $this->rownum = $rowoffset - 1; } $users = array_keys($assignment->list_participants($currentgroup, true)); if (count($users) == 0) { // insert a record that will never match to the sql is still valid. $users[] = -1; } $params = array(); $params['assignmentid1'] = (int) $this->assignment->get_instance()->id; $params['assignmentid2'] = (int) $this->assignment->get_instance()->id; $fields = user_picture::fields('u') . ', '; $fields .= 'u.id as userid, '; $fields .= 's.status as status, '; $fields .= 's.id as submissionid, '; $fields .= 's.timecreated as firstsubmission, '; $fields .= 's.timemodified as timesubmitted, '; $fields .= 'g.id as gradeid, '; $fields .= 'g.grade as grade, '; $fields .= 'g.timemodified as timemarked, '; $fields .= 'g.timecreated as firstmarked, '; $fields .= 'g.mailed as mailed, '; $fields .= 'g.locked as locked, '; $fields .= 'g.extensionduedate as extensionduedate'; $from = '{user} u LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid1' . ' LEFT JOIN {assign_grades} g ON u.id = g.userid AND g.assignment = :assignmentid2'; $userparams = array(); $userindex = 0; list($userwhere, $userparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED, 'user'); $where = 'u.id ' . $userwhere; $params = array_merge($params, $userparams); if ($filter == ASSIGN_FILTER_SUBMITTED) { $where .= ' AND s.timecreated > 0 '; } if ($filter == ASSIGN_FILTER_REQUIRE_GRADING) { $where .= ' AND (s.timemodified > g.timemodified OR (s.timemodified IS NOT NULL AND g.timemodified IS NULL))'; } if (strpos($filter, ASSIGN_FILTER_SINGLE_USER) === 0) { $userfilter = (int) array_pop(explode('=', $filter)); $where .= ' AND (u.id = :userid)'; $params['userid'] = $userfilter; } $this->set_sql($fields, $from, $where, $params); if ($downloadfilename) { $this->is_downloading('csv', $downloadfilename); } $columns = array(); $headers = array(); // Select. if (!$this->is_downloading()) { $columns[] = 'select'; $headers[] = get_string('select') . '<div class="selectall"><label class="accesshide" for="selectall">' . get_string('selectall') . '</label> <input type="checkbox" id="selectall" name="selectall" title="' . get_string('selectall') . '"/></div>'; } // User picture. if (!$this->assignment->is_blind_marking()) { if (!$this->is_downloading()) { $columns[] = 'picture'; $headers[] = get_string('pictureofuser'); } else { $columns[] = 'recordid'; $headers[] = get_string('recordid', 'assign'); } // Fullname. $columns[] = 'fullname'; $headers[] = get_string('fullname'); } else { // Record ID. $columns[] = 'recordid'; $headers[] = get_string('recordid', 'assign'); } // Submission status if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'status'; $headers[] = get_string('status'); } // Team submission columns if ($assignment->get_instance()->teamsubmission) { $columns[] = 'team'; $headers[] = get_string('submissionteam', 'assign'); $columns[] = 'teamstatus'; $headers[] = get_string('teamsubmissionstatus', 'assign'); } // Grade $columns[] = 'grade'; $headers[] = get_string('grade'); if ($this->is_downloading()) { if ($this->assignment->get_instance()->grade >= 0) { $columns[] = 'grademax'; $headers[] = get_string('maxgrade', 'assign'); } else { // This is a custom scale. $columns[] = 'scale'; $headers[] = get_string('scale', 'assign'); } } if (!$this->is_downloading()) { // We have to call this column userid so we can use userid as a default sortable column. $columns[] = 'userid'; $headers[] = get_string('edit'); } // Submission plugins if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'timesubmitted'; $headers[] = get_string('lastmodifiedsubmission', 'assign'); foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($this->is_downloading()) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_editor_fields() as $field => $description) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin, $field); $columns[] = $index; $headers[] = $plugin->get_name(); } } } else { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin); $columns[] = $index; $headers[] = $plugin->get_name(); } } } } // time marked $columns[] = 'timemarked'; $headers[] = get_string('lastmodifiedgrade', 'assign'); // Feedback plugins foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($this->is_downloading()) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_editor_fields() as $field => $description) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin, $field); $columns[] = $index; $headers[] = $description; } } } else { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin); $columns[] = $index; $headers[] = $plugin->get_name(); } } } // Exclude 'Final grade' column in downloaded grading worksheets. if (!$this->is_downloading()) { // Final grade. $columns[] = 'finalgrade'; $headers[] = get_string('finalgrade', 'grades'); } // load the grading info for all users $this->gradinginfo = grade_get_grades($this->assignment->get_course()->id, 'mod', 'assign', $this->assignment->get_instance()->id, $users); $this->hasgrantextension = has_capability('mod/assign:grantextension', $this->assignment->get_context()); if (!empty($CFG->enableoutcomes) && !empty($this->gradinginfo->outcomes)) { $columns[] = 'outcomes'; $headers[] = get_string('outcomes', 'grades'); } // set the columns $this->define_columns($columns); $this->define_headers($headers); // We require at least one unique column for the sort. $this->sortable(true, 'userid'); $this->no_sorting('recordid'); $this->no_sorting('finalgrade'); $this->no_sorting('userid'); $this->no_sorting('select'); $this->no_sorting('outcomes'); if ($assignment->get_instance()->teamsubmission) { $this->no_sorting('team'); $this->no_sorting('teamstatus'); } $plugincolumnindex = 0; foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $submissionpluginindex = 'plugin' . $plugincolumnindex++; $this->no_sorting($submissionpluginindex); } } foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $feedbackpluginindex = 'plugin' . $plugincolumnindex++; $this->no_sorting($feedbackpluginindex); } } // When there is no data we still want the column headers printed in the csv file. if ($this->is_downloading()) { $this->start_output(); } }
function plagiarism_urkund_get_file_object($plagiarismfile) { global $CFG, $DB; if (strpos($plagiarismfile->identifier, $CFG->tempdir) === true) { // This is a stored text file in temp dir. $file = new stdclass(); if (file_exists($plagiarismfile->identifier)) { $file->type = "tempurkund"; $file->filename = basename($plagiarismfile->identifier); $file->timestamp = time(); $file->identifier = sha1(file_get_contents($plagiarismfile->identifier)); $file->filepath = $plagiarismfile->identifier; // Sanity check to see if the Sha1 for this file has already been sent to urkund using a different record. if ($DB->record_exists('plagiarism_urkund_files', array('identifier' => $file->identifier, 'cm' => $plagiarismfile->cm, 'userid' => $plagiarismfile->userid))) { // This file has already been sent and multiple records for this file were created // Delete plagiarism record and file. $DB->delete_records('plagiarism_urkund_files', array('id' => $plagiarismfile->id)); debugging("This file has been duplicated, deleting the duplicate record. Identifier:" . $file->identifier); unlink($plagiarismfile->identifier); // Delete temp file as we don't need it anymore. return false; } return $file; } else { debugging("The local version of this file has been deleted, and this file cannot be sent"); return false; } } else { $cm = get_coursemodule_from_id('', $plagiarismfile->cm); $modulecontext = context_module::instance($plagiarismfile->cm); $fs = get_file_storage(); if ($cm->modname == 'assign') { require_once $CFG->dirroot . '/mod/assign/locallib.php'; $assign = new assign($modulecontext, null, null); if ($assign->get_instance()->teamsubmission) { $submission = $assign->get_group_submission($plagiarismfile->userid, 0, false); } else { $submission = $assign->get_user_submission($plagiarismfile->userid, false); } $submissionplugins = $assign->get_submission_plugins(); foreach ($submissionplugins as $submissionplugin) { $component = $submissionplugin->get_subtype() . '_' . $submissionplugin->get_type(); $fileareas = $submissionplugin->get_file_areas(); foreach ($fileareas as $filearea => $name) { $files = $fs->get_area_files($assign->get_context()->id, $component, $filearea, $submission->id, "timemodified", false); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { return $file; } } } } } else { if ($cm->modname == 'workshop') { require_once $CFG->dirroot . '/mod/workshop/locallib.php'; $cm = get_coursemodule_from_id('workshop', $plagiarismfile->cm, 0, false, MUST_EXIST); $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $workshop = new workshop($workshop, $cm, $course); $submissions = $workshop->get_submissions($plagiarismfile->userid); foreach ($submissions as $submission) { $files = $fs->get_area_files($workshop->context->id, 'mod_workshop', 'submission_attachment', $submission->id); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { return $file; } } } } else { if ($cm->modname == 'forum') { require_once $CFG->dirroot . '/mod/forum/lib.php'; $cm = get_coursemodule_from_id('forum', $plagiarismfile->cm, 0, false, MUST_EXIST); $posts = forum_get_user_posts($cm->instance, $plagiarismfile->userid); foreach ($posts as $post) { $files = $fs->get_area_files($modulecontext->id, 'mod_forum', 'attachment', $post->id, "timemodified", false); foreach ($files as $file) { if ($file->get_contenthash() == $plagiarismfile->identifier) { return $file; } } } } } } } }
* * @package mod_assign * @copyright 2016 Ilya Tregubov * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once dirname(__FILE__) . '/../../config.php'; require_once $CFG->dirroot . '/mod/assign/lib.php'; require_once $CFG->dirroot . '/mod/assign/locallib.php'; require_once $CFG->dirroot . '/mod/assign/override_form.php'; $overrideid = required_param('id', PARAM_INT); $confirm = optional_param('confirm', false, PARAM_BOOL); if (!($override = $DB->get_record('assign_overrides', array('id' => $overrideid)))) { print_error('invalidoverrideid', 'assign'); } $assign = new assign($DB->get_record('assign', array('id' => $override->assignid), '*', MUST_EXIST), null, null); if (!($cm = get_coursemodule_from_instance("assign", $assign->get_context()->id, $assign->get_context()->course))) { print_error('invalidcoursemodule'); } $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $context = context_module::instance($cm->id); require_login($course, false, $cm); // Check the user has the required capabilities to modify an override. require_capability('mod/assign:manageoverrides', $context); $url = new moodle_url('/mod/assign/overridedelete.php', array('id' => $override->id)); $confirmurl = new moodle_url($url, array('id' => $override->id, 'confirm' => 1)); $cancelurl = new moodle_url('/mod/assign/overrides.php', array('cmid' => $cm->id)); if (!empty($override->userid)) { $cancelurl->param('mode', 'user'); } // If confirm is set (PARAM_BOOL) then we have confirmation of intention to delete. if ($confirm) {
/** * This function converts all of the base settings for an instance of * the old assignment to the new format. Then it calls each of the plugins * to see if they can help upgrade this assignment. * @param int $oldassignmentid (don't rely on the old assignment type even being installed) * @param string $log This string gets appended to during the conversion process * @return bool true or false */ public function upgrade_assignment($oldassignmentid, &$log) { // steps to upgrade an assignment global $DB, $CFG, $USER; // steps to upgrade an assignment // is the user the admin? admin check goes here if (!is_siteadmin($USER->id)) { return false; } // should we use a shutdown handler to rollback on timeout? @set_time_limit(ASSIGN_MAX_UPGRADE_TIME_SECS); // get the module details $oldmodule = $DB->get_record('modules', array('name' => 'assignment'), '*', MUST_EXIST); $oldcoursemodule = $DB->get_record('course_modules', array('module' => $oldmodule->id, 'instance' => $oldassignmentid), '*', MUST_EXIST); $oldcontext = context_module::instance($oldcoursemodule->id); // first insert an assign instance to get the id $oldassignment = $DB->get_record('assignment', array('id' => $oldassignmentid), '*', MUST_EXIST); $oldversion = get_config('assignment_' . $oldassignment->assignmenttype, 'version'); $data = new stdClass(); $data->course = $oldassignment->course; $data->name = $oldassignment->name; $data->intro = $oldassignment->intro; $data->introformat = $oldassignment->introformat; $data->alwaysshowdescription = 1; $data->sendnotifications = $oldassignment->emailteachers; $data->sendlatenotifications = $oldassignment->emailteachers; $data->duedate = $oldassignment->timedue; $data->allowsubmissionsfromdate = $oldassignment->timeavailable; $data->grade = $oldassignment->grade; $data->submissiondrafts = $oldassignment->resubmit; $data->preventlatesubmissions = $oldassignment->preventlate; $newassignment = new assign(null, null, null); if (!$newassignment->add_instance($data, false)) { $log = get_string('couldnotcreatenewassignmentinstance', 'mod_assign'); return false; } // now create a new coursemodule from the old one $newmodule = $DB->get_record('modules', array('name' => 'assign'), '*', MUST_EXIST); $newcoursemodule = $this->duplicate_course_module($oldcoursemodule, $newmodule->id, $newassignment->get_instance()->id); if (!$newcoursemodule) { $log = get_string('couldnotcreatenewcoursemodule', 'mod_assign'); return false; } // convert the base database tables (assignment, submission, grade) // these are used to store information in case a rollback is required $gradingarea = null; $gradingdefinitions = null; $gradeidmap = array(); $completiondone = false; $gradesdone = false; // from this point we want to rollback on failure $rollback = false; try { $newassignment->set_context(context_module::instance($newcoursemodule->id)); // the course module has now been created - time to update the core tables // copy intro files $newassignment->copy_area_files_for_upgrade($oldcontext->id, 'mod_assignment', 'intro', 0, $newassignment->get_context()->id, 'mod_assign', 'intro', 0); // get the plugins to do their bit foreach ($newassignment->get_submission_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { $plugin->enable(); if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) { $rollback = true; } } else { $plugin->disable(); } } foreach ($newassignment->get_feedback_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { $plugin->enable(); if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) { $rollback = true; } } else { $plugin->disable(); } } // see if there is advanced grading upgrades required $gradingarea = $DB->get_record('grading_areas', array('contextid' => $oldcontext->id, 'areaname' => 'submission'), '*', IGNORE_MISSING); if ($gradingarea) { $DB->update_record('grading_areas', array('id' => $gradingarea->id, 'contextid' => $newassignment->get_context()->id, 'component' => 'mod_assign', 'areaname' => 'submissions')); $gradingdefinitions = $DB->get_records('grading_definitions', array('areaid' => $gradingarea->id)); } // upgrade completion data $DB->set_field('course_modules_completion', 'coursemoduleid', $newcoursemodule->id, array('coursemoduleid' => $oldcoursemodule->id)); $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $oldcoursemodule->id)); foreach ($allcriteria as $criteria) { $criteria->module = 'assign'; $criteria->moduleinstance = $newcoursemodule->id; $DB->update_record('course_completion_criteria', $criteria); } $completiondone = true; // Migrate log entries so we don't lose them. $logparams = array('cmid' => $oldcoursemodule->id, 'course' => $oldcoursemodule->course); $DB->set_field('log', 'module', 'assign', $logparams); $DB->set_field('log', 'cmid', $newcoursemodule->id, $logparams); // copy all the submission data (and get plugins to do their bit) $oldsubmissions = $DB->get_records('assignment_submissions', array('assignment' => $oldassignmentid)); foreach ($oldsubmissions as $oldsubmission) { $submission = new stdClass(); $submission->assignment = $newassignment->get_instance()->id; $submission->userid = $oldsubmission->userid; $submission->timecreated = $oldsubmission->timecreated; $submission->timemodified = $oldsubmission->timemodified; $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; $submission->id = $DB->insert_record('assign_submission', $submission); if (!$submission->id) { $log .= get_string('couldnotinsertsubmission', 'mod_assign', $submission->userid); $rollback = true; } foreach ($newassignment->get_submission_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { if (!$plugin->upgrade($oldcontext, $oldassignment, $oldsubmission, $submission, $log)) { $rollback = true; } } } if ($oldsubmission->timemarked) { // submission has been graded - create a grade record $grade = new stdClass(); $grade->assignment = $newassignment->get_instance()->id; $grade->userid = $oldsubmission->userid; $grade->grader = $oldsubmission->teacher; $grade->timemodified = $oldsubmission->timemarked; $grade->timecreated = $oldsubmission->timecreated; // $grade->locked = $oldsubmission->locked; $grade->grade = $oldsubmission->grade; $grade->mailed = $oldsubmission->mailed; $grade->id = $DB->insert_record('assign_grades', $grade); if (!$grade->id) { $log .= get_string('couldnotinsertgrade', 'mod_assign', $grade->userid); $rollback = true; } // copy any grading instances if ($gradingarea) { $gradeidmap[$grade->id] = $oldsubmission->id; foreach ($gradingdefinitions as $definition) { $DB->set_field('grading_instances', 'itemid', $grade->id, array('definitionid' => $definition->id, 'itemid' => $oldsubmission->id)); } } foreach ($newassignment->get_feedback_plugins() as $plugin) { if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) { if (!$plugin->upgrade($oldcontext, $oldassignment, $oldsubmission, $grade, $log)) { $rollback = true; } } } } } $newassignment->update_calendar($newcoursemodule->id); // Reassociate grade_items from the old assignment instance to the new assign instance. // This includes outcome linked grade_items. $params = array('assign', $newassignment->get_instance()->id, 'assignment', $oldassignment->id); $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?'; $DB->execute($sql, $params); $gradesdone = true; } catch (Exception $exception) { $rollback = true; $log .= get_string('conversionexception', 'mod_assign', $exception->error); } if ($rollback) { // roll back the grades changes if ($gradesdone) { // Reassociate grade_items from the new assign instance to the old assignment instance. $params = array('assignment', $oldassignment->id, 'assign', $newassignment->get_instance()->id); $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?'; $DB->execute($sql, $params); } // roll back the completion changes if ($completiondone) { $DB->set_field('course_modules_completion', 'coursemoduleid', $oldcoursemodule->id, array('coursemoduleid' => $newcoursemodule->id)); $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $newcoursemodule->id)); foreach ($allcriteria as $criteria) { $criteria->module = 'assignment'; $criteria->moduleinstance = $oldcoursemodule->id; $DB->update_record('course_completion_criteria', $criteria); } } // Roll back the log changes $logparams = array('cmid' => $newcoursemodule->id, 'course' => $newcoursemodule->course); $DB->set_field('log', 'module', 'assignment', $logparams); $DB->set_field('log', 'cmid', $oldcoursemodule->id, $logparams); // roll back the advanced grading update if ($gradingarea) { foreach ($gradeidmap as $newgradeid => $oldsubmissionid) { foreach ($gradingdefinitions as $definition) { $DB->set_field('grading_instances', 'itemid', $oldsubmissionid, array('definitionid' => $definition->id, 'itemid' => $newgradeid)); } } $DB->update_record('grading_areas', array('id' => $gradingarea->id, 'contextid' => $oldcontext->id, 'component' => 'mod_assignment', 'areaname' => 'submission')); } $newassignment->delete_instance(); return false; } // all is well, // delete the old assignment (use object delete) $cm = get_coursemodule_from_id('', $oldcoursemodule->id, $oldcoursemodule->course); if ($cm) { $this->delete_course_module($cm); } rebuild_course_cache($oldcoursemodule->course); return true; }