moodle/lib/grade/grade_object.php
2007-07-29 13:22:50 +00:00

323 lines
11 KiB
PHP

<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 2001-2007 Martin Dougiamas http://dougiamas.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/**
* An abstract object that holds methods and attributes common to all grade_* objects defined here.
* @abstract
*/
class grade_object {
/**
* Array of class variables that are not part of the DB table fields
* @var array $nonfields
*/
var $nonfields = array('nonfields', 'required_fields');
/**
* Array of required fields (keys) and their default values (values).
* @var array $required_fields
*/
var $required_fields = array();
/**
* The PK.
* @var int $id
*/
var $id;
/**
* The first time this grade_calculation was created.
* @var int $timecreated
*/
var $timecreated;
/**
* The last time this grade_calculation was modified.
* @var int $timemodified
*/
var $timemodified;
/**
* Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
* @param array $params an array with required parameters for this grade object.
* @param boolean $fetch Whether to fetch corresponding row from DB or not.
*/
function grade_object($params=NULL, $fetch = true) {
if (!empty($params) and (is_array($params) or is_object($params))) {
if ($fetch and $data = $this->fetch($params)) {
grade_object::set_properties($this, $data);
} else {
grade_object::set_properties($this, $params);
}
}
}
/**
* Finds and returns a grade_object instance based on params.
* @static abstract
*
* @param array $params associative arrays varname=>value
* @return object grade_object instance or false if none found.
*/
function fetch($params) {
error('Abstract method fetch() not overridden in '.get_class($this));
}
/**
* Finds and returns all grade_object instances based on params.
* @static abstract
*
* @param array $params associative arrays varname=>value
* @return array array of grade_object insatnces or false if none found.
*/
function fetch_all($params) {
error('Abstract method fetch_all() not overridden in '.get_class($this));
}
/**
* Factory method - uses the parameters to retrieve matching instance from the DB.
* @static final protected
* @return mixed object insatnce or false if not found
*/
function fetch_helper($table, $classname, $params) {
// we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
// in PHP5 we could do it much better
if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
if (count($instances) > 1) {
// we should not tolerate any errors here - problems might appear later
error('Found more than one record in fetch() !');
}
return reset($instances);
} else {
return false;
}
}
/**
* Factory method - uses the parameters to retrieve all matching instances from the DB.
* @static final protected
* @return mixed array of object instances or false if not found
*/
function fetch_all_helper($table, $classname, $params) {
// we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
// in PHP5 we could do it much better
$instance = new $classname();
$classvars = (array)$instance;
$params = (array)$params;
$wheresql = array();
// remove incorrect params - warn developer if needed
foreach ($params as $var=>$value) {
if (!in_array($var, array_keys($classvars)) or in_array($var, $instance->nonfields)) {
debugging("Incorrect property name $var for class $classname");
continue;
}
if (is_null($value)) {
$wheresql[] = " $var IS NULL ";
} else {
$value = addslashes($value);
$wheresql[] = " $var = '$value' ";
}
}
if (empty($wheresql)) {
$wheresql = '';
} else {
$wheresql = implode("AND", $wheresql);
}
if ($datas = get_records_select($table, $wheresql, 'id')) {
$result = array();
foreach($datas as $data) {
$instance = new $classname();
grade_object::set_properties($instance, $data);
$result[$instance->id] = $instance;
}
return $result;
} else {
return false;
}
}
/**
* Updates this object in the Database, based on its object variables. ID must be set.
* @param string $source from where was the object updated (mod/forum, manual, etc.)
* @return boolean success
*/
function update($source=null) {
global $USER;
$this->timemodified = time();
// we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
$data = new object();
foreach ($this as $var=>$value) {
if (!in_array($var, $this->nonfields)) {
if (is_object($value) or is_array($value)) {
debugging("Incorrect property '$var' found when updating grade object");
} else {
$data->$var = $value;
}
}
}
if(!update_record($this->table, addslashes_recursive($data))) {
return false;
}
// track history
// TODO: add history disable switch
unset($data->timecreated);
$data->action = GRADE_HISTORY_UPDATE;
$data->oldid = $this->id;
$data->source = $source;
$data->userlogged = $USER->id;
insert_record($this->table.'_history', addslashes_recursive($data));
return true;
}
/**
* Deletes this object from the database.
* @param string $source from where was the object deleted (mod/forum, manual, etc.)
* @return boolean success
*/
function delete($source=null) {
global $USER;
// track history
// TODO: add history disable switch
if ($data = get_record($this->table, 'id', $this->id)) {
unset($data->id);
unset($data->timecreated);
$data->action = GRADE_HISTORY_DELETE;
$data->oldid = $this->id;
$data->source = $source;
$data->timemodified = time();
$data->userlogged = $USER->id;
}
if (delete_records($this->table, 'id', $this->id)) {
if ($data) {
insert_record($this->table.'_history', addslashes_recursive($data));
}
return true;
} else {
return false;
}
}
/**
* Records this object in the Database, sets its id to the returned value, and returns that value.
* If successful this function also fetches the new object data from database and stores it
* in object properties.
* @param string $source from where was the object inserted (mod/forum, manual, etc.)
* @return int PK ID if successful, false otherwise
*/
function insert($source=null) {
global $USER;
if (!empty($this->id)) {
debugging("Grade object already exists!");
return false;
}
$this->timecreated = $this->timemodified = time();
// we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
$data = new object();
foreach ($this as $var=>$value) {
if (!in_array($var, $this->nonfields)) {
if (is_object($value) or is_array($value)) {
debugging("Incorrect property '$var' found when inserting grade object");
} else {
$data->$var = $value;
}
}
}
if (!$this->id = insert_record($this->table, addslashes_recursive($data))) {
debugging("Could not insert object into db");
return false;
}
// set all object properties from real db data
$this->update_from_db();
// track history
// TODO: add history disable switch
unset($data->timecreated);
$data->action = GRADE_HISTORY_INSERT;
$data->oldid = $this->id;
$data->source = $source;
$data->userlogged = $USER->id;
insert_record($this->table.'_history', addslashes_recursive($data));
return $this->id;
}
/**
* Using this object's id field, fetches the matching record in the DB, and looks at
* each variable in turn. If the DB has different data, the db's data is used to update
* the object. This is different from the update() function, which acts on the DB record
* based on the object.
*/
function update_from_db() {
if (empty($this->id)) {
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.");
return false;
}
if (!$params = get_record($this->table, 'id', $this->id)) {
debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
return false;
}
grade_object::set_properties($this, $params);
return true;
}
/**
* Given an associated array or object, cycles through each key/variable
* and assigns the value to the corresponding variable in this object.
* @static final
*/
function set_properties(&$instance, $params) {
$classvars = (array)$instance;
foreach ($params as $var => $value) {
if (in_array($var, array_keys($classvars))) {
$instance->$var = $value;
}
}
}
}
?>