From: nicolasconnault Date: Thu, 26 Apr 2007 04:39:40 +0000 (+0000) Subject: MDL-9506 More implementation of gradebook API and more unit tests. X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=27fbffb62b31b6aae8937f8153c9301802eae077;p=moodle.git MDL-9506 More implementation of gradebook API and more unit tests. --- diff --git a/lib/gradelib.php b/lib/gradelib.php index 86ac7cbb8a..d1e4169b7e 100644 --- a/lib/gradelib.php +++ b/lib/gradelib.php @@ -150,7 +150,7 @@ function in_object_vars($var, $object) * Class representing a grade item. It is responsible for handling its DB representation, * modifying and returning its metadata. */ -class grade_item +class grade_item extends grade_object { /** * The table name @@ -162,7 +162,7 @@ class grade_item * Array of class variables that are not part of the DB table fields * @var array $nonfields */ - var $nonfields = array('table', 'nonfields', 'required_fields'); + var $nonfields = array('table', 'nonfields', 'required_fields', 'calculation'); /** * Array of required fields (keys) and their default values (values). @@ -178,13 +178,7 @@ class grade_item 'hidden' => 0, 'locked' => 0, 'needsupdate' => 0); - - /** - * The grade_item PK. - * @var int $id The grade_item PK - */ - var $id; - + /** * The course this grade_item belongs to. * @var int $courseid @@ -304,23 +298,17 @@ class grade_item * @var boolean $needsupdate */ var $needsupdate; - - /** - * The first time this grade_item was created - * @var int $timecreated - */ - var $timecreated; - + /** - * The last time this grade_item was modified - * @var int $timemodified + * Calculation string used for this item. + * @var string $calculation */ - var $timemodified; - + var $calculation; + /** * Constructor * @param object $params an object with named parameters for this grade item. - */ + */ function grade_item($params=NULL) { if (!empty($params) && (is_array($params) || is_object($params))) { @@ -331,55 +319,10 @@ class grade_item } $this->set_defaults(); + $this->set_calculation(); } } - /** - * Replaces NULL values with defaults defined in the DB, for required fields. - * This should use the DB table METADATA, but to start with I am hard-coding it. - * - * @return void - */ - function set_defaults() - { - foreach ($this->required_fields as $field => $default) { - if (is_null($this->$field)) { - $this->$field = $default; - } - } - } - - /** - * Records this object in the Database, sets its id to the returned value, and returns that value. - * @return int PK ID if successful, false otherwise - */ - function insert() - { - $this->set_defaults(); - $this->id = insert_record($this->table, $this, true); - return $this->id; - } - - - /** - * Updates this object in the Database, based on its object variables. ID must be set. - * - * @return boolean - */ - function update() - { - $this->set_defaults(); - return update_record($this->table, $this); - } - - /** - * Deletes this object from the database. - */ - function delete() - { - return delete_records($this->table, 'id', $this->id); - } - /** * Finds and returns a grade_item object based on its ID number. @@ -429,26 +372,6 @@ class grade_item } } - /** - * Uses the variables of this object to retrieve all matching objects from the DB. - * @return array $objects - */ - function get_records_select() - { - $variables = get_object_vars($this); - $wheresql = ''; - - foreach ($variables as $var => $value) { - if (!empty($value) && !in_array($var, $this->nonfields)) { - $wheresql .= " $var = '$value' AND "; - } - } - - // Trim trailing AND - $wheresql = substr($wheresql, 0, strrpos($wheresql, 'AND')); - - return get_records_select($this->table, $wheresql); - } /** * Returns the raw value for this grade item (as imported by module or other source). @@ -485,6 +408,23 @@ class grade_item return $grade_calculation; } } + + /** + * Sets this item's calculation (creates it) if not yet set, or + * updates it if already set (in the DB). If no calculation is given, + * the method will attempt to retrieve one from the Database, based on + * the variables set in the current object. + * @param string $calculation + * @return boolean + */ + function set_calculation($calculation = null) + { + if (empty($calculation)) { + $this->calculation = new grade_calculation(); + } else { + + } + } /** * Returns the grade_category object this grade_item belongs to (if any). @@ -502,7 +442,7 @@ class grade_item } } -class grade_category +class grade_category extends grade_object { /** * The table name @@ -525,11 +465,6 @@ class grade_category 'fullname' => null, 'droplow' => 0, 'hidden' => 0); - /** - * The grade_category PK. - * @var int $id The grade_category PK - */ - var $id; /** * The course this category belongs to. @@ -596,51 +531,6 @@ class grade_category } } - /** - * Replaces NULL values with defaults defined in the DB, for required fields. - * This should use the DB table METADATA, but to start with I am hard-coding it. - * - * @return void - */ - function set_defaults() - { - foreach ($this->required_fields as $field => $default) { - if (is_null($this->$field)) { - $this->$field = $default; - } - } - } - - - /** - * Records this object in the Database, sets its id to the returned value, and returns that value. - * @return int PK ID if successful, false otherwise - */ - function insert() - { - $this->set_defaults(); - $this->id = insert_record($this->table, $this, true); - return $this->id; - } - - /** - * Updates this object in the Database, based on its object variables. ID must be set. - * - * @return boolean - */ - function update() - { - $this->set_defaults(); - return update_record($this->table, $this); - } - - /** - * Deletes this object from the database. - */ - function delete() - { - return delete_records($this->table, 'id', $this->id); - } /** * Finds and returns a grade_category object based on its ID number. @@ -690,4 +580,225 @@ class grade_category } } -} +} + +/** + * A calculation string used to compute the value displayed by a grade_item. + * There can be only one grade_calculation per grade_item (one-to-one). + */ +class grade_calculation extends grade_object +{ + /** + * The table name + * @var string $table + */ + var $table = 'grade_calculations'; + + /** + * A reference to the grade_item this calculation belongs to. + * @var int $itemid + */ + var $itemid; + + /** + * The string representation of the calculation. + * @var string $calculation + */ + var $calculation; + + /** + * The userid of the person who last modified this calculation. + * @var int $usermodified + */ + var $usermodified; + + /** + * Constructor. + * @param object $params Object or array of variables=>values to assign to this object upon creation + */ + function grade_calculation($params = null) + { + + } + + +} + +/** + * An abstract object that holds methods and attributes common to all grade_* objects defined here. + * @abstract + */ +class grade_object +{ + /** + * The table name + * @var string $table + */ + var $table = null; + + /** + * Array of class variables that are not part of the DB table fields + * @var array $nonfields + */ + var $nonfields = array('table', '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; + + /** + * Finds and returns a grade_object based on its ID number. + * + * @abstract + * @param int $id + * @param boolean $static Unless set to true, this method will also set $this object with the returned values. + * @return object grade_object or false if none found. + */ + function get_by_id($id, $static=false) + { + // Implemented in child objects + } + + + /** + * Finds and returns a grade_object based on 1-3 field values. + * + * @param boolean $static Unless set to true, this method will also set $this object with the returned values. + * @param string $field1 + * @param string $value1 + * @param string $field2 + * @param string $value2 + * @param string $field3 + * @param string $value3 + * @param string $fields + * @return object grade_object or false if none found. + */ + function get_record($static=false, $field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") + { + // Implemented in child objects + } + + /** + * Updates this object in the Database, based on its object variables. ID must be set. + * + * @return boolean + */ + function update() + { + $this->set_defaults(); + $result = update_record($this->table, $this); + if ($result) { + $this->timemodified = mktime(); + } + return $result; + } + + /** + * Deletes this object from the database. + */ + function delete() + { + return delete_records($this->table, 'id', $this->id); + } + + /** + * Replaces NULL values with defaults defined in the DB, for required fields. + * This should use the DB table METADATA, but to start with I am hard-coding it. + * + * @return void + */ + function set_defaults() + { + foreach ($this->required_fields as $field => $default) { + if (is_null($this->$field)) { + $this->$field = $default; + } + } + } + + /** + * Records this object in the Database, sets its id to the returned value, and returns that value. + * @return int PK ID if successful, false otherwise + */ + function insert() + { + $this->set_defaults(); + $this->set_timecreated(); + $this->id = insert_record($this->table, $this, true); + return $this->id; + } + + /** + * Uses the variables of this object to retrieve all matching objects from the DB. + * @return array $objects + */ + function get_records_select() + { + $variables = get_object_vars($this); + $wheresql = ''; + + foreach ($variables as $var => $value) { + if (!empty($value) && !in_array($var, $this->nonfields)) { + $wheresql .= " $var = '$value' AND "; + } + } + + // Trim trailing AND + $wheresql = substr($wheresql, 0, strrpos($wheresql, 'AND')); + + return get_records_select($this->table, $wheresql, 'id'); + } + + /** + * If this object hasn't yet been saved in DB (empty $id), this method sets the timecreated variable + * to the current or given time. If a value is already set in DB, + * this method will do nothing, unless the $override parameter is set to true. This is to avoid + * unintentional overwrites. + * + * @param int $timestamp Optional timestamp to override current timestamp. + * @param boolean $override Whether to override an existing value for this field in the DB. + * @return boolean True if successful, false otherwise. + */ + function set_timecreated($timestamp = null, $override = false) + { + if (empty($timestamp)) { + $timestamp = mktime(); + } + + if (empty($this->id)) { + $this->timecreated = $timestamp; + $this->timemodified = $timestamp; + } else { + $current_time = get_field($this->table, 'timecreated', 'id', $this->id); + + if (empty($current_time) || $override) { + $this->timecreated = $timestamp; + $this->timemodified = $timestamp; + return $this->timecreated; + } else { + return false; + } + } + return $this->timecreated; + } +} diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 7f302a81c9..ba592c1fa3 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -54,13 +54,15 @@ class gradelib_test extends UnitTestCase { function setUp() { $grade_category = new stdClass(); - + $grade_category->fullname = 'unittestcategory1'; $grade_category->courseid = $this->courseid; $grade_category->aggregation = GRADE_AGGREGATE_MEAN; $grade_category->keephigh = 100; $grade_category->droplow = 10; $grade_category->hidden = 0; + $grade_category->timecreated = mktime(); + $grade_category->timemodified = mktime(); if ($grade_category->id = insert_record('grade_categories', $grade_category)) { $this->grade_categories[] = $grade_category; @@ -75,7 +77,9 @@ class gradelib_test extends UnitTestCase { $grade_item->itemmodule = 'quiz'; $grade_item->iteminstance = 1; $grade_item->iteminfo = 'Grade item used for unit testing'; - + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } @@ -89,6 +93,8 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminstance = 2; $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->locked = mktime() + 240000; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; @@ -103,6 +109,10 @@ class gradelib_test extends UnitTestCase { $grade_item->itemmodule = 'forum'; $grade_item->iteminstance = 3; $grade_item->iteminfo = 'Grade item used for unit testing'; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + + // $grade_item->set_calculation('MEAN([unittestgradeitem1],[unittestgradeitem2])'); if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; @@ -122,6 +132,8 @@ class gradelib_test extends UnitTestCase { foreach ($this->grade_categories as $grade_category) { delete_records('grade_categories', 'id', $grade_category->id); } + unset($this->grade_items); + unset($this->grade_categories); } function test_grade_get_items() @@ -143,6 +155,8 @@ class gradelib_test extends UnitTestCase { $params->itemmodule = 'database'; $params->iteminstance = 4; $params->iteminfo = 'Grade item used for unit testing'; + $params->timecreated = mktime(); + $params->timemodified = mktime(); $params->id = grade_create_item($params); $last_grade_item = end($this->grade_items); @@ -154,6 +168,8 @@ class gradelib_test extends UnitTestCase { function test_grade_create_category() { $grade_category = new stdClass(); + $grade_category->timecreated = mktime(); + $grade_category->timemodified = mktime(); $grade_category->id = grade_create_category($this->courseid, 'unittestcategory2', $this->grade_items, GRADE_AGGREGATE_MEAN); $last_grade_category = end($this->grade_categories); @@ -191,6 +207,19 @@ class gradelib_test extends UnitTestCase { $this->assertEqual($params->itemmodule, $grade_item->itemmodule); $this->assertEqual($params->iteminstance, $grade_item->iteminstance); $this->assertEqual($params->iteminfo, $grade_item->iteminfo); + + $params = $this->grade_items[0]; + + $grade_item = new grade_item($params); + + $this->assertEqual($params->id, $grade_item->id); + $this->assertEqual($params->courseid, $grade_item->courseid); + $this->assertEqual($params->categoryid, $grade_item->categoryid); + $this->assertEqual($params->itemname, $grade_item->itemname); + $this->assertEqual($params->itemtype, $grade_item->itemtype); + $this->assertEqual($params->itemmodule, $grade_item->itemmodule); + $this->assertEqual($params->iteminstance, $grade_item->iteminstance); + $this->assertEqual($params->iteminfo, $grade_item->iteminfo); } function test_grade_item_insert() @@ -225,22 +254,45 @@ class gradelib_test extends UnitTestCase { $grade_item = new grade_item($this->grade_items[0]); $grade_item->iteminfo = 'Updated info for this unittest grade_item'; $this->assertTrue($grade_item->update()); - $this->assertEqual($grade_item->iteminfo, get_field('grade_items', 'iteminfo', 'id', $grade_item->id)); + $iteminfo = get_field('grade_items', 'iteminfo', 'id', $this->grade_items[0]->id); + $this->assertEqual($grade_item->iteminfo, $iteminfo); } - function test_grade_item_get_by_id() + function test_grade_item_set_timecreated() { + $grade_item = new grade_item($this->grade_items[0]); + $timestamp = mktime(); + $grade_item->set_timecreated(); + $this->assertEqual($timestamp, $grade_item->timecreated); + $this->assertEqual($grade_item->timecreated, get_field('grade_items', 'timecreated', 'id', $grade_item->id)); + } + function test_grade_item_get_by_id() + { + $grade_item = grade_item::get_by_id($this->grade_items[0]->id, true); + $this->assertEqual($this->grade_items[0]->id, $grade_item->id); + $this->assertEqual($this->grade_items[0]->iteminfo, $grade_item->iteminfo); } function test_grade_item_get_record() { - + $grade_item = grade_item::get_record(true, 'id', $this->grade_items[0]->id); + $this->assertEqual($this->grade_items[0]->id, $grade_item->id); + $this->assertEqual($this->grade_items[0]->iteminfo, $grade_item->iteminfo); + + $grade_item = grade_item::get_record(true, 'itemtype', $this->grade_items[1]->itemtype, 'itemmodule', $this->grade_items[1]->itemmodule); + $this->assertEqual($this->grade_items[1]->id, $grade_item->id); + $this->assertEqual($this->grade_items[1]->iteminfo, $grade_item->iteminfo); } function test_grade_item_get_records_select() { - + $grade_item = new grade_item(); + $grade_item->itemtype = 'mod'; + $grade_items = $grade_item->get_records_select(); + $this->assertEqual(2, count($grade_items)); + $first_grade_item = reset($grade_items); + $this->assertEqual($this->grade_items[0]->id, $first_grade_item->id); } function test_grade_item_get_raw()