Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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.
13
//
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/>.
16
 
17
/**
18
 * Definition of grade outcome class
19
 *
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
24
 */
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
require_once('grade_object.php');
29
 
30
/**
31
 * Class representing a grade outcome.
32
 *
33
 * It is responsible for handling its DB representation, modifying and returning its metadata.
34
 *
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
39
 */
40
class grade_outcome extends grade_object {
41
    /**
42
     * DB Table (used by grade_object).
43
     * @var string $table
44
     */
45
    public $table = 'grade_outcomes';
46
 
47
    /**
48
     * Array of required table fields, must start with 'id'.
49
     * @var array $required_fields
50
     */
51
    public $required_fields = array('id', 'courseid', 'shortname', 'fullname', 'scaleid','description',
52
                                 'descriptionformat', 'timecreated', 'timemodified', 'usermodified');
53
 
54
    /**
55
     * The course this outcome belongs to.
56
     * @var int $courseid
57
     */
58
    public $courseid;
59
 
60
    /**
61
     * The shortname of the outcome.
62
     * @var string $shortname
63
     */
64
    public $shortname;
65
 
66
    /**
67
     * The fullname of the outcome.
68
     * @var string $fullname
69
     */
70
    public $fullname;
71
 
72
    /**
73
     * A full grade_scale object referenced by $this->scaleid.
74
     * @var object $scale
75
     */
76
    public $scale;
77
 
78
    /**
79
     * The id of the scale referenced by this outcome.
80
     * @var int $scaleid
81
     */
82
    public $scaleid;
83
 
84
    /**
85
     * The description of this outcome - FORMAT_MOODLE.
86
     * @var string $description
87
     */
88
    public $description;
89
 
90
    /**
91
     * The userid of the person who last modified this outcome.
92
     *
93
     * @var int $usermodified
94
     */
95
    public $usermodified;
96
 
97
    /** @var int Identifier of the text format to be used. */
98
    public $descriptionformat = FORMAT_MOODLE;
99
 
100
    /**
101
     * Deletes this outcome from the database.
102
     *
103
     * @param string $source from where was the object deleted (mod/forum, manual, etc.)
104
     * @return bool success
105
     */
106
    public function delete($source=null) {
107
        global $DB;
108
        if (!empty($this->courseid)) {
109
            $DB->delete_records('grade_outcomes_courses', array('outcomeid' => $this->id, 'courseid' => $this->courseid));
110
        }
111
        if (parent::delete($source)) {
112
            $context = context_system::instance();
113
            $fs = get_file_storage();
114
            $files = $fs->get_area_files($context->id, 'grade', 'outcome', $this->id);
115
            foreach ($files as $file) {
116
                $file->delete();
117
            }
118
            return true;
119
        }
120
        return false;
121
    }
122
 
123
    /**
124
     * Records this object in the Database, sets its id to the returned value, and returns that value.
125
     * If successful this function also fetches the new object data from database and stores it
126
     * in object properties.
127
     *
128
     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
129
     * @param bool $isbulkupdate If bulk grade update is happening.
130
     * @return int PK ID if successful, false otherwise
131
     */
132
    public function insert($source = null, $isbulkupdate = false) {
133
        global $DB;
134
 
135
        $this->timecreated = $this->timemodified = time();
136
 
137
        if ($result = parent::insert($source)) {
138
            if (!empty($this->courseid)) {
139
                $goc = new stdClass();
140
                $goc->courseid = $this->courseid;
141
                $goc->outcomeid = $this->id;
142
                $DB->insert_record('grade_outcomes_courses', $goc);
143
            }
144
        }
145
        return $result;
146
    }
147
 
148
    /**
149
     * In addition to update() it also updates grade_outcomes_courses if needed
150
     *
151
     * @param string $source from where was the object inserted
152
     * @param bool $isbulkupdate If bulk grade update is happening.
153
     * @return bool success
154
     */
155
    public function update($source = null, $isbulkupdate = false) {
156
        $this->timemodified = time();
157
 
158
        if ($result = parent::update($source)) {
159
            if (!empty($this->courseid)) {
160
                $this->use_in($this->courseid);
161
            }
162
        }
163
        return $result;
164
    }
165
 
166
    /**
167
     * Mark outcome as used in a course
168
     *
169
     * @param int $courseid
170
     * @return False if invalid courseid requested
171
     */
172
    public function use_in($courseid) {
173
        global $DB;
174
        if (!empty($this->courseid) and $courseid != $this->courseid) {
175
            return false;
176
        }
177
 
178
        if (!$DB->record_exists('grade_outcomes_courses', array('courseid' => $courseid, 'outcomeid' => $this->id))) {
179
            $goc = new stdClass();
180
            $goc->courseid  = $courseid;
181
            $goc->outcomeid = $this->id;
182
            $DB->insert_record('grade_outcomes_courses', $goc);
183
        }
184
        return true;
185
    }
186
 
187
    /**
188
     * Finds and returns a grade_outcome instance based on params.
189
     *
190
     * @static
191
     * @param array $params associative arrays varname=>value
192
     * @return object grade_outcome instance or false if none found.
193
     */
194
    public static function fetch($params) {
195
        return grade_object::fetch_helper('grade_outcomes', 'grade_outcome', $params);
196
    }
197
 
198
    /**
199
     * Finds and returns all grade_outcome instances based on params.
200
     *
201
     * @static
202
     * @param array $params associative arrays varname=>value
203
     * @return array array of grade_outcome insatnces or false if none found.
204
     */
205
    public static function fetch_all($params) {
206
        return grade_object::fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
207
    }
208
 
209
    /**
210
     * Instantiates a grade_scale object whose data is retrieved from the database
211
     *
212
     * @return grade_scale
213
     */
214
    public function load_scale() {
215
        if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
216
            $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
217
            $this->scale->load_items();
218
        }
219
        return $this->scale;
220
    }
