2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * This file contains the moodle hooks for the assign module. It delegates most functions to the assignment class.
21 * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 defined('MOODLE_INTERNAL') || die();
27 * Adds an assignment instance
29 * This is done by calling the add_instance() method of the assignment type class
30 * @param stdClass $data
31 * @param mod_assign_mod_form $form
32 * @return int The instance id of the new assignment
34 function assign_add_instance(stdClass $data, mod_assign_mod_form $form) {
36 require_once($CFG->dirroot . '/mod/assign/locallib.php');
38 $assignment = new assign(context_module::instance($data->coursemodule), null, null);
39 return $assignment->add_instance($data, true);
43 * delete an assignment instance
47 function assign_delete_instance($id) {
49 require_once($CFG->dirroot . '/mod/assign/locallib.php');
50 $cm = get_coursemodule_from_instance('assign', $id, 0, false, MUST_EXIST);
51 $context = context_module::instance($cm->id);
53 $assignment = new assign($context, null, null);
54 return $assignment->delete_instance();
58 * Update an assignment instance
60 * This is done by calling the update_instance() method of the assignment type class
61 * @param stdClass $data
62 * @param mod_assign_mod_form $form
65 function assign_update_instance(stdClass $data, mod_assign_mod_form $form) {
67 require_once($CFG->dirroot . '/mod/assign/locallib.php');
68 $context = context_module::instance($data->coursemodule);
69 $assignment = new assign($context, null, null);
70 return $assignment->update_instance($data);
74 * Return the list if Moodle features this module supports
76 * @param string $feature FEATURE_xx constant for requested feature
77 * @return mixed True if module supports feature, null if doesn't know
79 function assign_supports($feature) {
81 case FEATURE_GROUPS: return true;
82 case FEATURE_GROUPINGS: return true;
83 case FEATURE_GROUPMEMBERSONLY: return true;
84 case FEATURE_MOD_INTRO: return true;
85 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
86 case FEATURE_COMPLETION_HAS_RULES: return true;
87 case FEATURE_GRADE_HAS_GRADE: return true;
88 case FEATURE_GRADE_OUTCOMES: return true;
89 case FEATURE_BACKUP_MOODLE2: return true;
90 case FEATURE_SHOW_DESCRIPTION: return true;
91 case FEATURE_ADVANCED_GRADING: return true;
92 case FEATURE_PLAGIARISM: return true;
99 * Lists all gradable areas for the advanced grading methods gramework
101 * @return array('string'=>'string') An array with area names as keys and descriptions as values
103 function assign_grading_areas_list() {
104 return array('submissions'=>get_string('submissions', 'assign'));
109 * extend an assigment navigation settings
111 * @param settings_navigation $settings
112 * @param navigation_node $navref
115 function assign_extend_settings_navigation(settings_navigation $settings, navigation_node $navref) {
123 $context = $cm->context;
124 $course = $PAGE->course;
133 if (has_capability('gradereport/grader:view', $cm->context) && has_capability('moodle/grade:viewall', $cm->context)) {
134 $link = new moodle_url('/grade/report/grader/index.php', array('id' => $course->id));
135 $node = $navref->add(get_string('viewgradebook', 'assign'), $link, navigation_node::TYPE_SETTING);
138 // Link to download all submissions
139 if (has_capability('mod/assign:grade', $context)) {
140 $link = new moodle_url('/mod/assign/view.php', array('id' => $cm->id,'action'=>'grading'));
141 $node = $navref->add(get_string('viewgrading', 'assign'), $link, navigation_node::TYPE_SETTING);
143 $link = new moodle_url('/mod/assign/view.php', array('id' => $cm->id,'action'=>'downloadall'));
144 $node = $navref->add(get_string('downloadall', 'assign'), $link, navigation_node::TYPE_SETTING);
151 * Add a get_coursemodule_info function in case any assignment type wants to add 'extra' information
152 * for the course (see resource).
154 * Given a course_module object, this function returns any "extra" information that may be needed
155 * when printing this activity in a course listing. See get_array_of_activities() in course/lib.php.
157 * @param stdClass $coursemodule The coursemodule object (record).
158 * @return cached_cm_info An object on information that the courses will know about (most noticeably, an icon).
160 function assign_get_coursemodule_info($coursemodule) {
163 if (! $assignment = $DB->get_record('assign', array('id'=>$coursemodule->instance),
164 'id, name, alwaysshowdescription, allowsubmissionsfromdate, intro, introformat')) {
168 $result = new cached_cm_info();
169 $result->name = $assignment->name;
170 if ($coursemodule->showdescription) {
171 if ($assignment->alwaysshowdescription || time() > $assignment->allowsubmissionsfromdate) {
172 // Convert intro to html. Do not filter cached version, filters run at display time.
173 $result->content = format_module_intro('assign', $assignment, $coursemodule->id, false);
181 * Return a list of page types
182 * @param string $pagetype current page type
183 * @param stdClass $parentcontext Block's parent context
184 * @param stdClass $currentcontext Current context of block
186 function assign_page_type_list($pagetype, $parentcontext, $currentcontext) {
187 $module_pagetype = array(
188 'mod-assign-*' => get_string('page-mod-assign-x', 'assign'),
189 'mod-assign-view' => get_string('page-mod-assign-view', 'assign'),
191 return $module_pagetype;
195 * Print an overview of all assignments
198 * @param mixed $courses The list of courses to print the overview for
199 * @param array $htmlarray The array of html to return
201 function assign_print_overview($courses, &$htmlarray) {
202 global $USER, $CFG, $DB;
204 if (empty($courses) || !is_array($courses) || count($courses) == 0) {
208 if (!$assignments = get_all_instances_in_courses('assign',$courses)) {
212 $assignmentids = array();
214 // Do assignment_base::isopen() here without loading the whole thing for speed
215 foreach ($assignments as $key => $assignment) {
218 if ($assignment->duedate) {
219 $isopen = $assignment->allowsubmissionsfromdate <= $time;
220 if ($assignment->preventlatesubmissions) {
221 $isopen = ($isopen && $time <= $assignment->duedate);
225 $assignmentids[] = $assignment->id;
229 if (empty($assignmentids)){
230 // no assignments to look at - we're done
234 $strduedate = get_string('duedate', 'assign');
235 $strduedateno = get_string('duedateno', 'assign');
236 $strgraded = get_string('graded', 'assign');
237 $strnotgradedyet = get_string('notgradedyet', 'assign');
238 $strnotsubmittedyet = get_string('notsubmittedyet', 'assign');
239 $strsubmitted = get_string('submitted', 'assign');
240 $strassignment = get_string('modulename', 'assign');
241 $strreviewed = get_string('reviewed','assign');
244 // NOTE: we do all possible database work here *outside* of the loop to ensure this scales
246 list($sqlassignmentids, $assignmentidparams) = $DB->get_in_or_equal($assignmentids);
248 // build up and array of unmarked submissions indexed by assignment id/ userid
249 // for use where the user has grading rights on assignment
250 $rs = $DB->get_recordset_sql("SELECT s.assignment as assignment, s.userid as userid, s.id as id, s.status as status, g.timemodified as timegraded
251 FROM {assign_submission} s LEFT JOIN {assign_grades} g ON s.userid = g.userid and s.assignment = g.assignment
252 WHERE g.timemodified = 0 OR s.timemodified > g.timemodified
253 AND s.assignment $sqlassignmentids", $assignmentidparams);
255 $unmarkedsubmissions = array();
256 foreach ($rs as $rd) {
257 $unmarkedsubmissions[$rd->assignment][$rd->userid] = $rd->id;
262 // get all user submissions, indexed by assignment id
263 $mysubmissions = $DB->get_records_sql("SELECT a.id AS assignment, a.nosubmissions AS offline, g.timemodified AS timemarked, g.grader AS grader, g.grade AS grade, s.status AS status
264 FROM {assign} a LEFT JOIN {assign_grades} g ON g.assignment = a.id AND g.userid = ? LEFT JOIN {assign_submission} s ON s.assignment = a.id AND s.userid = ?
265 AND a.id $sqlassignmentids", array_merge(array($USER->id, $USER->id), $assignmentidparams));
267 foreach ($assignments as $assignment) {
268 // Do not show assignments that are not open
269 if (!in_array($assignment->id, $assignmentids)) {
272 $str = '<div class="assign overview"><div class="name">'.$strassignment. ': '.
273 '<a '.($assignment->visible ? '':' class="dimmed"').
274 'title="'.$strassignment.'" href="'.$CFG->wwwroot.
275 '/mod/assign/view.php?id='.$assignment->coursemodule.'">'.
276 format_string($assignment->name).'</a></div>';
277 if ($assignment->duedate) {
278 $str .= '<div class="info">'.$strduedate.': '.userdate($assignment->duedate).'</div>';
280 $str .= '<div class="info">'.$strduedateno.'</div>';
282 $context = context_module::instance($assignment->coursemodule);
283 if (has_capability('mod/assign:grade', $context)) {
285 // count how many people can submit
286 $submissions = 0; // init
287 if ($students = get_enrolled_users($context, 'mod/assign:view', 0, 'u.id')) {
288 foreach ($students as $student) {
289 if (isset($unmarkedsubmissions[$assignment->id][$student->id])) {
296 $link = new moodle_url('/mod/assign/view.php', array('id'=>$assignment->coursemodule, 'action'=>'grading'));
297 $str .= '<div class="details"><a href="'.$link.'">'.get_string('submissionsnotgraded', 'assign', $submissions).'</a></div>';
299 } if (has_capability('mod/assign:submit', $context)) {
300 $str .= '<div class="details">';
301 $str .= get_string('mysubmission', 'assign');
302 $submission = $mysubmissions[$assignment->id];
303 if ($submission->offline) {
304 $str .= get_string('offline', 'assign');
305 } else if(!$submission->status || $submission->status == 'draft'){
306 $str .= $strnotsubmittedyet;
308 $str .= get_string('submissionstatus_' . $submission->status, 'assign');
310 if (!$submission->grade || $submission->grade < 0) {
311 $str .= ', ' . get_string('notgraded', 'assign');
313 $str .= ', ' . get_string('graded', 'assign');
318 if (empty($htmlarray[$assignment->course]['assign'])) {
319 $htmlarray[$assignment->course]['assign'] = $str;
321 $htmlarray[$assignment->course]['assign'] .= $str;
327 * Print recent activity from all assignments in a given course
329 * This is used by the recent activity block
330 * @param mixed $course the course to print activity for
331 * @param bool $viewfullnames boolean to determine whether to show full names or not
332 * @param int $timestart the time the rendering started
334 function assign_print_recent_activity($course, $viewfullnames, $timestart) {
335 global $CFG, $USER, $DB, $OUTPUT;
337 // do not use log table if possible, it may be huge
339 if (!$submissions = $DB->get_records_sql("SELECT asb.id, asb.timemodified, cm.id AS cmid, asb.userid,
340 u.firstname, u.lastname, u.email, u.picture
341 FROM {assign_submission} asb
342 JOIN {assign} a ON a.id = asb.assignment
343 JOIN {course_modules} cm ON cm.instance = a.id
344 JOIN {modules} md ON md.id = cm.module
345 JOIN {user} u ON u.id = asb.userid
346 WHERE asb.timemodified > ? AND
349 ORDER BY asb.timemodified ASC", array($timestart, $course->id))) {
353 $modinfo = get_fast_modinfo($course); // no need pass this by reference as the return object already being cached
357 $showrecentsubmissions = get_config('mod_assign', 'showrecentsubmissions');
359 foreach($submissions as $submission) {
360 if (!array_key_exists($submission->cmid, $modinfo->get_cms())) {
363 $cm = $modinfo->get_cm($submission->cmid);
364 if (!$cm->uservisible) {
367 if ($submission->userid == $USER->id) {
368 $show[] = $submission;
372 $context = context_module::instance($submission->cmid);
373 // the act of sumbitting of assignment may be considered private - only graders will see it if specified
374 if (empty($showrecentsubmissions)) {
375 if (!array_key_exists($cm->id, $grader)) {
376 $grader[$cm->id] = has_capability('moodle/grade:viewall',$context);
378 if (!$grader[$cm->id]) {
383 $groupmode = groups_get_activity_groupmode($cm, $course);
385 if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
387 // shortcut - guest user does not belong into any group
391 if (is_null($modinfo->get_groups())) {
392 $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo
395 // this will be slow - show only users that share group with me in this cm
396 if (empty($modinfo->groups[$cm->id])) {
399 $usersgroups = groups_get_all_groups($course->id, $submission->userid, $cm->groupingid);
400 if (is_array($usersgroups)) {
401 $usersgroups = array_keys($usersgroups);
402 $intersect = array_intersect($usersgroups, $modinfo->groups[$cm->id]);
403 if (empty($intersect)) {
408 $show[] = $submission;
415 echo $OUTPUT->heading(get_string('newsubmissions', 'assign').':', 3);
417 foreach ($show as $submission) {
418 $cm = $modinfo->get_cm($submission->cmid);
419 $link = $CFG->wwwroot.'/mod/assign/view.php?id='.$cm->id;
420 print_recent_activity_note($submission->timemodified, $submission, $cm->name, $link, false, $viewfullnames);
427 * Returns all assignments since a given time
429 * @param array $activities The activity information is returned in this array
430 * @param int $index The current index in the activities array
431 * @param int $timestart The earliest activity to show
432 * @param int $courseid Limit the search to this course
433 * @param int $cmid The course module id
434 * @param int $userid Optional user id
435 * @param int $groupid Optional group id
438 function assign_get_recent_mod_activity(&$activities, &$index, $timestart, $courseid, $cmid, $userid=0, $groupid=0) {
439 global $CFG, $COURSE, $USER, $DB;
441 if ($COURSE->id == $courseid) {
444 $course = $DB->get_record('course', array('id'=>$courseid));
447 $modinfo = get_fast_modinfo($course); // no need pass this by reference as the return object already being cached
449 $cm = $modinfo->get_cm($cmid);
452 $userselect = "AND u.id = :userid";
453 $params['userid'] = $userid;
459 $groupselect = "AND gm.groupid = :groupid";
460 $groupjoin = "JOIN {groups_members} gm ON gm.userid=u.id";
461 $params['groupid'] = $groupid;
467 $params['cminstance'] = $cm->instance;
468 $params['timestart'] = $timestart;
470 $userfields = user_picture::fields('u', null, 'userid');
472 if (!$submissions = $DB->get_records_sql("SELECT asb.id, asb.timemodified,
474 FROM {assign_submission} asb
475 JOIN {assign} a ON a.id = asb.assignment
476 JOIN {user} u ON u.id = asb.userid
478 WHERE asb.timemodified > :timestart AND a.id = :cminstance
479 $userselect $groupselect
480 ORDER BY asb.timemodified ASC", $params)) {
484 $groupmode = groups_get_activity_groupmode($cm, $course);
485 $cm_context = context_module::instance($cm->id);
486 $grader = has_capability('moodle/grade:viewall', $cm_context);
487 $accessallgroups = has_capability('moodle/site:accessallgroups', $cm_context);
488 $viewfullnames = has_capability('moodle/site:viewfullnames', $cm_context);
490 if (is_null($modinfo->get_groups())) {
491 $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo
494 $showrecentsubmissions = get_config('mod_assign', 'showrecentsubmissions');
496 $usersgroups = groups_get_all_groups($course->id, $USER->id, $cm->groupingid);
497 if (is_array($usersgroups)) {
498 $usersgroups = array_keys($usersgroups);
500 foreach($submissions as $submission) {
501 if ($submission->userid == $USER->id) {
502 $show[] = $submission;
505 // the act of submitting of assignment may be considered private - only graders will see it if specified
506 if (empty($showrecentsubmissions)) {
512 if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
514 // shortcut - guest user does not belong into any group
518 // this will be slow - show only users that share group with me in this cm
519 if (empty($modinfo->groups[$cm->id])) {
522 if (is_array($usersgroups)) {
523 $intersect = array_intersect($usersgroups, $modinfo->groups[$cm->id]);
524 if (empty($intersect)) {
529 $show[] = $submission;
537 require_once($CFG->libdir.'/gradelib.php');
539 foreach ($show as $id=>$submission) {
540 $userids[] = $submission->userid;
543 $grades = grade_get_grades($courseid, 'mod', 'assign', $cm->instance, $userids);
546 $aname = format_string($cm->name,true);
547 foreach ($show as $submission) {
548 $activity = new stdClass();
550 $activity->type = 'assign';
551 $activity->cmid = $cm->id;
552 $activity->name = $aname;
553 $activity->sectionnum = $cm->sectionnum;
554 $activity->timestamp = $submission->timemodified;
555 $activity->user = new stdClass();
557 $activity->grade = $grades->items[0]->grades[$submission->userid]->str_long_grade;
560 $userfields = explode(',', user_picture::fields());
561 foreach ($userfields as $userfield) {
562 if ($userfield == 'id') {
563 $activity->user->{$userfield} = $submission->userid; // aliased in SQL above
565 $activity->user->{$userfield} = $submission->{$userfield};
568 $activity->user->fullname = fullname($submission, $viewfullnames);
570 $activities[$index++] = $activity;
577 * Print recent activity from all assignments in a given course
579 * This is used by course/recent.php
580 * @param stdClass $activity
581 * @param int $courseid
582 * @param bool $detail
583 * @param array $modnames
585 function assign_print_recent_mod_activity($activity, $courseid, $detail, $modnames) {
586 global $CFG, $OUTPUT;
588 echo '<table border="0" cellpadding="3" cellspacing="0" class="assignment-recent">';
590 echo "<tr><td class=\"userpicture\" valign=\"top\">";
591 echo $OUTPUT->user_picture($activity->user);
595 $modname = $modnames[$activity->type];
596 echo '<div class="title">';
597 echo "<img src=\"" . $OUTPUT->pix_url('icon', 'assign') . "\" ".
598 "class=\"icon\" alt=\"$modname\">";
599 echo "<a href=\"$CFG->wwwroot/mod/assign/view.php?id={$activity->cmid}\">{$activity->name}</a>";
603 if (isset($activity->grade)) {
604 echo '<div class="grade">';
605 echo get_string('grade').': ';
606 echo $activity->grade;
610 echo '<div class="user">';
611 echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&course=$courseid\">"
612 ."{$activity->user->fullname}</a> - ".userdate($activity->timestamp);
615 echo "</td></tr></table>";
619 * Checks if a scale is being used by an assignment
621 * This is used by the backup code to decide whether to back up a scale
622 * @param int $assignmentid
623 * @param int $scaleid
624 * @return boolean True if the scale is used by the assignment
626 function assign_scale_used($assignmentid, $scaleid) {
630 $rec = $DB->get_record('assign', array('id'=>$assignmentid,'grade'=>-$scaleid));
632 if (!empty($rec) && !empty($scaleid)) {
640 * Checks if scale is being used by any instance of assignment
642 * This is used to find out if scale used anywhere
643 * @param int $scaleid
644 * @return boolean True if the scale is used by any assignment
646 function assign_scale_used_anywhere($scaleid) {
649 if ($scaleid and $DB->record_exists('assign', array('grade'=>-$scaleid))) {
657 * function to list the actions that correspond to a view of this module
658 * This is used by the participation report
661 function assign_get_view_actions() {
662 return array('view submission', 'view feedback');
666 * function to list the actions that correspond to a post of this module
667 * This is used by the participation report
670 function assign_get_post_actions() {
671 return array('upload', 'submit', 'submit for grading');
675 * Call cron on the assign module
677 function assign_cron() {
680 require_once($CFG->dirroot . '/mod/assign/locallib.php');
683 $plugins = get_plugin_list('assignsubmission');
685 foreach ($plugins as $name => $plugin) {
686 $disabled = get_config('assignsubmission_' . $name, 'disabled');
688 $class = 'assign_submission_' . $name;
689 require_once($CFG->dirroot . '/mod/assign/submission/' . $name . '/locallib.php');
693 $plugins = get_plugin_list('assignfeedback');
695 foreach ($plugins as $name => $plugin) {
696 $disabled = get_config('assignfeedback_' . $name, 'disabled');
698 $class = 'assign_feedback_' . $name;
699 require_once($CFG->dirroot . '/mod/assign/feedback/' . $name . '/locallib.php');
706 * Returns all other capabilities used by this module.
707 * @return array Array of capability strings
709 function assign_get_extra_capabilities() {
710 return array('gradereport/grader:view', 'moodle/grade:viewall', 'moodle/site:viewfullnames', 'moodle/site:config');
714 * Create grade item for given assignment
716 * @param stdClass $assign record with extra cmidnumber
717 * @param array $grades optional array/object of grade(s); 'reset' means reset grades in gradebook
718 * @return int 0 if ok, error code otherwise
720 function assign_grade_item_update($assign, $grades=NULL) {
722 require_once($CFG->libdir.'/gradelib.php');
724 if (!isset($assign->courseid)) {
725 $assign->courseid = $assign->course;
728 $params = array('itemname'=>$assign->name, 'idnumber'=>$assign->cmidnumber);
730 if ($assign->grade > 0) {
731 $params['gradetype'] = GRADE_TYPE_VALUE;
732 $params['grademax'] = $assign->grade;
733 $params['grademin'] = 0;
735 } else if ($assign->grade < 0) {
736 $params['gradetype'] = GRADE_TYPE_SCALE;
737 $params['scaleid'] = -$assign->grade;
740 $params['gradetype'] = GRADE_TYPE_TEXT; // allow text comments only
743 if ($grades === 'reset') {
744 $params['reset'] = true;
748 return grade_update('mod/assign', $assign->courseid, 'mod', 'assign', $assign->id, 0, $grades, $params);
752 * Return grade for given user or all users.
754 * @param stdClass $assign record of assign with an additional cmidnumber
755 * @param int $userid optional user id, 0 means all users
756 * @return array array of grades, false if none
758 function assign_get_user_grades($assign, $userid=0) {
760 require_once($CFG->dirroot . '/mod/assign/locallib.php');
762 $assignment = new assign(null, null, null);
763 $assignment->set_instance($assign);
764 return $assignment->get_user_grades_for_gradebook($userid);
768 * Update activity grades
770 * @param stdClass $assign database record
771 * @param int $userid specific user only, 0 means all
772 * @param bool $nullifnone - not used
774 function assign_update_grades($assign, $userid=0, $nullifnone=true) {
776 require_once($CFG->libdir.'/gradelib.php');
778 if ($assign->grade == 0) {
779 assign_grade_item_update($assign);
781 } else if ($grades = assign_get_user_grades($assign, $userid)) {
782 foreach($grades as $k=>$v) {
783 if ($v->rawgrade == -1) {
784 $grades[$k]->rawgrade = null;
787 assign_grade_item_update($assign, $grades);
790 assign_grade_item_update($assign);
795 * List the file areas that can be browsed
797 * @param stdClass $course
798 * @param stdClass $cm
799 * @param stdClass $context
802 function assign_get_file_areas($course, $cm, $context) {
804 require_once($CFG->dirroot . '/mod/assign/locallib.php');
807 $assignment = new assign($context, $cm, $course);
808 foreach ($assignment->get_submission_plugins() as $plugin) {
809 if ($plugin->is_visible()) {
810 $pluginareas = $plugin->get_file_areas();
813 $areas = array_merge($areas, $pluginareas);
817 foreach ($assignment->get_feedback_plugins() as $plugin) {
818 if ($plugin->is_visible()) {
819 $pluginareas = $plugin->get_file_areas();
822 $areas = array_merge($areas, $pluginareas);
831 * File browsing support for assign module.
833 * @param file_browser $browser
834 * @param object $areas
835 * @param object $course
837 * @param object $context
838 * @param string $filearea
840 * @param string $filepath
841 * @param string $filename
842 * @return object file_info instance or null if not found
844 function assign_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
846 require_once($CFG->dirroot . '/mod/assign/locallib.php');
848 if ($context->contextlevel != CONTEXT_MODULE) {
852 $fs = get_file_storage();
853 $filepath = is_null($filepath) ? '/' : $filepath;
854 $filename = is_null($filename) ? '.' : $filename;
856 // need to find the plugin this belongs to
857 $assignment = new assign($context, $cm, $course);
859 foreach ($assignment->get_submission_plugins() as $plugin) {
860 if ($plugin->is_visible()) {
861 $pluginareas = $plugin->get_file_areas();
863 if (array_key_exists($filearea, $pluginareas)) {
864 $pluginowner = $plugin;
870 foreach ($assignment->get_feedback_plugins() as $plugin) {
871 if ($plugin->is_visible()) {
872 $pluginareas = $plugin->get_file_areas();
874 if (array_key_exists($filearea, $pluginareas)) {
875 $pluginowner = $plugin;
886 $result = $pluginowner->get_file_info($browser, $filearea, $itemid, $filepath, $filename);
891 * Prints the complete info about a user's interaction with an assignment
893 * @param stdClass $course
894 * @param stdClass $user
895 * @param stdClass $coursemodule
896 * @param stdClass $assign the database assign record
898 * This prints the submission summary and feedback summary for this student
900 function assign_user_complete($course, $user, $coursemodule, $assign) {
902 require_once($CFG->dirroot . '/mod/assign/locallib.php');
903 $context = context_module::instance($coursemodule->id);
905 $assignment = new assign($context, $coursemodule, $course);
907 echo $assignment->view_student_summary($user, false);
911 * Print the grade information for the assignment for this user
913 * @param stdClass $course
914 * @param stdClass $user
915 * @param stdClass $coursemodule
916 * @param stdClass $assignment
918 function assign_user_outline($course, $user, $coursemodule, $assignment) {
920 require_once($CFG->libdir.'/gradelib.php');
921 require_once($CFG->dirroot.'/grade/grading/lib.php');
923 $gradinginfo = grade_get_grades($course->id,
929 $gradingitem = $gradinginfo->items[0];
930 $gradebookgrade = $gradingitem->grades[$user->id];
932 if (!$gradebookgrade) {
935 $result = new stdClass();
936 $result->info = get_string('outlinegrade', 'assign', $gradebookgrade->grade);
937 $result->time = $gradebookgrade->dategraded;
943 * Obtains the automatic completion state for this module based on any conditions
944 * in assign settings.
946 * @param object $course Course
947 * @param object $cm Course-module
948 * @param int $userid User ID
949 * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)
950 * @return bool True if completed, false if not, $type if conditions not set.
952 function assign_get_completion_state($course, $cm, $userid, $type) {
954 require_once($CFG->dirroot . '/mod/assign/locallib.php');
956 $assign = new assign(null, $cm, $course);
958 // If completion option is enabled, evaluate it and return true/false.
959 if ($assign->get_instance()->completionsubmit) {
960 $submission = $DB->get_record('assign_submission', array('assignment'=>$assign->get_instance()->id, 'userid'=>$userid), '*', IGNORE_MISSING);
961 return $submission && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED;
963 // Completion option is not enabled so just return $type.