/** * 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; } $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; // need to find the plugin this belongs to $assignment = new assign($context, $cm, $course); $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; }
/** * 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? * @param string $downloadfilename */ public function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgrading, $downloadfilename = null) { global $CFG, $PAGE, $DB, $USER; parent::__construct('mod_assign_grading'); $this->is_persistent(true); $this->assignment = $assignment; // Check permissions up front. $this->hasgrantextension = has_capability('mod/assign:grantextension', $this->assignment->get_context()); $this->hasgrade = $this->assignment->can_grade(); // Check if we have the elevated view capablities to see the blind details. $this->hasviewblind = has_capability('mod/assign:viewblinddetails', $this->assignment->get_context()); 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->hasgrade; $this->output = $PAGE->get_renderer('mod_assign'); $urlparams = array('action' => 'grading', 'id' => $assignment->get_course_module()->id); $url = new moodle_url($CFG->wwwroot . '/mod/assign/view.php', $urlparams); $this->define_baseurl($url); // 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; $params['assignmentid3'] = (int) $this->assignment->get_instance()->id; $extrauserfields = get_extra_user_fields($this->assignment->get_context()); $fields = user_picture::fields('u', $extrauserfields) . ', '; $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 .= 's.attemptnumber as attemptnumber, '; $fields .= 'g.id as gradeid, '; $fields .= 'g.grade as grade, '; $fields .= 'g.timemodified as timemarked, '; $fields .= 'g.timecreated as firstmarked, '; $fields .= 'uf.mailed as mailed, '; $fields .= 'uf.locked as locked, '; $fields .= 'uf.extensionduedate as extensionduedate, '; $fields .= 'uf.workflowstate as workflowstate, '; $fields .= 'uf.allocatedmarker as allocatedmarker '; $from = '{user} u LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid1 AND s.latest = 1 LEFT JOIN {assign_grades} g ON u.id = g.userid AND g.assignment = :assignmentid2 '; // For group submissions we don't immediately create an entry in the assign_submission table for each user, // instead the userid is set to 0. In this case we use a different query to retrieve the grade for the user. if ($this->assignment->get_instance()->teamsubmission) { $params['assignmentid4'] = (int) $this->assignment->get_instance()->id; $grademaxattempt = 'SELECT mxg.userid, MAX(mxg.attemptnumber) AS maxattempt FROM {assign_grades} mxg WHERE mxg.assignment = :assignmentid4 GROUP BY mxg.userid'; $from .= 'LEFT JOIN (' . $grademaxattempt . ') gmx ON u.id = gmx.userid AND g.attemptnumber = gmx.maxattempt '; } else { $from .= 'AND g.attemptnumber = s.attemptnumber '; } $from .= 'LEFT JOIN {assign_user_flags} uf ON u.id = uf.userid AND uf.assignment = :assignmentid3'; $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_NOT_SUBMITTED) { $where .= ' AND (s.timemodified IS NULL OR 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 OR g.grade 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; } } } } } if ($this->assignment->get_instance()->markingworkflow && $this->assignment->get_instance()->markingallocation) { if (has_capability('mod/assign:manageallocations', $this->assignment->get_context())) { // Check to see if marker filter is set. $markerfilter = (int) get_user_preferences('assign_markerfilter', ''); if (!empty($markerfilter)) { if ($markerfilter == ASSIGN_MARKER_FILTER_NO_MARKER) { $where .= ' AND (uf.allocatedmarker IS NULL OR uf.allocatedmarker = 0)'; } else { $where .= ' AND uf.allocatedmarker = :markerid'; $params['markerid'] = $markerfilter; } } } else { // Only show users allocated to this marker. $where .= ' AND uf.allocatedmarker = :markerid'; $params['markerid'] = $USER->id; } } if ($this->assignment->get_instance()->markingworkflow) { $workflowstates = $this->assignment->get_marking_workflow_states_for_current_user(); if (!empty($workflowstates)) { $workflowfilter = get_user_preferences('assign_workflowfilter', ''); if ($workflowfilter == ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED) { $where .= ' AND (uf.workflowstate = :workflowstate OR uf.workflowstate IS NULL OR ' . $DB->sql_isempty('assign_user_flags', 'workflowstate', true, true) . ')'; $params['workflowstate'] = $workflowfilter; } else { if (array_key_exists($workflowfilter, $workflowstates)) { $where .= ' AND uf.workflowstate = :workflowstate'; $params['workflowstate'] = $workflowfilter; } } } } $this->set_sql($fields, $from, $where, $params); if ($downloadfilename) { $this->is_downloading('csv', $downloadfilename); } $columns = array(); $headers = array(); // Select. if (!$this->is_downloading() && $this->hasgrade) { $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->hasviewblind || !$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'); foreach ($extrauserfields as $extrafield) { $columns[] = $extrafield; $headers[] = get_user_field_name($extrafield); } } else { // Record ID. $columns[] = 'recordid'; $headers[] = get_string('recordid', 'assign'); } // Submission status. $columns[] = 'status'; $headers[] = get_string('status', 'assign'); // Team submission columns. if ($assignment->get_instance()->teamsubmission) { $columns[] = 'team'; $headers[] = get_string('submissionteam', 'assign'); } // Allocated marker. if ($this->assignment->get_instance()->markingworkflow && $this->assignment->get_instance()->markingallocation && has_capability('mod/assign:manageallocations', $this->assignment->get_context())) { // Add a column for the allocated marker. $columns[] = 'allocatedmarker'; $headers[] = get_string('marker', '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->assignment->get_instance()->markingworkflow) { // Add a column for the marking workflow state. $columns[] = 'workflowstate'; $headers[] = get_string('markingworkflowstate', 'assign'); } // Add a column for the list of valid marking workflow states. $columns[] = 'gradecanbechanged'; $headers[] = get_string('gradecanbechanged', 'assign'); } if (!$this->is_downloading() && $this->hasgrade) { // 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); 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); } $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'); } $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(); } }
/** * Describes the parameters for save_grades * @return external_external_function_parameters * @since Moodle 2.7 */ public static function save_grades_parameters() { global $CFG; require_once "{$CFG->dirroot}/grade/grading/lib.php"; $instance = new assign(null, null, null); $pluginfeedbackparams = array(); foreach ($instance->get_feedback_plugins() as $plugin) { if ($plugin->is_visible()) { $pluginparams = $plugin->get_external_parameters(); if (!empty($pluginparams)) { $pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams); } } } $advancedgradingdata = array(); $methods = array_keys(grading_manager::available_methods(false)); foreach ($methods as $method) { require_once $CFG->dirroot . '/grade/grading/form/' . $method . '/lib.php'; $details = call_user_func('gradingform_' . $method . '_controller::get_external_instance_filling_details'); if (!empty($details)) { $items = array(); foreach ($details as $key => $value) { $value->required = VALUE_OPTIONAL; unset($value->content->keys['id']); $items[$key] = new external_multiple_structure(new external_single_structure(array('criterionid' => new external_value(PARAM_INT, 'criterion id'), 'fillings' => $value))); } $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL); } } return new external_function_parameters(array('assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' . 'to all members ' . 'of the group (for group assignments).'), 'grades' => new external_multiple_structure(new external_single_structure(array('userid' => new external_value(PARAM_INT, 'The student id to operate on'), 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user. ' . 'Ignored if advanced grading used'), 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'), 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if manual attempt reopen method'), 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'), 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', VALUE_DEFAULT, array()), 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data', VALUE_DEFAULT, array())))))); }
/** * 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(); } }
/** * 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 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; }
/** * 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; $fields = user_picture::fields('u') . ', u.id as userid, u.firstname as firstname, u.lastname as lastname, '; $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); 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); $columns = array(); $headers = array(); // Select $columns[] = 'select'; $headers[] = get_string('select') . '<div class="selectall"><input type="checkbox" name="selectall" title="' . get_string('selectall') . '"/></div>'; // Edit links if (!$this->is_downloading()) { $columns[] = 'edit'; $headers[] = get_string('edit'); } // User picture $columns[] = 'picture'; $headers[] = get_string('pictureofuser'); // Fullname $columns[] = 'fullname'; $headers[] = get_string('fullname'); // Submission status if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'status'; $headers[] = get_string('status'); } // Grade $columns[] = 'grade'; $headers[] = get_string('grade'); // 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); $this->no_sorting('finalgrade'); $this->no_sorting('edit'); $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()); } } }
/** * Describes the parameters for save_grade * @return external_external_function_parameters * @since Moodle 2.6 */ public static function save_grade_parameters() { global $CFG; require_once("$CFG->dirroot/mod/assign/locallib.php"); $instance = new assign(null, null, null); $pluginfeedbackparams = array(); foreach ($instance->get_feedback_plugins() as $plugin) { $pluginparams = $plugin->get_external_parameters(); if (!empty($pluginparams)) { $pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams); } } return new external_function_parameters( array( 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 'userid' => new external_value(PARAM_INT, 'The student id to operate on'), 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user'), 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'), 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if the attempt reopen method is manual'), 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'), 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' . 'to all members ' . 'of the group (for group assignments).'), 'plugindata' => new external_single_structure( $pluginfeedbackparams ) ) ); }
/** * 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; }