221
 
222
    /**
223
     * Static function returning all global outcomes
224
     *
225
     * @static
226
     * @return array
227
     */
228
    public static function fetch_all_global() {
229
        if (!$outcomes = grade_outcome::fetch_all(array('courseid'=>null))) {
230
            $outcomes = array();
231
        }
232
        return $outcomes;
233
    }
234
 
235
    /**
236
     * Static function returning all local course outcomes
237
     *
238
     * @static
239
     * @param int $courseid
240
     * @return array
241
     */
242
    public static function fetch_all_local($courseid) {
243
        if (!$outcomes =grade_outcome::fetch_all(array('courseid'=>$courseid))) {
244
            $outcomes = array();
245
        }
246
        return $outcomes;
247
    }
248
 
249
    /**
250
     * Static method that returns all outcomes available in course
251
     *
252
     * @static
253
     * @param int $courseid
254
     * @return array
255
     */
256
    public static function fetch_all_available($courseid) {
257
        global $CFG, $DB;
258
 
259
        $result = array();
260
        $params = array($courseid);
261
        $sql = "SELECT go.*
262
                  FROM {grade_outcomes} go, {grade_outcomes_courses} goc
263
                 WHERE go.id = goc.outcomeid AND goc.courseid = ?
264
              ORDER BY go.id ASC";
265
 
266
        if ($datas = $DB->get_records_sql($sql, $params)) {
267
            foreach($datas as $data) {
268
                $instance = new grade_outcome();
269
                grade_object::set_properties($instance, $data);
270
                $result[$instance->id] = $instance;
271
            }
272
        }
273
        return $result;
274
    }
275
 
276
 
277
    /**
278
     * Returns the most descriptive field for this object. This is a standard method used
279
     * when we do not know the exact type of an object.
280
     *
281
     * @return string name
282
     */
283
    public function get_name() {
284
        // Grade outcomes can be created at site or course context, so set the filter context appropriately.
285
        $context = empty($this->courseid) ? context_system::instance() : context_course::instance($this->courseid);
286
        return format_string($this->fullname, false, ["context" => $context]);
287
    }
288
 
289
    /**
290
     * Returns unique outcome short name.
291
     *
292
     * @return string name
293
     */
294
    public function get_shortname() {
295
        return $this->shortname;
296
    }
297
 
298
    /**
299
     * Returns the formatted grade description with URLs converted
300
     *
301
     * @return string
302
     */
