-<?php\r
-// This file is part of BasicLTI4Moodle\r
-//\r
-// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)\r
-// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web\r
-// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI\r
-// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS\r
-// are already supporting or going to support BasicLTI. This project Implements the consumer\r
-// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.\r
-// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem\r
-// at the GESSI research group at UPC.\r
-// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI\r
-// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a\r
-// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.\r
-//\r
-// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis\r
-// of the Universitat Politecnica de Catalunya http://www.upc.edu\r
-// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu\r
-//\r
-// Moodle is free software: you can redistribute it and/or modify\r
-// it under the terms of the GNU General Public License as published by\r
-// the Free Software Foundation, either version 3 of the License, or\r
-// (at your option) any later version.\r
-//\r
-// Moodle is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-// GNU General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU General Public License\r
-// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\r
-\r
-/**\r
- * This file contains a library of functions and constants for the\r
- * BasicLTI module\r
- *\r
- * @package lti\r
- * @copyright 2009 Marc Alier, Jordi Piguillem, Nikolas Galanis\r
- * marc.alier@upc.edu\r
- * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu\r
- *\r
- * @author Marc Alier\r
- * @author Jordi Piguillem\r
- * @author Nikolas Galanis\r
- *\r
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r
- */\r
-\r
-defined('MOODLE_INTERNAL') || die;\r
-\r
-require_once($CFG->dirroot.'/mod/lti/locallib.php');\r
-\r
-/**\r
- * List of features supported in URL module\r
- * @param string $feature FEATURE_xx constant for requested feature\r
- * @return mixed True if module supports feature, false if not, null if doesn't know\r
- */\r
-function lti_supports($feature) {\r
- switch($feature) {\r
- case FEATURE_GROUPS: return false;\r
- case FEATURE_GROUPINGS: return false;\r
- case FEATURE_GROUPMEMBERSONLY: return true;\r
- case FEATURE_MOD_INTRO: return true;\r
- case FEATURE_COMPLETION_TRACKS_VIEWS: return true;\r
- case FEATURE_GRADE_HAS_GRADE: return true;\r
- case FEATURE_GRADE_OUTCOMES: return true;\r
- case FEATURE_BACKUP_MOODLE2: return true;\r
-\r
- default: return null;\r
- }\r
-}\r
-\r
-/**\r
- * Given an object containing all the necessary data,\r
- * (defined by the form in mod.html) this function\r
- * will create a new instance and return the id number\r
- * of the new instance.\r
- *\r
- * @param object $instance An object from the form in mod.html\r
- * @return int The id of the newly inserted basiclti record\r
- **/\r
-function lti_add_instance($formdata) {\r
- global $DB;\r
- $formdata->timecreated = time();\r
- $formdata->timemodified = $formdata->timecreated;\r
- //$basiclti->placementsecret = uniqid('', true);\r
- //$basiclti->timeplacementsecret = time();\r
-\r
- $id = $DB->insert_record("lti", $formdata);\r
-\r
- if ($formdata->instructorchoiceacceptgrades == 1) {\r
- $basiclti = $DB->get_record('lti', array('id'=>$id));\r
- $basiclti->cmidnumber = $formdata->cmidnumber;\r
- \r
- lti_grade_item_update($basiclti);\r
- }\r
-\r
- return $id;\r
-}\r
-\r
-/**\r
- * Given an object containing all the necessary data,\r
- * (defined by the form in mod.html) this function\r
- * will update an existing instance with new data.\r
- *\r
- * @param object $instance An object from the form in mod.html\r
- * @return boolean Success/Fail\r
- **/\r
-function lti_update_instance($formdata) {\r
- global $DB;\r
-\r
- $formdata->timemodified = time();\r
- $formdata->id = $formdata->instance;\r
-\r
- if(!isset($formdata->showtitle)){\r
- $formdata->showtitle = 0;\r
- }\r
- \r
- if(!isset($formdata->showdescription)){\r
- $formdata->showdescription = 0;\r
- }\r
- \r
- if ($formdata->instructorchoiceacceptgrades == 1) {\r
- $basicltirec = $DB->get_record("lti", array("id" => $formdata->id));\r
- $basicltirec->cmidnumber = $formdata->cmidnumber;\r
- \r
- lti_grade_item_update($basicltirec);\r
- } else {\r
- lti_grade_item_delete($formdata);\r
- }\r
-\r
- return $DB->update_record("lti", $formdata);\r
-}\r
-\r
-/**\r
- * Given an ID of an instance of this module,\r
- * this function will permanently delete the instance\r
- * and any data that depends on it.\r
- *\r
- * @param int $id Id of the module instance\r
- * @return boolean Success/Failure\r
- **/\r
-function lti_delete_instance($id) {\r
- global $DB;\r
-\r
- if (! $basiclti = $DB->get_record("lti", array("id" => $id))) {\r
- return false;\r
- }\r
-\r
- $result = true;\r
-\r
- # Delete any dependent records here #\r
- lti_grade_item_delete($basiclti);\r
-\r
- return $DB->delete_records("lti", array("id" => $basiclti->id));\r
-}\r
-\r
-/**\r
- * Return a small object with summary information about what a\r
- * user has done with a given particular instance of this module\r
- * Used for user activity reports.\r
- * $return->time = the time they did it\r
- * $return->info = a short text description\r
- *\r
- * @return null\r
- * @TODO: implement this moodle function (if needed)\r
- **/\r
-function lti_user_outline($course, $user, $mod, $basiclti) {\r
- return $return;\r
-}\r
-\r
-/**\r
- * Print a detailed representation of what a user has done with\r
- * a given particular instance of this module, for user activity reports.\r
- *\r
- * @return boolean\r
- * @TODO: implement this moodle function (if needed)\r
- **/\r
-function lti_user_complete($course, $user, $mod, $basiclti) {\r
- return true;\r
-}\r
-\r
-/**\r
- * Given a course and a time, this module should find recent activity\r
- * that has occurred in basiclti activities and print it out.\r
- * Return true if there was output, or false is there was none.\r
- *\r
- * @uses $CFG\r
- * @return boolean\r
- * @TODO: implement this moodle function\r
- **/\r
-function lti_print_recent_activity($course, $isteacher, $timestart) {\r
- return false; // True if anything was printed, otherwise false\r
-}\r
-\r
-/**\r
- * Function to be run periodically according to the moodle cron\r
- * This function searches for things that need to be done, such\r
- * as sending out mail, toggling flags etc ...\r
- *\r
- * @uses $CFG\r
- * @return boolean\r
- **/\r
-function lti_cron () {\r
- return true;\r
-}\r
-\r
-/**\r
- * Must return an array of grades for a given instance of this module,\r
- * indexed by user. It also returns a maximum allowed grade.\r
- *\r
- * Example:\r
- * $return->grades = array of grades;\r
- * $return->maxgrade = maximum allowed grade;\r
- *\r
- * return $return;\r
- *\r
- * @param int $basicltiid ID of an instance of this module\r
- * @return mixed Null or object with an array of grades and with the maximum grade\r
- *\r
- * @TODO: implement this moodle function (if needed)\r
- **/\r
-function lti_grades($basicltiid) {\r
- return null;\r
-}\r
-\r
-/**\r
- * Must return an array of user records (all data) who are participants\r
- * for a given instance of basiclti. Must include every user involved\r
- * in the instance, independient of his role (student, teacher, admin...)\r
- * See other modules as example.\r
- *\r
- * @param int $basicltiid ID of an instance of this module\r
- * @return mixed boolean/array of students\r
- *\r
- * @TODO: implement this moodle function\r
- **/\r
-function lti_get_participants($basicltiid) {\r
- return false;\r
-}\r
-\r
-/**\r
- * This function returns if a scale is being used by one basiclti\r
- * it it has support for grading and scales. Commented code should be\r
- * modified if necessary. See forum, glossary or journal modules\r
- * as reference.\r
- *\r
- * @param int $basicltiid ID of an instance of this module\r
- * @return mixed\r
- *\r
- * @TODO: implement this moodle function (if needed)\r
- **/\r
-function lti_scale_used ($basicltiid, $scaleid) {\r
- $return = false;\r
-\r
- //$rec = get_record("basiclti","id","$basicltiid","scale","-$scaleid");\r
- //\r
- //if (!empty($rec) && !empty($scaleid)) {\r
- // $return = true;\r
- //}\r
-\r
- return $return;\r
-}\r
-\r
-/**\r
- * Checks if scale is being used by any instance of basiclti.\r
- * This function was added in 1.9\r
- *\r
- * This is used to find out if scale used anywhere\r
- * @param $scaleid int\r
- * @return boolean True if the scale is used by any basiclti\r
- *\r
- */\r
-function lti_scale_used_anywhere($scaleid) {\r
- global $DB;\r
-\r
- if ($scaleid and $DB->record_exists('lti', array('grade' => -$scaleid))) {\r
- return true;\r
- } else {\r
- return false;\r
- }\r
-}\r
-\r
-/**\r
- * Execute post-install custom actions for the module\r
- * This function was added in 1.9\r
- *\r
- * @return boolean true if success, false on error\r
- */\r
-function lti_install() {\r
- return true;\r
-}\r
-\r
-/**\r
- * Execute post-uninstall custom actions for the module\r
- * This function was added in 1.9\r
- *\r
- * @return boolean true if success, false on error\r
- */\r
-function lti_uninstall() {\r
- return true;\r
-}\r
-\r
-/**\r
- * Returns available Basic LTI types\r
- *\r
- * @return array of basicLTI types\r
- */\r
-function lti_get_lti_types() {\r
- global $DB;\r
-\r
- return $DB->get_records('lti_types');\r
-}\r
-\r
-/**\r
- * Returns Basic LTI types configuration\r
- *\r
- * @return array of basicLTI types\r
- */\r
-/*function lti_get_types() {\r
- $types = array();\r
-\r
- $basicltitypes = lti_get_lti_types();\r
- if (!empty($basicltitypes)) {\r
- foreach ($basicltitypes as $basicltitype) {\r
- $ltitypesconfig = lti_get_type_config($basicltitype->id);\r
-\r
- $modclass = MOD_CLASS_ACTIVITY;\r
- if (isset($ltitypesconfig['module_class_type'])) {\r
- if ($ltitypesconfig['module_class_type']=='1') {\r
- $modclass = MOD_CLASS_RESOURCE;\r
- }\r
- }\r
-\r
- $type = new object();\r
- $type->modclass = $modclass;\r
- $type->type = 'lti&type='.urlencode($basicltitype->rawname);\r
- $type->typestr = $basicltitype->name;\r
- $types[] = $type;\r
- }\r
- }\r
-\r
- return $types;\r
-}*/\r
-\r
-//////////////////////////////////////////////////////////////////////////////////////\r
-/// Any other basiclti functions go here. Each of them must have a name that\r
-/// starts with basiclti_\r
-/// Remember (see note in first lines) that, if this section grows, it's HIGHLY\r
-/// recommended to move all funcions below to a new "localib.php" file.\r
-\r
-///**\r
-// *\r
-// */\r
-//function process_outcomes($userid, $course, $basiclti) {\r
-// global $CFG, $USER;\r
-//\r
-// if (empty($CFG->enableoutcomes)) {\r
-// return;\r
-// }\r
-//\r
-// require_once($CFG->libdir.'/gradelib.php');\r
-//\r
-// if (!$formdata = data_submitted() or !confirm_sesskey()) {\r
-// return;\r
-// }\r
-//\r
-// $data = array();\r
-// $grading_info = grade_get_grades($course->id, 'mod', 'basiclti', $basiclti->id, $userid);\r
-//\r
-// if (!empty($grading_info->outcomes)) {\r
-// foreach ($grading_info->outcomes as $n => $old) {\r
-// $name = 'outcome_'.$n;\r
-// if (isset($formdata->{$name}[$userid]) and $old->grades[$userid]->grade != $formdata->{$name}[$userid]) {\r
-// $data[$n] = $formdata->{$name}[$userid];\r
-// }\r
-// }\r
-// }\r
-// if (count($data) > 0) {\r
-// grade_update_outcomes('mod/basiclti', $course->id, 'mod', 'basiclti', $basiclti->id, $userid, $data);\r
-// }\r
-//\r
-//}\r
-\r
-/**\r
- * Top-level function for handling of submissions called by submissions.php\r
- *\r
- * This is for handling the teacher interaction with the grading interface\r
- *\r
- * @global object\r
- * @param string $mode Specifies the kind of teacher interaction taking place\r
- */\r
-function lti_submissions($cm, $course, $basiclti, $mode) {\r
- ///The main switch is changed to facilitate\r
- ///1) Batch fast grading\r
- ///2) Skip to the next one on the popup\r
- ///3) Save and Skip to the next one on the popup\r
-\r
- //make user global so we can use the id\r
- global $USER, $OUTPUT, $DB;\r
-\r
- $mailinfo = optional_param('mailinfo', null, PARAM_BOOL);\r
-\r
- if (optional_param('next', null, PARAM_BOOL)) {\r
- $mode='next';\r
- }\r
- if (optional_param('saveandnext', null, PARAM_BOOL)) {\r
- $mode='saveandnext';\r
- }\r
-\r
- if (is_null($mailinfo)) {\r
- if (optional_param('sesskey', null, PARAM_BOOL)) {\r
- set_user_preference('lti_mailinfo', $mailinfo);\r
- } else {\r
- $mailinfo = get_user_preferences('lti_mailinfo', 0);\r
- }\r
- } else {\r
- set_user_preference('lti_mailinfo', $mailinfo);\r
- }\r
-\r
- switch ($mode) {\r
- case 'grade': // We are in a main window grading\r
- if ($submission = process_feedback()) {\r
- lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));\r
- } else {\r
- lti_display_submissions($cm, $course, $basiclti);\r
- }\r
- break;\r
-\r
- case 'single': // We are in a main window displaying one submission\r
- if ($submission = process_feedback()) {\r
- lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));\r
- } else {\r
- display_submission();\r
- }\r
- break;\r
-\r
- case 'all': // Main window, display everything\r
- lti_display_submissions($cm, $course, $basiclti);\r
- break;\r
-\r
- case 'fastgrade':\r
- /// do the fast grading stuff - this process should work for all 3 subclasses\r
- $grading = false;\r
- $commenting = false;\r
- $col = false;\r
- if (isset($_POST['submissioncomment'])) {\r
- $col = 'submissioncomment';\r
- $commenting = true;\r
- }\r
- if (isset($_POST['menu'])) {\r
- $col = 'menu';\r
- $grading = true;\r
- }\r
- if (!$col) {\r
- //both submissioncomment and grade columns collapsed..\r
- lti_display_submissions($cm, $course, $basiclti);\r
- break;\r
- }\r
-\r
- foreach ($_POST[$col] as $id => $unusedvalue) {\r
-\r
- $id = (int)$id; //clean parameter name\r
-\r
- // Get grade item\r
- $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));\r
-\r
- // Get grade\r
- $gradeentry = $DB->get_record('grade_grades', array('userid' => $id, 'itemid' => $gradeitem->id));\r
-\r
- $grade = $_POST['menu'][$id];\r
- $feedback = trim($_POST['submissioncomment'][$id]);\r
-\r
- if ((!$gradeentry) && (($grade != '-1') || ($feedback != ''))) {\r
- $newsubmission = true;\r
- } else {\r
- $newsubmission = false;\r
- }\r
-\r
- //for fast grade, we need to check if any changes take place\r
- $updatedb = false;\r
-\r
- if ($gradeentry) {\r
- if ($grading) {\r
- $grade = $_POST['menu'][$id];\r
- $updatedb = $updatedb || (($gradeentry->rawgrade != $grade) && ($gradeentry->rawgrade != '-1'));\r
- if ($grade != '-1') {\r
- $gradeentry->rawgrade = $grade;\r
- $gradeentry->finalgrade = $grade;\r
- } else {\r
- $gradeentry->rawgrade = null;\r
- $gradeentry->finalgrade = null;\r
- }\r
- } else {\r
- if (!$newsubmission) {\r
- unset($gradeentry->rawgrade); // Don't need to update this.\r
- }\r
- }\r
-\r
- if ($commenting) {\r
- $commentvalue = trim($_POST['submissioncomment'][$id]);\r
- $updatedb = $updatedb || ($gradeentry->feedback != $commentvalue);\r
- // Special case\r
- if (($gradeentry->feedback == null) && ($commentvalue == "")) {\r
- unset($gradeentry->feedback);\r
- }\r
- $gradeentry->feedback = $commentvalue;\r
- } else {\r
- unset($gradeentry->feedback); // Don't need to update this.\r
- }\r
-\r
- } else { // No previous grade entry found\r
- if ($newsubmission) {\r
- if ($grade != '-1') {\r
- $gradeentry->rawgrade = $grade;\r
- $updatedb = true;\r
- }\r
- if ($feedback != '') {\r
- $gradeentry->feedback = $feedback;\r
- $updatedb = true;\r
- }\r
- }\r
- }\r
-\r
- $gradeentry->usermodified = $USER->id;\r
- if (!$gradeentry->timecreated) {\r
- $gradeentry->timecreated = time();\r
- }\r
- $gradeentry->timemodified = time();\r
-\r
- //if it is not an update, we don't change the last modified time etc.\r
- //this will also not write into database if no submissioncomment and grade is entered.\r
- if ($updatedb) {\r
- if ($gradeentry->rawgrade == '-1') {\r
- $gradeentry->rawgrade = null;\r
- }\r
-\r
- if ($newsubmission) {\r
- if (!isset($gradeentry->feedback)) {\r
- $gradeentry->feedback = '';\r
- }\r
- $gradeentry->itemid = $gradeitem->id;\r
- $gradeentry->userid = $id;\r
- $sid = $DB->insert_record("grade_grades", $gradeentry);\r
- $gradeentry->id = $sid;\r
- } else {\r
- $DB->update_record("grade_grades", $gradeentry);\r
- }\r
-\r
- //add to log only if updating\r
- add_to_log($course->id, 'lti', 'update grades',\r
- 'submissions.php?id='.$cm->id.'&user='.$USER->id,\r
- $USER->id, $cm->id);\r
- }\r
-\r
- }\r
-\r
- $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');\r
-\r
- lti_display_submissions($cm, $course, $basiclti, $message);\r
- break;\r
-\r
- case 'saveandnext':\r
- ///We are in pop up. save the current one and go to the next one.\r
- //first we save the current changes\r
- if ($submission = process_feedback()) {\r
- //print_heading(get_string('changessaved'));\r
- //$extra_javascript = $this->update_main_listing($submission);\r
- }\r
-\r
- case 'next':\r
- /// We are currently in pop up, but we want to skip to next one without saving.\r
- /// This turns out to be similar to a single case\r
- /// The URL used is for the next submission.\r
- $offset = required_param('offset', PARAM_INT);\r
- $nextid = required_param('nextid', PARAM_INT);\r
- $id = required_param('id', PARAM_INT);\r
- $offset = (int)$offset+1;\r
- //$this->display_submission($offset+1 , $nextid);\r
- redirect('submissions.php?id='.$id.'&userid='. $nextid . '&mode=single&offset='.$offset);\r
- break;\r
-\r
- case 'singlenosave':\r
- display_submission();\r
- break;\r
-\r
- default:\r
- echo "Critical error. Something is seriously wrong!!";\r
- break;\r
- }\r
-}\r
-\r
-/**\r
- * Display all the submissions ready for grading\r
- *\r
- * @global object\r
- * @global object\r
- * @global object\r
- * @global object\r
- * @param string $message\r
- * @return bool|void\r
- */\r
-function lti_display_submissions($cm, $course, $basiclti, $message='') {\r
- global $CFG, $DB, $OUTPUT, $PAGE;\r
- require_once($CFG->libdir.'/gradelib.php');\r
-\r
- /* first we check to see if the form has just been submitted\r
- * to request user_preference updates\r
- */\r
- $updatepref = optional_param('updatepref', 0, PARAM_INT);\r
-\r
- if (isset($_POST['updatepref'])) {\r
- $perpage = optional_param('perpage', 10, PARAM_INT);\r
- $perpage = ($perpage <= 0) ? 10 : $perpage;\r
- $filter = optional_param('filter', 0, PARAM_INT);\r
- set_user_preference('lti_perpage', $perpage);\r
- set_user_preference('lti_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL));\r
- set_user_preference('lti_filter', $filter);\r
- }\r
-\r
- /* next we get perpage and quickgrade (allow quick grade) params\r
- * from database\r
- */\r
- $perpage = get_user_preferences('lti_perpage', 10);\r
- $quickgrade = get_user_preferences('lti_quickgrade', 0);\r
- $filter = get_user_preferences('lti_filter', 0);\r
- $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id);\r
-\r
- if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {\r
- $uses_outcomes = true;\r
- } else {\r
- $uses_outcomes = false;\r
- }\r
-\r
- $page = optional_param('page', 0, PARAM_INT);\r
- $strsaveallfeedback = get_string('saveallfeedback', 'lti');\r
-\r
- $tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet\r
- add_to_log($course->id, 'lti', 'view submission', 'submissions.php?id='.$cm->id, $basiclti->id, $cm->id);\r
-\r
- $PAGE->set_title(format_string($basiclti->name, true));\r
- $PAGE->set_heading($course->fullname);\r
- echo $OUTPUT->header();\r
-\r
- echo '<div class="usersubmissions">';\r
-\r
- //hook to allow plagiarism plugins to update status/print links.\r
- plagiarism_update_status($course, $cm);\r
-\r
- /// Print quickgrade form around the table\r
- if ($quickgrade) {\r
- $formattrs = array();\r
- $formattrs['action'] = new moodle_url('/mod/lti/submissions.php');\r
- $formattrs['id'] = 'fastg';\r
- $formattrs['method'] = 'post';\r
-\r
- echo html_writer::start_tag('form', $formattrs);\r
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'id', 'value'=> $cm->id));\r
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'mode', 'value'=> 'fastgrade'));\r
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'page', 'value'=> $page));\r
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=> sesskey()));\r
- }\r
-\r
- $course_context = get_context_instance(CONTEXT_COURSE, $course->id);\r
- if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {\r
- echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">'\r
- . get_string('seeallcoursegrades', 'grades') . '</a></div>';\r
- }\r
-\r
- if (!empty($message)) {\r
- echo $message; // display messages here if any\r
- }\r
-\r
- $context = get_context_instance(CONTEXT_MODULE, $cm->id);\r
-\r
-/// Check to see if groups are being used in this tool\r
-\r
- /// find out current groups mode\r
- $groupmode = groups_get_activity_groupmode($cm);\r
- $currentgroup = groups_get_activity_group($cm, true);\r
- groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/lti/submissions.php?id=' . $cm->id);\r
-\r
- /// Get all ppl that are allowed to submit tools\r
- list($esql, $params) = get_enrolled_sql($context, 'mod/lti:view', $currentgroup);\r
-\r
- $sql = "SELECT u.id FROM {user} u ".\r
- "LEFT JOIN ($esql) eu ON eu.id=u.id ".\r
- "WHERE u.deleted = 0 AND eu.id=u.id ";\r
-\r
- $users = $DB->get_records_sql($sql, $params);\r
- if (!empty($users)) {\r
- $users = array_keys($users);\r
- }\r
-\r
- // if groupmembersonly used, remove users who are not in any group\r
- if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) {\r
- if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) {\r
- $users = array_intersect($users, array_keys($groupingusers));\r
- }\r
- }\r
-\r
- $tablecolumns = array('picture', 'fullname', 'grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade');\r
- if ($uses_outcomes) {\r
- $tablecolumns[] = 'outcome'; // no sorting based on outcomes column\r
- }\r
-\r
- $tableheaders = array('',\r
- get_string('fullname'),\r
- get_string('grade'),\r
- get_string('comment', 'lti'),\r
- get_string('lastmodified').' ('.get_string('submission', 'lti').')',\r
- get_string('lastmodified').' ('.get_string('grade').')',\r
- get_string('status'),\r
- get_string('finalgrade', 'grades'));\r
- if ($uses_outcomes) {\r
- $tableheaders[] = get_string('outcome', 'grades');\r
- }\r
-\r
- require_once($CFG->libdir.'/tablelib.php');\r
- $table = new flexible_table('mod-lti-submissions');\r
-\r
- $table->define_columns($tablecolumns);\r
- $table->define_headers($tableheaders);\r
- $table->define_baseurl($CFG->wwwroot.'/mod/lti/submissions.php?id='.$cm->id.'&currentgroup='.$currentgroup);\r
-\r
- $table->sortable(true, 'lastname');//sorted by lastname by default\r
- $table->collapsible(true);\r
- $table->initialbars(true);\r
-\r
- $table->column_suppress('picture');\r
- $table->column_suppress('fullname');\r
-\r
- $table->column_class('picture', 'picture');\r
- $table->column_class('fullname', 'fullname');\r
- $table->column_class('grade', 'grade');\r
- $table->column_class('submissioncomment', 'comment');\r
- $table->column_class('timemodified', 'timemodified');\r
- $table->column_class('timemarked', 'timemarked');\r
- $table->column_class('status', 'status');\r
- $table->column_class('finalgrade', 'finalgrade');\r
- if ($uses_outcomes) {\r
- $table->column_class('outcome', 'outcome');\r
- }\r
-\r
- $table->set_attribute('cellspacing', '0');\r
- $table->set_attribute('id', 'attempts');\r
- $table->set_attribute('class', 'submissions');\r
- $table->set_attribute('width', '100%');\r
-\r
- $table->no_sorting('finalgrade');\r
- $table->no_sorting('outcome');\r
-\r
- // Start working -- this is necessary as soon as the niceties are over\r
- $table->setup();\r
-\r
- if (empty($users)) {\r
- echo $OUTPUT->heading(get_string('noviewusers', 'lti'));\r
- echo '</div>';\r
- return true;\r
- }\r
-\r
- /// Construct the SQL\r
- list($where, $params) = $table->get_sql_where();\r
- if ($where) {\r
- $where .= ' AND ';\r
- }\r
-\r
- if ($sort = $table->get_sql_sort()) {\r
- $sort = ' ORDER BY '.$sort;\r
- }\r
-\r
- $ufields = user_picture::fields('u');\r
-\r
- $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));\r
-\r
- $select = "SELECT $ufields,\r
- g.rawgrade, g.feedback,\r
- g.timemodified, g.timecreated ";\r
-\r
- $sql = 'FROM {user} u'.\r
- ' LEFT JOIN {grade_grades} g ON u.id = g.userid AND g.itemid = '.$gradeitem->id.\r
- ' LEFT JOIN {grade_items} i ON g.itemid = i.id'.\r
- ' AND i.iteminstance = '.$basiclti->id.\r
- ' WHERE '.$where.'u.id IN ('.implode(',', $users).') ';\r
-\r
- $ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size());\r
-\r
- $table->pagesize($perpage, count($users));\r
-\r
- ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next\r
- $offset = $page * $perpage;\r
- $strupdate = get_string('update');\r
- $strgrade = get_string('grade');\r
- $grademenu = make_grades_menu($basiclti->grade);\r
- if ($ausers !== false) {\r
- $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id, array_keys($ausers));\r
- $endposition = $offset + $perpage;\r
- $currentposition = 0;\r
- foreach ($ausers as $auser) {\r
-\r
- if ($auser->timemodified > 0) {\r
- $timemodified = '<div id="ts'.$auser->id.'">'.userdate($auser->timemodified).'</div>';\r
- } else {\r
- $timemodified = '<div id="ts'.$auser->id.'"> </div>';\r
- }\r
- if ($auser->timecreated > 0) {\r
- $timecreated = '<div id="ts'.$auser->id.'">'.userdate($auser->timecreated).'</div>';\r
- } else {\r
- $timecreated = '<div id="ts'.$auser->id.'"> </div>';\r
- }\r
-\r
- if ($currentposition == $offset && $offset < $endposition) {\r
- $final_grade = $grading_info->items[0]->grades[$auser->id];\r
- $grademax = $grading_info->items[0]->grademax;\r
- $final_grade->formatted_grade = round($final_grade->grade, 2) .' / ' . round($grademax, 2);\r
- $locked_overridden = 'locked';\r
- if ($final_grade->overridden) {\r
- $locked_overridden = 'overridden';\r
- }\r
-\r
- /// Calculate user status\r
- $picture = $OUTPUT->user_picture($auser);\r
-\r
- $studentmodified = '<div id="ts'.$auser->id.'"> </div>';\r
- $teachermodified = '<div id="tt'.$auser->id.'"> </div>';\r
- $status = '<div id="st'.$auser->id.'"> </div>';\r
-\r
- if ($final_grade->locked or $final_grade->overridden) {\r
- $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';\r
- } else if ($quickgrade) { // allow editing\r
- $attributes = array();\r
- $attributes['tabindex'] = $tabindex++;\r
- if ($auser->rawgrade != "") {\r
- $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', round($auser->rawgrade, 0), array(-1=>get_string('nograde')), $attributes);\r
- } else {\r
- $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', -1, array(-1=>get_string('nograde')), $attributes);\r
- }\r
- $grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';\r
- } else if ($final_grade->grade) {\r
- if ($auser->rawgrade != "") {\r
- $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade.'</div>';\r
- } else {\r
- $grade = '<div id="g'.$auser->id.'">-1</div>';\r
- }\r
-\r
- } else {\r
- $grade = '<div id="g'.$auser->id.'">No Grade</div>';\r
- }\r
-\r
- if ($final_grade->locked or $final_grade->overridden) {\r
- $comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';\r
- } else if ($quickgrade) {\r
- $comment = '<div id="com'.$auser->id.'">'\r
- . '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'\r
- . $auser->id.'" rows="2" cols="20">'.($auser->feedback).'</textarea></div>';\r
- } else {\r
- $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->feedback), 15).'</div>';\r
- }\r
-\r
- if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1\r
- $auser->status = 0;\r
- } else {\r
- $auser->status = 1;\r
- }\r
-\r
- $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;\r
-\r
- ///No more buttons, we use popups ;-).\r
- $popup_url = '/mod/lti/submissions.php?id='.$cm->id\r
- . '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&offset='.$offset++;\r
-\r
- $button = $OUTPUT->action_link($popup_url, $buttontext);\r
-\r
- $status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';\r
-\r
- $finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';\r
-\r
- $outcomes = '';\r
-\r
- if ($uses_outcomes) {\r
-\r
- foreach ($grading_info->outcomes as $n => $outcome) {\r
- $outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';\r
- $options = make_grades_menu(-$outcome->scaleid);\r
-\r
- if ($outcome->grades[$auser->id]->locked or !$quickgrade) {\r
- $options[0] = get_string('nooutcome', 'grades');\r
- $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';\r
- } else {\r
- $attributes = array();\r
- $attributes['tabindex'] = $tabindex++;\r
- $attributes['id'] = 'outcome_'.$n.'_'.$auser->id;\r
- $outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);\r
- }\r
- $outcomes .= '</div>';\r
- }\r
- }\r
-\r
- $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $context)) . '</a>';\r
- $row = array($picture, $userlink, $grade, $comment, $timemodified, $timecreated, $status, $finalgrade);\r
- if ($uses_outcomes) {\r
- $row[] = $outcomes;\r
- }\r
-\r
- $table->add_data($row);\r
- }\r
- $currentposition++;\r
- }\r
- }\r
-\r
- $table->print_html(); /// Print the whole table\r
-\r
- /// Print quickgrade form around the table\r
- if ($quickgrade && $table->started_output) {\r
- $mailinfopref = false;\r
- if (get_user_preferences('lti_mailinfo', 1)) {\r
- $mailinfopref = true;\r
- }\r
- $emailnotification = html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enableemailnotification', 'lti'));\r
-\r
- $emailnotification .= $OUTPUT->help_icon('enableemailnotification', 'lti');\r
- echo html_writer::tag('div', $emailnotification, array('class'=>'emailnotification'));\r
-\r
- $savefeedback = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'fastg', 'value'=>get_string('saveallfeedback', 'lti')));\r
- echo html_writer::tag('div', $savefeedback, array('class'=>'fastgbutton'));\r
-\r
- echo html_writer::end_tag('form');\r
- } else if ($quickgrade) {\r
- echo html_writer::end_tag('form');\r
- }\r
-\r
- echo '</div>';\r
- /// End of fast grading form\r
-\r
- /// Mini form for setting user preference\r
-\r
- $formaction = new moodle_url('/mod/lti/submissions.php', array('id'=>$cm->id));\r
- $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class'=>'optionspref'));\r
-\r
- $mform->addElement('hidden', 'updatepref');\r
- $mform->setDefault('updatepref', 1);\r
- $mform->addElement('header', 'qgprefs', get_string('optionalsettings', 'lti'));\r
-// $mform->addElement('select', 'filter', get_string('show'), $filters);\r
-\r
- $mform->setDefault('filter', $filter);\r
-\r
- $mform->addElement('text', 'perpage', get_string('pagesize', 'lti'), array('size'=>1));\r
- $mform->setDefault('perpage', $perpage);\r
-\r
- $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade', 'lti'));\r
- $mform->setDefault('quickgrade', $quickgrade);\r
- $mform->addHelpButton('quickgrade', 'quickgrade', 'lti');\r
-\r
- $mform->addElement('submit', 'savepreferences', get_string('savepreferences'));\r
-\r
- $mform->display();\r
-\r
- echo $OUTPUT->footer();\r
-}\r
-\r
-/**\r
- * Create grade item for given basiclti\r
- *\r
- * @param object $basiclti object with extra cmidnumber\r
- * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook\r
- * @return int 0 if ok, error code otherwise\r
- */\r
-function lti_grade_item_update($basiclti, $grades=null) {\r
- global $CFG;\r
- require_once($CFG->libdir.'/gradelib.php');\r
-\r
- $params = array('itemname'=>$basiclti->name, 'idnumber'=>$basiclti->cmidnumber);\r
-\r
- if ($basiclti->grade > 0) {\r
- $params['gradetype'] = GRADE_TYPE_VALUE;\r
- $params['grademax'] = $basiclti->grade;\r
- $params['grademin'] = 0;\r
-\r
- } else if ($basiclti->grade < 0) {\r
- $params['gradetype'] = GRADE_TYPE_SCALE;\r
- $params['scaleid'] = -$basiclti->grade;\r
-\r
- } else {\r
- $params['gradetype'] = GRADE_TYPE_TEXT; // allow text comments only\r
- }\r
-\r
- if ($grades === 'reset') {\r
- $params['reset'] = true;\r
- $grades = null;\r
- }\r
-\r
- return grade_update('mod/lti', $basiclti->course, 'mod', 'lti', $basiclti->id, 0, $grades, $params);\r
-}\r
-\r
-/**\r
- * Delete grade item for given basiclti\r
- *\r
- * @param object $basiclti object\r
- * @return object basiclti\r
- */\r
-function lti_grade_item_delete($basiclti) {\r
- global $CFG;\r
- require_once($CFG->libdir.'/gradelib.php');\r
-\r
- return grade_update('mod/lti', $basiclti->course, 'mod', 'lti', $basiclti->id, 0, null, array('deleted'=>1));\r
-}\r
-\r
+<?php
+// This file is part of BasicLTI4Moodle
+//
+// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
+// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
+// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
+// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
+// are already supporting or going to support BasicLTI. This project Implements the consumer
+// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
+// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
+// at the GESSI research group at UPC.
+// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
+// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
+// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
+//
+// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
+// of the Universitat Politecnica de Catalunya http://www.upc.edu
+// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu
+//
+// 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 a library of functions and constants for the
+ * BasicLTI module
+ *
+ * @package lti
+ * @copyright 2009 Marc Alier, Jordi Piguillem, Nikolas Galanis
+ * marc.alier@upc.edu
+ * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
+ *
+ * @author Marc Alier
+ * @author Jordi Piguillem
+ * @author Nikolas Galanis
+ *
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+require_once($CFG->dirroot.'/mod/lti/locallib.php');
+
+/**
+ * List of features supported in URL module
+ * @param string $feature FEATURE_xx constant for requested feature
+ * @return mixed True if module supports feature, false if not, null if doesn't know
+ */
+function lti_supports($feature) {
+ switch($feature) {
+ case FEATURE_GROUPS: return false;
+ case FEATURE_GROUPINGS: return false;
+ case FEATURE_GROUPMEMBERSONLY: return true;
+ case FEATURE_MOD_INTRO: return true;
+ case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
+ case FEATURE_GRADE_HAS_GRADE: return true;
+ case FEATURE_GRADE_OUTCOMES: return true;
+ case FEATURE_BACKUP_MOODLE2: return true;
+
+ default: return null;
+ }
+}
+
+/**
+ * Given an object containing all the necessary data,
+ * (defined by the form in mod.html) this function
+ * will create a new instance and return the id number
+ * of the new instance.
+ *
+ * @param object $instance An object from the form in mod.html
+ * @return int The id of the newly inserted basiclti record
+ **/
+function lti_add_instance($formdata) {
+ global $DB;
+ $formdata->timecreated = time();
+ $formdata->timemodified = $formdata->timecreated;
+ $formdata->servicesalt = uniqid('', true);
+
+ if(!isset($formdata->grade)){
+ $formdata->grade = 100;
+ }
+
+ $id = $DB->insert_record("lti", $formdata);
+
+ if ($formdata->instructorchoiceacceptgrades == 1) {
+ $basiclti = $DB->get_record('lti', array('id'=>$id));
+ $basiclti->cmidnumber = $formdata->cmidnumber;
+
+ lti_grade_item_update($basiclti);
+ }
+
+ return $id;
+}
+
+/**
+ * Given an object containing all the necessary data,
+ * (defined by the form in mod.html) this function
+ * will update an existing instance with new data.
+ *
+ * @param object $instance An object from the form in mod.html
+ * @return boolean Success/Fail
+ **/
+function lti_update_instance($formdata) {
+ global $DB;
+
+ $formdata->timemodified = time();
+ $formdata->id = $formdata->instance;
+
+ if(!isset($formdata->showtitle)){
+ $formdata->showtitle = 0;
+ }
+
+ if(!isset($formdata->showdescription)){
+ $formdata->showdescription = 0;
+ }
+
+ if ($formdata->instructorchoiceacceptgrades == 1) {
+ $basicltirec = $DB->get_record("lti", array("id" => $formdata->id));
+ $basicltirec->cmidnumber = $formdata->cmidnumber;
+
+ lti_grade_item_update($basicltirec);
+ } else {
+ lti_grade_item_delete($formdata);
+ }
+
+ return $DB->update_record("lti", $formdata);
+}
+
+/**
+ * Given an ID of an instance of this module,
+ * this function will permanently delete the instance
+ * and any data that depends on it.
+ *
+ * @param int $id Id of the module instance
+ * @return boolean Success/Failure
+ **/
+function lti_delete_instance($id) {
+ global $DB;
+
+ if (! $basiclti = $DB->get_record("lti", array("id" => $id))) {
+ return false;
+ }
+
+ $result = true;
+
+ # Delete any dependent records here #
+ lti_grade_item_delete($basiclti);
+
+ return $DB->delete_records("lti", array("id" => $basiclti->id));
+}
+
+/**
+ * Return a small object with summary information about what a
+ * user has done with a given particular instance of this module
+ * Used for user activity reports.
+ * $return->time = the time they did it
+ * $return->info = a short text description
+ *
+ * @return null
+ * @TODO: implement this moodle function (if needed)
+ **/
+function lti_user_outline($course, $user, $mod, $basiclti) {
+ return $return;
+}
+
+/**
+ * Print a detailed representation of what a user has done with
+ * a given particular instance of this module, for user activity reports.
+ *
+ * @return boolean
+ * @TODO: implement this moodle function (if needed)
+ **/
+function lti_user_complete($course, $user, $mod, $basiclti) {
+ return true;
+}
+
+/**
+ * Given a course and a time, this module should find recent activity
+ * that has occurred in basiclti activities and print it out.
+ * Return true if there was output, or false is there was none.
+ *
+ * @uses $CFG
+ * @return boolean
+ * @TODO: implement this moodle function
+ **/
+function lti_print_recent_activity($course, $isteacher, $timestart) {
+ return false; // True if anything was printed, otherwise false
+}
+
+/**
+ * Function to be run periodically according to the moodle cron
+ * This function searches for things that need to be done, such
+ * as sending out mail, toggling flags etc ...
+ *
+ * @uses $CFG
+ * @return boolean
+ **/
+function lti_cron () {
+ return true;
+}
+
+/**
+ * Must return an array of grades for a given instance of this module,
+ * indexed by user. It also returns a maximum allowed grade.
+ *
+ * Example:
+ * $return->grades = array of grades;
+ * $return->maxgrade = maximum allowed grade;
+ *
+ * return $return;
+ *
+ * @param int $basicltiid ID of an instance of this module
+ * @return mixed Null or object with an array of grades and with the maximum grade
+ *
+ * @TODO: implement this moodle function (if needed)
+ **/
+function lti_grades($basicltiid) {
+ return null;
+}
+
+/**
+ * Must return an array of user records (all data) who are participants
+ * for a given instance of basiclti. Must include every user involved
+ * in the instance, independient of his role (student, teacher, admin...)
+ * See other modules as example.
+ *
+ * @param int $basicltiid ID of an instance of this module
+ * @return mixed boolean/array of students
+ *
+ * @TODO: implement this moodle function
+ **/
+function lti_get_participants($basicltiid) {
+ return false;
+}
+
+/**
+ * This function returns if a scale is being used by one basiclti
+ * it it has support for grading and scales. Commented code should be
+ * modified if necessary. See forum, glossary or journal modules
+ * as reference.
+ *
+ * @param int $basicltiid ID of an instance of this module
+ * @return mixed
+ *
+ * @TODO: implement this moodle function (if needed)
+ **/
+function lti_scale_used ($basicltiid, $scaleid) {
+ $return = false;
+
+ //$rec = get_record("basiclti","id","$basicltiid","scale","-$scaleid");
+ //
+ //if (!empty($rec) && !empty($scaleid)) {
+ // $return = true;
+ //}
+
+ return $return;
+}
+
+/**
+ * Checks if scale is being used by any instance of basiclti.
+ * This function was added in 1.9
+ *
+ * This is used to find out if scale used anywhere
+ * @param $scaleid int
+ * @return boolean True if the scale is used by any basiclti
+ *
+ */
+function lti_scale_used_anywhere($scaleid) {
+ global $DB;
+
+ if ($scaleid and $DB->record_exists('lti', array('grade' => -$scaleid))) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Execute post-install custom actions for the module
+ * This function was added in 1.9
+ *
+ * @return boolean true if success, false on error
+ */
+function lti_install() {
+ return true;
+}
+
+/**
+ * Execute post-uninstall custom actions for the module
+ * This function was added in 1.9
+ *
+ * @return boolean true if success, false on error
+ */
+function lti_uninstall() {
+ return true;
+}
+
+/**
+ * Returns available Basic LTI types
+ *
+ * @return array of basicLTI types
+ */
+function lti_get_lti_types() {
+ global $DB;
+
+ return $DB->get_records('lti_types');
+}
+
+/**
+ * Returns Basic LTI types configuration
+ *
+ * @return array of basicLTI types
+ */
+/*function lti_get_types() {
+ $types = array();
+
+ $basicltitypes = lti_get_lti_types();
+ if (!empty($basicltitypes)) {
+ foreach ($basicltitypes as $basicltitype) {
+ $ltitypesconfig = lti_get_type_config($basicltitype->id);
+
+ $modclass = MOD_CLASS_ACTIVITY;
+ if (isset($ltitypesconfig['module_class_type'])) {
+ if ($ltitypesconfig['module_class_type']=='1') {
+ $modclass = MOD_CLASS_RESOURCE;
+ }
+ }
+
+ $type = new object();
+ $type->modclass = $modclass;
+ $type->type = 'lti&type='.urlencode($basicltitype->rawname);
+ $type->typestr = $basicltitype->name;
+ $types[] = $type;
+ }
+ }
+
+ return $types;
+}*/
+
+//////////////////////////////////////////////////////////////////////////////////////
+/// Any other basiclti functions go here. Each of them must have a name that
+/// starts with basiclti_
+/// Remember (see note in first lines) that, if this section grows, it's HIGHLY
+/// recommended to move all funcions below to a new "localib.php" file.
+
+///**
+// *
+// */
+//function process_outcomes($userid, $course, $basiclti) {
+// global $CFG, $USER;
+//
+// if (empty($CFG->enableoutcomes)) {
+// return;
+// }
+//
+// require_once($CFG->libdir.'/gradelib.php');
+//
+// if (!$formdata = data_submitted() or !confirm_sesskey()) {
+// return;
+// }
+//
+// $data = array();
+// $grading_info = grade_get_grades($course->id, 'mod', 'basiclti', $basiclti->id, $userid);
+//
+// if (!empty($grading_info->outcomes)) {
+// foreach ($grading_info->outcomes as $n => $old) {
+// $name = 'outcome_'.$n;
+// if (isset($formdata->{$name}[$userid]) and $old->grades[$userid]->grade != $formdata->{$name}[$userid]) {
+// $data[$n] = $formdata->{$name}[$userid];
+// }
+// }
+// }
+// if (count($data) > 0) {
+// grade_update_outcomes('mod/basiclti', $course->id, 'mod', 'basiclti', $basiclti->id, $userid, $data);
+// }
+//
+//}
+
+/**
+ * Top-level function for handling of submissions called by submissions.php
+ *
+ * This is for handling the teacher interaction with the grading interface
+ *
+ * @global object
+ * @param string $mode Specifies the kind of teacher interaction taking place
+ */
+function lti_submissions($cm, $course, $basiclti, $mode) {
+ ///The main switch is changed to facilitate
+ ///1) Batch fast grading
+ ///2) Skip to the next one on the popup
+ ///3) Save and Skip to the next one on the popup
+
+ //make user global so we can use the id
+ global $USER, $OUTPUT, $DB;
+
+ $mailinfo = optional_param('mailinfo', null, PARAM_BOOL);
+
+ if (optional_param('next', null, PARAM_BOOL)) {
+ $mode='next';
+ }
+ if (optional_param('saveandnext', null, PARAM_BOOL)) {
+ $mode='saveandnext';
+ }
+
+ if (is_null($mailinfo)) {
+ if (optional_param('sesskey', null, PARAM_BOOL)) {
+ set_user_preference('lti_mailinfo', $mailinfo);
+ } else {
+ $mailinfo = get_user_preferences('lti_mailinfo', 0);
+ }
+ } else {
+ set_user_preference('lti_mailinfo', $mailinfo);
+ }
+
+ switch ($mode) {
+ case 'grade': // We are in a main window grading
+ if ($submission = process_feedback()) {
+ lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));
+ } else {
+ lti_display_submissions($cm, $course, $basiclti);
+ }
+ break;
+
+ case 'single': // We are in a main window displaying one submission
+ if ($submission = process_feedback()) {
+ lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));
+ } else {
+ display_submission();
+ }
+ break;
+
+ case 'all': // Main window, display everything
+ lti_display_submissions($cm, $course, $basiclti);
+ break;
+
+ case 'fastgrade':
+ /// do the fast grading stuff - this process should work for all 3 subclasses
+ $grading = false;
+ $commenting = false;
+ $col = false;
+ if (isset($_POST['submissioncomment'])) {
+ $col = 'submissioncomment';
+ $commenting = true;
+ }
+ if (isset($_POST['menu'])) {
+ $col = 'menu';
+ $grading = true;
+ }
+ if (!$col) {
+ //both submissioncomment and grade columns collapsed..
+ lti_display_submissions($cm, $course, $basiclti);
+ break;
+ }
+
+ foreach ($_POST[$col] as $id => $unusedvalue) {
+
+ $id = (int)$id; //clean parameter name
+
+ // Get grade item
+ $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));
+
+ // Get grade
+ $gradeentry = $DB->get_record('grade_grades', array('userid' => $id, 'itemid' => $gradeitem->id));
+
+ $grade = $_POST['menu'][$id];
+ $feedback = trim($_POST['submissioncomment'][$id]);
+
+ if ((!$gradeentry) && (($grade != '-1') || ($feedback != ''))) {
+ $newsubmission = true;
+ } else {
+ $newsubmission = false;
+ }
+
+ //for fast grade, we need to check if any changes take place
+ $updatedb = false;
+
+ if ($gradeentry) {
+ if ($grading) {
+ $grade = $_POST['menu'][$id];
+ $updatedb = $updatedb || (($gradeentry->rawgrade != $grade) && ($gradeentry->rawgrade != '-1'));
+ if ($grade != '-1') {
+ $gradeentry->rawgrade = $grade;
+ $gradeentry->finalgrade = $grade;
+ } else {
+ $gradeentry->rawgrade = null;
+ $gradeentry->finalgrade = null;
+ }
+ } else {
+ if (!$newsubmission) {
+ unset($gradeentry->rawgrade); // Don't need to update this.
+ }
+ }
+
+ if ($commenting) {
+ $commentvalue = trim($_POST['submissioncomment'][$id]);
+ $updatedb = $updatedb || ($gradeentry->feedback != $commentvalue);
+ // Special case
+ if (($gradeentry->feedback == null) && ($commentvalue == "")) {
+ unset($gradeentry->feedback);
+ }
+ $gradeentry->feedback = $commentvalue;
+ } else {
+ unset($gradeentry->feedback); // Don't need to update this.
+ }
+
+ } else { // No previous grade entry found
+ if ($newsubmission) {
+ if ($grade != '-1') {
+ $gradeentry->rawgrade = $grade;
+ $updatedb = true;
+ }
+ if ($feedback != '') {
+ $gradeentry->feedback = $feedback;
+ $updatedb = true;
+ }
+ }
+ }
+
+ $gradeentry->usermodified = $USER->id;
+ if (!$gradeentry->timecreated) {
+ $gradeentry->timecreated = time();
+ }
+ $gradeentry->timemodified = time();
+
+ //if it is not an update, we don't change the last modified time etc.
+ //this will also not write into database if no submissioncomment and grade is entered.
+ if ($updatedb) {
+ if ($gradeentry->rawgrade == '-1') {
+ $gradeentry->rawgrade = null;
+ }
+
+ if ($newsubmission) {
+ if (!isset($gradeentry->feedback)) {
+ $gradeentry->feedback = '';
+ }
+ $gradeentry->itemid = $gradeitem->id;
+ $gradeentry->userid = $id;
+ $sid = $DB->insert_record("grade_grades", $gradeentry);
+ $gradeentry->id = $sid;
+ } else {
+ $DB->update_record("grade_grades", $gradeentry);
+ }
+
+ //add to log only if updating
+ add_to_log($course->id, 'lti', 'update grades',
+ 'submissions.php?id='.$cm->id.'&user='.$USER->id,
+ $USER->id, $cm->id);
+ }
+
+ }
+
+ $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
+
+ lti_display_submissions($cm, $course, $basiclti, $message);
+ break;
+
+ case 'saveandnext':
+ ///We are in pop up. save the current one and go to the next one.
+ //first we save the current changes
+ if ($submission = process_feedback()) {
+ //print_heading(get_string('changessaved'));
+ //$extra_javascript = $this->update_main_listing($submission);
+ }
+
+ case 'next':
+ /// We are currently in pop up, but we want to skip to next one without saving.
+ /// This turns out to be similar to a single case
+ /// The URL used is for the next submission.
+ $offset = required_param('offset', PARAM_INT);
+ $nextid = required_param('nextid', PARAM_INT);
+ $id = required_param('id', PARAM_INT);
+ $offset = (int)$offset+1;
+ //$this->display_submission($offset+1 , $nextid);
+ redirect('submissions.php?id='.$id.'&userid='. $nextid . '&mode=single&offset='.$offset);
+ break;
+
+ case 'singlenosave':
+ display_submission();
+ break;
+
+ default:
+ echo "Critical error. Something is seriously wrong!!";
+ break;
+ }
+}
+
+/**
+ * Display all the submissions ready for grading
+ *
+ * @global object
+ * @global object
+ * @global object
+ * @global object
+ * @param string $message
+ * @return bool|void
+ */
+function lti_display_submissions($cm, $course, $basiclti, $message='') {
+ global $CFG, $DB, $OUTPUT, $PAGE;
+ require_once($CFG->libdir.'/gradelib.php');
+
+ /* first we check to see if the form has just been submitted
+ * to request user_preference updates
+ */
+ $updatepref = optional_param('updatepref', 0, PARAM_INT);
+
+ if (isset($_POST['updatepref'])) {
+ $perpage = optional_param('perpage', 10, PARAM_INT);
+ $perpage = ($perpage <= 0) ? 10 : $perpage;
+ $filter = optional_param('filter', 0, PARAM_INT);
+ set_user_preference('lti_perpage', $perpage);
+ set_user_preference('lti_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL));
+ set_user_preference('lti_filter', $filter);
+ }
+
+ /* next we get perpage and quickgrade (allow quick grade) params
+ * from database
+ */
+ $perpage = get_user_preferences('lti_perpage', 10);
+ $quickgrade = get_user_preferences('lti_quickgrade', 0);
+ $filter = get_user_preferences('lti_filter', 0);
+ $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id);
+
+ if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {
+ $uses_outcomes = true;
+ } else {
+ $uses_outcomes = false;
+ }
+
+ $page = optional_param('page', 0, PARAM_INT);
+ $strsaveallfeedback = get_string('saveallfeedback', 'lti');
+
+ $tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet
+ add_to_log($course->id, 'lti', 'view submission', 'submissions.php?id='.$cm->id, $basiclti->id, $cm->id);
+
+ $PAGE->set_title(format_string($basiclti->name, true));
+ $PAGE->set_heading($course->fullname);
+ echo $OUTPUT->header();
+
+ echo '<div class="usersubmissions">';
+
+ //hook to allow plagiarism plugins to update status/print links.
+ plagiarism_update_status($course, $cm);
+
+ /// Print quickgrade form around the table
+ if ($quickgrade) {
+ $formattrs = array();
+ $formattrs['action'] = new moodle_url('/mod/lti/submissions.php');
+ $formattrs['id'] = 'fastg';
+ $formattrs['method'] = 'post';
+
+ echo html_writer::start_tag('form', $formattrs);
+ echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'id', 'value'=> $cm->id));
+ echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'mode', 'value'=> 'fastgrade'));
+ echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'page', 'value'=> $page));
+ echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=> sesskey()));
+ }
+
+ $course_context = get_context_instance(CONTEXT_COURSE, $course->id);
+ if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
+ echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">'
+ . get_string('seeallcoursegrades', 'grades') . '</a></div>';
+ }
+
+ if (!empty($message)) {
+ echo $message; // display messages here if any
+ }
+
+ $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+/// Check to see if groups are being used in this tool
+
+ /// find out current groups mode
+ $groupmode = groups_get_activity_groupmode($cm);
+ $currentgroup = groups_get_activity_group($cm, true);
+ groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/lti/submissions.php?id=' . $cm->id);
+
+ /// Get all ppl that are allowed to submit tools
+ list($esql, $params) = get_enrolled_sql($context, 'mod/lti:view', $currentgroup);
+
+ $sql = "SELECT u.id FROM {user} u ".
+ "LEFT JOIN ($esql) eu ON eu.id=u.id ".
+ "WHERE u.deleted = 0 AND eu.id=u.id ";
+
+ $users = $DB->get_records_sql($sql, $params);
+ if (!empty($users)) {
+ $users = array_keys($users);
+ }
+
+ // if groupmembersonly used, remove users who are not in any group
+ if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) {
+ if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) {
+ $users = array_intersect($users, array_keys($groupingusers));
+ }
+ }
+
+ $tablecolumns = array('picture', 'fullname', 'grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade');
+ if ($uses_outcomes) {
+ $tablecolumns[] = 'outcome'; // no sorting based on outcomes column
+ }
+
+ $tableheaders = array('',
+ get_string('fullname'),
+ get_string('grade'),
+ get_string('comment', 'lti'),
+ get_string('lastmodified').' ('.get_string('submission', 'lti').')',
+ get_string('lastmodified').' ('.get_string('grade').')',
+ get_string('status'),
+ get_string('finalgrade', 'grades'));
+ if ($uses_outcomes) {
+ $tableheaders[] = get_string('outcome', 'grades');
+ }
+
+ require_once($CFG->libdir.'/tablelib.php');
+ $table = new flexible_table('mod-lti-submissions');
+
+ $table->define_columns($tablecolumns);
+ $table->define_headers($tableheaders);
+ $table->define_baseurl($CFG->wwwroot.'/mod/lti/submissions.php?id='.$cm->id.'&currentgroup='.$currentgroup);
+
+ $table->sortable(true, 'lastname');//sorted by lastname by default
+ $table->collapsible(true);
+ $table->initialbars(true);
+
+ $table->column_suppress('picture');
+ $table->column_suppress('fullname');
+
+ $table->column_class('picture', 'picture');
+ $table->column_class('fullname', 'fullname');
+ $table->column_class('grade', 'grade');
+ $table->column_class('submissioncomment', 'comment');
+ $table->column_class('timemodified', 'timemodified');
+ $table->column_class('timemarked', 'timemarked');
+ $table->column_class('status', 'status');
+ $table->column_class('finalgrade', 'finalgrade');
+ if ($uses_outcomes) {
+ $table->column_class('outcome', 'outcome');
+ }
+
+ $table->set_attribute('cellspacing', '0');
+ $table->set_attribute('id', 'attempts');
+ $table->set_attribute('class', 'submissions');
+ $table->set_attribute('width', '100%');
+
+ $table->no_sorting('finalgrade');
+ $table->no_sorting('outcome');
+
+ // Start working -- this is necessary as soon as the niceties are over
+ $table->setup();
+
+ if (empty($users)) {
+ echo $OUTPUT->heading(get_string('noviewusers', 'lti'));
+ echo '</div>';
+ return true;
+ }
+
+ /// Construct the SQL
+ list($where, $params) = $table->get_sql_where();
+ if ($where) {
+ $where .= ' AND ';
+ }
+
+ if ($sort = $table->get_sql_sort()) {
+ $sort = ' ORDER BY '.$sort;
+ }
+
+ $ufields = user_picture::fields('u');
+
+ $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));
+
+ $select = "SELECT $ufields,
+ g.rawgrade, g.feedback,
+ g.timemodified, g.timecreated ";
+
+ $sql = 'FROM {user} u'.
+ ' LEFT JOIN {grade_grades} g ON u.id = g.userid AND g.itemid = '.$gradeitem->id.
+ ' LEFT JOIN {grade_items} i ON g.itemid = i.id'.
+ ' AND i.iteminstance = '.$basiclti->id.
+ ' WHERE '.$where.'u.id IN ('.implode(',', $users).') ';
+
+ $ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size());
+
+ $table->pagesize($perpage, count($users));
+
+ ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next
+ $offset = $page * $perpage;
+ $strupdate = get_string('update');
+ $strgrade = get_string('grade');
+ $grademenu = make_grades_menu($basiclti->grade);
+ if ($ausers !== false) {
+ $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id, array_keys($ausers));
+ $endposition = $offset + $perpage;
+ $currentposition = 0;
+ foreach ($ausers as $auser) {
+
+ if ($auser->timemodified > 0) {
+ $timemodified = '<div id="ts'.$auser->id.'">'.userdate($auser->timemodified).'</div>';
+ } else {
+ $timemodified = '<div id="ts'.$auser->id.'"> </div>';
+ }
+ if ($auser->timecreated > 0) {
+ $timecreated = '<div id="ts'.$auser->id.'">'.userdate($auser->timecreated).'</div>';
+ } else {
+ $timecreated = '<div id="ts'.$auser->id.'"> </div>';
+ }
+
+ if ($currentposition == $offset && $offset < $endposition) {
+ $final_grade = $grading_info->items[0]->grades[$auser->id];
+ $grademax = $grading_info->items[0]->grademax;
+ $final_grade->formatted_grade = round($final_grade->grade, 2) .' / ' . round($grademax, 2);
+ $locked_overridden = 'locked';
+ if ($final_grade->overridden) {
+ $locked_overridden = 'overridden';
+ }
+
+ /// Calculate user status
+ $picture = $OUTPUT->user_picture($auser);
+
+ $studentmodified = '<div id="ts'.$auser->id.'"> </div>';
+ $teachermodified = '<div id="tt'.$auser->id.'"> </div>';
+ $status = '<div id="st'.$auser->id.'"> </div>';
+
+ if ($final_grade->locked or $final_grade->overridden) {
+ $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';
+ } else if ($quickgrade) { // allow editing
+ $attributes = array();
+ $attributes['tabindex'] = $tabindex++;
+ if ($auser->rawgrade != "") {
+ $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', round($auser->rawgrade, 0), array(-1=>get_string('nograde')), $attributes);
+ } else {
+ $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', -1, array(-1=>get_string('nograde')), $attributes);
+ }
+ $grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
+ } else if ($final_grade->grade) {
+ if ($auser->rawgrade != "") {
+ $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade.'</div>';
+ } else {
+ $grade = '<div id="g'.$auser->id.'">-1</div>';
+ }
+
+ } else {
+ $grade = '<div id="g'.$auser->id.'">No Grade</div>';
+ }
+
+ if ($final_grade->locked or $final_grade->overridden) {
+ $comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';
+ } else if ($quickgrade) {
+ $comment = '<div id="com'.$auser->id.'">'
+ . '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
+ . $auser->id.'" rows="2" cols="20">'.($auser->feedback).'</textarea></div>';
+ } else {
+ $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->feedback), 15).'</div>';
+ }
+
+ if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1
+ $auser->status = 0;
+ } else {
+ $auser->status = 1;
+ }
+
+ $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
+
+ ///No more buttons, we use popups ;-).
+ $popup_url = '/mod/lti/submissions.php?id='.$cm->id
+ . '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&offset='.$offset++;
+
+ $button = $OUTPUT->action_link($popup_url, $buttontext);
+
+ $status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
+
+ $finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';
+
+ $outcomes = '';
+
+ if ($uses_outcomes) {
+
+ foreach ($grading_info->outcomes as $n => $outcome) {
+ $outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';
+ $options = make_grades_menu(-$outcome->scaleid);
+
+ if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
+ $options[0] = get_string('nooutcome', 'grades');
+ $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
+ } else {
+ $attributes = array();
+ $attributes['tabindex'] = $tabindex++;
+ $attributes['id'] = 'outcome_'.$n.'_'.$auser->id;
+ $outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);
+ }
+ $outcomes .= '</div>';
+ }
+ }
+
+ $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $context)) . '</a>';
+ $row = array($picture, $userlink, $grade, $comment, $timemodified, $timecreated, $status, $finalgrade);
+ if ($uses_outcomes) {
+ $row[] = $outcomes;
+ }
+
+ $table->add_data($row);
+ }
+ $currentposition++;
+ }
+ }
+
+ $table->print_html(); /// Print the whole table
+
+ /// Print quickgrade form around the table
+ if ($quickgrade && $table->started_output) {
+ $mailinfopref = false;
+ if (get_user_preferences('lti_mailinfo', 1)) {
+ $mailinfopref = true;
+ }
+ $emailnotification = html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enableemailnotification', 'lti'));
+
+ $emailnotification .= $OUTPUT->help_icon('enableemailnotification', 'lti');
+ echo html_writer::tag('div', $emailnotification, array('class'=>'emailnotification'));
+
+ $savefeedback = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'fastg', 'value'=>get_string('saveallfeedback', 'lti')));
+ echo html_writer::tag('div', $savefeedback, array('class'=>'fastgbutton'));
+
+ echo html_writer::end_tag('form');
+ } else if ($quickgrade) {
+ echo html_writer::end_tag('form');
+ }
+
+ echo '</div>';
+ /// End of fast grading form
+
+ /// Mini form for setting user preference
+
+ $formaction = new moodle_url('/mod/lti/submissions.php', array('id'=>$cm->id));
+ $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class'=>'optionspref'));
+
+ $mform->addElement('hidden', 'updatepref');
+ $mform->setDefault('updatepref', 1);
+ $mform->addElement('header', 'qgprefs', get_string('optionalsettings', 'lti'));
+// $mform->addElement('select', 'filter', get_string('show'), $filters);
+
+ $mform->setDefault('filter', $filter);
+
+ $mform->addElement('text', 'perpage', get_string('pagesize', 'lti'), array('size'=>1));
+ $mform->setDefault('perpage', $perpage);
+
+ $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade', 'lti'));
+ $mform->setDefault('quickgrade', $quickgrade);
+ $mform->addHelpButton('quickgrade', 'quickgrade', 'lti');
+
+ $mform->addElement('submit', 'savepreferences', get_string('savepreferences'));
+
+ $mform->display();
+
+ echo $OUTPUT->footer();
+}
+
+/**
+ * Create grade item for given basiclti
+ *
+ * @param object $basiclti object with extra cmidnumber
+ * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
+ * @return int 0 if ok, error code otherwise
+ */
+function lti_grade_item_update($basiclti, $grades=null) {
+ global $CFG;
+ require_once($CFG->libdir.'/gradelib.php');
+
+ $params = array('itemname'=>$basiclti->name, 'idnumber'=>$basiclti->cmidnumber);
+
+ if ($basiclti->grade > 0) {
+ $params['gradetype'] = GRADE_TYPE_VALUE;
+ $params['grademax'] = $basiclti->grade;
+ $params['grademin'] = 0;
+
+ } else if ($basiclti->grade < 0) {
+ $params['gradetype'] = GRADE_TYPE_SCALE;
+ $params['scaleid'] = -$basiclti->grade;
+
+ } else {
+ $params['gradetype'] = GRADE_TYPE_TEXT; // allow text comments only
+ }
+
+ if ($grades === 'reset') {
+ $params['reset'] = true;
+ $grades = null;
+ }
+
+ return grade_update('mod/lti', $basiclti->course, 'mod', 'lti', $basiclti->id, 0, $grades, $params);
+}
+
+/**
+ * Delete grade item for given basiclti
+ *
+ * @param object $basiclti object
+ * @return object basiclti
+ */
+function lti_grade_item_delete($basiclti) {
+ global $CFG;
+ require_once($CFG->libdir.'/gradelib.php');
+
+ return grade_update('mod/lti', $basiclti->course, 'mod', 'lti', $basiclti->id, 0, null, array('deleted'=>1));
+}
+