MDL-29794 Initial support for re-using a shared grading form
[moodle.git] / grade / querylib.php
CommitLineData
e060e33d 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
b9f49659 17
18/**
028553e7 19 * Returns the aggregated or calculated course grade(s) in given course.
b9f49659 20 * @public
21 * @param int $courseid id of course
22 * @param int $userid_or_ids optional id of the graded user or array of ids; if userid not used, returns only information about grade_item
23 * @return information about course grade item scaleid, name, grade and locked status, etc. + user grades
24 */
25function grade_get_course_grades($courseid, $userid_or_ids=null) {
26
27 $grade_item = grade_item::fetch_course_item($courseid);
28
29 if ($grade_item->needsupdate) {
30 grade_regrade_final_grades($courseid);
31 }
32
ace9051c 33 $item = new stdClass();
b9f49659 34 $item->scaleid = $grade_item->scaleid;
35 $item->name = $grade_item->get_name();
36 $item->grademin = $grade_item->grademin;
37 $item->grademax = $grade_item->grademax;
38 $item->gradepass = $grade_item->gradepass;
39 $item->locked = $grade_item->is_locked();
40 $item->hidden = $grade_item->is_hidden();
41 $item->grades = array();
42
43 switch ($grade_item->gradetype) {
44 case GRADE_TYPE_NONE:
45 continue;
46
47 case GRADE_TYPE_VALUE:
48 $item->scaleid = 0;
49 break;
50
51 case GRADE_TYPE_TEXT:
52 $item->scaleid = 0;
53 $item->grademin = 0;
54 $item->grademax = 0;
55 $item->gradepass = 0;
56 break;
57 }
58
59 if (empty($userid_or_ids)) {
60 $userids = array();
61
62 } else if (is_array($userid_or_ids)) {
63 $userids = $userid_or_ids;
64
65 } else {
66 $userids = array($userid_or_ids);
67 }
68
69 if ($userids) {
70 $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true);
71 foreach ($userids as $userid) {
72 $grade_grades[$userid]->grade_item =& $grade_item;
73
ace9051c 74 $grade = new stdClass();
b9f49659 75 $grade->grade = $grade_grades[$userid]->finalgrade;
76 $grade->locked = $grade_grades[$userid]->is_locked();
77 $grade->hidden = $grade_grades[$userid]->is_hidden();
78 $grade->overridden = $grade_grades[$userid]->overridden;
79 $grade->feedback = $grade_grades[$userid]->feedback;
80 $grade->feedbackformat = $grade_grades[$userid]->feedbackformat;
81 $grade->usermodified = $grade_grades[$userid]->usermodified;
b9f49659 82 $grade->dategraded = $grade_grades[$userid]->get_dategraded();
83
84 // create text representation of grade
85 if ($grade_item->needsupdate) {
85a0a69f 86 $grade->grade = false;
87 $grade->str_grade = get_string('error');
88 $grade->str_long_grade = $grade->str_grade;
b9f49659 89
90 } else if (is_null($grade->grade)) {
85a0a69f 91 $grade->str_grade = '-';
92 $grade->str_long_grade = $grade->str_grade;
b9f49659 93
94 } else {
95 $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item);
85a0a69f 96 if ($grade_item->gradetype == GRADE_TYPE_SCALE or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL) {
97 $grade->str_long_grade = $grade->str_grade;
98 } else {
ace9051c 99 $a = new stdClass();
85a0a69f 100 $a->grade = $grade->str_grade;
101 $a->max = grade_format_gradevalue($grade_item->grademax, $grade_item);
102 $grade->str_long_grade = get_string('gradelong', 'grades', $a);
103 }
b9f49659 104 }
105
106 // create html representation of feedback
107 if (is_null($grade->feedback)) {
108 $grade->str_feedback = '';
109 } else {
110 $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat);
111 }
112
113 $item->grades[$userid] = $grade;
114 }
115 }
116
117 return $item;
118}
119
028553e7 120/**
121 * Returns the aggregated or calculated course grade for the given user(s).
122 * @public
123 * @param int $userid
124 * @param int $courseid optional id of course or array of ids, empty means all uses courses (returns array if not present)
125 * @return mixed grade info or grades array including item info, false if error
126 */
127function grade_get_course_grade($userid, $courseid_or_ids=null) {
128
129 if (!is_array($courseid_or_ids)) {
130 if (empty($courseid_or_ids)) {
df997f84 131 if (!$courses = enrol_get_users_courses($userid)) {
028553e7 132 return false;
133 }
134 $courseids = array_keys($courses);
135 return grade_get_course_grade($userid, $courseids);
136 }
137 if (!is_numeric($courseid_or_ids)) {
138 return false;
139 }
140 if (!$grades = grade_get_course_grade($userid, array($courseid_or_ids))) {
141 return false;
142 } else {
143 // only one grade - not array
144 $grade = reset($grades);
145 return $grade;
146 }
147 }
148
149 foreach ($courseid_or_ids as $courseid) {
150 $grade_item = grade_item::fetch_course_item($courseid);
151 $course_items[$grade_item->courseid] = $grade_item;
152 }
153
154 $grades = array();
155 foreach ($course_items as $grade_item) {
156 if ($grade_item->needsupdate) {
157 grade_regrade_final_grades($courseid);
158 }
159
ace9051c 160 $item = new stdClass();
028553e7 161 $item->scaleid = $grade_item->scaleid;
162 $item->name = $grade_item->get_name();
163 $item->grademin = $grade_item->grademin;
164 $item->grademax = $grade_item->grademax;
165 $item->gradepass = $grade_item->gradepass;
166 $item->locked = $grade_item->is_locked();
167 $item->hidden = $grade_item->is_hidden();
168
169 switch ($grade_item->gradetype) {
170 case GRADE_TYPE_NONE:
171 continue;
172
173 case GRADE_TYPE_VALUE:
174 $item->scaleid = 0;
175 break;
176
177 case GRADE_TYPE_TEXT:
178 $item->scaleid = 0;
179 $item->grademin = 0;
180 $item->grademax = 0;
181 $item->gradepass = 0;
182 break;
183 }
184 $grade_grade = new grade_grade(array('userid'=>$userid, 'itemid'=>$grade_item->id));
185 $grade_grade->grade_item =& $grade_item;
186
ace9051c 187 $grade = new stdClass();
028553e7 188 $grade->grade = $grade_grade->finalgrade;
189 $grade->locked = $grade_grade->is_locked();
190 $grade->hidden = $grade_grade->is_hidden();
191 $grade->overridden = $grade_grade->overridden;
192 $grade->feedback = $grade_grade->feedback;
193 $grade->feedbackformat = $grade_grade->feedbackformat;
194 $grade->usermodified = $grade_grade->usermodified;
195 $grade->dategraded = $grade_grade->get_dategraded();
196 $grade->item = $item;
197
198 // create text representation of grade
199 if ($grade_item->needsupdate) {
85a0a69f 200 $grade->grade = false;
201 $grade->str_grade = get_string('error');
202 $grade->str_long_grade = $grade->str_grade;
028553e7 203
204 } else if (is_null($grade->grade)) {
85a0a69f 205 $grade->str_grade = '-';
206 $grade->str_long_grade = $grade->str_grade;
028553e7 207
208 } else {
209 $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item);
85a0a69f 210 if ($grade_item->gradetype == GRADE_TYPE_SCALE or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL) {
211 $grade->str_long_grade = $grade->str_grade;
212 } else {
ace9051c 213 $a = new stdClass();
85a0a69f 214 $a->grade = $grade->str_grade;
215 $a->max = grade_format_gradevalue($grade_item->grademax, $grade_item);
216 $grade->str_long_grade = get_string('gradelong', 'grades', $a);
217 }
028553e7 218 }
219
220 // create html representation of feedback
221 if (is_null($grade->feedback)) {
222 $grade->str_feedback = '';
223 } else {
224 $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat);
225 }
226
227 $grades[$grade_item->courseid] = $grade;
228 }
229
230 return $grades;
231}
232
b9f49659 233/**
234 * Returns all grade items (including outcomes) or main item for a given activity identified by $cm object.
235 *
236 * @param object $cm A course module object (preferably with modname property)
237 * @return mixed - array of grade item instances (one if $only_main_item true), false if error or not found
238 */
239function grade_get_grade_items_for_activity($cm, $only_main_item=false) {
d24832f9 240 global $CFG, $DB;
b9f49659 241
242 if (!isset($cm->modname)) {
d24832f9 243 $params = array($cm->id);
244 $cm = $DB->get_record_sql("SELECT cm.*, m.name, md.name as modname
245 FROM {course_modules} cm,
246 {modules} md,
247 WHERE cm.id = ? AND md.id = cm.module", $params);
b9f49659 248 }
249
250
251 if (empty($cm) or empty($cm->instance) or empty($cm->course)) {
252 debugging("Incorrect cm parameter in grade_get_grade_items_for_activity()!");
253 return false;
254 }
255
256 if ($only_main_item) {
257 return grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$cm->modname, 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course, 'itemnumber'=>0));
258 } else {
259 return grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$cm->modname, 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course));
260 }
261}
262
263/**
264 * Returns whether or not user received grades in main grade item for given activity.
265 *
266 * @param object $cm
267 * @param int $userid
268 * @return bool True if graded false if user not graded yet
269 */
270function grade_is_user_graded_in_activity($cm, $userid) {
271
272 $grade_items = grade_get_grade_items_for_activity($cm, true);
273 if (empty($grade_items)) {
274 return false;
275 }
276
277 $grade_item = reset($grade_items);
278
279 if ($grade_item->gradetype == GRADE_TYPE_NONE) {
280 return false;
281 }
282
283 if ($grade_item->needsupdate) {
284 // activity items should never fail to regrade
285 grade_regrade_final_grades($grade_item->courseid);
286 }
287
288 if (!$grade = $grade_item->get_final($userid)) {
289 return false;
290 }
291
292 if (is_null($grade->finalgrade)) {
293 return false;
294 }
295
296 return true;
297}
298
299/**
300 * Returns an array of activities (defined as $cm objects) which are gradeable from gradebook, outcomes are ignored.
301 *
302 * @param int $courseid If provided then restrict to one course.
303 * @param string $modulename If defined (could be 'forum', 'assignment' etc) then only that type are returned.
304 * @return array $cm objects
305 */
306function grade_get_gradable_activities($courseid, $modulename='') {
d24832f9 307 global $CFG, $DB;
b9f49659 308
309 if (empty($modulename)) {
d24832f9 310 if (!$modules = $DB->get_records('modules', array('visible' => '1'))) {
b9f49659 311 return false;
312 }
313 $result = array();
314 foreach ($modules as $module) {
315 if ($cms = grade_get_gradable_activities($courseid, $module->name)) {
316 $result = $result + $cms;
317 }
318 }
319 if (empty($result)) {
320 return false;
321 } else {
322 return $result;
323 }
324 }
325
d24832f9 326 $params = array($courseid, $modulename, GRADE_TYPE_NONE, $modulename);
b9f49659 327 $sql = "SELECT cm.*, m.name, md.name as modname
d24832f9 328 FROM {grade_items} gi, {course_modules} cm, {modules} md, {$modulename} m
329 WHERE gi.courseid = ? AND
b9f49659 330 gi.itemtype = 'mod' AND
d24832f9 331 gi.itemmodule = ? AND
b9f49659 332 gi.itemnumber = 0 AND
d24832f9 333 gi.gradetype != ? AND
b9f49659 334 gi.iteminstance = cm.instance AND
335 cm.instance = m.id AND
d24832f9 336 md.name = ? AND
b9f49659 337 md.id = cm.module";
338
d24832f9 339 return $DB->get_records_sql($sql, $params);
b9f49659 340}
6c3ef410 341