first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
ACTIVITY MODULES
----------------
These are main modules in Moodle, allowing various activities.
Each of these modules contains a number of expected components:
mod_form.php: a form to setup/update a module instance
version.php: defines some meta-info and provides upgrading code
pix/icon.gif: a 16x16 icon for the module
db/install.xml: an SQL dump of all the required db tables and data
index.php: a page to list all instances in a course
view.php: a page to view a particular instance
lib.php: any/all functions defined by the module should be in here.
constants should be defined using MODULENAME_xxxxxx
functions should be defined using modulename_xxxxxx
There are a number of standard functions:
modulename_add_instance()
modulename_update_instance()
modulename_delete_instance()
modulename_user_complete()
modulename_user_outline()
modulename_cron()
modulename_print_recent_activity()
If you are a developer and interested in developing new Modules see:
Moodle Documentation: http://moodle.org/doc
Moodle Community: http://moodle.org/community
+372
View File
@@ -0,0 +1,372 @@
<?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 classes for the admin settings of the 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();
require_once($CFG->libdir . '/adminlib.php');
/**
* Admin external page that displays a list of the installed submission plugins.
*
* @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_admin_page_manage_assign_plugins extends admin_externalpage {
/** @var string the name of plugin subtype */
private $subtype = '';
/**
* The constructor - calls parent constructor
*
* @param string $subtype
*/
public function __construct($subtype) {
$this->subtype = $subtype;
$url = new moodle_url('/mod/assign/adminmanageplugins.php', array('subtype'=>$subtype));
parent::__construct('manage' . $subtype . 'plugins',
get_string('manage' . $subtype . 'plugins', 'assign'),
$url);
}
/**
* Search plugins for the specified string
*
* @param string $query The string to search for
* @return array
*/
public function search($query) {
if ($result = parent::search($query)) {
return $result;
}
$found = false;
foreach (core_component::get_plugin_list($this->subtype) as $name => $notused) {
if (strpos(core_text::strtolower(get_string('pluginname', $this->subtype . '_' . $name)),
$query) !== false) {
$found = true;
break;
}
}
if ($found) {
$result = new stdClass();
$result->page = $this;
$result->settings = array();
return array($this->name => $result);
} else {
return array();
}
}
}
/**
* Class that handles the display and configuration of the list of submission plugins.
*
* @package mod_assign
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assign_plugin_manager {
/** @var object the url of the manage submission plugin page */
private $pageurl;
/** @var string any error from the current action */
private $error = '';
/** @var string either submission or feedback */
private $subtype = '';
/**
* Constructor for this assignment plugin manager
* @param string $subtype - either assignsubmission or assignfeedback
*/
public function __construct($subtype) {
$this->pageurl = new moodle_url('/mod/assign/adminmanageplugins.php', array('subtype'=>$subtype));
$this->subtype = $subtype;
}
/**
* Return a list of plugins sorted by the order defined in the admin interface
*
* @return array The list of plugins
*/
public function get_sorted_plugins_list() {
$names = core_component::get_plugin_list($this->subtype);
$result = array();
foreach ($names as $name => $path) {
$idx = get_config($this->subtype . '_' . $name, 'sortorder');
if (!$idx) {
$idx = 0;
}
while (array_key_exists($idx, $result)) {
$idx +=1;
}
$result[$idx] = $name;
}
ksort($result);
return $result;
}
/**
* Util function for writing an action icon link
*
* @param string $action URL parameter to include in the link
* @param string $plugin URL parameter to include in the link
* @param string $icon The key to the icon to use (e.g. 't/up')
* @param string $alt The string description of the link used as the title and alt text
* @return string The icon/link
*/
private function format_icon_link($action, $plugin, $icon, $alt) {
global $OUTPUT;
$url = $this->pageurl;
if ($action === 'delete') {
$url = core_plugin_manager::instance()->get_uninstall_url($this->subtype.'_'.$plugin, 'manage');
if (!$url) {
return '&nbsp;';
}
return html_writer::link($url, get_string('uninstallplugin', 'core_admin'));
}
return $OUTPUT->action_icon(new moodle_url($url,
array('action' => $action, 'plugin'=> $plugin, 'sesskey' => sesskey())),
new pix_icon($icon, $alt, 'moodle', array('title' => $alt)),
null, array('title' => $alt)) . ' ';
}
/**
* Write the HTML for the submission plugins table.
*
* @return None
*/
private function view_plugins_table() {
global $OUTPUT, $CFG;
require_once($CFG->libdir . '/tablelib.php');
// Set up the table.
$this->view_header();
$table = new flexible_table($this->subtype . 'pluginsadminttable');
$table->define_baseurl($this->pageurl);
$table->define_columns(array('pluginname', 'version', 'hideshow', 'order',
'settings', 'uninstall'));
$table->define_headers(array(get_string($this->subtype . 'pluginname', 'assign'),
get_string('version'), get_string('hideshow', 'assign'),
get_string('order'), get_string('settings'), get_string('uninstallplugin', 'core_admin')));
$table->set_attribute('id', $this->subtype . 'plugins');
$table->set_attribute('class', 'admintable generaltable');
$table->setup();
$plugins = $this->get_sorted_plugins_list();
$shortsubtype = substr($this->subtype, strlen('assign'));
foreach ($plugins as $idx => $plugin) {
$row = array();
$class = '';
$row[] = get_string('pluginname', $this->subtype . '_' . $plugin);
$row[] = get_config($this->subtype . '_' . $plugin, 'version');
$visible = !get_config($this->subtype . '_' . $plugin, 'disabled');
if ($visible) {
$row[] = $this->format_icon_link('hide', $plugin, 't/hide', get_string('disable'));
} else {
$row[] = $this->format_icon_link('show', $plugin, 't/show', get_string('enable'));
$class = 'dimmed_text';
}
$movelinks = '';
if (!$idx == 0) {
$movelinks .= $this->format_icon_link('moveup', $plugin, 't/up', get_string('up'));
} else {
$movelinks .= $OUTPUT->spacer(array('width'=>16));
}
if ($idx != count($plugins) - 1) {
$movelinks .= $this->format_icon_link('movedown', $plugin, 't/down', get_string('down'));
}
$row[] = $movelinks;
$exists = file_exists($CFG->dirroot . '/mod/assign/' . $shortsubtype . '/' . $plugin . '/settings.php');
if ($row[1] != '' && $exists) {
$row[] = html_writer::link(new moodle_url('/admin/settings.php',
array('section' => $this->subtype . '_' . $plugin)), get_string('settings'));
} else {
$row[] = '&nbsp;';
}
$row[] = $this->format_icon_link('delete', $plugin, 't/delete', get_string('uninstallplugin', 'core_admin'));
$table->add_data($row, $class);
}
$table->finish_output();
$this->view_footer();
}
/**
* Write the page header
*
* @return None
*/
private function view_header() {
global $OUTPUT;
admin_externalpage_setup('manage' . $this->subtype . 'plugins');
// Print the page heading.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('manage' . $this->subtype . 'plugins', 'assign'));
}
/**
* Write the page footer
*
* @return None
*/
private function view_footer() {
global $OUTPUT;
echo $OUTPUT->footer();
}
/**
* Check this user has permission to edit the list of installed plugins
*
* @return None
*/
private function check_permissions() {
// Check permissions.
require_login();
$systemcontext = context_system::instance();
require_capability('moodle/site:config', $systemcontext);
}
/**
* Hide this plugin.
*
* @param string $plugin - The plugin to hide
* @return string The next page to display
*/
public function hide_plugin($plugin) {
$class = \core_plugin_manager::resolve_plugininfo_class($this->subtype);
$class::enable_plugin($plugin, false);
return 'view';
}
/**
* Change the order of this plugin.
*
* @param string $plugintomove - The plugin to move
* @param string $dir - up or down
* @return string The next page to display
*/
public function move_plugin($plugintomove, $dir) {
// Get a list of the current plugins.
$plugins = $this->get_sorted_plugins_list();
$currentindex = 0;
// Throw away the keys.
$plugins = array_values($plugins);
// Find this plugin in the list.
foreach ($plugins as $key => $plugin) {
if ($plugin == $plugintomove) {
$currentindex = $key;
break;
}
}
// Make the switch.
if ($dir == 'up') {
if ($currentindex > 0) {
$tempplugin = $plugins[$currentindex - 1];
$plugins[$currentindex - 1] = $plugins[$currentindex];
$plugins[$currentindex] = $tempplugin;
}
} else if ($dir == 'down') {
if ($currentindex < (count($plugins) - 1)) {
$tempplugin = $plugins[$currentindex + 1];
$plugins[$currentindex + 1] = $plugins[$currentindex];
$plugins[$currentindex] = $tempplugin;
}
}
// Save the new normal order.
foreach ($plugins as $key => $plugin) {
set_config('sortorder', $key, $this->subtype . '_' . $plugin);
}
return 'view';
}
/**
* Show this plugin.
*
* @param string $plugin - The plugin to show
* @return string The next page to display
*/
public function show_plugin($plugin) {
$class = \core_plugin_manager::resolve_plugininfo_class($this->subtype);
$class::enable_plugin($plugin, true);
return 'view';
}
/**
* This is the entry point for this controller class.
*
* @param string $action - The action to perform
* @param string $plugin - Optional name of a plugin type to perform the action on
* @return None
*/
public function execute($action, $plugin) {
if ($action == null) {
$action = 'view';
}
$this->check_permissions();
// Process.
if ($action == 'hide' && $plugin != null) {
$action = $this->hide_plugin($plugin);
} else if ($action == 'show' && $plugin != null) {
$action = $this->show_plugin($plugin);
} else if ($action == 'moveup' && $plugin != null) {
$action = $this->move_plugin($plugin, 'up');
} else if ($action == 'movedown' && $plugin != null) {
$action = $this->move_plugin($plugin, 'down');
}
// View.
if ($action == 'view') {
$this->view_plugins_table();
}
}
}
+42
View File
@@ -0,0 +1,42 @@
<?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/>.
/**
* Allows the admin to manage assignment plugins
*
* @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
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot.'/mod/assign/adminlib.php');
$subtype = required_param('subtype', PARAM_PLUGIN);
$action = optional_param('action', null, PARAM_PLUGIN);
$plugin = optional_param('plugin', null, PARAM_PLUGIN);
if (!empty($plugin)) {
require_sesskey();
}
// Create the class for this controller.
$pluginmanager = new assign_plugin_manager($subtype);
$PAGE->set_context(context_system::instance());
// Execute the controller.
$pluginmanager->execute($action, $plugin);
+11
View File
@@ -0,0 +1,11 @@
/**
* Javascript controller for the "Actions" panel at the bottom of the page.
*
* @module mod_assign/grading_actions
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define("mod_assign/grading_actions",["jquery","mod_assign/grading_events"],(function($,GradingEvents){var GradingActions=function(selector){this._regionSelector=selector,this._region=$(selector),this.registerEventListeners()};return GradingActions.prototype._regionSelector=null,GradingActions.prototype._lastUserId=0,GradingActions.prototype._region=null,GradingActions.prototype._showActionsForm=function(event,userid){var form=this._region.find("[data-region=grading-actions-form]");userid!=this._lastUserId&&userid>0&&(this._lastUserId=userid),userid>0?form.removeClass("hide"):form.addClass("hide")},GradingActions.prototype._trigger=function(action){$(document).trigger(action)},GradingActions.prototype.getReviewPanelElement=function(){return $('[data-region="review-panel"]')},GradingActions.prototype.hasReviewPanelElement=function(){return this.getReviewPanelElement().length>0},GradingActions.prototype.getCollapseGradePanelButton=function(){return $('[data-region="grade-actions"] .collapse-grade-panel')},GradingActions.prototype.getCollapseReviewPanelButton=function(){return $('[data-region="grade-actions"] .collapse-review-panel')},GradingActions.prototype.getExpandAllPanelsButton=function(){return $('[data-region="grade-actions"] .collapse-none')},GradingActions.prototype.resetLayoutButtons=function(){this.getCollapseGradePanelButton().removeClass("active"),this.getCollapseReviewPanelButton().removeClass("active"),this.getExpandAllPanelsButton().removeClass("active")},GradingActions.prototype.collapseReviewPanel=function(){$(document).trigger(GradingEvents.COLLAPSE_REVIEW_PANEL),$(document).trigger(GradingEvents.EXPAND_GRADE_PANEL),this.resetLayoutButtons(),this.getCollapseReviewPanelButton().addClass("active")},GradingActions.prototype.collapseGradePanel=function(){$(document).trigger(GradingEvents.COLLAPSE_GRADE_PANEL),$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL),this.resetLayoutButtons(),this.getCollapseGradePanelButton().addClass("active")},GradingActions.prototype.expandAllPanels=function(){$(document).trigger(GradingEvents.EXPAND_GRADE_PANEL),$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL),this.resetLayoutButtons(),this.getExpandAllPanelsButton().addClass("active")},GradingActions.prototype.registerEventListeners=function(){if(this.hasReviewPanelElement()){var collapseReviewPanelButton=this.getCollapseReviewPanelButton();collapseReviewPanelButton.click(function(e){this.collapseReviewPanel(),e.preventDefault()}.bind(this)),collapseReviewPanelButton.keydown(function(e){e.metaKey||e.shiftKey||e.altKey||e.ctrlKey||13!==e.keyCode&&32!==e.keyCode||(this.collapseReviewPanel(),e.preventDefault())}.bind(this));var collapseGradePanelButton=this.getCollapseGradePanelButton();collapseGradePanelButton.click(function(e){this.collapseGradePanel(),e.preventDefault()}.bind(this)),collapseGradePanelButton.keydown(function(e){e.metaKey||e.shiftKey||e.altKey||e.ctrlKey||13!==e.keyCode&&32!==e.keyCode||(this.collapseGradePanel(),e.preventDefault())}.bind(this));var expandAllPanelsButton=this.getExpandAllPanelsButton();expandAllPanelsButton.click(function(e){this.expandAllPanels(),e.preventDefault()}.bind(this)),expandAllPanelsButton.keydown(function(e){e.metaKey||e.shiftKey||e.altKey||e.ctrlKey||13!==e.keyCode&&32!==e.keyCode||(this.expandAllPanels(),e.preventDefault())}.bind(this))}$(document).on("user-changed",this._showActionsForm.bind(this)),this._region.find('[name="savechanges"]').on("click",this._trigger.bind(this,"save-changes")),this._region.find('[name="saveandshownext"]').on("click",this._trigger.bind(this,"save-and-show-next")),this._region.find('[name="resetbutton"]').on("click",this._trigger.bind(this,"reset")),this._region.find("form").on("submit",(function(e){e.preventDefault()}))},GradingActions}));
//# sourceMappingURL=grading_actions.min.js.map
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
/**
* Events for the grading interface.
*
* @module mod_assign/grading_events
* @copyright 2016 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define("mod_assign/grading_events",(function(){return{COLLAPSE_REVIEW_PANEL:"grading:collapse-review-panel",EXPAND_REVIEW_PANEL:"grading:expand-review-panel",COLLAPSE_GRADE_PANEL:"grading:collapse-grade-panel",EXPAND_GRADE_PANEL:"grading:expand-grade-panel"}}));
//# sourceMappingURL=grading_events.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grading_events.min.js","sources":["../src/grading_events.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Events for the grading interface.\n *\n * @module mod_assign/grading_events\n * @copyright 2016 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.1\n */\ndefine(function() {\n return {\n COLLAPSE_REVIEW_PANEL: 'grading:collapse-review-panel',\n EXPAND_REVIEW_PANEL: 'grading:expand-review-panel',\n COLLAPSE_GRADE_PANEL: 'grading:collapse-grade-panel',\n EXPAND_GRADE_PANEL: 'grading:expand-grade-panel',\n };\n});\n"],"names":["define","COLLAPSE_REVIEW_PANEL","EXPAND_REVIEW_PANEL","COLLAPSE_GRADE_PANEL","EXPAND_GRADE_PANEL"],"mappings":";;;;;;;;AAuBAA,oCAAO,iBACI,CACHC,sBAAuB,gCACvBC,oBAAqB,8BACrBC,qBAAsB,+BACtBC,mBAAoB"}
+11
View File
@@ -0,0 +1,11 @@
/**
* Simple method to check for changes to a form between two points in time.
*
* @module mod_assign/grading_form_change_checker
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define("mod_assign/grading_form_change_checker",["jquery"],(function($){return{saveFormState:function(selector){$(selector).trigger("save-form-state");var data=$(selector).serialize();$(selector).data("saved-form-state",data)},checkFormForChanges:function(selector){$(selector).trigger("save-form-state");var data=$(selector).serialize(),previousdata=$(selector).data("saved-form-state");return void 0!==previousdata&&previousdata!=data}}}));
//# sourceMappingURL=grading_form_change_checker.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grading_form_change_checker.min.js","sources":["../src/grading_form_change_checker.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Simple method to check for changes to a form between two points in time.\n *\n * @module mod_assign/grading_form_change_checker\n * @copyright 2016 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.1\n */\ndefine(['jquery'], function($) {\n\n return {\n /**\n * Save the values in the form to a data attribute so they can be compared later for changes.\n *\n * @method saveFormState\n * @param {String} selector The selector for the form element.\n */\n saveFormState: function(selector) {\n $(selector).trigger('save-form-state');\n var data = $(selector).serialize();\n $(selector).data('saved-form-state', data);\n },\n\n /**\n * Compare the current values in the form to the previously saved state.\n *\n * @method checkFormForChanges\n * @param {String} selector The selector for the form element.\n * @return {Boolean} True if there are changes to the form data.\n */\n checkFormForChanges: function(selector) {\n\n $(selector).trigger('save-form-state');\n\n var data = $(selector).serialize(),\n previousdata = $(selector).data('saved-form-state');\n\n if (typeof previousdata === 'undefined') {\n return false;\n }\n return (previousdata != data);\n }\n };\n});\n"],"names":["define","$","saveFormState","selector","trigger","data","serialize","checkFormForChanges","previousdata"],"mappings":";;;;;;;;AAuBAA,gDAAO,CAAC,WAAW,SAASC,SAEjB,CAOHC,cAAe,SAASC,UACpBF,EAAEE,UAAUC,QAAQ,uBAChBC,KAAOJ,EAAEE,UAAUG,YACvBL,EAAEE,UAAUE,KAAK,mBAAoBA,OAUzCE,oBAAqB,SAASJ,UAE1BF,EAAEE,UAAUC,QAAQ,uBAEhBC,KAAOJ,EAAEE,UAAUG,YACnBE,aAAeP,EAAEE,UAAUE,KAAK,gCAER,IAAjBG,cAGHA,cAAgBH"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
/**
* Javascript controller for the "User summary" panel at the top of the page.
*
* @module mod_assign/grading_navigation_user_info
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define("mod_assign/grading_navigation_user_info",["jquery","core/notification","core/ajax","core/templates"],(function($,notification,ajax,templates){var UserInfo=function(selector){this._regionSelector=selector,this._region=$(selector),this._userCache={},$(document).on("user-changed",this._refreshUserInfo.bind(this))};return UserInfo.prototype._regionSelector=null,UserInfo.prototype._userCache=null,UserInfo.prototype._region=null,UserInfo.prototype._lastUserId=0,UserInfo.prototype._getAssignmentId=function(){return this._region.attr("data-assignmentid")},UserInfo.prototype._refreshUserInfo=function(event,userid){var promise=$.Deferred();this._region.attr("data-userid",userid),this._lastUserId!=userid&&(this._lastUserId=userid,templates.render("mod_assign/loading",{}).done(function(html,js){if(this._region.fadeOut("fast",function(){templates.replaceNodeContents(this._region,html,js),this._region.fadeIn("fast")}.bind(this)),userid<0)templates.render("mod_assign/grading_navigation_no_users",{}).done(function(html,js){userid==this._lastUserId&&this._region.fadeOut("fast",function(){templates.replaceNodeContents(this._region,html,js),this._region.fadeIn("fast")}.bind(this))}.bind(this)).fail(notification.exception);else{if(void 0!==this._userCache[userid])promise.resolve(this._userCache[userid]);else{var assignmentId=this._getAssignmentId();ajax.call([{methodname:"mod_assign_get_participant",args:{userid:userid,assignid:assignmentId,embeduser:!0}}])[0].done(function(participant){participant.hasOwnProperty("id")?(this._userCache[userid]=participant,promise.resolve(this._userCache[userid])):promise.reject("No users")}.bind(this)).fail(notification.exception)}promise.done(function(context){var identityfields=$("[data-showuseridentity]").data("showuseridentity").split(","),identity=[];context.courseid=$('[data-region="grading-navigation-panel"]').attr("data-courseid"),context.user&&($.each(identityfields,(function(i,k){void 0!==context.user[k]&&""!==context.user[k]&&(context.hasidentity=!0,identity.push(context.user[k]))})),context.identity=identity.join(", "),context.user.profileimageurl&&(context.profileimageurl=context.user.profileimageurl)),templates.render("mod_assign/grading_navigation_user_summary",context).done(function(html,js){userid==this._lastUserId&&this._region.fadeOut("fast",function(){templates.replaceNodeContents(this._region,html,js),this._region.fadeIn("fast")}.bind(this))}.bind(this)).fail(notification.exception)}.bind(this)).fail(function(){templates.render("mod_assign/grading_navigation_no_users",{}).done(function(html,js){this._region.fadeOut("fast",function(){templates.replaceNodeContents(this._region,html,js),this._region.fadeIn("fast")}.bind(this))}.bind(this)).fail(notification.exception)}.bind(this))}}.bind(this)).fail(notification.exception))},UserInfo}));
//# sourceMappingURL=grading_navigation_user_info.min.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
/**
* Javascript controller for the "Review" panel at the left of the page.
*
* @module mod_assign/grading_review_panel
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define("mod_assign/grading_review_panel",["jquery","mod_assign/grading_events"],(function($,GradingEvents){var GradingReviewPanel=function(){this._region=$('[data-region="review-panel-content"]'),this.registerEventListeners()};return GradingReviewPanel.prototype._region=null,GradingReviewPanel.prototype.getReviewPanel=function(pluginname){return void 0===this._region.data("panel-owner")&&this._region.data("review-panel-plugin",pluginname),this._region.data("review-panel-plugin")==pluginname&&this._region[0]},GradingReviewPanel.prototype.getTogglePanelButton=function(){return this.getPanelElement().find('[data-region="review-panel-toggle"]')},GradingReviewPanel.prototype.getPanelElement=function(){return $('[data-region="review-panel"]')},GradingReviewPanel.prototype.getPanelContentElement=function(){return $('[data-region="review-panel-content"]')},GradingReviewPanel.prototype.togglePanel=function(){this.getPanelElement().hasClass("collapsed")?$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL):$(document).trigger(GradingEvents.COLLAPSE_REVIEW_PANEL)},GradingReviewPanel.prototype.collapsePanel=function(){this.getPanelElement().addClass("collapsed").removeClass("grade-panel-collapsed"),this.getPanelContentElement().attr("aria-hidden",!0)},GradingReviewPanel.prototype.expandPanel=function(){this.getPanelElement().removeClass("collapsed"),this.getPanelContentElement().removeAttr("aria-hidden")},GradingReviewPanel.prototype.registerEventListeners=function(){var toggleReviewPanelButton=this.getTogglePanelButton();toggleReviewPanelButton.click(function(e){this.togglePanel(),e.preventDefault()}.bind(this)),toggleReviewPanelButton.keydown(function(e){e.metaKey||e.shiftKey||e.altKey||e.ctrlKey||13!==e.keyCode&&32!==e.keyCode||(this.togglePanel(),e.preventDefault())}.bind(this));var docElement=$(document);docElement.on(GradingEvents.COLLAPSE_REVIEW_PANEL,function(){this.collapsePanel()}.bind(this)),docElement.on(GradingEvents.COLLAPSE_GRADE_PANEL,function(){this.expandPanel(),this.getPanelElement().addClass("grade-panel-collapsed")}.bind(this)),docElement.on(GradingEvents.EXPAND_REVIEW_PANEL,function(){this.expandPanel()}.bind(this)),docElement.on(GradingEvents.EXPAND_GRADE_PANEL,function(){this.getPanelElement().removeClass("grade-panel-collapsed")}.bind(this))},GradingReviewPanel}));
//# sourceMappingURL=grading_review_panel.min.js.map
File diff suppressed because one or more lines are too long
+9
View File
@@ -0,0 +1,9 @@
define("mod_assign/override_form",["exports","jquery","core_form/changechecker"],(function(_exports,_jquery,FormChangeChecker){var obj;
/**
* A javascript module to enhance the override form.
*
* @copyright 2019 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj},FormChangeChecker=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(FormChangeChecker);_exports.init=(formId,selectElementName)=>{const form=document.getElementById(formId),selectElement=form.querySelector('[name="'.concat(selectElementName,'"]'));(0,_jquery.default)(selectElement).on("change",(()=>{const inputElement=document.createElement("input");inputElement.setAttribute("type","hidden"),inputElement.setAttribute("name","userchange"),inputElement.setAttribute("value",!0),form.appendChild(inputElement),FormChangeChecker.markFormSubmitted(inputElement),form.submit()}))}}));
//# sourceMappingURL=override_form.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"override_form.min.js","sources":["../src/override_form.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A javascript module to enhance the override form.\n *\n * @copyright 2019 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as FormChangeChecker from 'core_form/changechecker';\n\nexport const init = (formId, selectElementName) => {\n const form = document.getElementById(formId);\n const selectElement = form.querySelector(`[name=\"${selectElementName}\"]`);\n\n $(selectElement).on('change', () => {\n const inputElement = document.createElement('input');\n inputElement.setAttribute('type', 'hidden');\n inputElement.setAttribute('name', 'userchange');\n inputElement.setAttribute('value', true);\n\n form.appendChild(inputElement);\n\n FormChangeChecker.markFormSubmitted(inputElement);\n\n form.submit();\n });\n};\n"],"names":["formId","selectElementName","form","document","getElementById","selectElement","querySelector","on","inputElement","createElement","setAttribute","appendChild","FormChangeChecker","markFormSubmitted","submit"],"mappings":";;;;;;6lCAyBoB,CAACA,OAAQC,2BACnBC,KAAOC,SAASC,eAAeJ,QAC/BK,cAAgBH,KAAKI,+BAAwBL,6CAEjDI,eAAeE,GAAG,UAAU,WACpBC,aAAeL,SAASM,cAAc,SAC5CD,aAAaE,aAAa,OAAQ,UAClCF,aAAaE,aAAa,OAAQ,cAClCF,aAAaE,aAAa,SAAS,GAEnCR,KAAKS,YAAYH,cAEjBI,kBAAkBC,kBAAkBL,cAEpCN,KAAKY"}
+10
View File
@@ -0,0 +1,10 @@
/**
* Custom auto-complete adapter to load users from the assignment list_participants webservice.
*
* @module mod_assign/participant_selector
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define("mod_assign/participant_selector",["core/ajax","jquery","core/templates"],(function(ajax,$,templates){return{processResults:function(selector,data){return data},transport:function(selector,query,success,failure){var assignmentid=$(selector).attr("data-assignmentid"),groupid=$(selector).attr("data-groupid"),filters=$('[data-region="configure-filters"] input[type="checkbox"]'),filterstrings=[];filters.each((function(index,element){filterstrings[$(element).attr("name")]=$(element).prop("checked")})),ajax.call([{methodname:"mod_assign_list_participants",args:{assignid:assignmentid,groupid:groupid,filter:query,limit:30,includeenrolments:!1,tablesort:!0}}])[0].then((function(results){var promises=[],identityfields=$("[data-showuseridentity]").data("showuseridentity").split(",");return $.each(results,(function(index,user){var ctx=user,identity=[],show=!0;filterstrings.filter_submitted&&!user.submitted&&(show=!1),filterstrings.filter_notsubmitted&&user.submitted&&(show=!1),filterstrings.filter_requiregrading&&!user.requiregrading&&(show=!1),filterstrings.filter_grantedextension&&!user.grantedextension&&(show=!1),show&&($.each(identityfields,(function(i,k){void 0!==user[k]&&""!==user[k]&&(ctx.hasidentity=!0,identity.push(user[k]))})),ctx.identity=identity.join(", "),promises.push(templates.render("mod_assign/list_participant_user_summary",ctx).then((function(html){return{value:user.id,label:html}}))))})),$.when.apply($,promises)})).then((function(){var users=[];arguments[0]&&(users=Array.prototype.slice.call(arguments)),success(users)})).catch(failure)}}}));
//# sourceMappingURL=participant_selector.min.js.map
File diff suppressed because one or more lines are too long
+9
View File
@@ -0,0 +1,9 @@
define("mod_assign/timer",["exports","core/notification","core/str"],(function(_exports,_notification,_str){var obj;
/**
* A javascript module for the time in the assign module.
*
* @copyright 2020 Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=(obj=_notification)&&obj.__esModule?obj:{default:obj};let endTime=0,timeoutId=null,timer=null;const update=()=>{const now=(new Date).getTime(),secondsLeft=Math.floor((endTime-now)/1e3);if(secondsLeft<=0)return timer.classList.add("alert","alert-danger"),timer.innerHTML="00:00:00",document.getElementById("mod_assign_timelimit_block")&&(0,_str.getString)("caneditsubmission","mod_assign").then((message=>_notification.default.addNotification({message:message}))).catch(_notification.default.exception),void(timeoutId&&clearTimeout(timeoutId));var secs;secondsLeft<300?(timer.classList.remove("alert-warning"),timer.classList.add("alert","alert-danger")):secondsLeft<900&&(timer.classList.remove("alert-danger"),timer.classList.add("alert","alert-warning")),timer.innerHTML=(secs=secondsLeft,[Math.floor(secs/3600),Math.floor(secs/60)%60,secs%60].filter(((value,index)=>0!==value||index>0)).map((value=>"".concat(value).padStart(2,"0"))).join(":")),timeoutId=setTimeout(update,500)};_exports.init=timerId=>{timer=document.getElementById(timerId),endTime=M.pageloadstarttime.getTime()+1e3*timer.dataset.starttime,update()}}));
//# sourceMappingURL=timer.min.js.map
File diff suppressed because one or more lines are too long
+243
View File
@@ -0,0 +1,243 @@
// 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/>.
/**
* Javascript controller for the "Actions" panel at the bottom of the page.
*
* @module mod_assign/grading_actions
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'mod_assign/grading_events'], function($, GradingEvents) {
/**
* GradingActions class.
*
* @class mod_assign/grading_actions
* @param {String} selector The selector for the page region containing the actions panel.
*/
var GradingActions = function(selector) {
this._regionSelector = selector;
this._region = $(selector);
this.registerEventListeners();
};
/** @property {String} Selector for the page region containing the user navigation. */
GradingActions.prototype._regionSelector = null;
/** @property {Integer} Remember the last user id to prevent unnessecary reloads. */
GradingActions.prototype._lastUserId = 0;
/** @property {JQuery} JQuery node for the page region containing the user navigation. */
GradingActions.prototype._region = null;
/**
* Show the actions if there is valid user.
*
* @method _showActionsForm
* @private
* @param {Event} event
* @param {Integer} userid
*/
GradingActions.prototype._showActionsForm = function(event, userid) {
var form = this._region.find('[data-region=grading-actions-form]');
if (userid != this._lastUserId && userid > 0) {
this._lastUserId = userid;
}
if (userid > 0) {
form.removeClass('hide');
} else {
form.addClass('hide');
}
};
/**
* Trigger the named action.
*
* @method _trigger
* @private
* @param {String} action
*/
GradingActions.prototype._trigger = function(action) {
$(document).trigger(action);
};
/**
* Get the review panel element.
*
* @method getReviewPanelElement
* @return {jQuery}
*/
GradingActions.prototype.getReviewPanelElement = function() {
return $('[data-region="review-panel"]');
};
/**
* Check if the page has a review panel.
*
* @method hasReviewPanelElement
* @return {bool}
*/
GradingActions.prototype.hasReviewPanelElement = function() {
return this.getReviewPanelElement().length > 0;
};
/**
* Get the collapse grade panel button.
*
* @method getCollapseGradePanelButton
* @return {jQuery}
*/
GradingActions.prototype.getCollapseGradePanelButton = function() {
return $('[data-region="grade-actions"] .collapse-grade-panel');
};
/**
* Get the collapse review panel button.
*
* @method getCollapseReviewPanelButton
* @return {jQuery}
*/
GradingActions.prototype.getCollapseReviewPanelButton = function() {
return $('[data-region="grade-actions"] .collapse-review-panel');
};
/**
* Get the expand all panels button.
*
* @method getExpandAllPanelsButton
* @return {jQuery}
*/
GradingActions.prototype.getExpandAllPanelsButton = function() {
return $('[data-region="grade-actions"] .collapse-none');
};
/**
* Remove the active state from all layout buttons.
*
* @method resetLayoutButtons
*/
GradingActions.prototype.resetLayoutButtons = function() {
this.getCollapseGradePanelButton().removeClass('active');
this.getCollapseReviewPanelButton().removeClass('active');
this.getExpandAllPanelsButton().removeClass('active');
};
/**
* Hide the review panel.
*
* @method collapseReviewPanel
*/
GradingActions.prototype.collapseReviewPanel = function() {
$(document).trigger(GradingEvents.COLLAPSE_REVIEW_PANEL);
$(document).trigger(GradingEvents.EXPAND_GRADE_PANEL);
this.resetLayoutButtons();
this.getCollapseReviewPanelButton().addClass('active');
};
/**
* Show/Hide the grade panel.
*
* @method collapseGradePanel
*/
GradingActions.prototype.collapseGradePanel = function() {
$(document).trigger(GradingEvents.COLLAPSE_GRADE_PANEL);
$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL);
this.resetLayoutButtons();
this.getCollapseGradePanelButton().addClass('active');
};
/**
* Return the layout to default.
*
* @method expandAllPanels
*/
GradingActions.prototype.expandAllPanels = function() {
$(document).trigger(GradingEvents.EXPAND_GRADE_PANEL);
$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL);
this.resetLayoutButtons();
this.getExpandAllPanelsButton().addClass('active');
};
/**
* Register event listeners for the grade panel.
*
* @method registerEventListeners
*/
GradingActions.prototype.registerEventListeners = function() {
// Don't need layout controls if there is no review panel.
if (this.hasReviewPanelElement()) {
var collapseReviewPanelButton = this.getCollapseReviewPanelButton();
collapseReviewPanelButton.click(function(e) {
this.collapseReviewPanel();
e.preventDefault();
}.bind(this));
collapseReviewPanelButton.keydown(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode === 13 || e.keyCode === 32) {
this.collapseReviewPanel();
e.preventDefault();
}
}
}.bind(this));
var collapseGradePanelButton = this.getCollapseGradePanelButton();
collapseGradePanelButton.click(function(e) {
this.collapseGradePanel();
e.preventDefault();
}.bind(this));
collapseGradePanelButton.keydown(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode === 13 || e.keyCode === 32) {
this.collapseGradePanel();
e.preventDefault();
}
}
}.bind(this));
var expandAllPanelsButton = this.getExpandAllPanelsButton();
expandAllPanelsButton.click(function(e) {
this.expandAllPanels();
e.preventDefault();
}.bind(this));
expandAllPanelsButton.keydown(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode === 13 || e.keyCode === 32) {
this.expandAllPanels();
e.preventDefault();
}
}
}.bind(this));
}
$(document).on('user-changed', this._showActionsForm.bind(this));
this._region.find('[name="savechanges"]').on('click', this._trigger.bind(this, 'save-changes'));
this._region.find('[name="saveandshownext"]').on('click', this._trigger.bind(this, 'save-and-show-next'));
this._region.find('[name="resetbutton"]').on('click', this._trigger.bind(this, 'reset'));
this._region.find('form').on('submit', function(e) {
e.preventDefault();
});
};
return GradingActions;
});
+31
View File
@@ -0,0 +1,31 @@
// 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/>.
/**
* Events for the grading interface.
*
* @module mod_assign/grading_events
* @copyright 2016 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(function() {
return {
COLLAPSE_REVIEW_PANEL: 'grading:collapse-review-panel',
EXPAND_REVIEW_PANEL: 'grading:expand-review-panel',
COLLAPSE_GRADE_PANEL: 'grading:collapse-grade-panel',
EXPAND_GRADE_PANEL: 'grading:expand-grade-panel',
};
});
@@ -0,0 +1,59 @@
// 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/>.
/**
* Simple method to check for changes to a form between two points in time.
*
* @module mod_assign/grading_form_change_checker
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery'], function($) {
return {
/**
* Save the values in the form to a data attribute so they can be compared later for changes.
*
* @method saveFormState
* @param {String} selector The selector for the form element.
*/
saveFormState: function(selector) {
$(selector).trigger('save-form-state');
var data = $(selector).serialize();
$(selector).data('saved-form-state', data);
},
/**
* Compare the current values in the form to the previously saved state.
*
* @method checkFormForChanges
* @param {String} selector The selector for the form element.
* @return {Boolean} True if there are changes to the form data.
*/
checkFormForChanges: function(selector) {
$(selector).trigger('save-form-state');
var data = $(selector).serialize(),
previousdata = $(selector).data('saved-form-state');
if (typeof previousdata === 'undefined') {
return false;
}
return (previousdata != data);
}
};
});
+585
View File
@@ -0,0 +1,585 @@
// 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/>.
/**
* Javascript to handle changing users via the user selector in the header.
*
* @module mod_assign/grading_navigation
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/notification', 'core/str', 'core/form-autocomplete',
'core/ajax', 'core_user/repository', 'mod_assign/grading_form_change_checker'],
function($, notification, str, autocomplete, ajax, UserRepository, checker) {
/**
* GradingNavigation class.
*
* @class mod_assign/grading_navigation
* @param {String} selector The selector for the page region containing the user navigation.
*/
var GradingNavigation = function(selector) {
this._regionSelector = selector;
this._region = $(selector);
this._filters = [];
this._users = [];
this._filteredUsers = [];
this._lastXofYUpdate = 0;
this._firstLoadUsers = true;
let url = new URL(window.location);
if (parseInt(url.searchParams.get('treset')) > 0) {
// Remove 'treset' url parameter to make sure that
// table preferences won't be reset on page refresh.
url.searchParams.delete('treset');
window.history.replaceState({}, "", url);
}
// Get the current user list from a webservice.
this._loadAllUsers();
// We do not allow navigation while ajax requests are pending.
// Attach listeners to the select and arrow buttons.
this._region.find('[data-action="previous-user"]').on('click', this._handlePreviousUser.bind(this));
this._region.find('[data-action="next-user"]').on('click', this._handleNextUser.bind(this));
this._region.find('[data-action="change-user"]').on('change', this._handleChangeUser.bind(this));
this._region.find('[data-region="user-filters"]').on('click', this._toggleExpandFilters.bind(this));
this._region.find('[data-region="user-resettable"]').on('click', this._toggleResetTable.bind());
$(document).on('user-changed', this._refreshSelector.bind(this));
$(document).on('done-saving-show-next', this._handleNextUser.bind(this));
// Position the configure filters panel under the link that expands it.
var toggleLink = this._region.find('[data-region="user-filters"]');
var configPanel = $(document.getElementById(toggleLink.attr('aria-controls')));
configPanel.on('change', 'select', this._filterChanged.bind(this));
var userid = $('[data-region="grading-navigation-panel"]').data('first-userid');
if (userid) {
this._selectUserById(userid);
}
str.get_string('changeuser', 'mod_assign').done(function(s) {
autocomplete.enhance('[data-action=change-user]', false, 'mod_assign/participant_selector', s);
}
).fail(notification.exception);
$(document).bind("start-loading-user", function() {
this._isLoading = true;
}.bind(this));
$(document).bind("finish-loading-user", function() {
this._isLoading = false;
}.bind(this));
};
/** @property {Boolean} Boolean tracking active ajax requests. */
GradingNavigation.prototype._isLoading = false;
/** @property {String} Selector for the page region containing the user navigation. */
GradingNavigation.prototype._regionSelector = null;
/** @property {Array} The list of active filter keys */
GradingNavigation.prototype._filters = null;
/** @property {Array} The list of users */
GradingNavigation.prototype._users = null;
/** @property {JQuery} JQuery node for the page region containing the user navigation. */
GradingNavigation.prototype._region = null;
/** @property {String} Last active filters */
GradingNavigation.prototype._lastFilters = '';
/**
* Load the list of all users for this assignment.
*
* @private
* @method _loadAllUsers
* @return {Boolean} True if the user list was fetched.
*/
GradingNavigation.prototype._loadAllUsers = function() {
var select = this._region.find('[data-action=change-user]');
var assignmentid = select.attr('data-assignmentid');
var groupid = select.attr('data-groupid');
var filterPanel = this._region.find('[data-region="configure-filters"]');
var filter = filterPanel.find('select[name="filter"]').val();
var workflowFilter = filterPanel.find('select[name="workflowfilter"]');
if (workflowFilter) {
filter += ',' + workflowFilter.val();
}
var markerFilter = filterPanel.find('select[name="markerfilter"]');
if (markerFilter) {
filter += ',' + markerFilter.val();
}
if (this._lastFilters == filter) {
return false;
}
this._lastFilters = filter;
ajax.call([{
methodname: 'mod_assign_list_participants',
args: {assignid: assignmentid, groupid: groupid, filter: '', onlyids: true, tablesort: true},
done: this._usersLoaded.bind(this),
fail: notification.exception
}]);
return true;
};
/**
* Call back to rebuild the user selector and x of y info when the user list is updated.
*
* @private
* @method _usersLoaded
* @param {Array} users
*/
GradingNavigation.prototype._usersLoaded = function(users) {
this._firstLoadUsers = false;
this._filteredUsers = this._users = users;
if (this._users.length) {
// Position the configure filters panel under the link that expands it.
var toggleLink = this._region.find('[data-region="user-filters"]');
var configPanel = $(document.getElementById(toggleLink.attr('aria-controls')));
configPanel.find('select[name="filter"]').trigger('change');
} else {
this._selectNoUser();
}
this._triggerNextUserEvent();
};
/**
* Close the configure filters panel if a click is detected outside of it.
*
* @private
* @method _checkClickOutsideConfigureFilters
* @param {Event} event
*/
GradingNavigation.prototype._checkClickOutsideConfigureFilters = function(event) {
var configPanel = this._region.find('[data-region="configure-filters"]');
if (!configPanel.is(event.target) && configPanel.has(event.target).length === 0) {
var toggleLink = this._region.find('[data-region="user-filters"]');
configPanel.hide();
configPanel.attr('aria-hidden', 'true');
toggleLink.attr('aria-expanded', 'false');
$(document).unbind('click.mod_assign_grading_navigation');
}
};
/**
* Close the configure filters panel if a click is detected outside of it.
*
* @private
* @method _updateFilterPreference
* @param {Number} userId The current user id.
* @param {Array} filterList The list of current filter values.
* @param {Array} preferenceNames The names of the preferences to update
* @return {Promise} Resolved when all the preferences are updated.
*/
GradingNavigation.prototype._updateFilterPreferences = function(userId, filterList, preferenceNames) {
var preferences = [],
i = 0;
if (filterList.length == 0 || this._firstLoadUsers) {
// Nothing to update.
var deferred = $.Deferred();
deferred.resolve();
return deferred;
}
// General filter.
// Set the user preferences to the current filters.
for (i = 0; i < filterList.length; i++) {
var newValue = filterList[i];
if (newValue == 'none') {
newValue = '';
}
preferences.push({
userid: userId,
name: preferenceNames[i],
value: newValue
});
}
return UserRepository.setUserPreferences(preferences);
};
/**
* Turn a filter on or off.
*
* @private
* @method _filterChanged
*/
GradingNavigation.prototype._filterChanged = function() {
// There are 3 types of filter right now.
var filterPanel = this._region.find('[data-region="configure-filters"]');
var filters = filterPanel.find('select');
var preferenceNames = [];
this._filters = [];
filters.each(function(idx, ele) {
var element = $(ele);
this._filters.push(element.val());
preferenceNames.push('assign_' + element.prop('name'));
}.bind(this));
// Update the active filter string.
var filterlist = [];
filterPanel.find('option:checked').each(function(idx, ele) {
filterlist[filterlist.length] = $(ele).text();
});
if (filterlist.length) {
this._region.find('[data-region="user-filters"] span').text(filterlist.join(', '));
} else {
str.get_string('nofilters', 'mod_assign').done(function(s) {
this._region.find('[data-region="user-filters"] span').text(s);
}.bind(this)).fail(notification.exception);
}
var select = this._region.find('[data-action=change-user]');
var currentUserID = select.data('currentuserid');
this._updateFilterPreferences(currentUserID, this._filters, preferenceNames).done(function() {
// Reload the list of users to apply the new filters.
if (!this._loadAllUsers()) {
var userid = parseInt(select.attr('data-selected'));
let foundIndex = null;
// Search the returned users for the current selection.
$.each(this._filteredUsers, function(index, user) {
if (userid == user.id) {
foundIndex = index;
}
});
if (this._filteredUsers.length && foundIndex !== null) {
this._selectUserById(this._filteredUsers[foundIndex].id);
} else {
this._selectNoUser();
}
}
}.bind(this)).fail(notification.exception);
this._refreshCount();
};
/**
* Select no users, because no users match the filters.
*
* @private
* @method _selectNoUser
*/
GradingNavigation.prototype._selectNoUser = function() {
// Detect unsaved changes, and offer to save them - otherwise change user right now.
if (this._isLoading) {
return;
}
if (checker.checkFormForChanges('[data-region="grade-panel"] .gradeform')) {
// Form has changes, so we need to confirm before switching users.
str.get_strings([
{key: 'unsavedchanges', component: 'mod_assign'},
{key: 'unsavedchangesquestion', component: 'mod_assign'},
{key: 'saveandcontinue', component: 'mod_assign'},
{key: 'cancel', component: 'core'},
]).done(function(strs) {
notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {
$(document).trigger('save-changes', -1);
});
});
} else {
$(document).trigger('user-changed', -1);
}
};
/**
* Select the specified user by id.
*
* @private
* @method _selectUserById
* @param {Number} userid
*/
GradingNavigation.prototype._selectUserById = function(userid) {
var select = this._region.find('[data-action=change-user]');
var useridnumber = parseInt(userid, 10);
// Detect unsaved changes, and offer to save them - otherwise change user right now.
if (this._isLoading) {
return;
}
if (checker.checkFormForChanges('[data-region="grade-panel"] .gradeform')) {
// Form has changes, so we need to confirm before switching users.
str.get_strings([
{key: 'unsavedchanges', component: 'mod_assign'},
{key: 'unsavedchangesquestion', component: 'mod_assign'},
{key: 'saveandcontinue', component: 'mod_assign'},
{key: 'cancel', component: 'core'},
]).done(function(strs) {
notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {
$(document).trigger('save-changes', useridnumber);
});
});
} else {
select.attr('data-selected', userid);
// If we have some filtered users, and userid is specified, then trigger change.
if (this._filteredUsers.length > 0 && !isNaN(useridnumber) && useridnumber > 0) {
$(document).trigger('user-changed', useridnumber);
}
}
};
/**
* Expand or collapse the filter config panel.
*
* @private
* @method _toggleExpandFilters
* @param {Event} event
*/
GradingNavigation.prototype._toggleExpandFilters = function(event) {
event.preventDefault();
var toggleLink = $(event.target).closest('[data-region="user-filters"]');
var expanded = toggleLink.attr('aria-expanded') == 'true';
var configPanel = $(document.getElementById(toggleLink.attr('aria-controls')));
if (expanded) {
configPanel.hide();
configPanel.attr('aria-hidden', 'true');
toggleLink.attr('aria-expanded', 'false');
$(document).unbind('click.mod_assign_grading_navigation');
} else {
configPanel.css('display', 'inline-block');
configPanel.attr('aria-hidden', 'false');
toggleLink.attr('aria-expanded', 'true');
event.stopPropagation();
$(document).on('click.mod_assign_grading_navigation', this._checkClickOutsideConfigureFilters.bind(this));
}
};
/**
* Reset table preferences.
*
* @private
* @method _toggleResetTable
*/
GradingNavigation.prototype._toggleResetTable = function() {
let url = new URL(window.location);
url.searchParams.set('treset', '1');
window.location.href = url;
};
/**
* Change to the previous user in the grading list.
*
* @private
* @method _handlePreviousUser
* @param {Event} e
*/
GradingNavigation.prototype._handlePreviousUser = function(e) {
e.preventDefault();
var select = this._region.find('[data-action=change-user]');
var currentUserId = select.attr('data-selected');
var i = 0;
var currentIndex = 0;
for (i = 0; i < this._filteredUsers.length; i++) {
if (this._filteredUsers[i].id == currentUserId) {
currentIndex = i;
break;
}
}
var count = this._filteredUsers.length;
var newIndex = (currentIndex - 1);
if (newIndex < 0) {
newIndex = count - 1;
}
if (count) {
this._selectUserById(this._filteredUsers[newIndex].id);
}
};
/**
* Change to the next user in the grading list.
*
* @param {Event} e
* @param {Boolean} saved Has the form already been saved? Skips checking for changes if true.
*/
GradingNavigation.prototype._handleNextUser = function(e, saved) {
e.preventDefault();
var select = this._region.find('[data-action=change-user]');
var currentUserId = select.attr('data-selected');
var i = 0;
var currentIndex = 0;
for (i = 0; i < this._filteredUsers.length; i++) {
if (this._filteredUsers[i].id == currentUserId) {
currentIndex = i;
break;
}
}
var count = this._filteredUsers.length;
var newIndex = (currentIndex + 1) % count;
if (saved && count) {
// If we've already saved the grade, skip checking if we've made any changes.
var userid = this._filteredUsers[newIndex].id;
var useridnumber = parseInt(userid, 10);
select.attr('data-selected', userid);
if (!isNaN(useridnumber) && useridnumber > 0) {
$(document).trigger('user-changed', userid);
}
} else if (count) {
this._selectUserById(this._filteredUsers[newIndex].id);
}
};
/**
* Set count string. This method only sets the value for the last time it was ever called to deal
* with promises that return in a non-predictable order.
*
* @private
* @method _setCountString
* @param {Number} x
* @param {Number} y
*/
GradingNavigation.prototype._setCountString = function(x, y) {
var updateNumber = 0;
this._lastXofYUpdate++;
updateNumber = this._lastXofYUpdate;
var param = {x: x, y: y};
str.get_string('xofy', 'mod_assign', param).done(function(s) {
if (updateNumber == this._lastXofYUpdate) {
this._region.find('[data-region="user-count-summary"]').text(s);
}
}.bind(this)).fail(notification.exception);
};
/**
* Rebuild the x of y string.
*
* @private
* @method _refreshCount
*/
GradingNavigation.prototype._refreshCount = function() {
var select = this._region.find('[data-action=change-user]');
var userid = select.attr('data-selected');
var i = 0;
var currentIndex = 0;
if (isNaN(userid) || userid <= 0) {
this._region.find('[data-region="user-count"]').hide();
} else {
this._region.find('[data-region="user-count"]').show();
for (i = 0; i < this._filteredUsers.length; i++) {
if (this._filteredUsers[i].id == userid) {
currentIndex = i;
break;
}
}
var count = this._filteredUsers.length;
if (count) {
currentIndex += 1;
}
this._setCountString(currentIndex, count);
// Update window URL
if (currentIndex > 0) {
var url = new URL(window.location);
if (parseInt(url.searchParams.get('blindid')) > 0) {
var newid = this._filteredUsers[currentIndex - 1].recordid;
url.searchParams.set('blindid', newid);
} else {
url.searchParams.set('userid', userid);
}
// We do this so a browser refresh will return to the same user.
window.history.replaceState({}, "", url);
}
}
};
/**
* Respond to a user-changed event by updating the selector.
*
* @private
* @method _refreshSelector
* @param {Event} event
* @param {String} userid
*/
GradingNavigation.prototype._refreshSelector = function(event, userid) {
var select = this._region.find('[data-action=change-user]');
userid = parseInt(userid, 10);
if (!isNaN(userid) && userid > 0) {
select.attr('data-selected', userid);
}
this._refreshCount();
};
/**
* Trigger the next user event depending on the number of filtered users
*
* @private
* @method _triggerNextUserEvent
*/
GradingNavigation.prototype._triggerNextUserEvent = function() {
if (this._filteredUsers.length > 1) {
$(document).trigger('next-user', {nextUserId: null, nextUser: true});
} else {
$(document).trigger('next-user', {nextUser: false});
}
};
/**
* Change to a different user in the grading list.
*
* @private
* @method _handleChangeUser
*/
GradingNavigation.prototype._handleChangeUser = function() {
var select = this._region.find('[data-action=change-user]');
var userid = parseInt(select.val(), 10);
if (this._isLoading) {
return;
}
if (checker.checkFormForChanges('[data-region="grade-panel"] .gradeform')) {
// Form has changes, so we need to confirm before switching users.
str.get_strings([
{key: 'unsavedchanges', component: 'mod_assign'},
{key: 'unsavedchangesquestion', component: 'mod_assign'},
{key: 'saveandcontinue', component: 'mod_assign'},
{key: 'cancel', component: 'core'},
]).done(function(strs) {
notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {
$(document).trigger('save-changes', userid);
});
});
} else {
if (!isNaN(userid) && userid > 0) {
select.attr('data-selected', userid);
$(document).trigger('user-changed', userid);
}
}
};
return GradingNavigation;
});
@@ -0,0 +1,175 @@
// 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/>.
/**
* Javascript controller for the "User summary" panel at the top of the page.
*
* @module mod_assign/grading_navigation_user_info
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/notification', 'core/ajax', 'core/templates'], function($, notification, ajax, templates) {
/**
* UserInfo class.
*
* @class mod_assign/grading_navigation_user_info
* @param {String} selector The selector for the page region containing the user navigation.
*/
var UserInfo = function(selector) {
this._regionSelector = selector;
this._region = $(selector);
this._userCache = {};
$(document).on('user-changed', this._refreshUserInfo.bind(this));
};
/** @property {String} Selector for the page region containing the user navigation. */
UserInfo.prototype._regionSelector = null;
/** @property {Array} Cache of user info contexts. */
UserInfo.prototype._userCache = null;
/** @property {JQuery} JQuery node for the page region containing the user navigation. */
UserInfo.prototype._region = null;
/** @property {Integer} Remember the last user id to prevent unnecessary reloads. */
UserInfo.prototype._lastUserId = 0;
/**
* Get the assignment id
*
* @private
* @method _getAssignmentId
* @return {Integer} assignment id
*/
UserInfo.prototype._getAssignmentId = function() {
return this._region.attr('data-assignmentid');
};
/**
* Get the user context - re-render the template in the page.
*
* @private
* @method _refreshUserInfo
* @param {Event} event
* @param {Number} userid
*/
UserInfo.prototype._refreshUserInfo = function(event, userid) {
var promise = $.Deferred();
// Put the current user ID in the DOM so yui can access it.
this._region.attr('data-userid', userid);
// Skip reloading if it is the same user.
if (this._lastUserId == userid) {
return;
}
this._lastUserId = userid;
// First insert the loading template.
templates.render('mod_assign/loading', {}).done(function(html, js) {
// Update the page.
this._region.fadeOut("fast", function() {
templates.replaceNodeContents(this._region, html, js);
this._region.fadeIn("fast");
}.bind(this));
if (userid < 0) {
// Render the template.
templates.render('mod_assign/grading_navigation_no_users', {}).done(function(html, js) {
if (userid == this._lastUserId) {
// Update the page.
this._region.fadeOut("fast", function() {
templates.replaceNodeContents(this._region, html, js);
this._region.fadeIn("fast");
}.bind(this));
}
}.bind(this)).fail(notification.exception);
return;
}
if (typeof this._userCache[userid] !== "undefined") {
promise.resolve(this._userCache[userid]);
} else {
// Load context from ajax.
var assignmentId = this._getAssignmentId();
var requests = ajax.call([{
methodname: 'mod_assign_get_participant',
args: {
userid: userid,
assignid: assignmentId,
embeduser: true
}
}]);
requests[0].done(function(participant) {
if (!participant.hasOwnProperty('id')) {
promise.reject('No users');
} else {
this._userCache[userid] = participant;
promise.resolve(this._userCache[userid]);
}
}.bind(this)).fail(notification.exception);
}
promise.done(function(context) {
var identityfields = $('[data-showuseridentity]').data('showuseridentity').split(','),
identity = [];
// Render the template.
context.courseid = $('[data-region="grading-navigation-panel"]').attr('data-courseid');
if (context.user) {
// Build a string for the visible identity fields listed in showuseridentity config setting.
$.each(identityfields, function(i, k) {
if (typeof context.user[k] !== 'undefined' && context.user[k] !== '') {
context.hasidentity = true;
identity.push(context.user[k]);
}
});
context.identity = identity.join(', ');
// Add profile image url to context.
if (context.user.profileimageurl) {
context.profileimageurl = context.user.profileimageurl;
}
}
templates.render('mod_assign/grading_navigation_user_summary', context).done(function(html, js) {
// Update the page.
if (userid == this._lastUserId) {
this._region.fadeOut("fast", function() {
templates.replaceNodeContents(this._region, html, js);
this._region.fadeIn("fast");
}.bind(this));
}
}.bind(this)).fail(notification.exception);
}.bind(this)).fail(function() {
// Render the template.
templates.render('mod_assign/grading_navigation_no_users', {}).done(function(html, js) {
// Update the page.
this._region.fadeOut("fast", function() {
templates.replaceNodeContents(this._region, html, js);
this._region.fadeIn("fast");
}.bind(this));
}.bind(this)).fail(notification.exception);
}
.bind(this));
}.bind(this)).fail(notification.exception);
};
return UserInfo;
});
+445
View File
@@ -0,0 +1,445 @@
// 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/>.
/**
* Javascript controller for the "Grading" panel at the right of the page.
*
* @module mod_assign/grading_panel
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define([
'jquery',
'core/yui',
'core/notification',
'core/templates',
'core/fragment',
'core/ajax',
'core/str',
'mod_assign/grading_form_change_checker',
'mod_assign/grading_events',
'core_form/events',
'core/toast',
'core_form/changechecker',
], function(
$,
Y,
notification,
templates,
fragment,
ajax,
str,
checker,
GradingEvents,
FormEvents,
Toast,
FormChangeChecker
) {
/**
* GradingPanel class.
*
* @class mod_assign/grading_panel
* @param {String} selector The selector for the page region containing the user navigation.
*/
var GradingPanel = function(selector) {
this._regionSelector = selector;
this._region = $(selector);
this._userCache = [];
this.registerEventListeners();
};
/** @property {String} Selector for the page region containing the user navigation. */
GradingPanel.prototype._regionSelector = null;
/** @property {Integer} Remember the last user id to prevent unnessecary reloads. */
GradingPanel.prototype._lastUserId = 0;
/** @property {Integer} Remember the last attempt number to prevent unnessecary reloads. */
GradingPanel.prototype._lastAttemptNumber = -1;
/** @property {JQuery} JQuery node for the page region containing the user navigation. */
GradingPanel.prototype._region = null;
/** @property {Integer} The id of the next user in the grading list */
GradingPanel.prototype.nextUserId = null;
/** @property {Boolean} Next user exists in the grading list */
GradingPanel.prototype.nextUser = false;
/**
* Fade the dom node out, update it, and fade it back.
*
* @private
* @method _niceReplaceNodeContents
* @param {JQuery} node
* @param {String} html
* @param {String} js
* @return {Deferred} promise resolved when the animations are complete.
*/
GradingPanel.prototype._niceReplaceNodeContents = function(node, html, js) {
var promise = $.Deferred();
node.fadeOut("fast", function() {
templates.replaceNodeContents(node, html, js);
node.fadeIn("fast", function() {
promise.resolve();
});
});
return promise.promise();
};
/**
* Make sure all form fields have the latest saved state.
* @private
* @method _saveFormState
*/
GradingPanel.prototype._saveFormState = function() {
// Copy data from notify students checkbox which was moved out of the form.
var checked = $('[data-region="grading-actions-form"] [name="sendstudentnotifications"]').prop("checked");
$('.gradeform [name="sendstudentnotifications"]').val(checked);
};
/**
* Make form submit via ajax.
*
* @private
* @param {Object} event
* @param {Integer} nextUserId
* @param {Boolean} nextUser optional. Load next user in the grading list.
* @method _submitForm
* @fires event:formSubmittedByJavascript
*/
GradingPanel.prototype._submitForm = function(event, nextUserId, nextUser) {
// If the form has data in comment-area, then we need to save that comment
var commentAreaElement = document.querySelector('.comment-area');
if (commentAreaElement) {
var commentTextAreaElement = commentAreaElement.querySelector('.db > textarea');
if (commentTextAreaElement.value !== '') {
var commentActionPostElement = commentAreaElement.querySelector('.fd a[id^="comment-action-post-"]');
commentActionPostElement.click();
}
}
// The form was submitted - send it via ajax instead.
var form = $(this._region.find('form.gradeform'));
$('[data-region="overlay"]').show();
// Mark the form as submitted in the change checker.
FormChangeChecker.markFormSubmitted(form[0]);
// We call this, so other modules can update the form with the latest state.
form.trigger('save-form-state');
// Tell all form fields we are about to submit the form.
FormEvents.notifyFormSubmittedByJavascript(form[0]);
// Now we get all the current values from the form.
var data = form.serialize();
var assignmentid = this._region.attr('data-assignmentid');
// Now we can continue...
ajax.call([{
methodname: 'mod_assign_submit_grading_form',
args: {assignmentid: assignmentid, userid: this._lastUserId, jsonformdata: JSON.stringify(data)},
done: this._handleFormSubmissionResponse.bind(this, data, nextUserId, nextUser),
fail: notification.exception
}]);
};
/**
* Handle form submission response.
*
* @private
* @method _handleFormSubmissionResponse
* @param {Array} formdata - submitted values
* @param {Number} [nextUserId] The id of the user to load after the form is saved
* @param {Boolean} [nextUser] - Whether to switch to next user in the grading list.
* @param {Array} response List of errors.
*/
GradingPanel.prototype._handleFormSubmissionResponse = function(formdata, nextUserId, nextUser, response) {
if (typeof nextUserId === "undefined") {
nextUserId = this._lastUserId;
}
if (response.length) {
// There was an error saving the grade. Re-render the form using the submitted data so we can show
// validation errors.
$(document).trigger('reset', [this._lastUserId, formdata]);
} else {
str.get_string('gradechangessaveddetail', 'mod_assign')
.then(function(str) {
Toast.add(str);
return str;
})
.catch(notification.exception);
// Reset the form state.
var form = $(this._region.find('form.gradeform'));
FormChangeChecker.resetFormDirtyState(form[0]);
if (nextUserId == this._lastUserId) {
$(document).trigger('reset', nextUserId);
} else if (nextUser) {
$(document).trigger('done-saving-show-next', true);
} else {
$(document).trigger('user-changed', nextUserId);
}
}
$('[data-region="overlay"]').hide();
};
/**
* Refresh form with default values.
*
* @private
* @method _resetForm
* @param {Event} e
* @param {Integer} userid
* @param {Array} formdata
*/
GradingPanel.prototype._resetForm = function(e, userid, formdata) {
// The form was cancelled - refresh with default values.
var event = $.Event("custom");
if (typeof userid == "undefined") {
userid = this._lastUserId;
}
this._lastUserId = 0;
this._refreshGradingPanel(event, userid, formdata);
};
/**
* Open a picker to choose an older attempt.
*
* @private
* @param {Object} e
* @method _chooseAttempt
*/
GradingPanel.prototype._chooseAttempt = function(e) {
// Show a dialog.
// The form is in the element pointed to by data-submissions.
var link = $(e.target);
var submissionsId = link.data('submissions');
var submissionsform = $(document.getElementById(submissionsId));
var formcopy = submissionsform.clone();
var formhtml = formcopy.wrap($('<form/>')).html();
str.get_strings([
{key: 'viewadifferentattempt', component: 'mod_assign'},
{key: 'view', component: 'core'},
{key: 'cancel', component: 'core'},
]).done(function(strs) {
notification.confirm(strs[0], formhtml, strs[1], strs[2], function() {
var attemptnumber = $("input:radio[name='select-attemptnumber']:checked").val();
this._refreshGradingPanel(null, this._lastUserId, '', attemptnumber);
}.bind(this));
}.bind(this)).fail(notification.exception);
};
/**
* Add popout buttons
*
* @private
* @method _addPopoutButtons
* @param {JQuery} selector The region selector to add popout buttons to.
*/
GradingPanel.prototype._addPopoutButtons = function(selector) {
var region = $(selector);
templates.render('mod_assign/popout_button', {}).done(function(html) {
var parents = region.find('[data-fieldtype="filemanager"],[data-fieldtype="editor"],[data-fieldtype="grading"]')
.closest('.fitem');
parents.addClass('has-popout').find('label').parent().append(html);
region.on('click', '[data-region="popout-button"]', this._togglePopout.bind(this));
}.bind(this)).fail(notification.exception);
};
/**
* Make a div "popout" or "popback".
*
* @private
* @method _togglePopout
* @param {Event} event
*/
GradingPanel.prototype._togglePopout = function(event) {
event.preventDefault();
var container = $(event.target).closest('.fitem');
if (container.hasClass('popout')) {
$('.popout').removeClass('popout');
} else {
$('.popout').removeClass('popout');
container.addClass('popout');
container.addClass('moodle-has-zindex');
}
};
/**
* Get the user context - re-render the template in the page.
*
* @private
* @method _refreshGradingPanel
* @param {Event} event
* @param {Number} userid
* @param {String} submissiondata serialised submission data.
* @param {Integer} attemptnumber
*/
GradingPanel.prototype._refreshGradingPanel = function(event, userid, submissiondata, attemptnumber) {
var contextid = this._region.attr('data-contextid');
if (typeof submissiondata === 'undefined') {
submissiondata = '';
}
if (typeof attemptnumber === 'undefined') {
attemptnumber = -1;
}
// Skip reloading if it is the same user.
if (this._lastUserId == userid && this._lastAttemptNumber == attemptnumber && submissiondata === '') {
return;
}
this._lastUserId = userid;
this._lastAttemptNumber = attemptnumber;
$(document).trigger('start-loading-user');
// Tell behat to back off too.
window.M.util.js_pending('mod-assign-loading-user');
// First insert the loading template.
templates.render('mod_assign/loading', {}).done(function(html, js) {
// Update the page.
this._niceReplaceNodeContents(this._region, html, js).done(function() {
if (userid > 0) {
this._region.show();
// Reload the grading form "fragment" for this user.
var params = {userid: userid, attemptnumber: attemptnumber, jsonformdata: JSON.stringify(submissiondata)};
fragment.loadFragment('mod_assign', 'gradingpanel', contextid, params).done(function(html, js) {
this._niceReplaceNodeContents(this._region, html, js)
.done(function() {
checker.saveFormState('[data-region="grade-panel"] .gradeform');
$(document).on('editor-content-restored', function() {
// If the editor has some content that has been restored
// then save the form state again for comparison.
checker.saveFormState('[data-region="grade-panel"] .gradeform');
});
$('[data-region="attempt-chooser"]').on('click', this._chooseAttempt.bind(this));
this._addPopoutButtons('[data-region="grade-panel"] .gradeform');
$(document).trigger('finish-loading-user');
// Tell behat we are friends again.
window.M.util.js_complete('mod-assign-loading-user');
}.bind(this))
.fail(notification.exception);
}.bind(this)).fail(notification.exception);
$('[data-region="review-panel"]').show();
} else {
this._region.hide();
$('[data-region="review-panel"]').hide();
$(document).trigger('finish-loading-user');
// Tell behat we are friends again.
window.M.util.js_complete('mod-assign-loading-user');
}
}.bind(this));
}.bind(this)).fail(notification.exception);
};
/**
* Get next user data and store it in global variables
*
* @private
* @method _getNextUser
* @param {Event} event
* @param {Object} data Next user's data
*/
GradingPanel.prototype._getNextUser = function(event, data) {
this.nextUserId = data.nextUserId;
this.nextUser = data.nextUser;
};
/**
* Handle the save-and-show-next event
*
* @private
* @method _handleSaveAndShowNext
*/
GradingPanel.prototype._handleSaveAndShowNext = function() {
this._submitForm(null, this.nextUserId, this.nextUser);
};
/**
* Get the grade panel element.
*
* @method getPanelElement
* @return {jQuery}
*/
GradingPanel.prototype.getPanelElement = function() {
return $('[data-region="grade-panel"]');
};
/**
* Hide the grade panel.
*
* @method collapsePanel
*/
GradingPanel.prototype.collapsePanel = function() {
this.getPanelElement().addClass('collapsed');
};
/**
* Show the grade panel.
*
* @method expandPanel
*/
GradingPanel.prototype.expandPanel = function() {
this.getPanelElement().removeClass('collapsed');
};
/**
* Register event listeners for the grade panel.
*
* @method registerEventListeners
*/
GradingPanel.prototype.registerEventListeners = function() {
var docElement = $(document);
var region = $(this._region);
// Add an event listener to prevent form submission when pressing enter key.
region.on('submit', 'form', function(e) {
e.preventDefault();
});
docElement.on('next-user', this._getNextUser.bind(this));
docElement.on('user-changed', this._refreshGradingPanel.bind(this));
docElement.on('save-changes', this._submitForm.bind(this));
docElement.on('save-and-show-next', this._handleSaveAndShowNext.bind(this));
docElement.on('reset', this._resetForm.bind(this));
docElement.on('save-form-state', this._saveFormState.bind(this));
docElement.on(GradingEvents.COLLAPSE_GRADE_PANEL, function() {
this.collapsePanel();
}.bind(this));
// We should expand if the review panel is collapsed.
docElement.on(GradingEvents.COLLAPSE_REVIEW_PANEL, function() {
this.expandPanel();
}.bind(this));
docElement.on(GradingEvents.EXPAND_GRADE_PANEL, function() {
this.expandPanel();
}.bind(this));
};
return GradingPanel;
});
+164
View File
@@ -0,0 +1,164 @@
// 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/>.
/**
* Javascript controller for the "Review" panel at the left of the page.
*
* @module mod_assign/grading_review_panel
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'mod_assign/grading_events'], function($, GradingEvents) {
/**
* GradingReviewPanel class.
*
* @class mod_assign/grading_review_panel
*/
var GradingReviewPanel = function() {
this._region = $('[data-region="review-panel-content"]');
this.registerEventListeners();
};
/** @property {JQuery} JQuery node for the page region containing the user navigation. */
GradingReviewPanel.prototype._region = null;
/**
* It is first come first served to get ownership of the grading review panel.
* There can be only one.
*
* @public
* @method getReviewPanel
* @param {String} pluginname - the first plugin to ask for the panel gets it.
* @return {DOMNode} or false
*/
GradingReviewPanel.prototype.getReviewPanel = function(pluginname) {
var owner = this._region.data('panel-owner');
if (typeof owner == "undefined") {
this._region.data('review-panel-plugin', pluginname);
}
if (this._region.data('review-panel-plugin') == pluginname) {
return this._region[0];
}
return false;
};
/**
* Get the toggle review panel button.
*
* @method getTogglePanelButton
* @return {jQuery}
*/
GradingReviewPanel.prototype.getTogglePanelButton = function() {
return this.getPanelElement().find('[data-region="review-panel-toggle"]');
};
/**
* Get the review panel element.
*
* @method getPanelElement
* @return {jQuery}
*/
GradingReviewPanel.prototype.getPanelElement = function() {
return $('[data-region="review-panel"]');
};
/**
* Get the review panel content element.
*
* @method getPanelContentElement
* @return {jQuery}
*/
GradingReviewPanel.prototype.getPanelContentElement = function() {
return $('[data-region="review-panel-content"]');
};
/**
* Show/Hide the review panel.
*
* @method togglePanel
*/
GradingReviewPanel.prototype.togglePanel = function() {
if (this.getPanelElement().hasClass('collapsed')) {
$(document).trigger(GradingEvents.EXPAND_REVIEW_PANEL);
} else {
$(document).trigger(GradingEvents.COLLAPSE_REVIEW_PANEL);
}
};
/**
* Hide the review panel.
*
* @method collapsePanel
*/
GradingReviewPanel.prototype.collapsePanel = function() {
this.getPanelElement().addClass('collapsed').removeClass('grade-panel-collapsed');
this.getPanelContentElement().attr('aria-hidden', true);
};
/**
* Show the review panel.
*
* @method expandPanel
*/
GradingReviewPanel.prototype.expandPanel = function() {
this.getPanelElement().removeClass('collapsed');
this.getPanelContentElement().removeAttr('aria-hidden');
};
/**
* Register event listeners for the review panel.
*
* @method registerEventListeners
*/
GradingReviewPanel.prototype.registerEventListeners = function() {
var toggleReviewPanelButton = this.getTogglePanelButton();
toggleReviewPanelButton.click(function(e) {
this.togglePanel();
e.preventDefault();
}.bind(this));
toggleReviewPanelButton.keydown(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode === 13 || e.keyCode === 32) {
this.togglePanel();
e.preventDefault();
}
}
}.bind(this));
var docElement = $(document);
docElement.on(GradingEvents.COLLAPSE_REVIEW_PANEL, function() {
this.collapsePanel();
}.bind(this));
// Need special styling when grade panel is collapsed.
docElement.on(GradingEvents.COLLAPSE_GRADE_PANEL, function() {
this.expandPanel();
this.getPanelElement().addClass('grade-panel-collapsed');
}.bind(this));
docElement.on(GradingEvents.EXPAND_REVIEW_PANEL, function() {
this.expandPanel();
}.bind(this));
docElement.on(GradingEvents.EXPAND_GRADE_PANEL, function() {
this.getPanelElement().removeClass('grade-panel-collapsed');
}.bind(this));
};
return GradingReviewPanel;
});
+42
View File
@@ -0,0 +1,42 @@
// 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/>.
/**
* A javascript module to enhance the override form.
*
* @copyright 2019 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import $ from 'jquery';
import * as FormChangeChecker from 'core_form/changechecker';
export const init = (formId, selectElementName) => {
const form = document.getElementById(formId);
const selectElement = form.querySelector(`[name="${selectElementName}"]`);
$(selectElement).on('change', () => {
const inputElement = document.createElement('input');
inputElement.setAttribute('type', 'hidden');
inputElement.setAttribute('name', 'userchange');
inputElement.setAttribute('value', true);
form.appendChild(inputElement);
FormChangeChecker.markFormSubmitted(inputElement);
form.submit();
});
};
+121
View File
@@ -0,0 +1,121 @@
// 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/>.
/**
* Custom auto-complete adapter to load users from the assignment list_participants webservice.
*
* @module mod_assign/participant_selector
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['core/ajax', 'jquery', 'core/templates'], function(ajax, $, templates) {
return /** @alias module:mod_assign/participants_selector */ {
// Public variables and functions.
/**
* Process the results returned from transport (convert to value + label)
*
* @method processResults
* @param {String} selector
* @param {Array} data
* @return {Array}
*/
processResults: function(selector, data) {
return data;
},
/**
* Fetch results based on the current query. This also renders each result from a template before returning them.
*
* @method transport
* @param {String} selector Selector for the original select element
* @param {String} query Current search string
* @param {Function} success Success handler
* @param {Function} failure Failure handler
*/
transport: function(selector, query, success, failure) {
var assignmentid = $(selector).attr('data-assignmentid');
var groupid = $(selector).attr('data-groupid');
var filters = $('[data-region="configure-filters"] input[type="checkbox"]');
var filterstrings = [];
filters.each(function(index, element) {
filterstrings[$(element).attr('name')] = $(element).prop('checked');
});
ajax.call([{
methodname: 'mod_assign_list_participants',
args: {
assignid: assignmentid,
groupid: groupid,
filter: query,
limit: 30,
includeenrolments: false,
tablesort: true
}
}])[0].then(function(results) {
var promises = [];
var identityfields = $('[data-showuseridentity]').data('showuseridentity').split(',');
// We got the results, now we loop over them and render each one from a template.
$.each(results, function(index, user) {
var ctx = user,
identity = [],
show = true;
if (filterstrings.filter_submitted && !user.submitted) {
show = false;
}
if (filterstrings.filter_notsubmitted && user.submitted) {
show = false;
}
if (filterstrings.filter_requiregrading && !user.requiregrading) {
show = false;
}
if (filterstrings.filter_grantedextension && !user.grantedextension) {
show = false;
}
if (show) {
$.each(identityfields, function(i, k) {
if (typeof user[k] !== 'undefined' && user[k] !== '') {
ctx.hasidentity = true;
identity.push(user[k]);
}
});
ctx.identity = identity.join(', ');
promises.push(templates.render('mod_assign/list_participant_user_summary', ctx).then(function(html) {
return {value: user.id, label: html};
}));
}
});
// Do the dance for $.when()
return $.when.apply($, promises);
}).then(function() {
var users = [];
// Determine if we've been passed any arguments..
if (arguments[0]) {
// Undo the $.when() dance from arguments object into an array..
users = Array.prototype.slice.call(arguments);
}
success(users);
return;
}).catch(failure);
}
};
});
+126
View File
@@ -0,0 +1,126 @@
// 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/>.
import Notification from 'core/notification';
import {getString} from 'core/str';
/**
* A javascript module for the time in the assign module.
*
* @copyright 2020 Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Timestamp at which time runs out.
*
* @property {Number} endTime
*/
let endTime = 0;
/**
* ID of the timeout that updates the clock.
*
* @property {Number} timeoutId
*/
let timeoutId = null;
/**
* The timer element.
*
* @property {Element} timer
*/
let timer = null;
/**
* Helper method to convert time remaining in seconds into HH:MM:SS format.
*
* @method formatSeconds
* @param {Number} secs Time remaining in seconds to get value for.
* @return {String} Time remaining in HH:MM:SS format.
*/
const formatSeconds = (secs) => {
const hours = Math.floor(secs / 3600);
const minutes = Math.floor(secs / 60) % 60;
const seconds = secs % 60;
return [hours, minutes, seconds]
// Remove the hours column if there is less than 1 hour left.
.filter((value, index) => value !== 0 || index > 0)
// Ensure that all fields are two digit numbers.
.map(value => `${value}`.padStart(2, '0'))
.join(":");
};
/**
* Stop the timer, if it is running.
*
* @method stop
*/
const stop = () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
/**
* Function to update the clock with the current time left.
*
* @method update
*/
const update = () => {
const now = new Date().getTime();
const secondsLeft = Math.floor((endTime - now) / 1000);
// If time has expired, set the hidden form field that says time has expired.
if (secondsLeft <= 0) {
timer.classList.add('alert', 'alert-danger');
timer.innerHTML = '00:00:00';
// Only add a notification on the assign submission page.
if (document.getElementById("mod_assign_timelimit_block")) {
getString('caneditsubmission', 'mod_assign')
.then(message => Notification.addNotification({message}))
.catch(Notification.exception);
}
stop();
return;
} else if (secondsLeft < 300) { // Add danger style when less than 5 minutes left.
timer.classList.remove('alert-warning');
timer.classList.add('alert', 'alert-danger');
} else if (secondsLeft < 900) { // Add warning style when less than 15 minutes left.
timer.classList.remove('alert-danger');
timer.classList.add('alert', 'alert-warning');
}
// Update the time display.
timer.innerHTML = formatSeconds(secondsLeft);
// Arrange for this method to be called again soon.
timeoutId = setTimeout(update, 500);
};
/**
* Set up the submission timer.
*
* @method init
* @param {Number} timerId Unique ID of the timer element.
*/
export const init = (timerId) => {
timer = document.getElementById(timerId);
endTime = M.pageloadstarttime.getTime() + (timer.dataset.starttime * 1000);
update();
};
+701
View File
@@ -0,0 +1,701 @@
<?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 functions for assign_plugin abstract class
*
*
* @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();
/**
* Abstract class for assign_plugin (submission/feedback).
*
* @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
*/
abstract class assign_plugin {
/** @var assign $assignment the assignment record that contains the global
* settings for this assign instance
*/
protected $assignment;
/** @var string $type assignment plugin type */
private $type = '';
/** @var string $error error message */
private $error = '';
/** @var boolean|null $enabledcache Cached lookup of the is_enabled function */
private $enabledcache = null;
/** @var boolean|null $enabledcache Cached lookup of the is_visible function */
private $visiblecache = null;
/**
* Constructor for the abstract plugin type class
*
* @param assign $assignment
* @param string $type
*/
final public function __construct(assign $assignment, $type) {
$this->assignment = $assignment;
$this->type = $type;
}
/**
* Is this the first plugin in the list?
*
* @return bool
*/
final public function is_first() {
$order = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
if ($order == 0) {
return true;
}
return false;
}
/**
* Is this the last plugin in the list?
*
* @return bool
*/
final public function is_last() {
$lastindex = count(core_component::get_plugin_list($this->get_subtype()))-1;
$currentindex = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
if ($lastindex == $currentindex) {
return true;
}
return false;
}
/**
* This function should be overridden to provide an array of elements that can be added to a moodle
* form for display in the settings page for the assignment.
* @param MoodleQuickForm $mform The form to add the elements to
* @return $array
*/
public function get_settings(MoodleQuickForm $mform) {
return;
}
/**
* Allows the plugin 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 data_preprocessing(&$defaultvalues) {
return;
}
/**
* The assignment subtype is responsible for saving it's own settings as the database table for the
* standard type cannot be modified.
*
* @param stdClass $formdata - the data submitted from the form
* @return bool - on error the subtype should call set_error and return false.
*/
public function save_settings(stdClass $formdata) {
return true;
}
/**
* Save the error message from the last error
*
* @param string $msg - the error description
*/
final protected function set_error($msg) {
$this->error = $msg;
}
/**
* What was the last error?
*
* @return string
*/
final public function get_error() {
return $this->error;
}
/**
* Should return the name of this plugin type.
*
* @return string - the name
*/
abstract public function get_name();
/**
* Should return the subtype of this plugin.
*
* @return string - either 'assignsubmission' or 'feedback'
*/
abstract public function get_subtype();
/**
* Should return the type of this plugin.
*
* @return string - the type
*/
final public function get_type() {
return $this->type;
}
/**
* Get the installed version of this plugin
*
* @return string
*/
final public function get_version() {
$version = get_config($this->get_subtype() . '_' . $this->get_type(), 'version');
if ($version) {
return $version;
} else {
return '';
}
}
/**
* Get the required moodle version for this plugin
*
* @return string
*/
final public function get_requires() {
$requires = get_config($this->get_subtype() . '_' . $this->get_type(), 'requires');
if ($requires) {
return $requires;
} else {
return '';
}
}
/**
* Save any custom data for this form submission
*
* @param stdClass $submissionorgrade - assign_submission or assign_grade.
* For submission plugins this is the submission data,
* for feedback plugins it is the grade data
* @param stdClass $data - the data submitted from the form
* @return bool - on error the subtype should call set_error and return false.
*/
public function save(stdClass $submissionorgrade, stdClass $data) {
return true;
}
/**
* Set this plugin to enabled
*
* @return bool
*/
final public function enable() {
$this->enabledcache = true;
return $this->set_config('enabled', 1);
}
/**
* Set this plugin to disabled
*
* @return bool
*/
final public function disable() {
$this->enabledcache = false;
return $this->set_config('enabled', 0);
}
/**
* Allows hiding this plugin from the submission/feedback screen if it is not enabled.
*
* @return bool - if false - this plugin will not accept submissions / feedback
*/
public function is_enabled() {
if ($this->enabledcache === null) {
$this->enabledcache = $this->get_config('enabled');
}
return $this->enabledcache;
}
/**
* Get any additional fields for the submission/grading form for this assignment.
*
* @param mixed $submissionorgrade submission|grade - For submission plugins this is the submission data,
* for feedback plugins it is the grade data
* @param MoodleQuickForm $mform - This is the form
* @param stdClass $data - This is the form data that can be modified for example by a filemanager element
* @param int $userid - This is the userid for the current submission.
* This is passed separately as there may not yet be a submission or grade.
* @return boolean - true if we added anything to the form
*/
public function get_form_elements_for_user($submissionorgrade, MoodleQuickForm $mform, stdClass $data, $userid) {
return $this->get_form_elements($submissionorgrade, $mform, $data);
}
/**
* Get any additional fields for the submission/grading form for this assignment.
* This function is retained for backwards compatibility - new plugins should override {@link get_form_elements_for_user()}.
*
* @param mixed $submissionorgrade submission|grade - For submission plugins this is the submission data,
* for feedback plugins it is the grade data
* @param MoodleQuickForm $mform - This is the form
* @param stdClass $data - This is the form data that can be modified for example by a filemanager element
* @return boolean - true if we added anything to the form
*/
public function get_form_elements($submissionorgrade, MoodleQuickForm $mform, stdClass $data) {
return false;
}
/**
* Should not output anything - return the result as a string so it can be consumed by webservices.
*
* @param stdClass $submissionorgrade assign_submission or assign_grade
* For submission plugins this is the submission data,
* for feedback plugins it is the grade data
* @return string - return a string representation of the submission in full
*/
public function view(stdClass $submissionorgrade) {
return '';
}
/**
* Get the numerical sort order for this plugin
*
* @return int
*/
final public function get_sort_order() {
$order = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
return $order?$order:0;
}
/**
* Is this plugin enaled?
*
* @return bool
*/
final public function is_visible() {
if ($this->visiblecache === null) {
$disabled = get_config($this->get_subtype() . '_' . $this->get_type(), 'disabled');
$this->visiblecache = !$disabled;
}
return $this->visiblecache;
}
/**
* Has this plugin got a custom settings.php file?
*
* @return bool
*/
final public function has_admin_settings() {
global $CFG;
$pluginroot = $CFG->dirroot . '/mod/assign/' . substr($this->get_subtype(), strlen('assign')) . '/' . $this->get_type();
$settingsfile = $pluginroot . '/settings.php';
return file_exists($settingsfile);
}
/**
* Set a configuration value for this plugin
*
* @param string $name The config key
* @param string $value The config value
* @return bool
*/
final public function set_config($name, $value) {
global $DB;
$dbparams = array('assignment'=>$this->assignment->get_instance()->id,
'subtype'=>$this->get_subtype(),
'plugin'=>$this->get_type(),
'name'=>$name);
$current = $DB->get_record('assign_plugin_config', $dbparams, '*', IGNORE_MISSING);
if ($current) {
$current->value = $value;
return $DB->update_record('assign_plugin_config', $current);
} else {
$setting = new stdClass();
$setting->assignment = $this->assignment->get_instance()->id;
$setting->subtype = $this->get_subtype();
$setting->plugin = $this->get_type();
$setting->name = $name;
$setting->value = $value;
return $DB->insert_record('assign_plugin_config', $setting) > 0;
}
}
/**
* Get a configuration value for this plugin
*
* @param mixed $setting The config key (string) or null
* @return mixed string | false
*/
final public function get_config($setting = null) {
global $DB;
if ($setting) {
if (!$this->assignment->has_instance()) {
return false;
}
$assignment = $this->assignment->get_instance();
if ($assignment) {
$dbparams = array('assignment'=>$assignment->id,
'subtype'=>$this->get_subtype(),
'plugin'=>$this->get_type(),
'name'=>$setting);
$result = $DB->get_record('assign_plugin_config', $dbparams, '*', IGNORE_MISSING);
if ($result) {
return $result->value;
}
}
return false;
}
$dbparams = array('assignment'=>$this->assignment->get_instance()->id,
'subtype'=>$this->get_subtype(),
'plugin'=>$this->get_type());
$results = $DB->get_records('assign_plugin_config', $dbparams);
$config = new stdClass();
if (is_array($results)) {
foreach ($results as $setting) {
$name = $setting->name;
$config->$name = $setting->value;
}
}
return $config;
}
/**
* Get a list of file areas associated with the plugin configuration.
* This is used for backup/restore.
*
* @return array names of the fileareas, can be an empty array
*/
public function get_config_file_areas() {
return array();
}
/**
* Should not output anything - return the result as a string so it can be consumed by webservices.
*
* @param stdClass $submissionorgrade assign_submission or assign_grade
* For submission plugins this is the submission data, for feedback plugins it is the grade data
* @param bool $showviewlink Modifed to return whether or not to show a link to the full submission/feedback
* @return string - return a string representation of the submission in full
*/
public function view_summary(stdClass $submissionorgrade, & $showviewlink) {
return '';
}
/**
* Given a field name and value should update the text for this field in the plugins submission or grade
*
* @param string $name Name of the field.
* @param string $value Updated text
* @param int $submissionorgradeid The id of the submission or grade
* @return bool - true if the value was updated
*/
public function set_editor_text($name, $value, $submissionorgradeid) {
return false;
}
/**
* Given a field name and value should update the format for this field in the plugins submission or grade
*
* @param string $name Name of the field.
* @param int $format Updated format.
* @param int $submissionorgradeid The id of the submission or grade.
* @return bool - true if the value was updated
*/
public function set_editor_format($name, $format, $submissionorgradeid) {
return false;
}
/**
* Return a list of the fields that can be exported or imported via text.
*
* @return array - The list of field names (strings) and descriptions. ($name => $description)
*/
public function get_editor_fields() {
return array();
}
/**
* Given a field name, should return the text of an editor field that is part of
* this plugin. This is used when exporting to portfolio.
*
* @param string $name Name of the field.
* @param int $submissionorgradeid The id of the submission or grade
* @return string - The text for the editor field
*/
public function get_editor_text($name, $submissionorgradeid) {
return '';
}
/**
* Produce a list of files suitable for export that represent this feedback or submission
*
* @param stdClass $submissionorgrade assign_submission or assign_grade
* For submission plugins this is the submission data, for feedback plugins it is the grade data
* @param stdClass $user The user record for the current submission.
* Needed for url rewriting if this is a group submission.
* @return array - return an array of files indexed by filename
*/
public function get_files(stdClass $submissionorgrade, stdClass $user) {
return array();
}
/**
* Given a field name, should return the format of an editor field that is part of
* this plugin. This is used when exporting to portfolio.
*
* @param string $name Name of the field.
* @param int $submissionid The id of the submission
* @return int - The format for the editor field
*/
public function get_editor_format($name, $submissionid) {
return 0;
}
/**
* Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
* and version.
*
* @param string $type The old assignment subtype
* @param int $version The old assignment version
* @return bool True if upgrade is possible
*/
public function can_upgrade($type, $version) {
return false;
}
/**
* Upgrade the settings from the old assignment to the new one
*
* @param context $oldcontext The context for the old assignment module
* @param stdClass $oldassignment The data record for the old assignment
* @param string $log Record upgrade messages in the log
* @return bool true or false - false will trigger a rollback
*/
public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
$params = array('type'=>$this->type, 'subtype'=>$this->get_subtype());
$log .= ' ' . get_string('upgradenotimplemented', 'mod_assign', $params);
return false;
}
/**
* Upgrade the submission from the old assignment to the new one
*
* @param context $oldcontext The data record for the old context
* @param stdClass $oldassignment The data record for the old assignment
* @param stdClass $oldsubmissionorgrade The data record for the old submission
* @param stdClass $submissionorgrade assign_submission or assign_grade The new submission or grade
* @param string $log Record upgrade messages in the log
* @return boolean true or false - false will trigger a rollback
*/
public function upgrade(context $oldcontext,
stdClass $oldassignment,
stdClass $oldsubmissionorgrade,
stdClass $submissionorgrade,
& $log) {
$params = array('type'=>$this->type, 'subtype'=>$this->get_subtype());
$log = $log . ' ' . get_string('upgradenotimplemented', 'mod_assign', $params);
return false;
}
/**
* @deprecated since 2.7
*/
public function format_for_log() {
throw new coding_exception(__FUNCTION__ . ' has been deprecated, please do not use it any more');
}
/**
* The assignment has been deleted - remove the plugin specific data
*
* @return bool
*/
public function delete_instance() {
return true;
}
/**
* Run cron for this plugin
*/
public static function cron() {
}
/**
* Is this assignment plugin empty? (ie no submission or feedback)
* @param stdClass $submissionorgrade assign_submission or assign_grade
* @return bool
*/
public function is_empty(stdClass $submissionorgrade) {
return true;
}
/**
* Get file areas returns a list of areas this plugin stores files
* @return array - An array of fileareas (keys) and descriptions (values)
*/
public function get_file_areas() {
return array();
}
/**
* Default implementation of file_get_info for plugins.
* This is used by the filebrowser to browse a plugins file areas.
*
* This implementation should work for most plugins but can be overridden if required.
* @param file_browser $browser
* @param string $filearea
* @param int $itemid
* @param string $filepath
* @param string $filename
* @return file_info_stored
*/
public function get_file_info($browser, $filearea, $itemid, $filepath, $filename) {
global $CFG, $DB, $USER;
$urlbase = $CFG->wwwroot.'/pluginfile.php';
$writeaccess = false;
// Permission check on the itemid.
$assignment = $this->assignment;
if ($this->get_subtype() == 'assignsubmission') {
if ($itemid) {
$record = $DB->get_record('assign_submission', array('id' => $itemid), 'userid,groupid', IGNORE_MISSING);
if (!$record) {
return null;
}
if (!empty($record->userid)) {
if (!$assignment->can_view_submission($record->userid)) {
return null;
}
// We only report write access for teachers.
$writeaccess = $assignment->can_grade() && $assignment->can_edit_submission($record->userid);
} else {
// Must be a team submission with a group.
if (!$assignment->can_view_group_submission($record->groupid)) {
return null;
}
// We only report write access for teachers.
$writeaccess = $assignment->can_grade() && $assignment->can_edit_group_submission($record->groupid);
}
}
} else {
// Not supported for feedback plugins.
return null;
}
$fs = get_file_storage();
$filepath = is_null($filepath) ? '/' : $filepath;
$filename = is_null($filename) ? '.' : $filename;
if (!($storedfile = $fs->get_file($assignment->get_context()->id,
$this->get_subtype() . '_' . $this->get_type(),
$filearea,
$itemid,
$filepath,
$filename))) {
return null;
}
return new file_info_stored($browser,
$assignment->get_context(),
$storedfile,
$urlbase,
$filearea,
$itemid,
true,
$writeaccess,
false);
}
/**
* This allows a plugin to render a page in the context of the assignment
*
* If the plugin creates a link to the assignment view.php page with
* The following required parameters:
* id=coursemoduleid
* plugin=type
* pluginsubtype=assignfeedback|assignsubmission
* pluginaction=customaction
*
* Then this function will be called to display the page with the pluginaction passed as action
* @param string $action The plugin specified action
* @return string
*/
public function view_page($action) {
return '';
}
/**
* This allows a plugin to render an introductory section which is displayed
* right below the activity's "intro" section on the main assignment page.
*
* @return string
*/
public function view_header() {
return '';
}
/**
* If this plugin should not include a column in the grading table or a row on the summary page
* then return false
*
* @return bool
*/
public function has_user_summary() {
return true;
}
/**
* If this plugin can participate in a webservice (save_submission or save_grade),
* return a list of external_params to be included in the definition of that webservice.
*
* @return external_description|null
*/
public function get_external_parameters() {
return null;
}
/**
* If true, the plugin will appear on the module settings page and can be
* enabled/disabled per assignment instance.
*
* @return bool
*/
public function is_configurable() {
return true;
}
/**
* Return the plugin configs for external functions,
* in some cases the configs will need formatting or be returned only if the current user has some capabilities enabled.
*
* @return array the list of settings
* @since Moodle 3.2
*/
public function get_config_for_external() {
return array();
}
}
@@ -0,0 +1,73 @@
<?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 backup activity for the 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();
require_once($CFG->dirroot . '/mod/assign/backup/moodle2/backup_assign_stepslib.php');
/**
* assign backup task that provides all the settings and steps to perform one complete backup of the activity
*
* @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 backup_assign_activity_task extends backup_activity_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
// No particular settings for this activity.
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
$this->add_step(new backup_assign_activity_structure_step('assign_structure', 'assign.xml'));
}
/**
* Code the transformations to perform in the activity in
* order to get transportable (encoded) links
* @param string $content
* @return string
*/
public static function encode_content_links($content) {
global $CFG;
$base = preg_quote($CFG->wwwroot, "/");
$search="/(".$base."\/mod\/assign\/index.php\?id\=)([0-9]+)/";
$content= preg_replace($search, '$@ASSIGNINDEX*$2@$', $content);
$search="/(".$base."\/mod\/assign\/view.php\?id\=)([0-9]+)/";
$content= preg_replace($search, '$@ASSIGNVIEWBYID*$2@$', $content);
return $content;
}
}
@@ -0,0 +1,217 @@
<?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/>.
/**
* Define all the backup steps that will be used by the backup_assign_activity_task
*
* @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();
require_once($CFG->dirroot . '/mod/assign/locallib.php');
/**
* Define the complete choice structure for backup, with file and id annotations
*
* @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 backup_assign_activity_structure_step extends backup_activity_structure_step {
/**
* Annotate files from plugin configuration
* @param backup_nested_element $assign the backup structure of the activity
* @param string $subtype the plugin type to handle
* @return void
*/
protected function annotate_plugin_config_files(backup_nested_element $assign, $subtype) {
$dummyassign = new assign(null, null, null);
$plugins = $dummyassign->load_plugins($subtype);
foreach ($plugins as $plugin) {
$component = $plugin->get_subtype() . '_' . $plugin->get_type();
$areas = $plugin->get_config_file_areas();
foreach ($areas as $area) {
$assign->annotate_files($component, $area, null);
}
}
}
/**
* Define the structure for the assign activity
* @return backup_nested_element
*/
protected function define_structure() {
// To know if we are including userinfo.
$userinfo = $this->get_setting_value('userinfo');
$groupinfo = $this->get_setting_value('groups');
// Define each element separated.
$assign = new backup_nested_element('assign', array('id'),
array('name',
'intro',
'introformat',
'alwaysshowdescription',
'submissiondrafts',
'sendnotifications',
'sendlatenotifications',
'sendstudentnotifications',
'duedate',
'cutoffdate',
'gradingduedate',
'allowsubmissionsfromdate',
'grade',
'timemodified',
'completionsubmit',
'requiresubmissionstatement',
'teamsubmission',
'requireallteammemberssubmit',
'teamsubmissiongroupingid',
'blindmarking',
'hidegrader',
'revealidentities',
'attemptreopenmethod',
'maxattempts',
'markingworkflow',
'markingallocation',
'markinganonymous',
'preventsubmissionnotingroup',
'activity',
'activityformat',
'timelimit',
'submissionattachments'));
$userflags = new backup_nested_element('userflags');
$userflag = new backup_nested_element('userflag', array('id'),
array('userid',
'assignment',
'mailed',
'locked',
'extensionduedate',
'workflowstate',
'allocatedmarker'));
$submissions = new backup_nested_element('submissions');
$submission = new backup_nested_element('submission', array('id'),
array('userid',
'timecreated',
'timemodified',
'timestarted',
'status',
'groupid',
'attemptnumber',
'latest'));
$grades = new backup_nested_element('grades');
$grade = new backup_nested_element('grade', array('id'),
array('userid',
'timecreated',
'timemodified',
'grader',
'grade',
'attemptnumber'));
$pluginconfigs = new backup_nested_element('plugin_configs');
$pluginconfig = new backup_nested_element('plugin_config', array('id'),
array('plugin',
'subtype',
'name',
'value'));
$overrides = new backup_nested_element('overrides');
$override = new backup_nested_element('override', array('id'), array(
'groupid', 'userid', 'sortorder', 'allowsubmissionsfromdate', 'duedate', 'cutoffdate', 'timelimit'));
// Build the tree.
$assign->add_child($userflags);
$userflags->add_child($userflag);
$assign->add_child($submissions);
$submissions->add_child($submission);
$assign->add_child($grades);
$grades->add_child($grade);
$assign->add_child($pluginconfigs);
$pluginconfigs->add_child($pluginconfig);
$assign->add_child($overrides);
$overrides->add_child($override);
// Define sources.
$assign->set_source_table('assign', array('id' => backup::VAR_ACTIVITYID));
$pluginconfig->set_source_table('assign_plugin_config',
array('assignment' => backup::VAR_PARENTID));
// Assign overrides to backup are different depending of user info.
$overrideparams = array('assignid' => backup::VAR_PARENTID);
if ($userinfo) {
$userflag->set_source_table('assign_user_flags',
array('assignment' => backup::VAR_PARENTID));
$submissionparams = array('assignment' => backup::VAR_PARENTID);
if (!$groupinfo) {
// Without group info, skip group submissions.
$submissionparams['groupid'] = backup_helper::is_sqlparam(0);
}
$submission->set_source_table('assign_submission', $submissionparams);
$grade->set_source_table('assign_grades',
array('assignment' => backup::VAR_PARENTID));
// Support 2 types of subplugins.
$this->add_subplugin_structure('assignsubmission', $submission, true);
$this->add_subplugin_structure('assignfeedback', $grade, true);
} else {
$overrideparams['userid'] = backup_helper::is_sqlparam(null); // Without userinfo, skip user overrides.
}
if (!$groupinfo) {
// Without group info, skip group overrides.
$overrideparams['groupid'] = backup_helper::is_sqlparam(0);
}
$override->set_source_table('assign_overrides', $overrideparams);
// Define id annotations.
$userflag->annotate_ids('user', 'userid');
$userflag->annotate_ids('user', 'allocatedmarker');
$submission->annotate_ids('user', 'userid');
$submission->annotate_ids('group', 'groupid');
$grade->annotate_ids('user', 'userid');
$grade->annotate_ids('user', 'grader');
$assign->annotate_ids('grouping', 'teamsubmissiongroupingid');
$override->annotate_ids('user', 'userid');
$override->annotate_ids('group', 'groupid');
// Define file annotations.
// These file areas don't have an itemid.
$assign->annotate_files('mod_assign', 'intro', null);
$assign->annotate_files('mod_assign', 'introattachment', null);
$assign->annotate_files('mod_assign', 'activityattachment', null);
$this->annotate_plugin_config_files($assign, 'assignsubmission');
$this->annotate_plugin_config_files($assign, 'assignfeedback');
// Return the root element (choice), wrapped into standard activity structure.
return $this->prepare_activity_structure($assign);
}
}
@@ -0,0 +1,141 @@
<?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/>.
/**
* Define all the backup steps that will be used by the backup_assign_activity_task
*
* @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();
require_once($CFG->dirroot . '/mod/assign/backup/moodle2/restore_assign_stepslib.php');
/**
* assign restore task that provides all the settings and steps to perform one complete restore of the activity
*
* @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 restore_assign_activity_task extends restore_activity_task {
/**
* Define (add) particular settings this activity can have.
*/
protected function define_my_settings() {
// No particular settings for this activity.
}
/**
* Define (add) particular steps this activity can have.
*/
protected function define_my_steps() {
// Assignment only has one structure step.
$this->add_step(new restore_assign_activity_structure_step('assign_structure', 'assign.xml'));
}
/**
* Define the contents in the activity that must be
* processed by the link decoder.
*
* @return array
*/
public static function define_decode_contents() {
$contents = array();
$contents[] = new restore_decode_content('assign', array('intro'), 'assign');
return $contents;
}
/**
* Define the decoding rules for links belonging
* to the activity to be executed by the link decoder.
*
* @return array of restore_decode_rule
*/
public static function define_decode_rules() {
$rules = array();
$rules[] = new restore_decode_rule('ASSIGNVIEWBYID',
'/mod/assign/view.php?id=$1',
'course_module');
$rules[] = new restore_decode_rule('ASSIGNINDEX',
'/mod/assign/index.php?id=$1',
'course_module');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* assign logs. It must return one array
* of {@link restore_log_rule} objects.
*
* @return array of restore_log_rule
*/
public static function define_restore_log_rules() {
$rules = array();
$rules[] = new restore_log_rule('assign', 'add', 'view.php?id={course_module}', '{assign}');
$rules[] = new restore_log_rule('assign', 'update', 'view.php?id={course_module}', '{assign}');
$rules[] = new restore_log_rule('assign', 'view', 'view.php?id={course_module}', '{assign}');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* course logs. It must return one array
* of {@link restore_log_rule} objects
*
* Note this rules are applied when restoring course logs
* by the restore final task, but are defined here at
* activity level. All them are rules not linked to any module instance (cmid = 0)
*
* @return array
*/
public static function define_restore_log_rules_for_course() {
$rules = array();
return $rules;
}
/**
* Given a comment area, return the itemname that contains the itemid mappings.
*
* @param string $commentarea
* @return string
*/
public function get_comment_mapping_itemname($commentarea) {
switch ($commentarea) {
case 'submission_comments':
$itemname = 'submission';
break;
default:
$itemname = parent::get_comment_mapping_itemname($commentarea);
break;
}
return $itemname;
}
}
@@ -0,0 +1,435 @@
<?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/>.
/**
* Define all the restore steps that will be used by the restore_assign_activity_task
*
* @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();
require_once($CFG->dirroot . '/mod/assign/locallib.php');
/**
* Define the complete assignment structure for restore, with file and id annotations
*
* @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 restore_assign_activity_structure_step extends restore_activity_structure_step {
/**
* Store whether submission details should be included. Details may not be included if the
* this is a team submission, but groups/grouping information was not included in the backup.
*/
protected $includesubmission = true;
/**
* Define the structure of the restore workflow.
*
* @return restore_path_element $structure
*/
protected function define_structure() {
$paths = array();
// To know if we are including userinfo.
$userinfo = $this->get_setting_value('userinfo');
// Define each element separated.
$paths[] = new restore_path_element('assign', '/activity/assign');
if ($userinfo) {
$submission = new restore_path_element('assign_submission',
'/activity/assign/submissions/submission');
$paths[] = $submission;
$this->add_subplugin_structure('assignsubmission', $submission);
$grade = new restore_path_element('assign_grade', '/activity/assign/grades/grade');
$paths[] = $grade;
$this->add_subplugin_structure('assignfeedback', $grade);
$userflag = new restore_path_element('assign_userflag',
'/activity/assign/userflags/userflag');
$paths[] = $userflag;
}
$paths[] = new restore_path_element('assign_override', '/activity/assign/overrides/override');
$paths[] = new restore_path_element('assign_plugin_config',
'/activity/assign/plugin_configs/plugin_config');
return $this->prepare_activity_structure($paths);
}
/**
* Process an assign restore.
*
* @param object $data The data in object form
* @return void
*/
protected function process_assign($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->course = $this->get_courseid();
// Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
// See MDL-9367.
$data->allowsubmissionsfromdate = $this->apply_date_offset($data->allowsubmissionsfromdate);
$data->duedate = $this->apply_date_offset($data->duedate);
// If this is a team submission, but there is no group info we need to flag that the submission
// information should not be included. It should not be restored.
$groupinfo = $this->task->get_setting_value('groups');
if ($data->teamsubmission && !$groupinfo) {
$this->includesubmission = false;
}
// Reset revealidentities if blindmarking with no user data (MDL-43796).
$userinfo = $this->get_setting_value('userinfo');
if (!$userinfo && $data->blindmarking) {
$data->revealidentities = 0;
}
if (!empty($data->teamsubmissiongroupingid)) {
$data->teamsubmissiongroupingid = $this->get_mappingid('grouping',
$data->teamsubmissiongroupingid);
} else {
$data->teamsubmissiongroupingid = 0;
}
if (!isset($data->cutoffdate)) {
$data->cutoffdate = 0;
}
if (!isset($data->gradingduedate)) {
$data->gradingduedate = 0;
} else {
$data->gradingduedate = $this->apply_date_offset($data->gradingduedate);
}
if (!isset($data->markingworkflow)) {
$data->markingworkflow = 0;
}
if (!isset($data->markingallocation)) {
$data->markingallocation = 0;
}
if (!isset($data->markinganonymous)) {
$data->markinganonymous = 0;
}
if (!isset($data->preventsubmissionnotingroup)) {
$data->preventsubmissionnotingroup = 0;
}
if (!empty($data->preventlatesubmissions)) {
$data->cutoffdate = $data->duedate;
} else {
$data->cutoffdate = $this->apply_date_offset($data->cutoffdate);
}
if ($data->grade < 0) { // Scale found, get mapping.
$data->grade = -($this->get_mappingid('scale', abs($data->grade)));
}
$newitemid = $DB->insert_record('assign', $data);
$this->apply_activity_instance($newitemid);
}
/**
* Process a submission restore
* @param object $data The data in object form
* @return void
*/
protected function process_assign_submission($data) {
global $DB;
if (!$this->includesubmission) {
return;
}
$data = (object)$data;
$oldid = $data->id;
$data->assignment = $this->get_new_parentid('assign');
if ($data->userid > 0) {
$data->userid = $this->get_mappingid('user', $data->userid);
}
if (!empty($data->groupid)) {
$data->groupid = $this->get_mappingid('group', $data->groupid);
if (!$data->groupid) {
// If the group does not exist, then the submission cannot be viewed and restoring can
// violate the unique index on the submission table.
return;
}
} else {
$data->groupid = 0;
}
// We will correct this in set_latest_submission_field() once all submissions are restored.
$data->latest = 0;
$newitemid = $DB->insert_record('assign_submission', $data);
// Note - the old contextid is required in order to be able to restore files stored in
// sub plugin file areas attached to the submissionid.
$this->set_mapping('submission', $oldid, $newitemid, false, null, $this->task->get_old_contextid());
}
/**
* Process a user_flags restore
* @param object $data The data in object form
* @return void
*/
protected function process_assign_userflag($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->assignment = $this->get_new_parentid('assign');
$data->userid = $this->get_mappingid('user', $data->userid);
if (!empty($data->allocatedmarker)) {
$data->allocatedmarker = $this->get_mappingid('user', $data->allocatedmarker);
}
if (!empty($data->extensionduedate)) {
$data->extensionduedate = $this->apply_date_offset($data->extensionduedate);
} else {
$data->extensionduedate = 0;
}
// Flags mailed and locked need no translation on restore.
$newitemid = $DB->insert_record('assign_user_flags', $data);
}
/**
* Process a grade restore
* @param object $data The data in object form
* @return void
*/
protected function process_assign_grade($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->assignment = $this->get_new_parentid('assign');
$data->userid = $this->get_mappingid('user', $data->userid);
$data->grader = $this->get_mappingid('user', $data->grader);
// Handle flags restore to a different table (for upgrade from old backups).
if (!empty($data->extensionduedate) ||
!empty($data->mailed) ||
!empty($data->locked)) {
$flags = new stdClass();
$flags->assignment = $this->get_new_parentid('assign');
if (!empty($data->extensionduedate)) {
$flags->extensionduedate = $this->apply_date_offset($data->extensionduedate);
}
if (!empty($data->mailed)) {
$flags->mailed = $data->mailed;
}
if (!empty($data->locked)) {
$flags->locked = $data->locked;
}
$flags->userid = $this->get_mappingid('user', $data->userid);
$DB->insert_record('assign_user_flags', $flags);
}
// Fix null grades that were rescaled.
if ($data->grade < 0 && $data->grade != ASSIGN_GRADE_NOT_SET) {
$data->grade = ASSIGN_GRADE_NOT_SET;
}
$newitemid = $DB->insert_record('assign_grades', $data);
// Note - the old contextid is required in order to be able to restore files stored in
// sub plugin file areas attached to the gradeid.
$this->set_mapping('grade', $oldid, $newitemid, false, null, $this->task->get_old_contextid());
$this->set_mapping(restore_gradingform_plugin::itemid_mapping('submissions'), $oldid, $newitemid);
}
/**
* Process a plugin-config restore
* @param object $data The data in object form
* @return void
*/
protected function process_assign_plugin_config($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->assignment = $this->get_new_parentid('assign');
$newitemid = $DB->insert_record('assign_plugin_config', $data);
}
/**
* For all submissions in this assignment, either set the
* submission->latest field to 1 for the latest attempts
* or create a new submission record for grades with no submission.
*
* @return void
*/
protected function set_latest_submission_field() {
global $DB, $CFG;
// Required for constants.
require_once($CFG->dirroot . '/mod/assign/locallib.php');
$assignmentid = $this->get_new_parentid('assign');
// First check for records with a grade, but no submission record.
// This happens when a teacher marks a student before they have submitted anything.
$records = $DB->get_recordset_sql('SELECT g.id, g.userid, g.attemptnumber
FROM {assign_grades} g
LEFT JOIN {assign_submission} s
ON s.assignment = g.assignment
AND s.userid = g.userid
WHERE s.id IS NULL AND g.assignment = ?', array($assignmentid));
$submissions = array();
foreach ($records as $record) {
$submission = new stdClass();
$submission->assignment = $assignmentid;
$submission->userid = $record->userid;
$submission->attemptnumber = $record->attemptnumber;
$submission->status = ASSIGN_SUBMISSION_STATUS_NEW;
$submission->groupid = 0;
$submission->latest = 0;
$submission->timecreated = time();
$submission->timemodified = time();
array_push($submissions, $submission);
}
$records->close();
$DB->insert_records('assign_submission', $submissions);
// This code could be rewritten as a monster SQL - but the point of adding this "latest" field
// to the submissions table in the first place was to get away from those hard to maintain SQL queries.
// First user submissions.
$sql = 'SELECT DISTINCT userid FROM {assign_submission} WHERE assignment = ? AND groupid = ?';
$params = array($assignmentid, 0);
$users = $DB->get_records_sql($sql, $params);
foreach ($users as $userid => $unused) {
$params = array('assignment'=>$assignmentid, 'groupid'=>0, 'userid'=>$userid);
// Only return the row with the highest attemptnumber.
$submission = null;
$submissions = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', '*', 0, 1);
if ($submissions) {
$submission = reset($submissions);
$submission->latest = 1;
$DB->update_record('assign_submission', $submission);
}
}
// Then group submissions (if any).
$sql = 'SELECT DISTINCT groupid FROM {assign_submission} WHERE assignment = ? AND userid = ?';
$params = array($assignmentid, 0);
$groups = $DB->get_records_sql($sql, $params);
foreach ($groups as $groupid => $unused) {
$params = array('assignment'=>$assignmentid, 'userid'=>0, 'groupid'=>$groupid);
// Only return the row with the highest attemptnumber.
$submission = null;
$submissions = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', '*', 0, 1);
if ($submissions) {
$submission = reset($submissions);
$submission->latest = 1;
$DB->update_record('assign_submission', $submission);
}
}
}
/**
* Restore files from plugin configuration
* @param string $subtype the plugin type to handle
* @return void
*/
protected function add_plugin_config_files($subtype) {
$dummyassign = new assign(null, null, null);
$plugins = $dummyassign->load_plugins($subtype);
foreach ($plugins as $plugin) {
$component = $plugin->get_subtype() . '_' . $plugin->get_type();
$areas = $plugin->get_config_file_areas();
foreach ($areas as $area) {
$this->add_related_files($component, $area, null);
}
}
}
/**
* Process a assign override restore
* @param object $data The data in object form
* @return void
*/
protected function process_assign_override($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
// Based on userinfo, we'll restore user overides or no.
$userinfo = $this->get_setting_value('userinfo');
// Skip user overrides if we are not restoring userinfo.
if (!$userinfo && !is_null($data->userid)) {
return;
}
// Skip group overrides if we are not restoring groupinfo.
$groupinfo = $this->get_setting_value('groups');
if (!$groupinfo && !is_null($data->groupid)) {
return;
}
$data->assignid = $this->get_new_parentid('assign');
if (!is_null($data->userid)) {
$data->userid = $this->get_mappingid('user', $data->userid);
}
if (!is_null($data->groupid)) {
$data->groupid = $this->get_mappingid('group', $data->groupid);
}
$data->allowsubmissionsfromdate = $this->apply_date_offset($data->allowsubmissionsfromdate);
$data->duedate = $this->apply_date_offset($data->duedate);
$data->cutoffdate = $this->apply_date_offset($data->cutoffdate);
$newitemid = $DB->insert_record('assign_overrides', $data);
// Add mapping, restore of logs needs it.
$this->set_mapping('assign_override', $oldid, $newitemid);
}
/**
* Once the database tables have been fully restored, restore the files
*/
protected function after_execute() {
$this->add_related_files('mod_assign', 'intro', null);
$this->add_related_files('mod_assign', 'introattachment', null);
$this->add_related_files('mod_assign', 'activityattachment', null);
$this->add_plugin_config_files('assignsubmission');
$this->add_plugin_config_files('assignfeedback');
$this->set_latest_submission_field();
}
}
@@ -0,0 +1,62 @@
<?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 forms to set the allocated marker for selected submissions.
*
* @package mod_assign
* @copyright 2013 Catalyst IT {@link http://www.catalyst.net.nz}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot . '/mod/assign/feedback/file/locallib.php');
/**
* Set allocated marker form.
*
* @package mod_assign
* @copyright 2013 Catalyst IT {@link http://www.catalyst.net.nz}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_assign_batch_set_allocatedmarker_form extends moodleform {
/**
* Define this form - called by the parent constructor
*/
public function definition() {
$mform = $this->_form;
$params = $this->_customdata;
$mform->addElement('header', 'general', get_string('batchsetallocatedmarker', 'assign', $params['userscount']));
$mform->addElement('static', 'userslist', get_string('selectedusers', 'assign'), $params['usershtml']);
$options = $params['markers'];
$mform->addElement('select', 'allocatedmarker', get_string('allocatedmarker', 'assign'), $options);
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', 'setbatchmarkingallocation');
$mform->setType('action', PARAM_ALPHA);
$mform->addElement('hidden', 'selectedusers');
$mform->setType('selectedusers', PARAM_SEQUENCE);
$this->add_action_buttons(true, get_string('savechanges'));
}
}
@@ -0,0 +1,87 @@
<?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 forms to set the marking workflow for selected submissions.
*
* @package mod_assign
* @copyright 2013 Catalyst IT {@link http://www.catalyst.net.nz}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot . '/mod/assign/feedback/file/locallib.php');
/**
* Set marking workflow form.
*
* @package mod_assign
* @copyright 2013 Catalyst IT {@link http://www.catalyst.net.nz}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_assign_batch_set_marking_workflow_state_form extends moodleform {
/**
* Define this form - called by the parent constructor
*/
public function definition() {
$mform = $this->_form;
$params = $this->_customdata;
$formheader = get_string('batchsetmarkingworkflowstateforusers', 'assign', $params['userscount']);
$mform->addElement('header', 'general', $formheader);
$mform->addElement('static', 'userslist', get_string('selectedusers', 'assign'), $params['usershtml']);
$options = $params['markingworkflowstates'];
$mform->addElement('select', 'markingworkflowstate', get_string('markingworkflowstate', 'assign'), $options);
// Don't allow notification to be sent until in "Released" state.
$mform->addElement('selectyesno', 'sendstudentnotifications', get_string('sendstudentnotifications', 'assign'));
$mform->setDefault('sendstudentnotifications', 0);
$mform->disabledIf('sendstudentnotifications', 'markingworkflowstate', 'neq', ASSIGN_MARKING_WORKFLOW_STATE_RELEASED);
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', 'setbatchmarkingworkflowstate');
$mform->setType('action', PARAM_ALPHA);
$mform->addElement('hidden', 'selectedusers');
$mform->setType('selectedusers', PARAM_SEQUENCE);
$this->add_action_buttons(true, get_string('savechanges'));
}
/**
* Validate the submitted form data.
*
* @param array $data array of ("fieldname"=>value) of submitted data
* @param array $files array of uploaded files "element_name"=>tmp_file_path
* @return array of "element_name"=>"error_description" if there are errors
*/
public function validation($data, $files) {
$errors = parent::validation($data, $files);
// As the implementation of this feature exists currently, no user will see a validation
// failure from this form, but this check ensures the form won't validate if someone
// manipulates the 'sendstudentnotifications' field's disabled attribute client-side.
if (!empty($data['sendstudentnotifications']) && $data['markingworkflowstate'] != ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) {
$errors['sendstudentnotifications'] = get_string('studentnotificationworkflowstateerror', 'assign');
}
return $errors;
}
}
@@ -0,0 +1,66 @@
<?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/>.
/**
* Activity base class.
*
* @package mod_assign
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Activity base class.
*
* @package mod_assign
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
/**
* feedback_viewed_events
*
* @return string[]
*/
protected function feedback_viewed_events() {
return array('\mod_assign\event\feedback_viewed');
}
/**
* feedback_check_grades
*
* @return bool
*/
protected function feedback_check_grades() {
// We need the grade to be released to the student to consider that feedback has been provided.
return true;
}
/**
* Returns the name of the field that controls activity availability.
*
* @return null|string
*/
protected function get_timeclose_field() {
return 'duedate';
}
}
@@ -0,0 +1,80 @@
<?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/>.
/**
* Cognitive depth indicator - assign.
*
* @package mod_assign
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Cognitive depth indicator - assign.
*
* @package mod_assign
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cognitive_depth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:cognitivedepth', 'mod_assign');
}
public function get_indicator_type() {
return self::INDICATOR_COGNITIVE;
}
public function get_cognitive_depth_level(\cm_info $cm) {
return self::COGNITIVE_LEVEL_5;
}
/**
* feedback_submitted_events
*
* @return string[]
*/
protected function feedback_submitted_events() {
return array('\mod_assign\event\assessable_submitted');
}
/**
* feedback_replied
*
* @param \cm_info $cm
* @param int $contextid
* @param int $userid
* @param int $after
* @return bool
*/
protected function feedback_replied(\cm_info $cm, $contextid, $userid, $after = false) {
// No level 4.
return false;
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* Social breadth indicator - assign.
*
* @package mod_assign
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Social breadth indicator - assign.
*
* @package mod_assign
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class social_breadth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:socialbreadth', 'mod_assign');
}
public function get_indicator_type() {
return self::INDICATOR_SOCIAL;
}
public function get_social_breadth_level(\cm_info $cm) {
return self::SOCIAL_LEVEL_2;
}
}
+110
View File
@@ -0,0 +1,110 @@
<?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/>.
/**
* Cache data source for the assign overrides.
*
* @package mod_assign
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
namespace mod_assign\cache;
use cache_definition;
/**
* Class assign_overrides
*
* @package mod_assign
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overrides implements \cache_data_source {
/** @var overrides the singleton instance of this class. */
protected static $instance = null;
/**
* Returns an instance of the data source class that the cache can use for loading data using the other methods
* specified by this interface.
*
* @param cache_definition $definition
* @return object
*/
public static function get_instance_for_cache(cache_definition $definition): overrides {
if (is_null(self::$instance)) {
self::$instance = new overrides();
}
return self::$instance;
}
/**
* Loads the data for the key provided ready formatted for caching.
*
* @param string|int $key The key to load.
* @return mixed What ever data should be returned, or false if it can't be loaded.
* @throws \coding_exception
*/
public function load_for_cache($key) {
global $DB;
[$assignid, $ug, $ugid] = explode('_', $key);
$assignid = (int) $assignid;
switch ($ug) {
case 'u':
$userid = (int) $ugid;
$override = $DB->get_record(
'assign_overrides',
['assignid' => $assignid, 'userid' => $userid],
'duedate, cutoffdate, allowsubmissionsfromdate'
);
break;
case 'g':
$groupid = (int) $ugid;
$override = $DB->get_record(
'assign_overrides',
['assignid' => $assignid, 'groupid' => $groupid],
'sortorder, duedate, cutoffdate, allowsubmissionsfromdate'
);
break;
default:
throw new \coding_exception('Invalid cache key');
}
// Return null instead of false, because false will not be cached.
return $override ?: null;
}
/**
* Loads several keys for the cache.
*
* @param array $keys An array of keys each of which will be string|int.
* @return array An array of matching data items.
*/
public function load_many_for_cache(array $keys) {
$results = [];
foreach ($keys as $key) {
$results[] = $this->load_for_cache($key);
}
return $results;
}
}
@@ -0,0 +1,95 @@
<?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/>.
declare(strict_types=1);
namespace mod_assign\completion;
use core_completion\activity_custom_completion;
/**
* Activity custom completion subclass for the assign activity.
*
* Class for defining mod_assign's custom completion rules and fetching the completion statuses
* of the custom completion rules for a given assign instance and a user.
*
* @package mod_assign
* @copyright Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_completion extends activity_custom_completion {
/**
* Fetches the completion state for a given completion rule.
*
* @param string $rule The completion rule.
* @return int The completion state.
*/
public function get_state(string $rule): int {
global $CFG;
$this->validate_rule($rule);
$userid = $this->userid;
$cm = $this->cm;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
$assign = new \assign(null, $cm, $cm->get_course());
if ($assign->get_instance()->teamsubmission) {
$submission = $assign->get_group_submission($userid, 0, false);
} else {
$submission = $assign->get_user_submission($userid, false);
}
$status = $submission && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED;
return $status ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE;
}
/**
* Fetch the list of custom completion rules that this module defines.
*
* @return array
*/
public static function get_defined_custom_rules(): array {
return ['completionsubmit'];
}
/**
* Returns an associative array of the descriptions of custom completion rules.
*
* @return array
*/
public function get_custom_rule_descriptions(): array {
return [
'completionsubmit' => get_string('completiondetail:submit', 'assign')
];
}
/**
* Returns an array of all completion rules, in the order they should be displayed to users.
*
* @return array
*/
public function get_sort_order(): array {
return [
'completionview',
'completionsubmit',
'completionusegrade',
'completionpassgrade',
];
}
}
+99
View File
@@ -0,0 +1,99 @@
<?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/>.
/**
* Contains the class for fetching the important dates in mod_assign for a given module instance and a user.
*
* @package mod_assign
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
namespace mod_assign;
use core\activity_dates;
/**
* Class for fetching the important dates in mod_assign for a given module instance and a user.
*
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dates extends activity_dates {
/**
* Returns a list of important dates in mod_assign
*
* @return array
*/
protected function get_dates(): array {
global $CFG;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
$course = get_course($this->cm->course);
$context = \context_module::instance($this->cm->id);
$assign = new \assign($context, $this->cm, $course);
$timeopen = $this->cm->customdata['allowsubmissionsfromdate'] ?? null;
$timedue = $this->cm->customdata['duedate'] ?? null;
$activitygroup = groups_get_activity_group($this->cm, true);
if ($activitygroup) {
if ($assign->can_view_grades()) {
$groupoverride = \cache::make('mod_assign', 'overrides')->get("{$this->cm->instance}_g_{$activitygroup}");
if (!empty($groupoverride->allowsubmissionsfromdate)) {
$timeopen = $groupoverride->allowsubmissionsfromdate;
}
if (!empty($groupoverride->duedate)) {
$timedue = $groupoverride->duedate;
}
}
}
$now = time();
$dates = [];
if ($timeopen) {
$openlabelid = $timeopen > $now ? 'activitydate:submissionsopen' : 'activitydate:submissionsopened';
$date = [
'dataid' => 'allowsubmissionsfromdate',
'label' => get_string($openlabelid, 'mod_assign'),
'timestamp' => (int) $timeopen,
];
if ($course->relativedatesmode && $assign->can_view_grades()) {
$date['relativeto'] = $course->startdate;
}
$dates[] = $date;
}
if ($timedue) {
$date = [
'dataid' => 'duedate',
'label' => get_string('activitydate:submissionsdue', 'mod_assign'),
'timestamp' => (int) $timedue,
];
if ($course->relativedatesmode && $assign->can_view_grades()) {
$date['relativeto'] = $course->startdate;
}
$dates[] = $date;
}
return $dates;
}
}
+289
View File
@@ -0,0 +1,289 @@
<?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/>.
namespace mod_assign;
use assign;
use core_php_time_limit;
use mod_assign\event\all_submissions_downloaded;
use core\session\manager as sessionmanager;
use core_files\archive_writer;
use stdClass;
use assign_plugin;
use stored_file;
/**
* Class to download user submissions.
*
* @package mod_assign
* @copyright 2022 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class downloader {
/** @var assign the module manager instance. */
private $manager;
/** @var stdClass the assign instance record. */
private $instance;
/** @var array|null the selected user ids, if any. */
private $userids = null;
/** @var int $groupmode the activity group mode. */
private $groupmode = '';
/** @var int $groupid the exported groupid. */
private $groupid = 0;
/** @var array $filesforzipping the files to zipo (path => file) */
protected $filesforzipping;
/** @var array $prefixes all loaded the student prefixes.
*
* A prefix will be converted into a file prefix or a folder name (depends on downloadasfolders).
*/
private $prefixes;
/** @var int $downloadasfolders the files to zipo (path => file) */
private $downloadasfolders;
/**
* Class constructor.
*
* @param assign $manager the instance manager
* @param array|null $userids the user ids to download.
*/
public function __construct(assign $manager, ?array $userids = null) {
$this->manager = $manager;
$this->userids = $userids;
$this->instance = $manager->get_instance();
$this->downloadasfolders = get_user_preferences('assign_downloadasfolders', 1);
$cm = $manager->get_course_module();
$this->groupmode = groups_get_activity_groupmode($cm);
if ($this->groupmode) {
$this->groupid = groups_get_activity_group($cm, true);
}
}
/**
* Load the filelist.
*
* @return bool true if there are some files to zip.
*/
public function load_filelist(): bool {
$manager = $this->manager;
$groupid = $this->groupid;
// Increase the server timeout to handle the creation and sending of large zip files.
core_php_time_limit::raise();
$manager->require_view_grades();
// Load all users with submit.
$students = get_enrolled_users(
$manager->get_context(),
"mod/assign:submit",
0,
'u.*',
null,
0,
0,
$manager->show_only_active_users()
);
// Build a list of files to zip.
$this->filesforzipping = [];
// Get all the files for each student.
foreach ($students as $student) {
// Download all assigments submission or only selected users.
if ($this->userids && !in_array($student->id, $this->userids)) {
continue;
}
if (!groups_is_member($groupid, $student->id) && $this->groupmode && $groupid) {
continue;
}
$this->load_student_filelist($student);
}
return !empty($this->filesforzipping);
}
/**
* Load an individual student filelist.
*
* @param stdClass $student the user record
*/
private function load_student_filelist(stdClass $student) {
$submission = $this->get_student_submission($student);
if (!$submission) {
return;
}
$prefix = $this->get_student_prefix($student);
if (isset($this->prefixes[$prefix])) {
// We already send that file (in group mode).
return;
}
$this->prefixes[$prefix] = $student->id;
foreach ($this->manager->get_submission_plugins() as $plugin) {
if (!$plugin->is_enabled() || !$plugin->is_visible()) {
continue;
}
$this->load_submissionplugin_filelist($student, $plugin, $submission, $prefix);
}
}
/**
* Return the student submission if any.
*
* @param stdClass $student the user record
* @return stdClass|null the user submission or null if none
*/
private function get_student_submission(stdClass $student): ?stdClass {
if ($this->instance->teamsubmission) {
$submission = $this->manager->get_group_submission($student->id, 0, false);
} else {
$submission = $this->manager->get_user_submission($student->id, false);
}
return $submission ?: null;
}
/**
* Return the file prefix used to generate the each submission folder or file.
*
* @param stdClass $student the user record
* @return string the submission prefix
*/
private function get_student_prefix(stdClass $student): string {
$manager = $this->manager;
// Team submissions are by group, not by student.
if ($this->instance->teamsubmission) {
$submissiongroup = $manager->get_submission_group($student->id);
if ($submissiongroup) {
$groupname = format_string($submissiongroup->name, true, ['context' => $manager->get_context()]);
$groupinfo = '_' . $submissiongroup->id;
} else {
$groupname = get_string('defaultteam', 'mod_assign');
$groupinfo = '';
}
$prefix = str_replace('_', ' ', $groupname);
return clean_filename($prefix . $groupinfo);
}
// Individual submissions are by user.
if ($manager->is_blind_marking()) {
$fullname = get_string('participant', 'mod_assign');
} else {
$fullname = fullname($student, has_capability('moodle/site:viewfullnames', $manager->get_context()));
}
$prefix = str_replace('_', ' ', $fullname);
$prefix = clean_filename($prefix . '_' . $manager->get_uniqueid_for_user($student->id));
return $prefix;
}
/**
* Load a submission plugin filelist for a specific user.
*
* @param stdClass $student the user record
* @param assign_plugin $plugin the submission plugin instance
* @param stdClass $submission the submission object
* @param string $prefix the files prefix
*/
private function load_submissionplugin_filelist(
stdClass $student,
assign_plugin $plugin,
stdClass $submission,
string $prefix
) {
$subtype = $plugin->get_subtype();
$type = $plugin->get_type();
if ($this->downloadasfolders) {
// Create a folder for each user for each assignment plugin.
// This is the default behavior for version of Moodle >= 3.1.
$submission->exportfullpath = true;
$pluginfiles = $plugin->get_files($submission, $student);
foreach ($pluginfiles as $zipfilepath => $file) {
$zipfilename = basename($zipfilepath);
$prefixedfilename = clean_filename($prefix . '_' . $subtype . '_' . $type);
if ($type == 'file') {
$pathfilename = $prefixedfilename . $file->get_filepath() . $zipfilename;
} else {
$pathfilename = $prefixedfilename . '/' . $zipfilename;
}
$pathfilename = clean_param($pathfilename, PARAM_PATH);
$this->filesforzipping[$pathfilename] = $file;
}
} else {
// Create a single folder for all users of all assignment plugins.
// This was the default behavior for version of Moodle < 3.1.
$submission->exportfullpath = false;
$pluginfiles = $plugin->get_files($submission, $student);
foreach ($pluginfiles as $zipfilename => $file) {
$prefixedfilename = clean_filename($prefix . '_' . $subtype . '_' . $type . '_' . $zipfilename);
$this->filesforzipping[$prefixedfilename] = $file;
}
}
}
/**
* Download the exported zip.
*
* This method will terminate the current script when the file is send.
*/
public function download_zip() {
$filename = $this->get_zip_filename();
all_submissions_downloaded::create_from_assign($this->manager)->trigger();
sessionmanager::write_close();
$zipwriter = archive_writer::get_stream_writer($filename, archive_writer::ZIP_WRITER);
// Stream the files into the zip.
foreach ($this->filesforzipping as $pathinzip => $file) {
if ($file instanceof stored_file) {
// Most of cases are stored_file.
$zipwriter->add_file_from_stored_file($pathinzip, $file);
} else if (is_array($file)) {
// Save $file as contents, from onlinetext subplugin.
$content = reset($file);
$zipwriter->add_file_from_string($pathinzip, $content);
}
}
// Finish the archive.
$zipwriter->finish();
exit();
}
/**
* Generate the zip filename.
*
* @return string the zip filename
*/
private function get_zip_filename(): string {
$manager = $this->manager;
$filenameparts = [
$manager->get_course()->shortname,
$this->instance->name,
];
if (!empty($this->groupid)) {
$filenameparts[] = format_string(groups_get_group_name($this->groupid), true, ['context' => $manager->get_context()]);
}
$filenameparts[] = $manager->get_course_module()->id;
return clean_filename(implode('-', $filenameparts). '.zip');
}
}
@@ -0,0 +1,112 @@
<?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/>.
/**
* The mod_assign all submissions downloaded event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign all submissions downloaded event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class all_submissions_downloaded extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @return all_submissions_downloaded
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id
);
self::$preventcreatecall = false;
/** @var submission_graded $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has downloaded all the submissions for the assignment " .
"with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventallsubmissionsdownloaded', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call all_submissions_downloaded::create() directly, use all_submissions_downloaded::create_from_assign() instead.');
}
parent::validate_data();
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
@@ -0,0 +1,126 @@
<?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/>.
/**
* The mod_assign assessable submitted event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign assessable submitted event class.
*
* @property-read array $other {
* Extra information about event.
*
* - bool submission_editable: is submission editable.
* }
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assessable_submitted extends base {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $submission
* @param bool $editable
* @return assessable_submitted
*/
public static function create_from_submission(\assign $assign, \stdClass $submission, $editable) {
global $USER;
$data = array(
'context' => $assign->get_context(),
'objectid' => $submission->id,
'other' => array(
'submission_editable' => $editable,
),
);
if (!empty($submission->userid) && ($submission->userid != $USER->id)) {
$data['relateduserid'] = $submission->userid;
}
/** @var assessable_submitted $event */
$event = self::create($data);
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has submitted the submission with id '$this->objectid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventassessablesubmitted', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['objecttable'] = 'assign_submission';
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['submission_editable'])) {
throw new \coding_exception('The \'submission_editable\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign_submission', 'restore' => 'submission');
}
public static function get_other_mapping() {
// Nothing to map.
return false;
}
}
+114
View File
@@ -0,0 +1,114 @@
<?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/>.
/**
* The mod_assign abstract base event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign abstract base event class.
*
* Most mod_assign events can extend this class.
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class base extends \core\event\base {
/** @var \assign */
protected $assign;
/**
* Legacy log data.
*
* @var array
*/
protected $legacylogdata;
/**
* Set assign instance for this event.
* @param \assign $assign
* @throws \coding_exception
*/
public function set_assign(\assign $assign) {
if ($this->is_triggered()) {
throw new \coding_exception('set_assign() must be done before triggerring of event');
}
if ($assign->get_context()->id != $this->get_context()->id) {
throw new \coding_exception('Invalid assign isntance supplied!');
}
if ($assign->is_blind_marking()) {
$this->data['anonymous'] = 1;
}
$this->assign = $assign;
}
/**
* Get assign instance.
*
* NOTE: to be used from observers only.
*
* @throws \coding_exception
* @return \assign
*/
public function get_assign() {
if ($this->is_restored()) {
throw new \coding_exception('get_assign() is intended for event observers only');
}
if (!isset($this->assign)) {
debugging('assign property should be initialised in each event', DEBUG_DEVELOPER);
global $CFG;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
$cm = get_coursemodule_from_id('assign', $this->contextinstanceid, 0, false, MUST_EXIST);
$course = get_course($cm->course);
$this->assign = new \assign($this->get_context(), $cm, $course);
}
return $this->assign;
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/view.php', array('id' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
parent::validate_data();
if ($this->contextlevel != CONTEXT_MODULE) {
throw new \coding_exception('Context level must be CONTEXT_MODULE.');
}
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign batch set marker allocation viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign batch set marker allocation viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class batch_set_marker_allocation_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return batch_set_marker_allocation_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var batch_set_marker_allocation_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventbatchsetmarkerallocationviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the batch set marker allocation for the assignment with course " .
"module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call batch_set_marker_allocation_viewed::create() directly, use batch_set_marker_allocation_viewed::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign assignment batch set workflow stated viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign assignment batch set workflow stated viewed event.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class batch_set_workflow_state_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return batch_set_workflow_state_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var batch_set_workflow_state_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventbatchsetworkflowstateviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the batch set workflow for the assignment with course " .
"module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call batch_set_workflow_state_viewed::create() directly, use batch_set_workflow_state_viewed::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,52 @@
<?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/>.
/**
* The mod_assign instance list viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign instance list viewed event class.
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
/**
* Create the event from course record.
*
* @param \stdClass $course
* @return course_module_instance_list_viewed
*/
public static function create_from_course(\stdClass $course) {
$params = array(
'context' => \context_course::instance($course->id)
);
$event = \mod_assign\event\course_module_instance_list_viewed::create($params);
$event->add_record_snapshot('course', $course);
return $event;
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* The mod_assign course module viewed event.
*
* @package mod_assign
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
global $CFG;
/**
* The mod_assign course module viewed event class.
*
* @package mod_assign
* @since Moodle 3.6
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'assign';
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
@@ -0,0 +1,118 @@
<?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/>.
/**
* The mod_assign extension granted event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign extension granted event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class extension_granted extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param int $userid
* @return extension_granted
*/
public static function create_from_assign(\assign $assign, $userid) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id,
'relateduserid' => $userid,
);
self::$preventcreatecall = false;
/** @var extension_granted $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has granted an extension for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventextensiongranted', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call extension_granted::create() directly, use extension_granted::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign feedback viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign feedback viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_viewed extends base {
/**
* Create instance of event.
*
* @param \assign $assign
* @param \stdClass $grade
* @return feedback_viewed
*/
public static function create_from_grade(\assign $assign, \stdClass $grade) {
$data = array(
'objectid' => $grade->id,
'relateduserid' => $grade->userid,
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
/** @var feedback_viewed $event */
$event = self::create($data);
$event->set_assign($assign);
$event->add_record_snapshot('assign_grades', $grade);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_grades';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventfeedbackviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the feedback for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign_grades', 'restore' => 'grade');
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,128 @@
<?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/>.
/**
* The mod_assign grading form viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign grading form viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grading_form_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @param \stdClass $user
* @return grading_form_viewed
*/
public static function create_from_user(\assign $assign, \stdClass $user) {
$data = array(
'relateduserid' => $user->id,
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var grading_form_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventgradingformviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the grading form for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call grading_form_viewed::create() directly, use grading_form_viewed::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign grading table viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign grading table viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grading_table_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return grading_table_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var grading_table_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventgradingtableviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the grading table for the assignment with course module " .
"id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call grading_table_viewed::create() directly, use grading_table_viewed::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,118 @@
<?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/>.
/**
* The mod_assign group override created event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign group override created event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* - int groupid: the id of the group.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class group_override_created extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverridecreated', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' created the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrideedit.php', array('id' => $this->objectid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
if (!isset($this->other['groupid'])) {
throw new \coding_exception('The \'groupid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
$othermapped['groupid'] = array('db' => 'groups', 'restore' => 'group');
return $othermapped;
}
}
@@ -0,0 +1,117 @@
<?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/>.
/**
* The mod_assign group override deleted event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign group override deleted event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* - int groupid: the id of the group.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class group_override_deleted extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverridedeleted', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' deleted the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrides.php', array('cmid' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
if (!isset($this->other['groupid'])) {
throw new \coding_exception('The \'groupid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
$othermapped['groupid'] = array('db' => 'groups', 'restore' => 'group');
return $othermapped;
}
}
@@ -0,0 +1,117 @@
<?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/>.
/**
* The mod_assign group override updated event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign group override updated event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* - int groupid: the id of the group.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class group_override_updated extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverrideupdated', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' updated the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrideedit.php', array('id' => $this->objectid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
if (!isset($this->other['groupid'])) {
throw new \coding_exception('The \'groupid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
$othermapped['groupid'] = array('db' => 'groups', 'restore' => 'group');
return $othermapped;
}
}
@@ -0,0 +1,112 @@
<?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/>.
/**
* The mod_assign identities revealed event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign identities revealed event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class identities_revealed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @return identities_revealed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id
);
self::$preventcreatecall = false;
/** @var identities_revealed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has revealed identities in the assignment with course module " .
"id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventidentitiesrevealed', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call identities_revealed::create() directly, use identities_revealed::create_from_assign() instead.');
}
parent::validate_data();
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
+140
View File
@@ -0,0 +1,140 @@
<?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/>.
/**
* The mod_assign marker updated event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign marker updated event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int markerid: user id of marker.
* }
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class marker_updated extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $user
* @param \stdClass $marker
* @return marker_updated
*/
public static function create_from_marker(\assign $assign, \stdClass $user, \stdClass $marker) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id,
'relateduserid' => $user->id,
'other' => array(
'markerid' => $marker->id,
),
);
self::$preventcreatecall = false;
/** @var marker_updated $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
$event->add_record_snapshot('user', $marker);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has set the marker for the user with id '$this->relateduserid' to " .
"'{$this->other['markerid']}' for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventmarkerupdated', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call marker_updated::create() directly, use marker_updated::create_from_marker() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['markerid'])) {
throw new \coding_exception('The \'markerid\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['markerid'] = array('db' => 'user', 'restore' => 'user');
return $othermapped;
}
}
@@ -0,0 +1,134 @@
<?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/>.
/**
* The mod_assign remove submission form viewed event.
*
* @package mod_assign
* @copyright 2019 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign remove submission form viewed event class.
*
* @package mod_assign
* @copyright 2019 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class remove_submission_form_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @param \stdClass $user
* @return remove_submission_form_viewed
*/
public static function create_from_user(\assign $assign, \stdClass $user) {
$data = array(
'relateduserid' => $user->id,
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var remove_submission_form_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventremovesubmissionformviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
if ($this->userid != $this->relateduserid) {
return "The user with id '$this->userid' viewed the " .
"remove submission form for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
return "The user with id '$this->userid' viewed their remove submission form for the assignment with course module id " .
"'$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call remove_submission_form_viewed::create() directly, use ' .
'remove_submission_form_viewed::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
/**
* This is documented in the parent class.
*
* @return array an array of other values and their corresponding mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,121 @@
<?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/>.
/**
* The mod_assign reveal identities confirmation page viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign reveal identities confirmation page viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reveal_identities_confirmation_page_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return reveal_identities_confirmation_page_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var reveal_identities_confirmation_page_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventrevealidentitiesconfirmationpageviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the confirmation page for revealing identities for the " .
"assignment with course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call reveal_identities_confirmation_page_viewed::create() directly, use reveal_identities_confirmation_page_viewed::create_from_grade() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,114 @@
<?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/>.
/**
* The mod_assign statement accepted event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign statement accepted event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class statement_accepted extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $submission
* @return statement_accepted
*/
public static function create_from_submission(\assign $assign, \stdClass $submission) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $submission->id
);
self::$preventcreatecall = false;
/** @var statement_accepted $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has accepted the statement of the submission with id '$this->objectid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventstatementaccepted', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
$this->data['objecttable'] = 'assign_submission';
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call statement_accepted::create() directly, use statement_accepted::create_from_submission() instead.');
}
parent::validate_data();
}
public static function get_objectid_mapping() {
return array('db' => 'assign_submission', 'restore' => 'submission');
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign submission form viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission form viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_confirmation_form_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return submission_confirmation_form_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var submission_confirmation_form_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionconfirmationformviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the submission confirmation form for the assignment with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_confirmation_form_viewed::create() directly, use submission_confirmation_form_viewed::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,92 @@
<?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/>.
/**
* The mod_assign submission_created abstract event.
*
* @package mod_assign
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission_created abstract event class.
*
* @property-read array $other {
* Extra information about the event.
*
* - int submissionid: ID number of this submission.
* - int submissionattempt: Number of attempts made on this submission.
* - string submissionstatus: Status of the submission.
* - int groupid: (optional) The group ID if this is a teamsubmission.
* - string groupname: (optional) The name of the group if this is a teamsubmission.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class submission_created extends base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissioncreated', 'mod_assign');
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['submissionid'])) {
throw new \coding_exception('The \'submissionid\' value must be set in other.');
}
if (!isset($this->other['submissionattempt'])) {
throw new \coding_exception('The \'submissionattempt\' value must be set in other.');
}
if (!isset($this->other['submissionstatus'])) {
throw new \coding_exception('The \'submissionstatus\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['submissionid'] = array('db' => 'assign_submission', 'restore' => 'submission');
$othermapped['groupid'] = array('db' => 'groups', 'restore' => 'group');
return $othermapped;
}
}
@@ -0,0 +1,113 @@
<?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/>.
/**
* The mod_assign submission duplicated event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission duplicated event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_duplicated extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $submission
* @return submission_duplicated
*/
public static function create_from_submission(\assign $assign, \stdClass $submission) {
$data = array(
'objectid' => $submission->id,
'context' => $assign->get_context(),
);
self::$preventcreatecall = false;
/** @var submission_duplicated $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' duplicated their submission with id '$this->objectid' for the " .
"assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionduplicated', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'assign_submission';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_duplicated::create() directly, use submission_duplicated::create_from_submission() instead.');
}
parent::validate_data();
}
public static function get_objectid_mapping() {
return array('db' => 'assign_submission', 'restore' => 'submission');
}
}
@@ -0,0 +1,133 @@
<?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/>.
/**
* The mod_assign submission form viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission form viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_form_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @param \stdClass $user
* @return submission_form_viewed
*/
public static function create_from_user(\assign $assign, \stdClass $user) {
$data = array(
'relateduserid' => $user->id,
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var submission_form_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionformviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
if ($this->userid != $this->relateduserid) {
return "The user with id '$this->userid' viewed the submission form for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
return "The user with id '$this->userid' viewed their submission for the assignment with course module id " .
"'$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_form_viewed::create() directly, use submission_form_viewed::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,119 @@
<?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/>.
/**
* The mod_assign submission graded event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission graded event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_graded extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $grade
* @return submission_graded
*/
public static function create_from_grade(\assign $assign, \stdClass $grade) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $grade->id,
'relateduserid' => $grade->userid
);
self::$preventcreatecall = false;
/** @var submission_graded $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('assign_grades', $grade);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has graded the submission '$this->objectid' for the user with " .
"id '$this->relateduserid' for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissiongraded', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign_grades';
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_graded::create() directly, use submission_graded::create_from_grade() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign_grades', 'restore' => 'grade');
}
}
@@ -0,0 +1,118 @@
<?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/>.
/**
* The mod_assign submission locked event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission locked event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_locked extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $user
* @return submission_locked
*/
public static function create_from_user(\assign $assign, \stdClass $user) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id,
'relateduserid' => $user->id,
);
self::$preventcreatecall = false;
/** @var submission_locked $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' locked the submission for the user with id '$this->relateduserid' for " .
"the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionlocked', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_locked::create() directly, use submission_locked::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
@@ -0,0 +1,154 @@
<?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/>.
namespace mod_assign\event;
use assign;
use coding_exception;
use stdClass;
/**
* The mod_assign submission removed event class.
*
* @property-read array $other {
* Extra information about the event.
*
* - int submissionid: ID number of this submission.
* - int submissionattempt: Number of attempts made on this submission.
* - string submissionstatus: Status of the submission.
* - int groupid: (optional) The group ID if this is a teamsubmission.
* - string groupname: (optional) The name of the group if this is a teamsubmission.
* }
*
* @package mod_assign
* @since Moodle 4.0
* @copyright 2022 TU Berlin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_removed extends base {
/**
* Create instance of event.
*
* @param assign $assign
* @param stdClass $submission
* @return submission_removed
* @throws coding_exception
*/
public static function create_from_submission(assign $assign, stdClass $submission): submission_removed {
$groupname = null;
$groupid = 0;
if (empty($submission->userid) && !empty($submission->groupid)) {
$groupname = groups_get_group_name($submission->groupid);
$groupid = $submission->groupid;
}
$data = [
'context' => $assign->get_context(),
'objectid' => $submission->id,
'relateduserid' => $assign->get_instance()->teamsubmission ? null : $submission->userid,
'anonymous' => $assign->is_blind_marking() ? 1 : 0,
'other' => [
'submissionid' => $submission->id,
'submissionattempt' => $submission->attemptnumber,
'submissionstatus' => $submission->status,
'groupid' => $groupid,
'groupname' => $groupname
]
];
/** @var submission_removed $event */
$event = self::create($data);
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'assign_submission';
}
/**
* Returns localised general event name.
*
* @return string
* @throws coding_exception
*/
public static function get_name(): string {
return get_string('eventsubmissionremoved', 'mod_assign');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description(): string {
$descriptionstring = "The user with id '$this->userid' removed the submission with id '$this->objectid' in " .
"the assignment with course module id '$this->contextinstanceid' submitted by ";
if (!empty($this->other['groupid'])) {
$groupname = $this->other['groupname'];
$groupid = $this->other['groupid'];
$descriptionstring .= "the group '$groupname' with id '$groupid'.";
} else {
$descriptionstring .= "the user with id '$this->relateduserid'.";
}
return $descriptionstring;
}
/**
* Custom validation.
*
* @return void
* @throws coding_exception
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['submissionid'])) {
throw new coding_exception('The \'submissionid\' value must be set in other.');
}
if (!isset($this->other['submissionattempt'])) {
throw new coding_exception('The \'submissionattempt\' value must be set in other.');
}
if (!isset($this->other['submissionstatus'])) {
throw new coding_exception('The \'submissionstatus\' value must be set in other.');
}
}
/**
* Get objectid mapping.
*
* @return array
*/
public static function get_objectid_mapping(): array {
return ['db' => 'assign_submission', 'restore' => 'submission'];
}
/**
* Get other mapping.
*
* @return array
*/
public static function get_other_mapping(): array {
$othermapped = [];
$othermapped['submissionid'] = ['db' => 'assign_submission', 'restore' => 'submission'];
$othermapped['groupid'] = ['db' => 'groups', 'restore' => 'group'];
return $othermapped;
}
}
@@ -0,0 +1,120 @@
<?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/>.
/**
* The mod_assign submission status updated event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission status updated event class.
*
* @property-read array $other {
* Extra information about event.
*
* - string newstatus: status of submission.
* }
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_status_updated extends base {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $submission
* @return submission_status_updated
*/
public static function create_from_submission(\assign $assign, \stdClass $submission) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $submission->id,
'relateduserid' => ($assign->get_instance()->teamsubmission) ? null : $submission->userid,
'other' => array(
'newstatus' => $submission->status
)
);
/** @var submission_status_updated $event */
$event = self::create($data);
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has updated the status of the submission with id '$this->objectid' for " .
"the assignment with course module id '$this->contextinstanceid' to the status '{$this->other['newstatus']}'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionstatusupdated', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign_submission';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['newstatus'])) {
throw new \coding_exception('The \'newstatus\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign_submission', 'restore' => 'submission');
}
public static function get_other_mapping() {
// Nothing to map.
return false;
}
}
@@ -0,0 +1,124 @@
<?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/>.
/**
* The mod_assign submission status viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission status viewed event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_status_viewed extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @param \assign $assign
* @return submission_status_viewed
*/
public static function create_from_assign(\assign $assign) {
$data = array(
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
self::$preventcreatecall = false;
/** @var submission_status_viewed $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
return $event;
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionstatusviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has viewed the submission status page for the assignment with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_status_viewed::create() directly, use submission_status_viewed::create_from_assign() instead.');
}
parent::validate_data();
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,118 @@
<?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/>.
/**
* The mod_assign submission unlocked event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission unlocked event class.
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_unlocked extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $user
* @return submission_unlocked
*/
public static function create_from_user(\assign $assign, \stdClass $user) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id,
'relateduserid' => $user->id,
);
self::$preventcreatecall = false;
/** @var submission_unlocked $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' unlocked the submission for the user with id '$this->relateduserid' " .
"for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionunlocked', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call submission_unlocked::create() directly, use submission_unlocked::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
}
@@ -0,0 +1,92 @@
<?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/>.
/**
* The mod_assign submission updated event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission updated event class.
*
* @property-read array $other {
* Extra information about the event.
*
* - int submissionid: ID number of this submission.
* - int submissionattempt: Number of attempts made on this submission.
* - string submissionstatus: Status of the submission.
* - int groupid: (optional) The group ID if this is a teamsubmission.
* - string groupname: (optional) The name of the group if this is a teamsubmission.
* }
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class submission_updated extends base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionupdated', 'mod_assign');
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['submissionid'])) {
throw new \coding_exception('The \'submissionid\' value must be set in other.');
}
if (!isset($this->other['submissionattempt'])) {
throw new \coding_exception('The \'submissionattempt\' value must be set in other.');
}
if (!isset($this->other['submissionstatus'])) {
throw new \coding_exception('The \'submissionstatus\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['submissionid'] = array('db' => 'assign_submission', 'restore' => 'submission');
$othermapped['groupid'] = array('db' => 'groups', 'restore' => 'group');
return $othermapped;
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* The mod_assign submission viewed event.
*
* @package mod_assign
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign submission viewed event class.
*
* @property-read array $other {
* Extra information about the event.
*
* - int assignid: the id of the assignment.
* }
*
* @package mod_assign
* @since Moodle 2.7
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_viewed extends base {
/**
* Create instance of event.
*
* @param \assign $assign
* @param \stdClass $submission
* @return submission_viewed
*/
public static function create_from_submission(\assign $assign, \stdClass $submission) {
$data = array(
'objectid' => $submission->id,
'relateduserid' => $submission->userid,
'context' => $assign->get_context(),
'other' => array(
'assignid' => $assign->get_instance()->id,
),
);
/** @var submission_viewed $event */
$event = self::create($data);
$event->set_assign($assign);
$event->add_record_snapshot('assign_submission', $submission);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_submission';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissionviewed', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the submission for the user with id '$this->relateduserid' for the " .
"assignment with course module id '$this->contextinstanceid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign_submission', 'restore' => 'submission');
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,115 @@
<?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/>.
/**
* The mod_assign user override created event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign user override created event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_override_created extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverridecreated', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' created the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrideedit.php', array('id' => $this->objectid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,115 @@
<?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/>.
/**
* The mod_assign user override deleted event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign user override deleted event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_override_deleted extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverridedeleted', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' deleted the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrides.php', array('cmid' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,116 @@
<?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/>.
/**
* The mod_assign user override updated event.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_assign user override updated event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int assignid: the id of the assign.
* }
*
* @package mod_assign
* @since Moodle 3.2
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_override_updated extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'assign_overrides';
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoverrideupdated', 'mod_assign');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' updated the override with id '$this->objectid' for the assign with " .
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/overrideedit.php', array('id' => $this->objectid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['assignid'])) {
throw new \coding_exception('The \'assignid\' value must be set in other.');
}
}
/**
* Get objectid mapping
*/
public static function get_objectid_mapping() {
return array('db' => 'assign_overrides', 'restore' => 'assign_override');
}
/**
* Get other mapping
*/
public static function get_other_mapping() {
$othermapped = array();
$othermapped['assignid'] = array('db' => 'assign', 'restore' => 'assign');
return $othermapped;
}
}
@@ -0,0 +1,137 @@
<?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/>.
/**
* mod_assign workflow state updated event.
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* mod_assign workflow state updated event class.
*
* @property-read array $other {
* Extra information about event.
*
* - string newstate: state of submission.
* }
*
* @package mod_assign
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class workflow_state_updated extends base {
/**
* Flag for prevention of direct create() call.
* @var bool
*/
protected static $preventcreatecall = true;
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \assign $assign
* @param \stdClass $user
* @param string $state
* @return workflow_state_updated
*/
public static function create_from_user(\assign $assign, \stdClass $user, $state) {
$data = array(
'context' => $assign->get_context(),
'objectid' => $assign->get_instance()->id,
'relateduserid' => $user->id,
'other' => array(
'newstate' => $state,
),
);
self::$preventcreatecall = false;
/** @var workflow_state_updated $event */
$event = self::create($data);
self::$preventcreatecall = true;
$event->set_assign($assign);
$event->add_record_snapshot('user', $user);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has set the workflow state of the user with id '$this->relateduserid' " .
"to the state '{$this->other['newstate']}' for the assignment with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventworkflowstateupdated', 'mod_assign');
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'assign';
}
/**
* Custom validation.
*
* @throws \coding_exception
*/
protected function validate_data() {
if (self::$preventcreatecall) {
throw new \coding_exception('cannot call workflow_state_updated::create() directly, use workflow_state_updated::create_from_user() instead.');
}
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['newstate'])) {
throw new \coding_exception('The \'newstate\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'assign', 'restore' => 'assign');
}
public static function get_other_mapping() {
// Nothing to map.
return false;
}
}
+114
View File
@@ -0,0 +1,114 @@
<?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/>.
namespace mod_assign\external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once("$CFG->dirroot/mod/assign/locallib.php");
/**
* Extend the base external_api class with mod_assign utility methods.
*
* @package mod_assign
* @author Andrew Madden <andrewmadden@catalyst-au.net>
* @copyright 2021 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class external_api extends \core_external\external_api {
/**
* Generate a warning in a standard structure for a known failure.
*
* @param int $assignmentid - The assignment
* @param string $warningcode - The key for the warning message
* @param string $detail - A description of the error
* @return array - Warning structure containing item, itemid, warningcode, message
*/
protected static function generate_warning(int $assignmentid, string $warningcode, string $detail): array {
$warningmessages = [
'couldnotlock' => 'Could not lock the submission for this user.',
'couldnotunlock' => 'Could not unlock the submission for this user.',
'couldnotsubmitforgrading' => 'Could not submit assignment for grading.',
'couldnotrevealidentities' => 'Could not reveal identities.',
'couldnotgrantextensions' => 'Could not grant submission date extensions.',
'couldnotrevert' => 'Could not revert submission to draft.',
'invalidparameters' => 'Invalid parameters.',
'couldnotsavesubmission' => 'Could not save submission.',
'couldnotsavegrade' => 'Could not save grade.',
'couldnotstartsubmission' => 'Could not start submission with time limit.',
'submissionnotopen' => 'This assignment is not open for submissions',
'timelimitnotenabled' => 'Time limit is not enabled for assignment.',
'opensubmissionexists' => 'Open assignment submission already exists.',
];
$message = $warningmessages[$warningcode];
if (empty($message)) {
$message = 'Unknown warning type.';
}
return [
'item' => s($detail),
'itemid' => $assignmentid,
'warningcode' => $warningcode,
'message' => $message,
];
}
/**
* Utility function for validating an assign.
*
* @param int $assignid assign instance id
* @return array array containing the assign, course, context and course module objects
* @since Moodle 3.2
*/
protected static function validate_assign(int $assignid): array {
global $DB;
// Request and permission validation.
$assign = $DB->get_record('assign', ['id' => $assignid], 'id', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($assign, 'assign');
$context = \context_module::instance($cm->id);
// Please, note that is not required to check mod/assign:view because is done by validate_context->require_login.
self::validate_context($context);
$assign = new \assign($context, $cm, $course);
return [$assign, $course, $cm, $context];
}
/**
* Get a submission from an assignment for a user. Encapsulates checking whether it's a solo or team submission.
*
* @param \assign $assignment Assignment object.
* @param int|null $userid User id.
* @param int $groupid Group id.
* @param bool $create Whether a new submission should be created.
* @param int $attemptnumber Attempt number. Use -1 for last attempt.
* @return bool|\stdClass
*/
protected static function get_user_or_group_submission(\assign $assignment, int $userid = null,
int $groupid = 0, bool $create = false, int $attemptnumber = -1) {
if ($assignment->get_instance($userid)->teamsubmission) {
$submission = $assignment->get_group_submission($userid, $groupid, $create, $attemptnumber);
} else {
$submission = $assignment->get_user_submission($userid, $create, $attemptnumber);
}
return $submission;
}
}
+118
View File
@@ -0,0 +1,118 @@
<?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/>.
namespace mod_assign\external;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
/**
* External function to notify Moodle that an assignment submission is starting.
*
* @package mod_assign
* @author Andrew Madden <andrewmadden@catalyst-au.net>
* @copyright 2021 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class start_submission extends external_api {
/**
* Describes the parameters for submission_start.
*
* @return external_function_parameters
* @since Moodle 4.0
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters ([
'assignid' => new external_value(PARAM_INT, 'Assignment instance id'),
]
);
}
/**
* Call to start an assignment submission.
*
* @param int $assignid Assignment ID.
* @return array
* @since Moodle 4.0
*/
public static function execute(int $assignid): array {
global $DB, $USER;
$result = $warnings = [];
$submission = null;
[
'assignid' => $assignid,
] = self::validate_parameters(self::execute_parameters(), [
'assignid' => $assignid,
]);
list($assignment, $course, $cm, $context) = self::validate_assign($assignid);
$assignment->update_effective_access($USER->id);
$latestsubmission = external_api::get_user_or_group_submission($assignment, $USER->id);
if (!$assignment->submissions_open($USER->id)) {
$warnings[] = self::generate_warning($assignid,
'submissionnotopen',
get_string('submissionnotopen', 'assign'));
}
if (!$assignment->is_time_limit_enabled()) {
$warnings[] = self::generate_warning($assignid,
'timelimitnotenabled',
get_string('timelimitnotenabled', 'assign'));
} else if ($assignment->is_attempt_in_progress()) {
$warnings[] = self::generate_warning($assignid,
'opensubmissionexists',
get_string('opensubmissionexists', 'assign'));
}
if (empty($warnings)) {
// If there is an open submission with no start time, use latest submission, otherwise create a new submission.
if (!empty($latestsubmission)
&& $latestsubmission->status !== ASSIGN_SUBMISSION_STATUS_SUBMITTED
&& empty($latestsubmission->timestarted)) {
$submission = $latestsubmission;
} else {
$submission = external_api::get_user_or_group_submission($assignment, $USER->id, 0, true);
}
// Set the start time of the submission.
$submission->timestarted = time();
$DB->update_record('assign_submission', $submission);
}
$result['submissionid'] = $submission ? $submission->id : 0;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the submission_start return value.
*
* @return external_single_structure
* @since Moodle 4.0
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'submissionid' => new external_value(PARAM_INT, 'New submission ID.'),
'warnings' => new external_warnings(),
]);
}
}
+62
View File
@@ -0,0 +1,62 @@
<?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/>.
/**
* Grade item mappings for the activity.
*
* @package mod_assign
* @copyright Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types = 1);
namespace mod_assign\grades;
use \core_grades\local\gradeitem\itemnumber_mapping;
use \core_grades\local\gradeitem\advancedgrading_mapping;
/**
* Grade item mappings for the activity.
*
* @package mod_assign
* @copyright Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gradeitems implements itemnumber_mapping, advancedgrading_mapping {
/**
* Return the list of grade item mappings for the assign.
*
* @return array
*/
public static function get_itemname_mapping_for_component(): array {
return [
0 => 'submissions',
];
}
/**
* Get the list of advanced grading item names for this component.
*
* @return array
*/
public static function get_advancedgrading_itemnames(): array {
return [
'submissions',
];
}
}
+85
View File
@@ -0,0 +1,85 @@
<?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/>.
/**
* Group observers.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/assign/locallib.php');
/**
* Group observers class.
*
* @package mod_assign
* @copyright 2016 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class group_observers {
/**
* Flag whether a course reset is in progress or not.
*
* @var int The course ID.
*/
protected static $resetinprogress = false;
/**
* A course reset has started.
*
* @param \core\event\base $event The event.
* @return void
*/
public static function course_reset_started($event) {
self::$resetinprogress = $event->courseid;
}
/**
* A course reset has ended.
*
* @param \core\event\base $event The event.
* @return void
*/
public static function course_reset_ended($event) {
if (!empty(self::$resetinprogress)) {
if (!empty($event->other['reset_options']['reset_groups_remove'])) {
assign_process_group_deleted_in_course($event->courseid);
}
}
self::$resetinprogress = null;
}
/**
* A group was deleted.
*
* @param \core\event\base $event The event.
* @return void
*/
public static function group_deleted($event) {
if (!empty(self::$resetinprogress)) {
// We will take care of that once the course reset ends.
return;
}
assign_process_group_deleted_in_course($event->courseid, $event->objectid);
}
}
@@ -0,0 +1,45 @@
<?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/>.
namespace mod_assign\navigation\views;
use core\navigation\views\secondary as core_secondary;
/**
* Class secondary_navigation_view.
*
* Custom implementation for a plugin.
*
* @package mod_assign
* @category navigation
* @copyright 2021 onwards Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class secondary extends core_secondary {
protected function get_default_module_mapping(): array {
$defaultmaping = parent::get_default_module_mapping();
$defaultmaping[self::TYPE_SETTING] = array_merge($defaultmaping[self::TYPE_SETTING], [
'modedit' => 1,
"mod_{$this->page->activityname}_useroverrides" => 2, // Overrides are module specific.
"mod_{$this->page->activityname}_groupoverrides" => 3,
]);
$defaultmaping[self::TYPE_CUSTOM] = array_merge($defaultmaping[self::TYPE_CUSTOM], [
'advgrading' => 4,
]);
return $defaultmaping;
}
}
+61
View File
@@ -0,0 +1,61 @@
<?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/>.
namespace mod_assign\output;
use templatable;
use renderable;
use moodle_url;
/**
* Output the actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class actionmenu implements templatable, renderable {
/** @var int The course module ID. */
private $cmid;
/**
* Constructor for this object.
*
* @param int $cmid The course module ID.
*/
public function __construct(int $cmid) {
$this->cmid = $cmid;
}
/**
* Data to be used for a template.
*
* @param \renderer_base $output renderer base output.
* @return array Data to be used for a template.
*/
public function export_for_template(\renderer_base $output): array {
$submissionlink = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'grading']);
$return = ['submissionlink' => $submissionlink->out(false)];
if (has_capability('mod/assign:grade', \context_module::instance($this->cmid))) {
$gradelink = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'grader']);
$return['gradelink'] = $gradelink->out(false);
}
return $return;
}
}
@@ -0,0 +1,87 @@
<?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 renderable assign header.
*
* @package mod_assign
* @copyright 2020 Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
/**
* This file contains the definition for the renderable assign header.
*
* @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_header implements \renderable {
/** @var \stdClass The assign record. */
public $assign;
/** @var mixed \context|null the context record. */
public $context;
/** @var bool $showintro Show or hide the intro. */
public $showintro;
/** @var int coursemoduleid The course module id. */
public $coursemoduleid;
/** @var string $subpage Optional subpage (extra level in the breadcrumbs). */
public $subpage;
/** @var string $preface Optional preface (text to show before the heading). */
public $preface;
/** @var string $postfix Optional postfix (text to show after the intro). */
public $postfix;
/** @var \moodle_url|null $subpageurl link for the sub page */
public $subpageurl;
/** @var bool $activity optional show activity text. */
public $activity;
/**
* Constructor
*
* @param \stdClass $assign The assign database record.
* @param \context|null $context The course module context.
* @param bool $showintro Show or hide the intro.
* @param int $coursemoduleid The course module id.
* @param string $subpage An optional sub page in the navigation.
* @param string $preface An optional preface to show before the heading.
* @param string $postfix An optional postfix to show after the intro.
* @param \moodle_url|null $subpageurl An optional sub page URL link for the subpage.
* @param bool $activity Optional show activity text if true.
*/
public function __construct(
\stdClass $assign,
$context,
$showintro,
$coursemoduleid,
$subpage = '',
$preface = '',
$postfix = '',
\moodle_url $subpageurl = null,
bool $activity = false
) {
$this->assign = $assign;
$this->context = $context;
$this->showintro = $showintro;
$this->coursemoduleid = $coursemoduleid;
$this->subpage = $subpage;
$this->preface = $preface;
$this->postfix = $postfix;
$this->subpageurl = $subpageurl;
$this->activity = $activity;
}
}
@@ -0,0 +1,204 @@
<?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 renderable assign submission status.
*
* @package mod_assign
* @copyright 2020 Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
/**
* This file contains the definition for the renderable assign submission status.
*
* @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_submission_status implements \renderable {
/** @var int STUDENT_VIEW */
const STUDENT_VIEW = 10;
/** @var int GRADER_VIEW */
const GRADER_VIEW = 20;
/** @var int allowsubmissionsfromdate */
public $allowsubmissionsfromdate = 0;
/** @var bool alwaysshowdescription */
public $alwaysshowdescription = false;
/** @var mixed the submission info (may be null or an integer) */
public $submission = null;
/** @var boolean teamsubmissionenabled - true or false */
public $teamsubmissionenabled = false;
/** @var \stdClass teamsubmission the team submission info (may be null) */
public $teamsubmission = null;
/** @var mixed submissiongroup the submission group info (may be null) */
public $submissiongroup = null;
/** @var array submissiongroupmemberswhoneedtosubmit list of users who still need to submit */
public $submissiongroupmemberswhoneedtosubmit = array();
/** @var bool submissionsenabled */
public $submissionsenabled = false;
/** @var bool locked */
public $locked = false;
/** @var bool graded */
public $graded = false;
/** @var int duedate */
public $duedate = 0;
/** @var int cutoffdate */
public $cutoffdate = 0;
/** @var array submissionplugins - the list of submission plugins */
public $submissionplugins = array();
/** @var string returnaction */
public $returnaction = '';
/** @var string returnparams */
public $returnparams = array();
/** @var int courseid */
public $courseid = 0;
/** @var int coursemoduleid */
public $coursemoduleid = 0;
/** @var int the view (STUDENT_VIEW OR GRADER_VIEW) */
public $view = self::STUDENT_VIEW;
/** @var bool canviewfullnames */
public $canviewfullnames = false;
/** @var bool canedit */
public $canedit = false;
/** @var bool cansubmit */
public $cansubmit = false;
/** @var int extensionduedate */
public $extensionduedate = 0;
/** @var \context context */
public $context = 0;
/** @var bool blindmarking - Should we hide student identities from graders? */
public $blindmarking = false;
/** @var string gradingcontrollerpreview */
public $gradingcontrollerpreview = '';
/** @var string attemptreopenmethod */
public $attemptreopenmethod = 'none';
/** @var int maxattempts */
public $maxattempts = -1;
/** @var string gradingstatus */
public $gradingstatus = '';
/** @var bool preventsubmissionnotingroup */
public $preventsubmissionnotingroup = 0;
/** @var array usergroups */
public $usergroups = array();
/** @var int The time limit for the assignment */
public $timelimit = 0;
/** @var bool */
public $caneditowner;
/**
* Constructor
*
* @param int $allowsubmissionsfromdate
* @param bool $alwaysshowdescription
* @param mixed $submission
* @param bool $teamsubmissionenabled
* @param \stdClass $teamsubmission
* @param mixed $submissiongroup
* @param array $submissiongroupmemberswhoneedtosubmit
* @param bool $submissionsenabled
* @param bool $locked
* @param bool $graded
* @param int $duedate
* @param int $cutoffdate
* @param array $submissionplugins
* @param string $returnaction
* @param array $returnparams
* @param int $coursemoduleid
* @param int $courseid
* @param string $view
* @param bool $canedit
* @param bool $cansubmit
* @param bool $canviewfullnames
* @param int $extensionduedate Any extension to the due date granted for this user.
* @param \context $context Any extension to the due date granted for this user.
* @param bool $blindmarking Should we hide student identities from graders?
* @param string $gradingcontrollerpreview
* @param string $attemptreopenmethod The method of reopening student attempts.
* @param int $maxattempts How many attempts can a student make?
* @param string $gradingstatus The submission status (ie. Graded, Not Released etc).
* @param bool $preventsubmissionnotingroup Prevent submission if user is not in a group.
* @param array $usergroups Array containing all groups the user is assigned to.
* @param int $timelimit The time limit for the assignment.
*/
public function __construct(
$allowsubmissionsfromdate,
$alwaysshowdescription,
$submission,
$teamsubmissionenabled,
$teamsubmission,
$submissiongroup,
$submissiongroupmemberswhoneedtosubmit,
$submissionsenabled,
$locked,
$graded,
$duedate,
$cutoffdate,
$submissionplugins,
$returnaction,
$returnparams,
$coursemoduleid,
$courseid,
$view,
$canedit,
$cansubmit,
$canviewfullnames,
$extensionduedate,
$context,
$blindmarking,
$gradingcontrollerpreview,
$attemptreopenmethod,
$maxattempts,
$gradingstatus,
$preventsubmissionnotingroup,
$usergroups,
$timelimit
) {
$this->allowsubmissionsfromdate = $allowsubmissionsfromdate;
$this->alwaysshowdescription = $alwaysshowdescription;
$this->submission = $submission;
$this->teamsubmissionenabled = $teamsubmissionenabled;
$this->teamsubmission = $teamsubmission;
$this->submissiongroup = $submissiongroup;
$this->submissiongroupmemberswhoneedtosubmit = $submissiongroupmemberswhoneedtosubmit;
$this->submissionsenabled = $submissionsenabled;
$this->locked = $locked;
$this->graded = $graded;
$this->duedate = $duedate;
$this->cutoffdate = $cutoffdate;
$this->submissionplugins = $submissionplugins;
$this->returnaction = $returnaction;
$this->returnparams = $returnparams;
$this->coursemoduleid = $coursemoduleid;
$this->courseid = $courseid;
$this->view = $view;
$this->canedit = $canedit;
$this->cansubmit = $cansubmit;
$this->canviewfullnames = $canviewfullnames;
$this->extensionduedate = $extensionduedate;
$this->context = $context;
$this->blindmarking = $blindmarking;
$this->gradingcontrollerpreview = $gradingcontrollerpreview;
$this->attemptreopenmethod = $attemptreopenmethod;
$this->maxattempts = $maxattempts;
$this->gradingstatus = $gradingstatus;
$this->preventsubmissionnotingroup = $preventsubmissionnotingroup;
$this->usergroups = $usergroups;
$this->timelimit = $timelimit;
}
}
@@ -0,0 +1,77 @@
<?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/>.
/**
* Output the grading actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
use templatable;
use renderable;
use moodle_url;
/**
* Output the grading actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grading_actionmenu implements templatable, renderable {
/** @var int Course module ID. */
protected $cmid;
/** @var bool If any submission plugins are enabled. */
protected $submissionpluginenabled;
/** @var int The number of submissions made. */
protected $submissioncount;
/**
* Constructor for this object.
*
* @param int $cmid Course module ID.
* @param bool $submissionpluginenabled If any submission plugins are enabled.
* @param int $submissioncount The number of submissions made.
*/
public function __construct(int $cmid, bool $submissionpluginenabled = false, int $submissioncount = 0) {
$this->cmid = $cmid;
$this->submissionpluginenabled = $submissionpluginenabled;
$this->submissioncount = $submissioncount;
}
/**
* Data to render in a template.
*
* @param \renderer_base $output renderer base output.
* @return array Data to render.
*/
public function export_for_template(\renderer_base $output): array {
$downloadall = '';
if ($this->submissionpluginenabled && $this->submissioncount) {
$downloadall = (new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'downloadall']))->out(false);
}
return [
'downloadall' => $downloadall
];
}
}
+181
View File
@@ -0,0 +1,181 @@
<?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/>.
/**
* Renderable that initialises the grading "app".
*
* @package mod_assign
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
defined('MOODLE_INTERNAL') || die();
use renderer_base;
use renderable;
use templatable;
use stdClass;
/**
* Grading app renderable.
*
* @package mod_assign
* @since Moodle 3.1
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grading_app implements templatable, renderable {
/**
* @var $userid - The initial user id.
*/
public $userid = 0;
/**
* @var $groupid - The initial group id.
*/
public $groupid = 0;
/**
* @var $assignment - The assignment instance.
*/
public $assignment = null;
/**
* @var array - List of user records with extra fields.
*/
public $participants = [];
/**
* Constructor for this renderable.
*
* @param int $userid The user we will open the grading app too.
* @param int $groupid If groups are enabled this is the current course group.
* @param \assign $assignment The assignment class
*/
public function __construct($userid, $groupid, $assignment) {
$this->userid = $userid;
$this->groupid = $groupid;
$this->assignment = $assignment;
$this->participants = $assignment->list_participants_with_filter_status_and_group($groupid);
if (!$this->userid && count($this->participants)) {
$this->userid = reset($this->participants)->id;
}
}
/**
* Export this class data as a flat list for rendering in a template.
*
* @param renderer_base $output The current page renderer.
* @return stdClass - Flat list of exported data.
*/
public function export_for_template(renderer_base $output) {
global $CFG, $USER;
$export = new stdClass();
$export->userid = $this->userid;
$export->assignmentid = $this->assignment->get_instance()->id;
$export->cmid = $this->assignment->get_course_module()->id;
$export->contextid = $this->assignment->get_context()->id;
$export->groupid = $this->groupid;
$export->name = $this->assignment->get_context()->get_context_name(true, false, false);
$export->courseid = $this->assignment->get_course()->id;
$export->participants = array();
$export->filters = $this->assignment->get_filters();
$export->markingworkflowfilters = $this->assignment->get_marking_workflow_filters(true);
$export->hasmarkingworkflow = count($export->markingworkflowfilters) > 0;
$export->markingallocationfilters = $this->assignment->get_marking_allocation_filters(true);
$export->hasmarkingallocation = count($export->markingallocationfilters) > 0;
$num = 1;
foreach ($this->participants as $idx => $record) {
$user = new stdClass();
$user->id = $record->id;
$user->fullname = fullname($record);
$user->requiregrading = $record->requiregrading;
$user->grantedextension = $record->grantedextension;
$user->submitted = $record->submitted;
if (!empty($record->groupid)) {
$user->groupid = $record->groupid;
$user->groupname = $record->groupname;
}
if ($record->id == $this->userid) {
$export->index = $num;
$user->current = true;
}
$export->participants[] = $user;
$num++;
}
$feedbackplugins = $this->assignment->get_feedback_plugins();
$showreview = false;
foreach ($feedbackplugins as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible()) {
if ($plugin->supports_review_panel()) {
$showreview = true;
}
}
}
$export->actiongrading = 'grading';
$export->viewgrading = get_string('viewgrading', 'mod_assign');
$export->showreview = $showreview;
$time = time();
$export->count = count($export->participants);
$export->coursename = $this->assignment->get_course_context()->get_context_name(true, false, false);
$export->caneditsettings = has_capability('mod/assign:addinstance', $this->assignment->get_context());
$export->duedate = $this->assignment->get_instance()->duedate;
$export->duedatestr = userdate($this->assignment->get_instance()->duedate);
// Time remaining.
$due = '';
if ($export->duedate - $time <= 0) {
$due = get_string('assignmentisdue', 'assign');
} else {
$due = get_string('timeremainingcolon', 'assign', format_time($export->duedate - $time));
}
$export->timeremainingstr = $due;
if ($export->duedate < $time) {
$export->cutoffdate = $this->assignment->get_instance()->cutoffdate;
$cutoffdate = $export->cutoffdate;
if ($cutoffdate) {
if ($cutoffdate > $time) {
$late = get_string('latesubmissionsaccepted', 'assign', userdate($export->cutoffdate));
} else {
$late = get_string('nomoresubmissionsaccepted', 'assign');
}
$export->cutoffdatestr = $late;
}
}
$export->defaultsendnotifications = $this->assignment->get_instance()->sendstudentnotifications;
$export->rarrow = $output->rarrow();
$export->larrow = $output->larrow();
// List of identity fields to display (the user info will not contain any fields the user cannot view anyway).
// TODO Does not support custom user profile fields (MDL-70456).
$export->showuseridentity = implode(',', \core_user\fields::get_identity_fields(null, false));
$export->currentuserid = $USER->id;
$helpicon = new \help_icon('sendstudentnotifications', 'assign');
$export->helpicon = $helpicon->export_for_template($output);
return $export;
}
}
@@ -0,0 +1,161 @@
<?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/>.
/**
* Output the override actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
use core_availability\info_module;
use moodle_url;
use templatable;
use renderable;
use url_select;
use single_button;
/**
* Output the override actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class override_actionmenu implements templatable, renderable {
/** @var moodle_url The current url for this page. */
protected $currenturl;
/** @var \cm_info course module information */
protected $cm;
/** @var bool Can all groups be accessed */
protected $canaccessallgroups;
/** @var array Groups related to this activity */
protected $groups;
/**
* Constructor for this action menu.
*
* @param moodle_url $currenturl The current url for this page.
* @param \cm_info $cm course module information.
*/
public function __construct(moodle_url $currenturl, \cm_info $cm) {
$this->currenturl = $currenturl;
$this->cm = $cm;
$groupmode = groups_get_activity_groupmode($this->cm);
$this->canaccessallgroups = ($groupmode === NOGROUPS) ||
has_capability('moodle/site:accessallgroups', $this->cm->context);
$this->groups = $this->canaccessallgroups ? groups_get_all_groups($this->cm->course) :
groups_get_activity_allowed_groups($this->cm);
}
/**
* Create a select menu for overrides.
*
* @return url_select A url select object.
*/
protected function get_select_menu(): url_select {
$userlink = new moodle_url('/mod/assign/overrides.php', ['cmid' => $this->cm->id, 'mode' => 'user']);
$grouplink = new moodle_url('/mod/assign/overrides.php', ['cmid' => $this->cm->id, 'mode' => 'group']);
$menu = [
$userlink->out(false) => get_string('useroverrides', 'mod_assign'),
$grouplink->out(false) => get_string('groupoverrides', 'mod_assign'),
];
return new url_select($menu, $this->currenturl->out(false), null, 'mod_assign_override_select');
}
/**
* Whether to show groups or not. Assignments can be have group overrides if there are groups available in the course.
* There is no restriction related to the assignment group setting.
*
* @return bool
*/
protected function show_groups(): bool {
if ($this->canaccessallgroups) {
$groups = groups_get_all_groups($this->cm->course);
} else {
$groups = groups_get_activity_allowed_groups($this->cm);
}
return !(empty($groups));
}
/**
* Whether to enable/disable user override button or not.
*
* @return bool
*/
protected function show_useroverride(): bool {
global $DB;
$users = [];
$context = $this->cm->context;
if ($this->canaccessallgroups) {
$users = get_enrolled_users($context, '', 0, 'u.id');
} else if ($this->groups) {
$enrolledjoin = get_enrolled_join($context, 'u.id');
list($ingroupsql, $ingroupparams) = $DB->get_in_or_equal(array_keys($this->groups), SQL_PARAMS_NAMED);
$params = $enrolledjoin->params + $ingroupparams;
$sql = "SELECT u.id
FROM {user} u
JOIN {groups_members} gm ON gm.userid = u.id
{$enrolledjoin->joins}
WHERE gm.groupid $ingroupsql
AND {$enrolledjoin->wheres}";
$users = $DB->get_records_sql($sql, $params);
}
$info = new info_module($this->cm);
$users = $info->filter_user_list($users);
return !empty($users);
}
/**
* Data to be used in a template.
*
* @param \renderer_base $output renderer base output.
* @return array The data to be used in a template.
*/
public function export_for_template(\renderer_base $output): array {
$type = $this->currenturl->get_param('mode');
if ($type == 'user') {
$text = get_string('addnewuseroverride', 'mod_assign');
} else {
$text = get_string('addnewgroupoverride', 'mod_assign');
}
$action = ($type == 'user') ? 'adduser' : 'addgroup';
$params = ['cmid' => $this->currenturl->get_param('cmid'), 'action' => $action];
$url = new moodle_url('/mod/assign/overrideedit.php', $params);
$options = [];
if ($action == 'addgroup' && !$this->show_groups()) {
$options = ['disabled' => 'true'];
} else if ($action === 'adduser' && !$this->show_useroverride()) {
$options = ['disabled' => 'true'];
}
$overridebutton = new single_button($url, $text, 'post', single_button::BUTTON_PRIMARY, $options);
$urlselect = $this->get_select_menu();
return [
'addoverride' => $overridebutton->export_for_template($output),
'urlselect' => $urlselect->export_for_template($output)
];
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
<?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/>.
/**
* Represents the timer panel.
*
* @package mod_assign
* @copyright 2020 Ilya Tregubov <ilyatregubov@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
use renderable;
use renderer_base;
use stdClass;
use templatable;
/**
* Represents the timer panel.
*
* @package mod_assign
* @copyright 2020 Ilya Tregubov <ilyatregubov@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class timelimit_panel implements templatable, renderable {
/** @var \stdClass assign submission attempt.*/
protected $submission;
/** @var object assign object.*/
protected $assign;
/**
* Constructor.
*
* @param \stdClass $submission assign submission.
* @param \stdClass $assign assign object.
*/
public function __construct(\stdClass $submission, \stdClass $assign) {
$this->submission = $submission;
$this->assign = $assign;
}
/**
* Render timer.
*
* @param renderer_base $output The current page renderer.
* @return stdClass - Flat list of exported data.
*/
public function export_for_template(renderer_base $output): stdClass {
return (object)['timerstartvalue' => $this->end_time() - time()];
}
/**
* Compute end time for this assign attempt.
*
* @return int the time when assign attempt is due.
*/
private function end_time(): int {
$timedue = $this->submission->timestarted + $this->assign->timelimit;
if ($this->assign->duedate) {
return min($timedue, $this->assign->duedate);
}
if ($this->assign->cutoffdate) {
return min($timedue, $this->assign->cutoffdate);
}
return $timedue;
}
}
@@ -0,0 +1,174 @@
<?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/>.
/**
* Output the user submission actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\output;
use templatable;
use renderable;
use moodle_url;
use help_icon;
use single_button;
use stdClass;
/**
* Output the user submission actionbar for this activity.
*
* @package mod_assign
* @copyright 2021 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_submission_actionmenu implements templatable, renderable {
/** @var int The course module ID. */
protected $cmid;
/** @var bool Whether to show the submit button. */
protected $showsubmit;
/** @var bool Whether to show the edit button. */
protected $showedit;
/** @var stdClass A submission for this activity. */
protected $submission;
/** @var stdClass A team submission for this activity. */
protected $teamsubmission;
/** @var int The time limit for the submission. 0 = no time limit. */
protected $timelimit;
/**
* Constructor for this object.
*
* @param int $cmid The course module ID.
* @param bool $showsubmit Whether to show the submit button.
* @param bool $showedit Whether to show the edit button.
* @param stdClass|null $submission A submission for this activity.
* @param stdClass|null $teamsubmission A team submission for this activity.
* @param int $timelimit The time limit for completing this activity.
*/
public function __construct(int $cmid, bool $showsubmit, bool $showedit, stdClass $submission = null,
stdClass $teamsubmission = null, int $timelimit = 0) {
$this->cmid = $cmid;
$this->showsubmit = $showsubmit;
$this->showedit = $showedit;
$this->submission = $submission;
$this->teamsubmission = $teamsubmission;
$this->timelimit = $timelimit;
}
/**
* Get the submission status.
*
* @return string The status of the submission.
*/
protected function get_current_status(): string {
if (!is_null($this->teamsubmission) && isset($this->teamsubmission->status)) {
return $this->teamsubmission->status;
} else if (!empty((array)$this->submission)) {
return $this->submission->status;
} else {
return ASSIGN_SUBMISSION_STATUS_NEW;
}
}
/**
* Export the submission buttons for the page.
*
* @param \renderer_base $output renderer base output.
* @return array The data to be rendered.
*/
public function export_for_template(\renderer_base $output): array {
$data = ['edit' => false, 'submit' => false, 'remove' => false, 'previoussubmission' => false];
if ($this->showedit) {
$url = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'editsubmission']);
$button = new single_button($url, get_string('editsubmission', 'mod_assign'), 'get');
$data['edit'] = [
'button' => $button->export_for_template($output),
];
$status = $this->get_current_status();
if ($status !== ASSIGN_SUBMISSION_STATUS_NEW && $status !== ASSIGN_SUBMISSION_STATUS_REOPENED) {
$url = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'removesubmissionconfirm']);
$button = new single_button($url, get_string('removesubmission', 'mod_assign'), 'get');
$data['remove'] = ['button' => $button->export_for_template($output)];
}
if ($status === ASSIGN_SUBMISSION_STATUS_REOPENED) {
$params = ['id' => $this->cmid, 'action' => 'editprevioussubmission', 'sesskey' => sesskey()];
$url = new moodle_url('/mod/assign/view.php', $params);
$button = new single_button($url, get_string('addnewattemptfromprevious', 'mod_assign'), 'get');
$help = new help_icon('addnewattemptfromprevious', 'mod_assign');
$data['previoussubmission'] = [
'button' => $button->export_for_template($output),
'help' => $help->export_for_template($output)
];
$url = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'editsubmission']);
$newattemptbutton = new single_button(
$url,
get_string('addnewattempt', 'mod_assign'),
'get',
single_button::BUTTON_PRIMARY
);
$newattempthelp = new help_icon('addnewattempt', 'mod_assign');
$data['edit']['button'] = $newattemptbutton->export_for_template($output);
$data['edit']['help'] = $newattempthelp->export_for_template($output);
}
if ($status === ASSIGN_SUBMISSION_STATUS_NEW) {
$timelimitenabled = get_config('assign', 'enabletimelimit');
if ($timelimitenabled && $this->timelimit && empty($this->submission->timestarted)) {
$confirmation = new \confirm_action(
get_string('confirmstart', 'assign', format_time($this->timelimit)),
null,
get_string('beginassignment', 'assign')
);
$urlparams = array('id' => $this->cmid, 'action' => 'editsubmission');
$beginbutton = new \action_link(
new moodle_url('/mod/assign/view.php', $urlparams),
get_string('beginassignment', 'assign'),
$confirmation,
['class' => 'btn btn-primary']
);
$data['edit']['button'] = $beginbutton->export_for_template($output);
$data['edit']['begin'] = true;
$data['edit']['help'] = '';
} else {
$newattemptbutton = new single_button(
$url,
get_string('addsubmission', 'mod_assign'),
'get',
single_button::BUTTON_PRIMARY
);
$data['edit']['button'] = $newattemptbutton->export_for_template($output);
$data['edit']['help'] = '';
}
}
}
if ($this->showsubmit) {
$url = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'submit']);
$button = new single_button($url, get_string('submitassignment', 'mod_assign'), 'get', single_button::BUTTON_PRIMARY);
$help = new help_icon('submitassignment', 'mod_assign');
$data['submit'] = [
'button' => $button->export_for_template($output),
'help' => $help->export_for_template($output)
];
}
return $data;
}
}
@@ -0,0 +1,150 @@
<?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/>.
namespace mod_assign\plugininfo;
use core\plugininfo\base;
use core_plugin_manager;
use moodle_url;
/**
* Assign feedback subplugin info class.
*
* @package mod_assign
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assignfeedback extends base {
public static function plugintype_supports_disabling(): bool {
return true;
}
/**
* Finds all enabled plugins, the result may include missing plugins.
* @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown
*/
public static function get_enabled_plugins() {
global $DB;
$plugins = core_plugin_manager::instance()->get_installed_plugins('assignfeedback');
if (!$plugins) {
return array();
}
$installed = array();
foreach ($plugins as $plugin => $version) {
$installed[] = 'assignfeedback_'.$plugin;
}
list($installed, $params) = $DB->get_in_or_equal($installed, SQL_PARAMS_NAMED);
$disabled = $DB->get_records_select('config_plugins', "plugin $installed AND name = 'disabled'", $params, 'plugin ASC');
foreach ($disabled as $conf) {
if (empty($conf->value)) {
continue;
}
list($type, $name) = explode('_', $conf->plugin, 2);
unset($plugins[$name]);
}
$enabled = array();
foreach ($plugins as $plugin => $version) {
$enabled[$plugin] = $plugin;
}
return $enabled;
}
public static function enable_plugin(string $pluginname, int $enabled): bool {
$haschanged = false;
$plugin = 'assignfeedback_' . $pluginname;
$oldvalue = get_config($plugin, 'disabled');
$disabled = !$enabled;
// Only set value if there is no config setting or if the value is different from the previous one.
if ($oldvalue === false || ((bool) $oldvalue != $disabled)) {
set_config('disabled', $disabled, $plugin);
$haschanged = true;
add_to_config_log('disabled', $oldvalue, $disabled, $plugin);
\core_plugin_manager::reset_caches();
}
return $haschanged;
}
public function is_uninstall_allowed() {
return true;
}
/**
* Return URL used for management of plugins of this type.
* @return moodle_url
*/
public static function get_manage_url() {
return new moodle_url('/mod/assign/adminmanageplugins.php', array('subtype'=>'assignfeedback'));
}
/**
* Pre-uninstall hook.
* @private
*/
public function uninstall_cleanup() {
global $DB;
$DB->delete_records('assign_plugin_config', array('plugin'=>$this->name, 'subtype'=>'assignfeedback'));
parent::uninstall_cleanup();
}
public function get_settings_section_name() {
return $this->type . '_' . $this->name;
}
/**
* Loads plugin settings to the settings tree
*
* This function usually includes settings.php file in plugins folder.
* Alternatively it can create a link to some settings page (instance of admin_externalpage)
*
* @param \part_of_admin_tree $adminroot
* @param string $parentnodename
* @param bool $hassiteconfig whether the current user has moodle/site:config capability
*/
public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
$ADMIN = $adminroot; // May be used in settings.php.
$plugininfo = $this; // Also can be used inside settings.php.
if (!$this->is_installed_and_upgraded()) {
return;
}
if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) {
return;
}
$section = $this->get_settings_section_name();
$settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
if ($adminroot->fulltree) {
$shortsubtype = substr($this->type, strlen('assign'));
include($this->full_path('settings.php'));
}
$adminroot->add($this->type . 'plugins', $settings);
}
}
@@ -0,0 +1,150 @@
<?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/>.
namespace mod_assign\plugininfo;
use core\plugininfo\base;
use core_plugin_manager;
use moodle_url;
/**
* Assign submission subplugin info class.
*
* @package mod_assign
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assignsubmission extends base {
public static function plugintype_supports_disabling(): bool {
return true;
}
/**
* Finds all enabled plugins, the result may include missing plugins.
* @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown
*/
public static function get_enabled_plugins() {
global $DB;
$plugins = core_plugin_manager::instance()->get_installed_plugins('assignsubmission');
if (!$plugins) {
return array();
}
$installed = array();
foreach ($plugins as $plugin => $version) {
$installed[] = 'assignsubmission_'.$plugin;
}
list($installed, $params) = $DB->get_in_or_equal($installed, SQL_PARAMS_NAMED);
$disabled = $DB->get_records_select('config_plugins', "plugin $installed AND name = 'disabled'", $params, 'plugin ASC');
foreach ($disabled as $conf) {
if (empty($conf->value)) {
continue;
}
list($type, $name) = explode('_', $conf->plugin, 2);
unset($plugins[$name]);
}
$enabled = array();
foreach ($plugins as $plugin => $version) {
$enabled[$plugin] = $plugin;
}
return $enabled;
}
public static function enable_plugin(string $pluginname, int $enabled): bool {
$haschanged = false;
$plugin = 'assignsubmission_' . $pluginname;
$oldvalue = get_config($plugin, 'disabled');
$disabled = !$enabled;
// Only set value if there is no config setting or if the value is different from the previous one.
if ($oldvalue === false || ((bool) $oldvalue != $disabled)) {
set_config('disabled', $disabled, $plugin);
$haschanged = true;
add_to_config_log('disabled', $oldvalue, $disabled, $plugin);
\core_plugin_manager::reset_caches();
}
return $haschanged;
}
public function is_uninstall_allowed() {
return true;
}
/**
* Return URL used for management of plugins of this type.
* @return moodle_url
*/
public static function get_manage_url() {
return new moodle_url('/mod/assign/adminmanageplugins.php', array('subtype'=>'assignsubmission'));
}
/**
* Pre-uninstall hook.
* @private
*/
public function uninstall_cleanup() {
global $DB;
$DB->delete_records('assign_plugin_config', array('plugin'=>$this->name, 'subtype'=>'assignsubmission'));
parent::uninstall_cleanup();
}
public function get_settings_section_name() {
return $this->type . '_' . $this->name;
}
/**
* Loads plugin settings to the settings tree
*
* This function usually includes settings.php file in plugins folder.
* Alternatively it can create a link to some settings page (instance of admin_externalpage)
*
* @param \part_of_admin_tree $adminroot
* @param string $parentnodename
* @param bool $hassiteconfig whether the current user has moodle/site:config capability
*/
public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
$ADMIN = $adminroot; // May be used in settings.php.
$plugininfo = $this; // Also can be used inside settings.php.
if (!$this->is_installed_and_upgraded()) {
return;
}
if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) {
return;
}
$section = $this->get_settings_section_name();
$settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
if ($adminroot->fulltree) {
$shortsubtype = substr($this->type, strlen('assign'));
include($this->full_path('settings.php'));
}
$adminroot->add($this->type . 'plugins', $settings);
}
}
@@ -0,0 +1,206 @@
<?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 mod_assign assign_plugin_request_data class
*
* For assign plugin privacy data to fulfill requests.
*
* @package mod_assign
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* An object for fulfilling an assign plugin data request.
*
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assign_plugin_request_data {
/** @var \context The context that we are dealing with. */
protected $context;
/** @var object For submisisons the submission object, for feedback the grade object. */
protected $pluginobject;
/** @var array The path or location that we are exporting data to. */
protected $subcontext;
/** @var object If set then only export data related directly to this user. */
protected $user;
/** @var array The user IDs of the users that will be affected. */
protected $userids;
/** @var array The submissions related to the users added. */
protected $submissions = [];
/** @var array The grades related to the users added. */
protected $grades = [];
/** @var \assign The assign object */
protected $assign;
/**
* Object creator for assign plugin request data.
*
* @param \context $context Context object.
* @param \stdClass $pluginobject The grade object.
* @param array $subcontext Directory / file location.
* @param \stdClass $user The user object.
* @param \assign $assign The assign object.
*/
public function __construct(\context $context, \assign $assign, \stdClass $pluginobject = null, array $subcontext = [],
\stdClass $user = null) {
$this->context = $context;
$this->pluginobject = $pluginobject;
$this->subcontext = $subcontext;
$this->user = $user;
$this->assign = $assign;
}
/**
* Method for adding an array of user IDs. This will do a query to populate the submissions and grades
* for these users.
*
* @param array $userids User IDs to do something with.
*/
public function set_userids(array $userids) {
$this->userids = $userids;
}
/**
* Getter for this attribute.
*
* @return \context Context
*/
public function get_context() {
return $this->context;
}
/**
* Getter for this attribute.
*
* @return object The assign plugin object
*/
public function get_pluginobject() {
return $this->pluginobject;
}
/**
* Getter for this attribute.
*
* @return array The location (path) that this data is being writter to.
*/
public function get_subcontext() {
return $this->subcontext;
}
/**
* Getter for this attribute.
*
* @return object The user id. If set then only information directly related to this user ID will be returned.
*/
public function get_user() {
return $this->user;
}
/**
* Getter for this attribute.
*
* @return \assign The assign object.
*/
public function get_assign() {
return $this->assign;
}
/**
* A method to conveniently fetch the assign id.
*
* @return int The assign id.
*/
public function get_assignid() {
return $this->assign->get_instance()->id;
}
/**
* Get all of the user IDs
*
* @return array User IDs
*/
public function get_userids() {
return $this->userids;
}
/**
* Returns all of the submission IDs
*
* @return array submission IDs
*/
public function get_submissionids() {
return array_keys($this->submissions);
}
/**
* Returns the submissions related to the user IDs
*
* @return array User submissions.
*/
public function get_submissions() {
return $this->submissions;
}
/**
* Returns the grade IDs related to the user IDs
*
* @return array User grade IDs.
*/
public function get_gradeids() {
return array_keys($this->grades);
}
/**
* Returns the grades related to the user IDs
*
* @return array User grades.
*/
public function get_grades() {
return $this->grades;
}
/**
* Fetches all of the submissions and grades related to the User IDs provided. Use get_grades, get_submissions etc to
* retrieve this information.
*/
public function populate_submissions_and_grades() {
global $DB;
if (empty($this->get_userids())) {
throw new \coding_exception('Please use set_userids() before calling this method.');
}
list($sql, $params) = $DB->get_in_or_equal($this->get_userids(), SQL_PARAMS_NAMED);
$params['assign'] = $this->get_assign()->get_instance()->id;
$this->submissions = $DB->get_records_select('assign_submission', "assignment = :assign AND userid $sql", $params);
$this->grades = $DB->get_records_select('assign_grades', "assignment = :assign AND userid $sql", $params);
}
}
@@ -0,0 +1,87 @@
<?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 assignfeedback_provider interface.
*
* Assignment Sub plugins should implement this if they store personal information.
*
* @package mod_assign
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\privacy;
use core_privacy\local\request\contextlist;
defined('MOODLE_INTERNAL') || die();
interface assignfeedback_provider extends \core_privacy\local\request\plugin\subplugin_provider {
/**
* Retrieves the contextids associated with the provided userid for this subplugin.
* NOTE if your subplugin must have an entry in the assign_grade table to work, then this
* method can be empty.
*
* @param int $userid The user ID to get context IDs for.
* @param \core_privacy\local\request\contextlist $contextlist Use add_from_sql with this object to add your context IDs.
*/
public static function get_context_for_userid_within_feedback(int $userid, contextlist $contextlist);
/**
* Returns student user ids related to the provided teacher ID. If an entry must be present in the assign_grade table for
* your plugin to work then there is no need to fill in this method. If you filled in get_context_for_userid_within_feedback()
* then you probably have to fill this in as well.
*
* @param useridlist $useridlist A list of user IDs of students graded by this user.
*/
public static function get_student_user_ids(useridlist $useridlist);
/**
* Export feedback data with the available grade and userid information provided.
* assign_plugin_request_data contains:
* - context
* - grade object
* - current path (subcontext)
* - user object
*
* @param assign_plugin_request_data $exportdata Contains data to help export the user information.
*/
public static function export_feedback_user_data(assign_plugin_request_data $exportdata);
/**
* Any call to this method should delete all user data for the context defined in the deletion_criteria.
* assign_plugin_request_data contains:
* - context
* - assign object
*
* @param assign_plugin_request_data $requestdata Data useful for deleting user data from this sub-plugin.
*/
public static function delete_feedback_for_context(assign_plugin_request_data $requestdata);
/**
* Calling this function should delete all user data associated with this grade.
* assign_plugin_request_data contains:
* - context
* - grade object
* - user object
* - assign object
*
* @param assign_plugin_request_data $requestdata Data useful for deleting user data.
*/
public static function delete_feedback_for_grade(assign_plugin_request_data $requestdata);
}

Some files were not shown because too many files have changed in this diff Show More