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 * Functions used to retrieve grades objects
20 * @package core_grades
22 * @copyright 2008 Petr Skoda and Nicolas Connault
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 * Returns the aggregated or calculated course grade(s) for a single course for one or more users
29 * @param int $courseid The ID of course
30 * @param int|array $userid_or_ids Optional ID of the graded user or array of user IDs; if userid not used, returns only information about grade_item
31 * @return stdClass Returns an object containing information about course grade item. scaleid, name, grade
32 * and locked status etc and user course grades: $item->grades[$userid] => $usercoursegrade
34 function grade_get_course_grades($courseid, $userid_or_ids=null) {
36 $grade_item = grade_item
::fetch_course_item($courseid);
38 if ($grade_item->needsupdate
) {
39 grade_regrade_final_grades($courseid);
42 $item = new stdClass();
43 $item->scaleid
= $grade_item->scaleid
;
44 $item->name
= $grade_item->get_name();
45 $item->grademin
= $grade_item->grademin
;
46 $item->grademax
= $grade_item->grademax
;
47 $item->gradepass
= $grade_item->gradepass
;
48 $item->locked
= $grade_item->is_locked();
49 $item->hidden
= $grade_item->is_hidden();
50 $item->grades
= array();
52 switch ($grade_item->gradetype
) {
56 case GRADE_TYPE_VALUE
:
68 if (empty($userid_or_ids)) {
71 } else if (is_array($userid_or_ids)) {
72 $userids = $userid_or_ids;
75 $userids = array($userid_or_ids);
79 $grade_grades = grade_grade
::fetch_users_grades($grade_item, $userids, true);
80 foreach ($userids as $userid) {
81 $grade_grades[$userid]->grade_item
=& $grade_item;
83 $grade = new stdClass();
84 $grade->grade
= $grade_grades[$userid]->finalgrade
;
85 $grade->locked
= $grade_grades[$userid]->is_locked();
86 $grade->hidden
= $grade_grades[$userid]->is_hidden();
87 $grade->overridden
= $grade_grades[$userid]->overridden
;
88 $grade->feedback
= $grade_grades[$userid]->feedback
;
89 $grade->feedbackformat
= $grade_grades[$userid]->feedbackformat
;
90 $grade->usermodified
= $grade_grades[$userid]->usermodified
;
91 $grade->dategraded
= $grade_grades[$userid]->get_dategraded();
93 // create text representation of grade
94 if ($grade_item->needsupdate
) {
95 $grade->grade
= false;
96 $grade->str_grade
= get_string('error');
97 $grade->str_long_grade
= $grade->str_grade
;
99 } else if (is_null($grade->grade
)) {
100 $grade->str_grade
= '-';
101 $grade->str_long_grade
= $grade->str_grade
;
104 $grade->str_grade
= grade_format_gradevalue($grade->grade
, $grade_item);
105 if ($grade_item->gradetype
== GRADE_TYPE_SCALE
or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL
) {
106 $grade->str_long_grade
= $grade->str_grade
;
109 $a->grade
= $grade->str_grade
;
110 $a->max
= grade_format_gradevalue($grade_item->grademax
, $grade_item);
111 $grade->str_long_grade
= get_string('gradelong', 'grades', $a);
115 // create html representation of feedback
116 if (is_null($grade->feedback
)) {
117 $grade->str_feedback
= '';
119 $grade->str_feedback
= format_text($grade->feedback
, $grade->feedbackformat
);
122 $item->grades
[$userid] = $grade;
130 * Returns the aggregated or calculated course grade for a single user for one or more courses
132 * @param int $userid The ID of the single user
133 * @param int|array $courseid_or_ids Optional ID of course or array of IDs, empty means all of the user's courses
134 * @return mixed grade info or grades array including item info, false if error
136 function grade_get_course_grade($userid, $courseid_or_ids=null) {
138 if (!is_array($courseid_or_ids)) {
139 if (empty($courseid_or_ids)) {
140 if (!$courses = enrol_get_users_courses($userid)) {
143 $courseids = array_keys($courses);
144 return grade_get_course_grade($userid, $courseids);
146 if (!is_numeric($courseid_or_ids)) {
149 if (!$grades = grade_get_course_grade($userid, array($courseid_or_ids))) {
152 // only one grade - not array
153 $grade = reset($grades);
158 foreach ($courseid_or_ids as $courseid) {
159 $grade_item = grade_item
::fetch_course_item($courseid);
160 $course_items[$grade_item->courseid
] = $grade_item;
164 foreach ($course_items as $grade_item) {
165 if ($grade_item->needsupdate
) {
166 grade_regrade_final_grades($courseid);
169 $item = new stdClass();
170 $item->scaleid
= $grade_item->scaleid
;
171 $item->name
= $grade_item->get_name();
172 $item->grademin
= $grade_item->grademin
;
173 $item->grademax
= $grade_item->grademax
;
174 $item->gradepass
= $grade_item->gradepass
;
175 $item->locked
= $grade_item->is_locked();
176 $item->hidden
= $grade_item->is_hidden();
178 switch ($grade_item->gradetype
) {
179 case GRADE_TYPE_NONE
:
182 case GRADE_TYPE_VALUE
:
186 case GRADE_TYPE_TEXT
:
190 $item->gradepass
= 0;
193 $grade_grade = new grade_grade(array('userid'=>$userid, 'itemid'=>$grade_item->id
));
194 $grade_grade->grade_item
=& $grade_item;
196 $grade = new stdClass();
197 $grade->grade
= $grade_grade->finalgrade
;
198 $grade->locked
= $grade_grade->is_locked();
199 $grade->hidden
= $grade_grade->is_hidden();
200 $grade->overridden
= $grade_grade->overridden
;
201 $grade->feedback
= $grade_grade->feedback
;
202 $grade->feedbackformat
= $grade_grade->feedbackformat
;
203 $grade->usermodified
= $grade_grade->usermodified
;
204 $grade->dategraded
= $grade_grade->get_dategraded();
205 $grade->item
= $item;
207 // create text representation of grade
208 if ($grade_item->needsupdate
) {
209 $grade->grade
= false;
210 $grade->str_grade
= get_string('error');
211 $grade->str_long_grade
= $grade->str_grade
;
213 } else if (is_null($grade->grade
)) {
214 $grade->str_grade
= '-';
215 $grade->str_long_grade
= $grade->str_grade
;
218 $grade->str_grade
= grade_format_gradevalue($grade->grade
, $grade_item);
219 if ($grade_item->gradetype
== GRADE_TYPE_SCALE
or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL
) {
220 $grade->str_long_grade
= $grade->str_grade
;
223 $a->grade
= $grade->str_grade
;
224 $a->max
= grade_format_gradevalue($grade_item->grademax
, $grade_item);
225 $grade->str_long_grade
= get_string('gradelong', 'grades', $a);
229 // create html representation of feedback
230 if (is_null($grade->feedback
)) {
231 $grade->str_feedback
= '';
233 $grade->str_feedback
= format_text($grade->feedback
, $grade->feedbackformat
);
236 $grades[$grade_item->courseid
] = $grade;
243 * Returns all grade items (including outcomes) or main item for a given activity identified by $cm object.
245 * @param cm_info $cm A course module object (preferably with modname property)
246 * @param bool $only_main_item Limit the search to the primary grade item for the activity, 'itemnumber'==0
247 * @return mixed An array of grade item instances, one grade item if $only_main_item == true, false if error or not found
249 function grade_get_grade_items_for_activity($cm, $only_main_item=false) {
252 if (!isset($cm->modname
)) {
253 $params = array($cm->id
);
254 $cm = $DB->get_record_sql("SELECT cm.*, md.name as modname
255 FROM {course_modules} cm,
257 WHERE cm.id = ? AND md.id = cm.module", $params);
261 if (empty($cm) or empty($cm->instance
) or empty($cm->course
)) {
262 debugging("Incorrect cm parameter in grade_get_grade_items_for_activity()!");
266 if ($only_main_item) {
267 return grade_item
::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$cm->modname
, 'iteminstance'=>$cm->instance
, 'courseid'=>$cm->course
, 'itemnumber'=>0));
269 return grade_item
::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$cm->modname
, 'iteminstance'=>$cm->instance
, 'courseid'=>$cm->course
));
274 * Returns whether or not a user received grades in main grade item for given activity
276 * @param cm_info $cm The activity context module
277 * @param int $userid The user ID
278 * @return bool True if graded, false if user not graded yet
280 function grade_is_user_graded_in_activity($cm, $userid) {
282 $grade_items = grade_get_grade_items_for_activity($cm, true);
283 if (empty($grade_items)) {
287 $grade_item = reset($grade_items);
289 if ($grade_item->gradetype
== GRADE_TYPE_NONE
) {
293 if ($grade_item->needsupdate
) {
294 // activity items should never fail to regrade
295 grade_regrade_final_grades($grade_item->courseid
);
298 if (!$grade = $grade_item->get_final($userid)) {
302 if (is_null($grade->finalgrade
)) {
310 * Returns an array of activities (defined as $cm objects) which are gradeable from gradebook, outcomes are ignored.
312 * @param int $courseid If provided then restrict to one course.
313 * @param string $modulename If defined (could be 'forum', 'assignment' etc) then only that type are returned.
314 * @return array $cm objects
316 function grade_get_gradable_activities($courseid, $modulename='') {
319 if (empty($modulename)) {
320 if (!$modules = $DB->get_records('modules', array('visible' => '1'))) {
324 foreach ($modules as $module) {
325 if ($cms = grade_get_gradable_activities($courseid, $module->name
)) {
326 $result = $result +
$cms;
329 if (empty($result)) {
336 $params = array($courseid, $modulename, GRADE_TYPE_NONE
, $modulename);
337 $sql = "SELECT cm.*, m.name, md.name as modname
338 FROM {grade_items} gi, {course_modules} cm, {modules} md, {{$modulename}} m
339 WHERE gi.courseid = ? AND
340 gi.itemtype = 'mod' AND
341 gi.itemmodule = ? AND
342 gi.itemnumber = 0 AND
343 gi.gradetype != ? AND
344 gi.iteminstance = cm.instance AND
345 cm.instance = m.id AND
349 return $DB->get_records_sql($sql, $params);