303
    public function get_description() {
304
        global $CFG;
305
        require_once($CFG->libdir . '/filelib.php');
306
 
307
        $options = new stdClass;
308
        $options->noclean = true;
309
        $systemcontext = context_system::instance();
310
        $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade', 'outcome', $this->id);
311
        return format_text($description, $this->descriptionformat, $options);
312
    }
313
 
314
    /**
315
     * Checks if outcome can be deleted.
316
     *
317
     * @return bool
318
     */
319
    public function can_delete() {
320
        if ($this->get_item_uses_count()) {
321
            return false;
322
        }
323
        if (empty($this->courseid)) {
324
            if ($this->get_course_uses_count()) {
325
                return false;
326
            }
327
        }
328
        return true;
329
    }
330
 
331
    /**
332
     * Returns the number of places where outcome is used.
333
     *
334
     * @return int
335
     */
336
    public function get_course_uses_count() {
337
        global $DB;
338
 
339
        if (!empty($this->courseid)) {
340
            return 1;
341
        }
342
 
343
        return $DB->count_records('grade_outcomes_courses', array('outcomeid' => $this->id));
344
    }
345
 
346
    /**
347
     * Returns the number of grade items that use this grade outcome
348
     *
349
     * @return int
350
     */
351
    public function get_item_uses_count() {
352
        global $DB;
353
        return $DB->count_records('grade_items', array('outcomeid' => $this->id));
354
    }
355
 
356
    /**
357
     * Computes then returns extra information about this outcome and other objects that are linked to it.
358
     * The average of all grades that use this outcome, for all courses (or 1 course if courseid is given) can
359
     * be requested, and is returned as a float if requested alone. If the list of items that use this outcome
360
     * is also requested, then a single array is returned, which contains the grade_items AND the average grade
361
     * if such is still requested (array('items' => array(...), 'avg' => 2.30)). This combining of two
362
     * methods into one is to save on DB queries, since both queries are similar and can be performed together.
363
     *
364
     * @param int $courseid An optional courseid to narrow down the average to 1 course only
365
     * @param bool $average Whether or not to return the average grade for this outcome
366
     * @param bool $items Whether or not to return the list of items using this outcome
367
     * @return float
368
     */
369
    public function get_grade_info($courseid=null, $average=true, $items=false) {
370
        global $CFG, $DB;
371
 
372
        if (!isset($this->id)) {
373
            debugging("You must setup the outcome's id before calling its get_grade_info() method!");
374
            return false; // id must be defined for this to work
375
        }
376
 
377
        if ($average === false && $items === false) {
378
            debugging('Either the 1st or 2nd param of grade_outcome::get_grade_info() must be true, or both, but not both false!');
379
            return false;
380
        }
381
 
382
        $params = array($this->id);
383
 
384
        $wheresql = '';
385
        if (!is_null($courseid)) {
386
            $wheresql = " AND {grade_items}.courseid = ? ";
387
            $params[] = $courseid;
388
        }
389
 
390
        $selectadd = '';
391
        if ($items !== false) {
392
            $selectadd = ", {grade_items}.* ";
393
        }
394
 
395
        $sql = "SELECT finalgrade $selectadd
396
                  FROM {grade_grades}, {grade_items}, {grade_outcomes}
397
                 WHERE {grade_outcomes}.id = {grade_items}.outcomeid
398
                   AND {grade_items}.id = {grade_grades}.itemid
399
                   AND {grade_outcomes}.id = ?
400
                   $wheresql";
401
 
402
        $grades = $DB->get_records_sql($sql, $params);
403
        $retval = array();
404
 
405
        if ($average !== false && count($grades) > 0) {
406
            $count = 0;
407
            $total = 0;
408
 
409
            foreach ($grades as $k => $grade) {
410
                // Skip null finalgrades
411
                if (!is_null($grade->finalgrade)) {
412
                    $total += $grade->finalgrade;
413
                    $count++;
414
                }
415
                unset($grades[$k]->finalgrade);
416
            }
417
 
418
            $retval['avg'] = $total / $count;
419
        }
420
 
421
        if ($items !== false) {
422
            foreach ($grades as $grade) {
423
                $retval['items'][$grade->id] = new grade_item($grade);
424
            }
425
        }
426
 
427
        return $retval;
428
    }
429
}