Merge branch 'wip-mdl-50675-m28' of https://github.com/rajeshtaneja/moodle into MOODL...
[moodle.git] / lib / grade / grade_outcome.php
blobffb47de5dd6c1aa1db464a4425dacc058e25aee6
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
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.
8 //
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/>.
17 /**
18 * Definition of grade outcome class
20 * @package core_grades
21 * @category grade
22 * @copyright 2006 Nicolas Connault
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 require_once('grade_object.php');
30 /**
31 * Class representing a grade outcome.
33 * It is responsible for handling its DB representation, modifying and returning its metadata.
35 * @package core_grades
36 * @category grade
37 * @copyright 2006 Nicolas Connault
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 class grade_outcome extends grade_object {
41 /**
42 * DB Table (used by grade_object).
43 * @var string $table
45 public $table = 'grade_outcomes';
47 /**
48 * Array of required table fields, must start with 'id'.
49 * @var array $required_fields
51 public $required_fields = array('id', 'courseid', 'shortname', 'fullname', 'scaleid','description',
52 'descriptionformat', 'timecreated', 'timemodified', 'usermodified');
54 /**
55 * The course this outcome belongs to.
56 * @var int $courseid
58 public $courseid;
60 /**
61 * The shortname of the outcome.
62 * @var string $shortname
64 public $shortname;
66 /**
67 * The fullname of the outcome.
68 * @var string $fullname
70 public $fullname;
72 /**
73 * A full grade_scale object referenced by $this->scaleid.
74 * @var object $scale
76 public $scale;
78 /**
79 * The id of the scale referenced by this outcome.
80 * @var int $scaleid
82 public $scaleid;
84 /**
85 * The description of this outcome - FORMAT_MOODLE.
86 * @var string $description
88 public $description;
90 /**
91 * The userid of the person who last modified this outcome.
93 * @var int $usermodified
95 public $usermodified;
97 /**
98 * Deletes this outcome from the database.
100 * @param string $source from where was the object deleted (mod/forum, manual, etc.)
101 * @return bool success
103 public function delete($source=null) {
104 global $DB;
105 if (!empty($this->courseid)) {
106 $DB->delete_records('grade_outcomes_courses', array('outcomeid' => $this->id, 'courseid' => $this->courseid));
108 if (parent::delete($source)) {
109 $context = context_system::instance();
110 $fs = get_file_storage();
111 $files = $fs->get_area_files($context->id, 'grade', 'outcome', $this->id);
112 foreach ($files as $file) {
113 $file->delete();
115 return true;
117 return false;
121 * Records this object in the Database, sets its id to the returned value, and returns that value.
122 * If successful this function also fetches the new object data from database and stores it
123 * in object properties.
125 * @param string $source from where was the object inserted (mod/forum, manual, etc.)
126 * @return int PK ID if successful, false otherwise
128 public function insert($source=null) {
129 global $DB;
131 $this->timecreated = $this->timemodified = time();
133 if ($result = parent::insert($source)) {
134 if (!empty($this->courseid)) {
135 $goc = new stdClass();
136 $goc->courseid = $this->courseid;
137 $goc->outcomeid = $this->id;
138 $DB->insert_record('grade_outcomes_courses', $goc);
141 return $result;
145 * In addition to update() it also updates grade_outcomes_courses if needed
147 * @param string $source from where was the object inserted
148 * @return bool success
150 public function update($source=null) {
151 $this->timemodified = time();
153 if ($result = parent::update($source)) {
154 if (!empty($this->courseid)) {
155 $this->use_in($this->courseid);
158 return $result;
162 * Mark outcome as used in a course
164 * @param int $courseid
165 * @return False if invalid courseid requested
167 public function use_in($courseid) {
168 global $DB;
169 if (!empty($this->courseid) and $courseid != $this->courseid) {
170 return false;
173 if (!$DB->record_exists('grade_outcomes_courses', array('courseid' => $courseid, 'outcomeid' => $this->id))) {
174 $goc = new stdClass();
175 $goc->courseid = $courseid;
176 $goc->outcomeid = $this->id;
177 $DB->insert_record('grade_outcomes_courses', $goc);
179 return true;
183 * Finds and returns a grade_outcome instance based on params.
185 * @static
186 * @param array $params associative arrays varname=>value
187 * @return object grade_outcome instance or false if none found.
189 public static function fetch($params) {
190 return grade_object::fetch_helper('grade_outcomes', 'grade_outcome', $params);
194 * Finds and returns all grade_outcome instances based on params.
196 * @static
197 * @param array $params associative arrays varname=>value
198 * @return array array of grade_outcome insatnces or false if none found.
200 public static function fetch_all($params) {
201 return grade_object::fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
205 * Instantiates a grade_scale object whose data is retrieved from the database
207 * @return grade_scale
209 public function load_scale() {
210 if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
211 $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
212 $this->scale->load_items();
214 return $this->scale;
218 * Static function returning all global outcomes
220 * @static
221 * @return array
223 public static function fetch_all_global() {
224 if (!$outcomes = grade_outcome::fetch_all(array('courseid'=>null))) {
225 $outcomes = array();
227 return $outcomes;
231 * Static function returning all local course outcomes
233 * @static
234 * @param int $courseid
235 * @return array
237 public static function fetch_all_local($courseid) {
238 if (!$outcomes =grade_outcome::fetch_all(array('courseid'=>$courseid))) {
239 $outcomes = array();
241 return $outcomes;
245 * Static method that returns all outcomes available in course
247 * @static
248 * @param int $courseid
249 * @return array
251 public static function fetch_all_available($courseid) {
252 global $CFG, $DB;
254 $result = array();
255 $params = array($courseid);
256 $sql = "SELECT go.*
257 FROM {grade_outcomes} go, {grade_outcomes_courses} goc
258 WHERE go.id = goc.outcomeid AND goc.courseid = ?
259 ORDER BY go.id ASC";
261 if ($datas = $DB->get_records_sql($sql, $params)) {
262 foreach($datas as $data) {
263 $instance = new grade_outcome();
264 grade_object::set_properties($instance, $data);
265 $result[$instance->id] = $instance;
268 return $result;
273 * Returns the most descriptive field for this object. This is a standard method used
274 * when we do not know the exact type of an object.
276 * @return string name
278 public function get_name() {
279 return format_string($this->fullname);
283 * Returns unique outcome short name.
285 * @return string name
287 public function get_shortname() {
288 return $this->shortname;
292 * Returns the formatted grade description with URLs converted
294 * @return string
296 public function get_description() {
297 global $CFG;
298 require_once($CFG->libdir . '/filelib.php');
300 $options = new stdClass;
301 $options->noclean = true;
302 $systemcontext = context_system::instance();
303 $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade', 'outcome', $this->id);
304 return format_text($description, $this->descriptionformat, $options);
308 * Checks if outcome can be deleted.
310 * @return bool
312 public function can_delete() {
313 if ($this->get_item_uses_count()) {
314 return false;
316 if (empty($this->courseid)) {
317 if ($this->get_course_uses_count()) {
318 return false;
321 return true;
325 * Returns the number of places where outcome is used.
327 * @return int
329 public function get_course_uses_count() {
330 global $DB;
332 if (!empty($this->courseid)) {
333 return 1;
336 return $DB->count_records('grade_outcomes_courses', array('outcomeid' => $this->id));
340 * Returns the number of grade items that use this grade outcome
342 * @return int
344 public function get_item_uses_count() {
345 global $DB;
346 return $DB->count_records('grade_items', array('outcomeid' => $this->id));
350 * Computes then returns extra information about this outcome and other objects that are linked to it.
351 * The average of all grades that use this outcome, for all courses (or 1 course if courseid is given) can
352 * be requested, and is returned as a float if requested alone. If the list of items that use this outcome
353 * is also requested, then a single array is returned, which contains the grade_items AND the average grade
354 * if such is still requested (array('items' => array(...), 'avg' => 2.30)). This combining of two
355 * methods into one is to save on DB queries, since both queries are similar and can be performed together.
357 * @param int $courseid An optional courseid to narrow down the average to 1 course only
358 * @param bool $average Whether or not to return the average grade for this outcome
359 * @param bool $items Whether or not to return the list of items using this outcome
360 * @return float
362 public function get_grade_info($courseid=null, $average=true, $items=false) {
363 global $CFG, $DB;
365 if (!isset($this->id)) {
366 debugging("You must setup the outcome's id before calling its get_grade_info() method!");
367 return false; // id must be defined for this to work
370 if ($average === false && $items === false) {
371 debugging('Either the 1st or 2nd param of grade_outcome::get_grade_info() must be true, or both, but not both false!');
372 return false;
375 $params = array($this->id);
377 $wheresql = '';
378 if (!is_null($courseid)) {
379 $wheresql = " AND {grade_items}.courseid = ? ";
380 $params[] = $courseid;
383 $selectadd = '';
384 if ($items !== false) {
385 $selectadd = ", {grade_items}.* ";
388 $sql = "SELECT finalgrade $selectadd
389 FROM {grade_grades}, {grade_items}, {grade_outcomes}
390 WHERE {grade_outcomes}.id = {grade_items}.outcomeid
391 AND {grade_items}.id = {grade_grades}.itemid
392 AND {grade_outcomes}.id = ?
393 $wheresql";
395 $grades = $DB->get_records_sql($sql, $params);
396 $retval = array();
398 if ($average !== false && count($grades) > 0) {
399 $count = 0;
400 $total = 0;
402 foreach ($grades as $k => $grade) {
403 // Skip null finalgrades
404 if (!is_null($grade->finalgrade)) {
405 $total += $grade->finalgrade;
406 $count++;
408 unset($grades[$k]->finalgrade);
411 $retval['avg'] = $total / $count;
414 if ($items !== false) {
415 foreach ($grades as $grade) {
416 $retval['items'][$grade->id] = new grade_item($grade);
420 return $retval;