Merge commit 'catalyst/MOODLE_19_STABLE' into mdl19-linuxchix
[moodle-linuxchix.git] / lib / grade / grade_object.php
blobb730ee81afe5428f01ff3eaa5d728fb7f21b2e6c
1 <?php // $Id$
3 ///////////////////////////////////////////////////////////////////////////
4 // //
5 // NOTICE OF COPYRIGHT //
6 // //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment //
8 // http://moodle.com //
9 // //
10 // Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
11 // //
12 // This program is free software; you can redistribute it and/or modify //
13 // it under the terms of the GNU General Public License as published by //
14 // the Free Software Foundation; either version 2 of the License, or //
15 // (at your option) any later version. //
16 // //
17 // This program is distributed in the hope that it will be useful, //
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20 // GNU General Public License for more details: //
21 // //
22 // http://www.gnu.org/copyleft/gpl.html //
23 // //
24 ///////////////////////////////////////////////////////////////////////////
26 /**
27 * An abstract object that holds methods and attributes common to all grade_* objects defined here.
28 * @abstract
30 class grade_object {
31 /**
32 * Array of required table fields, must start with 'id'.
33 * @var array $required_fields
35 var $required_fields = array('id', 'timecreated', 'timemodified');
37 /**
38 * Array of optional fields with default values - usually long text information that is not always needed.
39 * If you want to create an instance without optional fields use: new grade_object($only_required_fields, false);
40 * @var array $optional_fields
42 var $optional_fields = array();
44 /**
45 * The PK.
46 * @var int $id
48 var $id;
50 /**
51 * The first time this grade_object was created.
52 * @var int $timecreated
54 var $timecreated;
56 /**
57 * The last time this grade_object was modified.
58 * @var int $timemodified
60 var $timemodified;
62 /**
63 * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
64 * @param array $params an array with required parameters for this grade object.
65 * @param boolean $fetch Whether to fetch corresponding row from DB or not,
66 * optional fields might not be defined if false used
68 function grade_object($params=NULL, $fetch=true) {
69 if (!empty($params) and (is_array($params) or is_object($params))) {
70 if ($fetch) {
71 if ($data = $this->fetch($params)) {
72 grade_object::set_properties($this, $data);
73 } else {
74 grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
75 grade_object::set_properties($this, $params);
78 } else {
79 grade_object::set_properties($this, $params);
82 } else {
83 grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
87 /**
88 * Makes sure all the optional fields are loaded.
89 * If id present (==instance exists in db) fetches data from db.
90 * Defaults are used for new instances.
92 function load_optional_fields() {
93 foreach ($this->optional_fields as $field=>$default) {
94 if (array_key_exists($field, $this)) {
95 continue;
97 if (empty($this->id)) {
98 $this->$field = $default;
99 } else {
100 $this->$field = get_field($this->table, $field, 'id', $this->id);
106 * Finds and returns a grade_object instance based on params.
107 * @static abstract
109 * @param array $params associative arrays varname=>value
110 * @return object grade_object instance or false if none found.
112 function fetch($params) {
113 error('Abstract method fetch() not overridden in '.get_class($this));
117 * Finds and returns all grade_object instances based on params.
118 * @static abstract
120 * @param array $params associative arrays varname=>value
121 * @return array array of grade_object insatnces or false if none found.
123 function fetch_all($params) {
124 error('Abstract method fetch_all() not overridden in '.get_class($this));
128 * Factory method - uses the parameters to retrieve matching instance from the DB.
129 * @static final protected
130 * @return mixed object instance or false if not found
132 function fetch_helper($table, $classname, $params) {
133 if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
134 if (count($instances) > 1) {
135 // we should not tolerate any errors here - problems might appear later
136 error('Found more than one record in fetch() !');
138 return reset($instances);
139 } else {
140 return false;
145 * Factory method - uses the parameters to retrieve all matching instances from the DB.
146 * @static final protected
147 * @return mixed array of object instances or false if not found
149 function fetch_all_helper($table, $classname, $params) {
150 $instance = new $classname();
152 $classvars = (array)$instance;
153 $params = (array)$params;
155 $wheresql = array();
157 // remove incorrect params
158 foreach ($params as $var=>$value) {
159 if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) {
160 continue;
162 if (is_null($value)) {
163 $wheresql[] = " $var IS NULL ";
164 } else {
165 $value = addslashes($value);
166 $wheresql[] = " $var = '$value' ";
170 if (empty($wheresql)) {
171 $wheresql = '';
172 } else {
173 $wheresql = implode("AND", $wheresql);
176 if ($datas = get_records_select($table, $wheresql, 'id')) {
177 $result = array();
178 foreach($datas as $data) {
179 $instance = new $classname();
180 grade_object::set_properties($instance, $data);
181 $result[$instance->id] = $instance;
183 return $result;
185 } else {
186 return false;
191 * Updates this object in the Database, based on its object variables. ID must be set.
192 * @param string $source from where was the object updated (mod/forum, manual, etc.)
193 * @return boolean success
195 function update($source=null) {
196 global $USER, $CFG;
198 if (empty($this->id)) {
199 debugging('Can not update grade object, no id!');
200 return false;
203 $data = $this->get_record_data();
205 if (!update_record($this->table, addslashes_recursive($data))) {
206 return false;
209 if (empty($CFG->disablegradehistory)) {
210 unset($data->timecreated);
211 $data->action = GRADE_HISTORY_UPDATE;
212 $data->oldid = $this->id;
213 $data->source = $source;
214 $data->timemodified = time();
215 $data->userlogged = $USER->id;
216 insert_record($this->table.'_history', addslashes_recursive($data));
219 return true;
223 * Deletes this object from the database.
224 * @param string $source from where was the object deleted (mod/forum, manual, etc.)
225 * @return boolean success
227 function delete($source=null) {
228 global $USER, $CFG;
230 if (empty($this->id)) {
231 debugging('Can not delete grade object, no id!');
232 return false;
235 $data = $this->get_record_data();
237 if (delete_records($this->table, 'id', $this->id)) {
238 if (empty($CFG->disablegradehistory)) {
239 unset($data->id);
240 unset($data->timecreated);
241 $data->action = GRADE_HISTORY_DELETE;
242 $data->oldid = $this->id;
243 $data->source = $source;
244 $data->timemodified = time();
245 $data->userlogged = $USER->id;
246 insert_record($this->table.'_history', addslashes_recursive($data));
248 return true;
250 } else {
251 return false;
256 * Returns object with fields and values that are defined in database
258 function get_record_data() {
259 $data = new object();
260 // we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
261 foreach ($this as $var=>$value) {
262 if (in_array($var, $this->required_fields) or array_key_exists($var, $this->optional_fields)) {
263 if (is_object($value) or is_array($value)) {
264 debugging("Incorrect property '$var' found when inserting grade object");
265 } else {
266 $data->$var = $value;
270 return $data;
274 * Records this object in the Database, sets its id to the returned value, and returns that value.
275 * If successful this function also fetches the new object data from database and stores it
276 * in object properties.
277 * @param string $source from where was the object inserted (mod/forum, manual, etc.)
278 * @return int PK ID if successful, false otherwise
280 function insert($source=null) {
281 global $USER, $CFG;
283 if (!empty($this->id)) {
284 debugging("Grade object already exists!");
285 return false;
288 $data = $this->get_record_data();
290 if (!$this->id = insert_record($this->table, addslashes_recursive($data))) {
291 debugging("Could not insert object into db");
292 return false;
295 // set all object properties from real db data
296 $this->update_from_db();
298 $data = $this->get_record_data();
300 if (empty($CFG->disablegradehistory)) {
301 unset($data->timecreated);
302 $data->action = GRADE_HISTORY_INSERT;
303 $data->oldid = $this->id;
304 $data->source = $source;
305 $data->timemodified = time();
306 $data->userlogged = $USER->id;
307 insert_record($this->table.'_history', addslashes_recursive($data));
310 return $this->id;
314 * Using this object's id field, fetches the matching record in the DB, and looks at
315 * each variable in turn. If the DB has different data, the db's data is used to update
316 * the object. This is different from the update() function, which acts on the DB record
317 * based on the object.
319 function update_from_db() {
320 if (empty($this->id)) {
321 debugging("The object could not be used in its state to retrieve a matching record from the DB, because its id field is not set.");
322 return false;
325 if (!$params = get_record($this->table, 'id', $this->id)) {
326 debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
327 return false;
330 grade_object::set_properties($this, $params);
332 return true;
336 * Given an associated array or object, cycles through each key/variable
337 * and assigns the value to the corresponding variable in this object.
338 * @static final
340 function set_properties(&$instance, $params) {
341 $params = (array) $params;
342 foreach ($params as $var => $value) {
343 if (in_array($var, $instance->required_fields) or array_key_exists($var, $instance->optional_fields)) {
344 $instance->$var = $value;