Added hooks to qtype import/export
[moodle-linuxchix.git] / lib / grade / grade_object.php
blob0881d2905e5760048bce6c0bb4f1582a609a19f7
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) 2001-2007 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 class variables that are not part of the DB table fields
33 * @var array $nonfields
35 var $nonfields = array('nonfields', 'required_fields');
37 /**
38 * Array of required fields (keys) and their default values (values).
39 * @var array $required_fields
41 var $required_fields = array();
43 /**
44 * The PK.
45 * @var int $id
47 var $id;
49 /**
50 * The first time this grade_calculation was created.
51 * @var int $timecreated
53 var $timecreated;
55 /**
56 * The last time this grade_calculation was modified.
57 * @var int $timemodified
59 var $timemodified;
61 /**
62 * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
63 * @param array $params an array with required parameters for this grade object.
64 * @param boolean $fetch Whether to fetch corresponding row from DB or not.
66 function grade_object($params=NULL, $fetch = true) {
67 if (!empty($params) and (is_array($params) or is_object($params))) {
68 if ($fetch and $data = $this->fetch($params)) {
69 grade_object::set_properties($this, $data);
71 } else {
72 grade_object::set_properties($this, $params);
77 /**
78 * Finds and returns a grade_object instance based on params.
79 * @static abstract
81 * @param array $params associative arrays varname=>value
82 * @return object grade_object instance or false if none found.
84 function fetch($params) {
85 error('Abstract method fetch() not overridden in '.get_class($this));
88 /**
89 * Finds and returns all grade_object instances based on params.
90 * @static abstract
92 * @param array $params associative arrays varname=>value
93 * @return array array of grade_object insatnces or false if none found.
95 function fetch_all($params) {
96 error('Abstract method fetch_all() not overridden in '.get_class($this));
99 /**
100 * Factory method - uses the parameters to retrieve matching instance from the DB.
101 * @static final protected
102 * @return mixed object insatnce or false if not found
104 function fetch_helper($table, $classname, $params) {
105 // we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
106 // in PHP5 we could do it much better
107 if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
108 if (count($instances) > 1) {
109 // we should not tolerate any errors here - problems might appear later
110 error('Found more than one record in fetch() !');
112 return reset($instances);
113 } else {
114 return false;
119 * Factory method - uses the parameters to retrieve all matching instances from the DB.
120 * @static final protected
121 * @return mixed array of object instances or false if not found
123 function fetch_all_helper($table, $classname, $params) {
124 // we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
125 // in PHP5 we could do it much better
126 $instance = new $classname();
128 $classvars = (array)$instance;
129 $params = (array)$params;
131 $wheresql = array();
133 // remove incorrect params - warn developer if needed
134 foreach ($params as $var=>$value) {
135 if (!in_array($var, array_keys($classvars)) or in_array($var, $instance->nonfields)) {
136 debugging("Incorrect property name $var for class $classname");
137 continue;
139 if (is_null($value)) {
140 $wheresql[] = " $var IS NULL ";
141 } else {
142 $value = addslashes($value);
143 $wheresql[] = " $var = '$value' ";
147 if (empty($wheresql)) {
148 $wheresql = '';
149 } else {
150 $wheresql = implode("AND", $wheresql);
153 if ($datas = get_records_select($table, $wheresql, 'id')) {
154 $result = array();
155 foreach($datas as $data) {
156 $instance = new $classname();
157 grade_object::set_properties($instance, $data);
158 $result[$instance->id] = $instance;
160 return $result;
162 } else {
163 return false;
168 * Updates this object in the Database, based on its object variables. ID must be set.
169 * @param string $source from where was the object updated (mod/forum, manual, etc.)
170 * @return boolean success
172 function update($source=null) {
173 global $USER;
175 $this->timemodified = time();
177 // we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
178 $data = new object();
179 foreach ($this as $var=>$value) {
180 if (!in_array($var, $this->nonfields)) {
181 if (is_object($value) or is_array($value)) {
182 debugging("Incorrect property '$var' found when updating grade object");
183 } else {
184 $data->$var = $value;
189 if(!update_record($this->table, addslashes_recursive($data))) {
190 return false;
193 // track history
194 // TODO: add history disable switch
195 unset($data->timecreated);
196 $data->action = GRADE_HISTORY_UPDATE;
197 $data->oldid = $this->id;
198 $data->source = $source;
199 $data->userlogged = $USER->id;
200 insert_record($this->table.'_history', addslashes_recursive($data));
202 return true;
206 * Deletes this object from the database.
207 * @param string $source from where was the object deleted (mod/forum, manual, etc.)
208 * @return boolean success
210 function delete($source=null) {
211 global $USER;
213 // track history
214 // TODO: add history disable switch
215 if ($data = get_record($this->table, 'id', $this->id)) {
216 unset($data->id);
217 unset($data->timecreated);
218 $data->action = GRADE_HISTORY_DELETE;
219 $data->oldid = $this->id;
220 $data->source = $source;
221 $data->timemodified = time();
222 $data->userlogged = $USER->id;
225 if (delete_records($this->table, 'id', $this->id)) {
226 if ($data) {
227 insert_record($this->table.'_history', addslashes_recursive($data));
229 return true;
231 } else {
232 return false;
237 * Records this object in the Database, sets its id to the returned value, and returns that value.
238 * If successful this function also fetches the new object data from database and stores it
239 * in object properties.
240 * @param string $source from where was the object inserted (mod/forum, manual, etc.)
241 * @return int PK ID if successful, false otherwise
243 function insert($source=null) {
244 global $USER;
246 if (!empty($this->id)) {
247 debugging("Grade object already exists!");
248 return false;
251 $this->timecreated = $this->timemodified = time();
253 // we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
254 $data = new object();
255 foreach ($this as $var=>$value) {
256 if (!in_array($var, $this->nonfields)) {
257 if (is_object($value) or is_array($value)) {
258 debugging("Incorrect property '$var' found when inserting grade object");
259 } else {
260 $data->$var = $value;
265 if (!$this->id = insert_record($this->table, addslashes_recursive($data))) {
266 debugging("Could not insert object into db");
267 return false;
270 // set all object properties from real db data
271 $this->update_from_db();
273 // track history
274 // TODO: add history disable switch
275 unset($data->timecreated);
276 $data->action = GRADE_HISTORY_INSERT;
277 $data->oldid = $this->id;
278 $data->source = $source;
279 $data->userlogged = $USER->id;
280 insert_record($this->table.'_history', addslashes_recursive($data));
282 return $this->id;
286 * Using this object's id field, fetches the matching record in the DB, and looks at
287 * each variable in turn. If the DB has different data, the db's data is used to update
288 * the object. This is different from the update() function, which acts on the DB record
289 * based on the object.
291 function update_from_db() {
292 if (empty($this->id)) {
293 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.");
294 return false;
297 if (!$params = get_record($this->table, 'id', $this->id)) {
298 debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
299 return false;
302 grade_object::set_properties($this, $params);
304 return true;
308 * Given an associated array or object, cycles through each key/variable
309 * and assigns the value to the corresponding variable in this object.
310 * @static final
312 function set_properties(&$instance, $params) {
313 $classvars = (array)$instance;
314 foreach ($params as $var => $value) {
315 if (in_array($var, array_keys($classvars))) {
316 $instance->$var = $value;