/mod/assign/locallib.php
PHP | 7217 lines | 4865 code | 882 blank | 1470 comment | 964 complexity | 25f2d5a4f4869fd9c988edf0db8aaadd MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
Large files files are truncated, but you can click here to view the full file
- <?php
- // This file is part of Moodle - http://moodle.org/
- //
- // Moodle is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // Moodle is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
- /**
- * This file contains the definition for the class assignment
- *
- * This class provides all the functionality for the new assign module.
- *
- * @package mod_assign
- * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- defined('MOODLE_INTERNAL') || die();
- // Assignment submission statuses.
- define('ASSIGN_SUBMISSION_STATUS_REOPENED', 'reopened');
- define('ASSIGN_SUBMISSION_STATUS_DRAFT', 'draft');
- define('ASSIGN_SUBMISSION_STATUS_SUBMITTED', 'submitted');
- // Search filters for grading page.
- define('ASSIGN_FILTER_SUBMITTED', 'submitted');
- define('ASSIGN_FILTER_SINGLE_USER', 'singleuser');
- define('ASSIGN_FILTER_REQUIRE_GRADING', 'require_grading');
- // Reopen attempt methods.
- define('ASSIGN_ATTEMPT_REOPEN_METHOD_NONE', 'none');
- define('ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL', 'manual');
- define('ASSIGN_ATTEMPT_REOPEN_METHOD_UNTILPASS', 'untilpass');
- // Special value means allow unlimited attempts.
- define('ASSIGN_UNLIMITED_ATTEMPTS', -1);
- // Marking workflow states.
- define('ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED', 'notmarked');
- define('ASSIGN_MARKING_WORKFLOW_STATE_INMARKING', 'inmarking');
- define('ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW', 'readyforreview');
- define('ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW', 'inreview');
- define('ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE', 'readyforrelease');
- define('ASSIGN_MARKING_WORKFLOW_STATE_RELEASED', 'released');
- require_once($CFG->libdir . '/accesslib.php');
- require_once($CFG->libdir . '/formslib.php');
- require_once($CFG->dirroot . '/repository/lib.php');
- require_once($CFG->dirroot . '/mod/assign/mod_form.php');
- require_once($CFG->libdir . '/gradelib.php');
- require_once($CFG->dirroot . '/grade/grading/lib.php');
- require_once($CFG->dirroot . '/mod/assign/feedbackplugin.php');
- require_once($CFG->dirroot . '/mod/assign/submissionplugin.php');
- require_once($CFG->dirroot . '/mod/assign/renderable.php');
- require_once($CFG->dirroot . '/mod/assign/gradingtable.php');
- require_once($CFG->libdir . '/eventslib.php');
- require_once($CFG->libdir . '/portfolio/caller.php');
- /**
- * Standard base class for mod_assign (assignment types).
- *
- * @package mod_assign
- * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- class assign {
- /** @var stdClass the assignment record that contains the global settings for this assign instance */
- private $instance;
- /** @var stdClass the grade_item record for this assign instance's primary grade item. */
- private $gradeitem;
- /** @var context the context of the course module for this assign instance
- * (or just the course if we are creating a new one)
- */
- private $context;
- /** @var stdClass the course this assign instance belongs to */
- private $course;
- /** @var stdClass the admin config for all assign instances */
- private $adminconfig;
- /** @var assign_renderer the custom renderer for this module */
- private $output;
- /** @var stdClass the course module for this assign instance */
- private $coursemodule;
- /** @var array cache for things like the coursemodule name or the scale menu -
- * only lives for a single request.
- */
- private $cache;
- /** @var array list of the installed submission plugins */
- private $submissionplugins;
- /** @var array list of the installed feedback plugins */
- private $feedbackplugins;
- /** @var string action to be used to return to this page
- * (without repeating any form submissions etc).
- */
- private $returnaction = 'view';
- /** @var array params to be used to return to this page */
- private $returnparams = array();
- /** @var string modulename prevents excessive calls to get_string */
- private static $modulename = null;
- /** @var string modulenameplural prevents excessive calls to get_string */
- private static $modulenameplural = null;
- /** @var array of marking workflow states for the current user */
- private $markingworkflowstates = null;
- /** @var bool whether to exclude users with inactive enrolment */
- private $showonlyactiveenrol = null;
- /** @var array cached list of participants for this assignment. The cache key will be group, showactive and the context id */
- private $participants = array();
- /**
- * Constructor for the base assign class.
- *
- * @param mixed $coursemodulecontext context|null the course module context
- * (or the course context if the coursemodule has not been
- * created yet).
- * @param mixed $coursemodule the current course module if it was already loaded,
- * otherwise this class will load one from the context as required.
- * @param mixed $course the current course if it was already loaded,
- * otherwise this class will load one from the context as required.
- */
- public function __construct($coursemodulecontext, $coursemodule, $course) {
- $this->context = $coursemodulecontext;
- $this->coursemodule = $coursemodule;
- $this->course = $course;
- // Temporary cache only lives for a single request - used to reduce db lookups.
- $this->cache = array();
- $this->submissionplugins = $this->load_plugins('assignsubmission');
- $this->feedbackplugins = $this->load_plugins('assignfeedback');
- }
- /**
- * Set the action and parameters that can be used to return to the current page.
- *
- * @param string $action The action for the current page
- * @param array $params An array of name value pairs which form the parameters
- * to return to the current page.
- * @return void
- */
- public function register_return_link($action, $params) {
- global $PAGE;
- $params['action'] = $action;
- $currenturl = $PAGE->url;
- $currenturl->params($params);
- $PAGE->set_url($currenturl);
- }
- /**
- * Return an action that can be used to get back to the current page.
- *
- * @return string action
- */
- public function get_return_action() {
- global $PAGE;
- $params = $PAGE->url->params();
- if (!empty($params['action'])) {
- return $params['action'];
- }
- return '';
- }
- /**
- * Based on the current assignment settings should we display the intro.
- *
- * @return bool showintro
- */
- protected function show_intro() {
- if ($this->get_instance()->alwaysshowdescription ||
- time() > $this->get_instance()->allowsubmissionsfromdate) {
- return true;
- }
- return false;
- }
- /**
- * Return a list of parameters that can be used to get back to the current page.
- *
- * @return array params
- */
- public function get_return_params() {
- global $PAGE;
- $params = $PAGE->url->params();
- unset($params['id']);
- unset($params['action']);
- return $params;
- }
- /**
- * Set the submitted form data.
- *
- * @param stdClass $data The form data (instance)
- */
- public function set_instance(stdClass $data) {
- $this->instance = $data;
- }
- /**
- * Set the context.
- *
- * @param context $context The new context
- */
- public function set_context(context $context) {
- $this->context = $context;
- }
- /**
- * Set the course data.
- *
- * @param stdClass $course The course data
- */
- public function set_course(stdClass $course) {
- $this->course = $course;
- }
- /**
- * Get list of feedback plugins installed.
- *
- * @return array
- */
- public function get_feedback_plugins() {
- return $this->feedbackplugins;
- }
- /**
- * Get list of submission plugins installed.
- *
- * @return array
- */
- public function get_submission_plugins() {
- return $this->submissionplugins;
- }
- /**
- * Is blind marking enabled and reveal identities not set yet?
- *
- * @return bool
- */
- public function is_blind_marking() {
- return $this->get_instance()->blindmarking && !$this->get_instance()->revealidentities;
- }
- /**
- * Does an assignment have submission(s) or grade(s) already?
- *
- * @return bool
- */
- public function has_submissions_or_grades() {
- $allgrades = $this->count_grades();
- $allsubmissions = $this->count_submissions();
- if (($allgrades == 0) && ($allsubmissions == 0)) {
- return false;
- }
- return true;
- }
- /**
- * Get a specific submission plugin by its type.
- *
- * @param string $subtype assignsubmission | assignfeedback
- * @param string $type
- * @return mixed assign_plugin|null
- */
- public function get_plugin_by_type($subtype, $type) {
- $shortsubtype = substr($subtype, strlen('assign'));
- $name = $shortsubtype . 'plugins';
- if ($name != 'feedbackplugins' && $name != 'submissionplugins') {
- return null;
- }
- $pluginlist = $this->$name;
- foreach ($pluginlist as $plugin) {
- if ($plugin->get_type() == $type) {
- return $plugin;
- }
- }
- return null;
- }
- /**
- * Get a feedback plugin by type.
- *
- * @param string $type - The type of plugin e.g comments
- * @return mixed assign_feedback_plugin|null
- */
- public function get_feedback_plugin_by_type($type) {
- return $this->get_plugin_by_type('assignfeedback', $type);
- }
- /**
- * Get a submission plugin by type.
- *
- * @param string $type - The type of plugin e.g comments
- * @return mixed assign_submission_plugin|null
- */
- public function get_submission_plugin_by_type($type) {
- return $this->get_plugin_by_type('assignsubmission', $type);
- }
- /**
- * Load the plugins from the sub folders under subtype.
- *
- * @param string $subtype - either submission or feedback
- * @return array - The sorted list of plugins
- */
- protected function load_plugins($subtype) {
- global $CFG;
- $result = array();
- $names = core_component::get_plugin_list($subtype);
- foreach ($names as $name => $path) {
- if (file_exists($path . '/locallib.php')) {
- require_once($path . '/locallib.php');
- $shortsubtype = substr($subtype, strlen('assign'));
- $pluginclass = 'assign_' . $shortsubtype . '_' . $name;
- $plugin = new $pluginclass($this, $name);
- if ($plugin instanceof assign_plugin) {
- $idx = $plugin->get_sort_order();
- while (array_key_exists($idx, $result)) {
- $idx +=1;
- }
- $result[$idx] = $plugin;
- }
- }
- }
- ksort($result);
- return $result;
- }
- /**
- * Display the assignment, used by view.php
- *
- * The assignment is displayed differently depending on your role,
- * the settings for the assignment and the status of the assignment.
- *
- * @param string $action The current action if any.
- * @return string - The page output.
- */
- public function view($action='') {
- $o = '';
- $mform = null;
- $notices = array();
- $nextpageparams = array();
- if (!empty($this->get_course_module()->id)) {
- $nextpageparams['id'] = $this->get_course_module()->id;
- }
- // Handle form submissions first.
- if ($action == 'savesubmission') {
- $action = 'editsubmission';
- if ($this->process_save_submission($mform, $notices)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'view';
- }
- } else if ($action == 'editprevioussubmission') {
- $action = 'editsubmission';
- if ($this->process_copy_previous_attempt($notices)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'editsubmission';
- }
- } else if ($action == 'lock') {
- $this->process_lock_submission();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'addattempt') {
- $this->process_add_attempt(required_param('userid', PARAM_INT));
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'reverttodraft') {
- $this->process_revert_to_draft();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'unlock') {
- $this->process_unlock_submission();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'setbatchmarkingworkflowstate') {
- $this->process_set_batch_marking_workflow_state();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'setbatchmarkingallocation') {
- $this->process_set_batch_marking_allocation();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'confirmsubmit') {
- $action = 'submit';
- if ($this->process_submit_for_grading($mform)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'view';
- }
- } else if ($action == 'gradingbatchoperation') {
- $action = $this->process_grading_batch_operation($mform);
- if ($action == 'grading') {
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- }
- } else if ($action == 'submitgrade') {
- if (optional_param('saveandshownext', null, PARAM_RAW)) {
- // Save and show next.
- $action = 'grade';
- if ($this->process_save_grade($mform)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'grade';
- $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) + 1;
- $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
- }
- } else if (optional_param('nosaveandprevious', null, PARAM_RAW)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'grade';
- $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) - 1;
- $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
- } else if (optional_param('nosaveandnext', null, PARAM_RAW)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'grade';
- $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) + 1;
- $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
- } else if (optional_param('savegrade', null, PARAM_RAW)) {
- // Save changes button.
- $action = 'grade';
- if ($this->process_save_grade($mform)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'savegradingresult';
- }
- } else {
- // Cancel button.
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- }
- } else if ($action == 'quickgrade') {
- $message = $this->process_save_quick_grades();
- $action = 'quickgradingresult';
- } else if ($action == 'saveoptions') {
- $this->process_save_grading_options();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- } else if ($action == 'saveextension') {
- $action = 'grantextension';
- if ($this->process_save_extension($mform)) {
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- }
- } else if ($action == 'revealidentitiesconfirm') {
- $this->process_reveal_identities();
- $action = 'redirect';
- $nextpageparams['action'] = 'grading';
- }
- $returnparams = array('rownum'=>optional_param('rownum', 0, PARAM_INT),
- 'useridlistid'=>optional_param('useridlistid', 0, PARAM_INT));
- $this->register_return_link($action, $returnparams);
- // Now show the right view page.
- if ($action == 'redirect') {
- $nextpageurl = new moodle_url('/mod/assign/view.php', $nextpageparams);
- redirect($nextpageurl);
- return;
- } else if ($action == 'savegradingresult') {
- $message = get_string('gradingchangessaved', 'assign');
- $o .= $this->view_savegrading_result($message);
- } else if ($action == 'quickgradingresult') {
- $mform = null;
- $o .= $this->view_quickgrading_result($message);
- } else if ($action == 'grade') {
- $o .= $this->view_single_grade_page($mform);
- } else if ($action == 'viewpluginassignfeedback') {
- $o .= $this->view_plugin_content('assignfeedback');
- } else if ($action == 'viewpluginassignsubmission') {
- $o .= $this->view_plugin_content('assignsubmission');
- } else if ($action == 'editsubmission') {
- $o .= $this->view_edit_submission_page($mform, $notices);
- } else if ($action == 'grading') {
- $o .= $this->view_grading_page();
- } else if ($action == 'downloadall') {
- $o .= $this->download_submissions();
- } else if ($action == 'submit') {
- $o .= $this->check_submit_for_grading($mform);
- } else if ($action == 'grantextension') {
- $o .= $this->view_grant_extension($mform);
- } else if ($action == 'revealidentities') {
- $o .= $this->view_reveal_identities_confirm($mform);
- } else if ($action == 'plugingradingbatchoperation') {
- $o .= $this->view_plugin_grading_batch_operation($mform);
- } else if ($action == 'viewpluginpage') {
- $o .= $this->view_plugin_page();
- } else if ($action == 'viewcourseindex') {
- $o .= $this->view_course_index();
- } else if ($action == 'viewbatchsetmarkingworkflowstate') {
- $o .= $this->view_batch_set_workflow_state($mform);
- } else if ($action == 'viewbatchmarkingallocation') {
- $o .= $this->view_batch_markingallocation($mform);
- } else {
- $o .= $this->view_submission_page();
- }
- return $o;
- }
- /**
- * Add this instance to the database.
- *
- * @param stdClass $formdata The data submitted from the form
- * @param bool $callplugins This is used to skip the plugin code
- * when upgrading an old assignment to a new one (the plugins get called manually)
- * @return mixed false if an error occurs or the int id of the new instance
- */
- public function add_instance(stdClass $formdata, $callplugins) {
- global $DB;
- $err = '';
- // Add the database record.
- $update = new stdClass();
- $update->name = $formdata->name;
- $update->timemodified = time();
- $update->timecreated = time();
- $update->course = $formdata->course;
- $update->courseid = $formdata->course;
- $update->intro = $formdata->intro;
- $update->introformat = $formdata->introformat;
- $update->alwaysshowdescription = !empty($formdata->alwaysshowdescription);
- $update->submissiondrafts = $formdata->submissiondrafts;
- $update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
- $update->sendnotifications = $formdata->sendnotifications;
- $update->sendlatenotifications = $formdata->sendlatenotifications;
- $update->duedate = $formdata->duedate;
- $update->cutoffdate = $formdata->cutoffdate;
- $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
- $update->grade = $formdata->grade;
- $update->completionsubmit = !empty($formdata->completionsubmit);
- $update->teamsubmission = $formdata->teamsubmission;
- $update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
- if (isset($formdata->teamsubmissiongroupingid)) {
- $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
- }
- $update->blindmarking = $formdata->blindmarking;
- $update->attemptreopenmethod = ASSIGN_ATTEMPT_REOPEN_METHOD_NONE;
- if (!empty($formdata->attemptreopenmethod)) {
- $update->attemptreopenmethod = $formdata->attemptreopenmethod;
- }
- if (!empty($formdata->maxattempts)) {
- $update->maxattempts = $formdata->maxattempts;
- }
- $update->markingworkflow = $formdata->markingworkflow;
- $update->markingallocation = $formdata->markingallocation;
- if (empty($update->markingworkflow)) { // If marking workflow is disabled, make sure allocation is disabled.
- $update->markingallocation = 0;
- }
- $returnid = $DB->insert_record('assign', $update);
- $this->instance = $DB->get_record('assign', array('id'=>$returnid), '*', MUST_EXIST);
- // Cache the course record.
- $this->course = $DB->get_record('course', array('id'=>$formdata->course), '*', MUST_EXIST);
- if ($callplugins) {
- // Call save_settings hook for submission plugins.
- foreach ($this->submissionplugins as $plugin) {
- if (!$this->update_plugin_instance($plugin, $formdata)) {
- print_error($plugin->get_error());
- return false;
- }
- }
- foreach ($this->feedbackplugins as $plugin) {
- if (!$this->update_plugin_instance($plugin, $formdata)) {
- print_error($plugin->get_error());
- return false;
- }
- }
- // In the case of upgrades the coursemodule has not been set,
- // so we need to wait before calling these two.
- $this->update_calendar($formdata->coursemodule);
- $this->update_gradebook(false, $formdata->coursemodule);
- }
- $update = new stdClass();
- $update->id = $this->get_instance()->id;
- $update->nosubmissions = (!$this->is_any_submission_plugin_enabled()) ? 1: 0;
- $DB->update_record('assign', $update);
- return $returnid;
- }
- /**
- * Delete all grades from the gradebook for this assignment.
- *
- * @return bool
- */
- protected function delete_grades() {
- global $CFG;
- $result = grade_update('mod/assign',
- $this->get_course()->id,
- 'mod',
- 'assign',
- $this->get_instance()->id,
- 0,
- null,
- array('deleted'=>1));
- return $result == GRADE_UPDATE_OK;
- }
- /**
- * Delete this instance from the database.
- *
- * @return bool false if an error occurs
- */
- public function delete_instance() {
- global $DB;
- $result = true;
- foreach ($this->submissionplugins as $plugin) {
- if (!$plugin->delete_instance()) {
- print_error($plugin->get_error());
- $result = false;
- }
- }
- foreach ($this->feedbackplugins as $plugin) {
- if (!$plugin->delete_instance()) {
- print_error($plugin->get_error());
- $result = false;
- }
- }
- // Delete files associated with this assignment.
- $fs = get_file_storage();
- if (! $fs->delete_area_files($this->context->id) ) {
- $result = false;
- }
- // Delete_records will throw an exception if it fails - so no need for error checking here.
- $DB->delete_records('assign_submission', array('assignment'=>$this->get_instance()->id));
- $DB->delete_records('assign_grades', array('assignment'=>$this->get_instance()->id));
- $DB->delete_records('assign_plugin_config', array('assignment'=>$this->get_instance()->id));
- // Delete items from the gradebook.
- if (! $this->delete_grades()) {
- $result = false;
- }
- // Delete the instance.
- $DB->delete_records('assign', array('id'=>$this->get_instance()->id));
- return $result;
- }
- /**
- * Actual implementation of the reset course functionality, delete all the
- * assignment submissions for course $data->courseid.
- *
- * @param stdClass $data the data submitted from the reset course.
- * @return array status array
- */
- public function reset_userdata($data) {
- global $CFG, $DB;
- $componentstr = get_string('modulenameplural', 'assign');
- $status = array();
- $fs = get_file_storage();
- if (!empty($data->reset_assign_submissions)) {
- // Delete files associated with this assignment.
- foreach ($this->submissionplugins as $plugin) {
- $fileareas = array();
- $plugincomponent = $plugin->get_subtype() . '_' . $plugin->get_type();
- $fileareas = $plugin->get_file_areas();
- foreach ($fileareas as $filearea) {
- $fs->delete_area_files($this->context->id, $plugincomponent, $filearea);
- }
- if (!$plugin->delete_instance()) {
- $status[] = array('component'=>$componentstr,
- 'item'=>get_string('deleteallsubmissions', 'assign'),
- 'error'=>$plugin->get_error());
- }
- }
- foreach ($this->feedbackplugins as $plugin) {
- $fileareas = array();
- $plugincomponent = $plugin->get_subtype() . '_' . $plugin->get_type();
- $fileareas = $plugin->get_file_areas();
- foreach ($fileareas as $filearea) {
- $fs->delete_area_files($this->context->id, $plugincomponent, $filearea);
- }
- if (!$plugin->delete_instance()) {
- $status[] = array('component'=>$componentstr,
- 'item'=>get_string('deleteallsubmissions', 'assign'),
- 'error'=>$plugin->get_error());
- }
- }
- $assignssql = 'SELECT a.id
- FROM {assign} a
- WHERE a.course=:course';
- $params = array('course'=>$data->courseid);
- $DB->delete_records_select('assign_submission', "assignment IN ($assignssql)", $params);
- $status[] = array('component'=>$componentstr,
- 'item'=>get_string('deleteallsubmissions', 'assign'),
- 'error'=>false);
- if (!empty($data->reset_gradebook_grades)) {
- $DB->delete_records_select('assign_grades', "assignment IN ($assignssql)", $params);
- // Remove all grades from gradebook.
- require_once($CFG->dirroot.'/mod/assign/lib.php');
- assign_reset_gradebook($data->courseid);
- }
- }
- // Updating dates - shift may be negative too.
- if ($data->timeshift) {
- shift_course_mod_dates('assign',
- array('duedate', 'allowsubmissionsfromdate', 'cutoffdate'),
- $data->timeshift,
- $data->courseid, $this->get_instance()->id);
- $status[] = array('component'=>$componentstr,
- 'item'=>get_string('datechanged'),
- 'error'=>false);
- }
- return $status;
- }
- /**
- * Update the settings for a single plugin.
- *
- * @param assign_plugin $plugin The plugin to update
- * @param stdClass $formdata The form data
- * @return bool false if an error occurs
- */
- protected function update_plugin_instance(assign_plugin $plugin, stdClass $formdata) {
- if ($plugin->is_visible()) {
- $enabledname = $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled';
- if (!empty($formdata->$enabledname)) {
- $plugin->enable();
- if (!$plugin->save_settings($formdata)) {
- print_error($plugin->get_error());
- return false;
- }
- } else {
- $plugin->disable();
- }
- }
- return true;
- }
- /**
- * Update the gradebook information for this assignment.
- *
- * @param bool $reset If true, will reset all grades in the gradbook for this assignment
- * @param int $coursemoduleid This is required because it might not exist in the database yet
- * @return bool
- */
- public function update_gradebook($reset, $coursemoduleid) {
- global $CFG;
- require_once($CFG->dirroot.'/mod/assign/lib.php');
- $assign = clone $this->get_instance();
- $assign->cmidnumber = $coursemoduleid;
- $param = null;
- if ($reset) {
- $param = 'reset';
- }
- return assign_grade_item_update($assign, $param);
- }
- /**
- * Load and cache the admin config for this module.
- *
- * @return stdClass the plugin config
- */
- public function get_admin_config() {
- if ($this->adminconfig) {
- return $this->adminconfig;
- }
- $this->adminconfig = get_config('assign');
- return $this->adminconfig;
- }
- /**
- * Update the calendar entries for this assignment.
- *
- * @param int $coursemoduleid - Required to pass this in because it might
- * not exist in the database yet.
- * @return bool
- */
- public function update_calendar($coursemoduleid) {
- global $DB, $CFG;
- require_once($CFG->dirroot.'/calendar/lib.php');
- // Special case for add_instance as the coursemodule has not been set yet.
- $instance = $this->get_instance();
- if ($instance->duedate) {
- $event = new stdClass();
- $params = array('modulename'=>'assign', 'instance'=>$instance->id);
- $event->id = $DB->get_field('event', 'id', $params);
- $event->name = $instance->name;
- $event->timestart = $instance->duedate;
- // Convert the links to pluginfile. It is a bit hacky but at this stage the files
- // might not have been saved in the module area yet.
- $intro = $instance->intro;
- if ($draftid = file_get_submitted_draft_itemid('introeditor')) {
- $intro = file_rewrite_urls_to_pluginfile($intro, $draftid);
- }
- // We need to remove the links to files as the calendar is not ready
- // to support module events with file areas.
- $intro = strip_pluginfile_content($intro);
- if ($this->show_intro()) {
- $event->description = array(
- 'text' => $intro,
- 'format' => $instance->introformat
- );
- } else {
- $event->description = array(
- 'text' => '',
- 'format' => $instance->introformat
- );
- }
- if ($event->id) {
- $calendarevent = calendar_event::load($event->id);
- $calendarevent->update($event);
- } else {
- unset($event->id);
- $event->courseid = $instance->course;
- $event->groupid = 0;
- $event->userid = 0;
- $event->modulename = 'assign';
- $event->instance = $instance->id;
- $event->eventtype = 'due';
- $event->timeduration = 0;
- calendar_event::create($event);
- }
- } else {
- $DB->delete_records('event', array('modulename'=>'assign', 'instance'=>$instance->id));
- }
- }
- /**
- * Update this instance in the database.
- *
- * @param stdClass $formdata - the data submitted from the form
- * @return bool false if an error occurs
- */
- public function update_instance($formdata) {
- global $DB;
- $update = new stdClass();
- $update->id = $formdata->instance;
- $update->name = $formdata->name;
- $update->timemodified = time();
- $update->course = $formdata->course;
- $update->intro = $formdata->intro;
- $update->introformat = $formdata->introformat;
- $update->alwaysshowdescription = !empty($formdata->alwaysshowdescription);
- $update->submissiondrafts = $formdata->submissiondrafts;
- $update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
- $update->sendnotifications = $formdata->sendnotifications;
- $update->sendlatenotifications = $formdata->sendlatenotifications;
- $update->duedate = $formdata->duedate;
- $update->cutoffdate = $formdata->cutoffdate;
- $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
- $update->grade = $formdata->grade;
- if (!empty($formdata->completionunlocked)) {
- $update->completionsubmit = !empty($formdata->completionsubmit);
- }
- $update->teamsubmission = $formdata->teamsubmission;
- $update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
- if (isset($formdata->teamsubmissiongroupingid)) {
- $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
- }
- $update->blindmarking = $formdata->blindmarking;
- $update->attemptreopenmethod = ASSIGN_ATTEMPT_REOPEN_METHOD_NONE;
- if (!empty($formdata->attemptreopenmethod)) {
- $update->attemptreopenmethod = $formdata->attemptreopenmethod;
- }
- if (!empty($formdata->maxattempts)) {
- $update->maxattempts = $formdata->maxattempts;
- }
- $update->markingworkflow = $formdata->markingworkflow;
- $update->markingallocation = $formdata->markingallocation;
- if (empty($update->markingworkflow)) { // If marking workflow is disabled, make sure allocation is disabled.
- $update->markingallocation = 0;
- }
- $result = $DB->update_record('assign', $update);
- $this->instance = $DB->get_record('assign', array('id'=>$update->id), '*', MUST_EXIST);
- // Load the assignment so the plugins have access to it.
- // Call save_settings hook for submission plugins.
- foreach ($this->submissionplugins as $plugin) {
- if (!$this->update_plugin_instance($plugin, $formdata)) {
- print_error($plugin->get_error());
- return false;
- }
- }
- foreach ($this->feedbackplugins as $plugin) {
- if (!$this->update_plugin_instance($plugin, $formdata)) {
- print_error($plugin->get_error());
- return false;
- }
- }
- $this->update_calendar($this->get_course_module()->id);
- $this->update_gradebook(false, $this->get_course_module()->id);
- $update = new stdClass();
- $update->id = $this->get_instance()->id;
- $update->nosubmissions = (!$this->is_any_submission_plugin_enabled()) ? 1: 0;
- $DB->update_record('assign', $update);
- return $result;
- }
- /**
- * Add elements in grading plugin form.
- *
- * @param mixed $grade stdClass|null
- * @param MoodleQuickForm $mform
- * @param stdClass $data
- * @param int $userid - The userid we are grading
- * @return void
- */
- protected function add_plugin_grade_elements($grade, MoodleQuickForm $mform, stdClass $data, $userid) {
- foreach ($this->feedbackplugins as $plugin) {
- if ($plugin->is_enabled() && $plugin->is_visible()) {
- $mform->addElement('header', 'header_' . $plugin->get_type(), $plugin->get_name());
- $mform->setExpanded('header_' . $plugin->get_type());
- if (!$plugin->get_form_elements_for_user($grade, $mform, $data, $userid)) {
- $mform->removeElement('header_' . $plugin->get_type());
- }
- }
- }
- }
- /**
- * Add one plugins settings to edit plugin form.
- *
- * @param assign_plugin $plugin The plugin to add the settings from
- * @param MoodleQuickForm $mform The form to add the configuration settings to.
- * This form is modified directly (not returned).
- * @param array $pluginsenabled A list of form elements to be added to a group.
- * The new element is added to this array by this function.
- * @return void
- */
- protected function add_plugin_settings(assign_plugin $plugin, MoodleQuickForm $mform, & $pluginsenabled) {
- global $CFG;
- if ($plugin->is_visible() && !$plugin->is_configurable() && $plugin->is_enabled()) {
- $name = $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled';
- $pluginsenabled[] = $mform->createElement('hidden', $name, 1);
- $mform->setType($name, PARAM_BOOL);
- $plugin->get_settings($mform);
- } else if ($plugin->is_visible() && $plugin->is_configurable()) {
- $name = $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled';
- $label = $plugin->get_name();
- $label .= ' ' . $this->get_renderer()->help_icon('enabled', $plugin->get_subtype() . '_' . $plugin->get_type());
- $pluginsenabled[] = $mform->createElement('checkbox', $name, '', $label);
- $default = get_config($plugin->get_subtype() . '_' . $plugin->get_type(), 'default');
- if ($plugin->get_config('enabled') !== false) {
- $default = $plugin->is_enabled();
- }
- $mform->setDefault($plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled', $default);
- $plugin->get_settings($mform);
- }
- }
- /**
- * Add settings to edit plugin form.
- *
- * @param MoodleQuickForm $mform The form to add the configuration settings to.
- * This form is modified directly (not returned).
- * @return void
- */
- public function add_all_plugin_settings(MoodleQuickForm $mform) {
- $mform->addElement('header', 'submissiontypes', get_string('submissiontypes', 'assign'));
- $submissionpluginsenabled = array();
- $group = $mform->addGroup(array(), 'submissionplugins', get_string('submissiontypes', 'assign'), array(' '), false);
- foreach ($this->submissionplugins as $plugin) {
- $this->add_plugin_settings($plugin, $mform, $submissionpluginsenabled);
- }
- $group->setElements($submissionpluginsenabled);
- $mform->addElement('header', 'feedbacktypes', get_string('feedbacktypes', 'assign'));
- $feedbackpluginsenabled = array();
- $group = $mform->addGroup(array(), 'feedbackplugins', get_string('feedbacktypes', 'assign'), array(' '), false);
- foreach ($this->feedbackplugins as $plugin) {
- $this->add_plugin_settings($plugin, $mform, $feedbackpluginsenabled);
- }
- $group->setElements($feedbackpluginsenabled);
- $mform->setExpanded('submissiontypes');
- }
- /**
- * Allow each plugin an opportunity to update the defaultvalues
- * passed in to the settings form (needed to set up draft areas for
- * editor and filemanager elements)
- *
- * @param array $defaultvalues
- */
- public function plugin_data_preprocessing(&$defaultvalues) {
- foreach ($this->submissionplugins as $plugin) {
- if ($plugin->is_visible()) {
- $plugin->data_preprocessing($defaultvalues);
- }
- }
- foreach ($this->feedbackplugins as $plugin) {
- if ($plugin->is_visible()) {
- $plugin->data_preprocessing($defaultvalues);
- }
- }
- }
- /**
- * Get the name of the current module.
- *
- * @return string the module name (Assignment)
- */
- protected function get_module_name() {
- if (isset(self::$modulename)) {
- return self::$modulename;
- }
- self::$modulename = get_string('modulename', 'assign');
- return self::$modulename;
- }
- /**
- * Get the plural name of the current module.
- *
- * @return string the module name plural (Assignments)
- */
- protected function get_module_name_plural() {
- if (isset(self::$modulenameplural)) {
- return self::$modulenameplural;
- }
- self::$modulenameplural = get_string('modulenameplural', 'assign');
- return self::$modulenameplural;
- }
- /**
- * Has this assignment been constructed from an instance?
- *
- * @return bool
- */
- public function has_instance() {
- return $this->instance || $this->get_course_module();
- }
- /**
- * Get the settings for the current instance of this assignment
- *
- * @return stdClass The settings
- */
- public function get_instance() {
- global $DB;
- if ($this->instance) {
- return $this->instance;
- }
- if ($this->get_course_module()) {
- $params = array('id' => $this->get_course_module()->instance);
- $this->instance = $DB->get_record('assign', $params, '*', MUST_EXIST);
- }
- if (!$this->instance) {
- throw new coding_exception('Improper use of the assignment class. ' .
- 'Cannot load the assignment record.');
- }
- return $this->instance;
- }
- /**
- * Get the primary grade item for this assign instance.
- *
- * @return stdClass The grade_item record
- */
- public function get_grade_item() {
- if ($this->gradeitem) {
- return $this->gradeitem;
- }
- $instance = $this->get_instance();
- $params = array('itemtype' => 'mod',
- 'itemmodule' => 'assign',
- 'iteminstance' => $instance->id,
- 'courseid' => $instance->course,
- 'itemnumber' => 0);
- $this->gradeitem = grade_item::fetch($params);
- if (!$this->gradeitem) {
- throw new coding_exception('Improper use of the assignment class. ' .
- 'Cannot load the grade item.');
- }
- return $this->gradeitem;
- }
- /**
- * Get the context of the current course.
- *
- * @return mixed context|null The course context
- */
- public function get_course_context() {
- if (!$this->context && !$this->course) {
- throw new coding_exception('Improper use of the assignment class. ' .
- 'Cannot load the course context.');
- }
- if ($this->context) {
- return $this->context->get_course_context();
- } else {
- return context_course::instance($this->course->id);
- }
- }
- /**
- * Get the current course module.
- *
- * @return mixed stdClass|null The course module
- */
- public function get_course_module() {
- if ($this->coursemodule) {
- return $this->coursemodule;
- }
- if (!$this->context) {
- return null;
- }
- if ($this->context->contextlevel == CONTEXT_MODULE) {
- $this->coursemodule = get_coursemodule_from_id('assign',
- $this->context->instanceid,
- 0,
- false,
- MUST_EXIST);
- return $this->coursemodule;
- }
- return null;
- }
- /**
- * Get context module.
- *
- * @return context
- */
- public function get_context() {
- return $this->context;
- }
- /**
- * Get the current course.
- *
- * @return mixed stdClass|null The course
- */
- public function get_course() {
- global $DB;
- if ($this->course) {
- return $this->course;
- }
- if (!$this->context) {
- return null;
- }
- $params = array('id' => $this->get_course_context()->instanceid);
- $this->course = $DB->get_record('course', $params, '*', MUST_EXIST);
- return $this->course;
- }
- /**
- * Return a grade in user-friendly form, whether it's a scale or not.
- *
- * @param mixed $grade int|null
- * @param boolean $editing Are we allowing changes to this grade?
- * @param int $userid The user id the grade belongs to
- * @param int $modified Timestamp from when the grade was last modified
- * @return string User-friendly representation of grade
- */
- public function display_grade($grade, $editing, $userid=0, $modified=0) {
- global $DB;
- static $scalegrades = array();
- $o = '';
- if ($this->get_instance()->grade >= 0) {
- // Normal number.
- if ($editing && $this->get_instance()->grade > 0) {
- if ($grade < 0) {
- $displaygrade = '';
- } else {
- $displaygrade = format_float($grade, 2);
- }
- $o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' .
- get_string('usergrade', 'assign') .
- '</label>';
- $o .= '<input type="text"
- id="quickgrade_' . $userid . '"
- name="quickgrade_' . $userid . '"
- value="' . $displaygrade . '"
- size="6"
- maxlength="10"
- class="quickgrade"/>';
- $o .= ' / ' . format_float($this->get_instance()->grade, 2);
- return $o;
- } else {
- if ($grade == -1 || $grade === null) {
- $o .= '-';
- } else {
- $item = $this->get_grade_item();
- $o .= grade_format_gradevalue($grade, $item);
- if ($item->get_displaytype() == GRADE_DISPLAY_TYPE_REAL) {
- // If displaying the raw grade, also display the total value.
- $o .= ' / ' . format_float($this->get_instance()->grade, 2);
- }
- }
- return $o;
- }
- } else {
- // Scale.
- if (empty($this->cache['scale'])) {
- if ($scale = $DB->get_record('scale', array('id'=>-($this->get_instance()->grade)))) {
- $this->cache['scale'] = make_menu_from_list($scale->scale);
- } else {
- $o .= '-';
- return $o;
- }
- }
- if ($editing) {
- $o .= '<label class="accesshide"
- for="quickgrade_' . $userid . '">' .
- get_string('usergrade', 'assign') .
- '</label>';
- $o .= '<select name="quickgrade_' . $userid . '" class="quickgrade">';
- $o .= '<option value="-1">' . get_string('nograde') . '</option>';
- foreach ($this->cache['scale'] as $optionid => $option) {
- $selected = '';
- if ($grade == $optionid) {
- $selected = 'selected="selected"';
- }
- $o .= '<option value="' . $optionid . '" ' . $selected . '>' . $option . '</option>';
- }
- $o .= '</select>';
- return $o;
- } else {
- $scaleid = (int)$grade;
- if (isset($this->cache['scale'][$scaleid])) {
- $o .= $this->cache['scale'][$scaleid];
- return $o;
- }
- $o .= '-';
- return $o;
- }
- }
- }
- /**
- * Load a list of users enrolled in the current course with the specified permission and group.
- * 0 for no group.
- *
- * @param int $currentgroup
- * @param bool $idsonly
- * @return array List of user records
- */
- public function list_participants($currentgroup, $idsonly) {
- $key = $this->context->id…
Large files files are truncated, but you can click here to view the full file