array(TYPE, REQUIRED, VERIFY METHOD (:self for self-named method)) * @var array */ var $fields = array(); /** * Values array: sanitized and verified field values * @var array */ var $values = array(); /** * Fields that were manually set with set(), not by using set_existing() * @var array */ var $setfields = array(); /** * WHERE condition * @var string */ var $condition = ''; /** * The object table row; a fetched row that represents this instance * @var array */ var $objdata = array(); /** * Insert ID from the insert() command * @var integer */ var $insertid = 0; /** * Constructor: cannot instantiate class directly */ function API(&$registry) { if (!is_subclass_of($this, 'API')) { trigger_error('Cannot instantiate the API module directly', E_USER_ERROR); } if (!is_object($registry)) { trigger_error('The passed registry is not an object', E_USER_ERROR); } $this->registry =& $registry; } /** * Sets a value, sanitizes it, and verifies it * * @param string Field name * @param mixed Value * @param bool Do clean? * @param bool Do verify? */ function set($field, $value, $doclean = true, $doverify = true) { if (!isset($this->fields["$field"])) { trigger_error('Field `' . $field . '` is not valid', E_USER_WARNING); return; } $this->values["$field"] = ($doclean ? $this->do_clean($value, $this->fields["$field"][0]) : $value); $this->setfields[] = $field; if (isset($this->fields["$field"][2]) AND $doverify) { if ($this->fields["$field"][2] == ':self') { $verify = $this->{$this->{"verify_$field"}}($field); } else { $verify = $this->{$this->fields["$field"][2]}($field); } if (!$verify) { // trigger_error('Validation of `' . $field . '` failed', E_USER_ERROR); } } } /** * Sets the condition to use in the WHERE clause; if not passed, then it calculates it * from the REQ_AUTO field * * @param string WHERE conditional bit */ function set_condition($condition = '') { if ($condition != '') { $this->condition = $condition; } else { foreach ($this->fields AS $name => $options) { if ($options[1] == REQ_AUTO) { if (!$this->values["$name"]) { trigger_error('Cannot determine condition from the REQ_AUTO field because it is not set', E_USER_WARNING); continue; } $this->condition = "$name = " . (($options[0] == TYPE_NOCLEAN OR $options[0] == TYPE_STR) ? "'" . $this->values["$name"] . "'" : $this->values["$name"]); } } if ($this->condition == '') { trigger_error('No REQ_AUTO fields are present and therefore the condition cannot be created', E_USER_WARNING); } } } /** * Sets existing data into $values where it's not already present */ function set_existing() { static $run; if ($run) { return; } $this->fetch(); foreach ($this->objdata AS $field => $value) { if (!isset($this->values["$field"])) { $this->values["$field"] = $value; } } $run = true; } /** * Fetches a record based on the condition */ function fetch() { if ($this->condition == '') { trigger_error('Condition is empty: cannot fetch', E_USER_ERROR); } $actmethod = (method_exists($this, 'pre_fetch') ? $this->pre_fetch() : ''); $result = $this->registry->modules['db_mysql']->query_first("SELECT * FROM {$this->prefix}{$this->table} WHERE {$this->condition}"); if (!$result) { // trigger_error('No record was returned', E_USER_ERROR); return; } $actmethod = (method_exists($this, 'post_fetch') ? $this->post_fetch() : ''); $this->objdata = $result; } /** * Inserts a record in the database */ function insert() { $this->verify(); $actmethod = (method_exists($this, 'pre_insert') ? $this->pre_insert() : ''); foreach ($this->setfields AS $field) { $fields[] = $field; $values[] = (($this->fields["$field"][0] == TYPE_NOCLEAN OR $this->fields["$field"][0] == TYPE_STR) ? "'" . $this->values["$field"] . "'" : $this->values["$field"]); } $this->registry->modules['db_mysql']->query("INSERT INTO {$this->prefix}{$this->table} (" . implode(',', $fields) . ") VALUES (" . implode(',', $values) . ")"); $this->insertid = $this->registry->modules['db_mysql']->insert_id(); $actmethod = (method_exists($this, 'post_insert') ? $this->post_insert() : ''); } /** * Updates a record in the database using the data in $vaues */ function update() { if ($this->condition == '') { trigger_error('Condition is empty: cannot fetch', E_USER_ERROR); } $this->set_existing(); $this->verify(); $actmethod = (method_exists($this, 'pre_update') ? $this->pre_update() : ''); foreach ($this->setfields AS $field) { $updates[] = "$field = " . (($this->fields["$field"][0] == TYPE_NOCLEAN OR $this->fields["$field"][0] == TYPE_STR) ? "'" . $this->values["$field"] . "'" : $this->values["$field"]); } $updates = implode(', ', $updates); $this->registry->modules['db_mysql']->query("UPDATE {$this->prefix}{$this->table} SET $updates WHERE {$this->condition}"); $actmethod = (method_exists($this, 'post_update') ? $this->post_update() : ''); } /** * Deletes a record */ function delete() { if ($this->condition == '') { trigger_error('Condition is empty: cannot fetch', E_USER_ERROR); } $this->set_existing(); $actmethod = (method_exists($this, 'pre_delete') ? $this->pre_delete() : ''); $this->registry->modules['db_mysql']->query("DELETE FROM {$this->prefix}{$this->table} WHERE {$this->condition}"); $actmethod = (method_exists($this, 'post_delete') ? $this->post_delete() : ''); } /** * Verifies that all required fields are set */ function verify() { foreach ($this->fields AS $name => $options) { if ($options[1] == REQ_YES) { if (!isset($this->values["$name"])) { // trigger_error('Field `' . $name . '` was not set', E_USER_ERROR); } } } } /** * Verify field: not a zero value */ function verify_nozero($field) { if ($this->values["$field"] == 0) { return false; } return true; } /** * Cleans a value based on the field option * * @param mixed Uncleaned data * @param integer Cleaning type * * @return mixed Cleaned data */ function do_clean($value, $type) { if ($type == TYPE_INT) { $value = intval($value); } else if ($type == TYPE_UINT) { $value = abs(intval($value)); } else if ($type == TYPE_FLOAT) { $value = floatval($value); } else if ($type == TYPE_BOOL) { $value = (bool)$value; } else if ($type == TYPE_STR) { if (!$this->registry->escapestrings) { $value = $this->registry->escape($value); } } else if ($type == TYPE_STRUN) { $value = $this->registry->unsanitize($value); } else if ($type == TYPE_NOCLEAN) { } else { trigger_error('Invalid clean type specified', E_USER_ERROR); } return $value; } } /*=====================================================================*\ || ################################################################### || # $HeadURL$ || # $Id$ || ################################################################### \*=====================================================================*/ ?>