Location: PHPKode > projects > Dbscript > db/library/dbscript/record.php
<?php

  /** 
   * dbscript for PHP 4 & 5 - restful crud framework
   * @version 0.3.0 -- 10-Jun-2007
   * @author Brian Hendrickson <hide@address.com>
   * @link http://dbscript.net/
   * @copyright Copyright 2007 Brian Hendrickson
   * @package dbscript
   * @license http://www.opensource.org/licenses/mit-license.php MIT License
   */

  /**
   * Record
   * 
   * an item in a database table.
   * 
   * Usage:
   * <code>
   * // INSERT
   * $User = $db->get_record( 'people' );
   * $User->save();
   * // UPDATE
   * $User = $db->get_record( 'people', $req->userid );
   * $User->set_value( 'first_name', $req->first_name );
   * // DELETE
   * $User = $db->get_record( 'people', $req->userid );
   * $db->delete_record( $User );
   * // SELECT ONE
   * $User = $db->get_record( 'people', $req->userid );
   * print "Hello, $User->first_name!";
   * // SELECT MULTIPLE
   * $people = $db->get_recordset( "SELECT * FROM people WHERE disk_usage > 1000" );
   * </code>
   * 
   * More info...
   * {@link http://dbscript.net/record}
   * 
   * @package dbscript
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @version 0.3.0
   */

class Record {

  /**
   * attribute names and data from the database field
   * @var string[]
   */
  var $attributes;

  /**
   * list of changed fields since last save_changes
   * @var string[]
   */
  var $modified_fields;
  
  /**
   * primary key field
   * @var string
   */
  var $primary_key;

  /**
   * arguments from Record object instantiation
   * @var string[]
   */
  var $func_args;

  /**
   * fields to SELECT if not *
   * @var string[]
   */
  var $select;

  /**
   * list of related records returned by query
   * @var string[]
   */
  var $children;

  /**
   * sql query used to fetch this record
   * @var string
   */
  var $selecttext;
  
  /**
   * true if this is an unsaved skeleton record
   * @var boolean
   */
  var $skeleton;

  /**
   * true if this record is an unsaved skeleton record
   * @var string[]
   */
  var $relationships;

  /**
   * name of database table
   * @var string
   */
  var $table;

  /**
   * true if the record exists in the database
   * @var string
   */
  var $exists;
  
  var $last_modified;
  
  var $etag;
  
  /**
   * Record
   * 
   * initialize a new record data object
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string table
   */
  function Record( $table, &$db ) {
    trigger_before( 'Record', $this, $db );
    $func_args = func_get_args();
    // check to see if field names were passed via the awesome "dot notation"
    // otherwise we select all fields, using all system memory until crash.
    $select = explode(".",$table);
    if (count($select) > 1) {
      for ($p=1;$p<count($select);$p++) {
        if ($p == 1) {
          $this->selecttext = $select[$p];
        } else {
          $this->selecttext .= "," . $select[$p];
        }
      }
      $this->table = $select[0];
      $table = $select[0];
    } else {
      $this->table = $table;
      $this->selecttext = "*";
    }
    
    // the record does not exist in the database
    $this->exists = false;
    // check for a primary key as the fourth argument
    if (isset($func_args[3])) {
      $this->primary_key = $func_args[3];
    } elseif (isset($db->models[$table]->primary_key)) {
      $this->primary_key = $db->models[$table]->primary_key;
    } else {
      $this->primary_key = "id";
    }
    // if a record ID was passed, fetch the record
    if (isset($func_args[2])) {
      $db->fetch_record($this,$func_args[2]);
      if ( isset( $db->models[$table]->primary_key ) ) {
        $this->primary_key = $db->models[$table]->primary_key;
      }
    } else {
      // otherwise a new blank record is created
      $this->attributes = array();
      $this->modified_fields = array();
      $this->relationships = array();
      $this->children = array();
      $this->skeleton = false;
      $this->set_value($this->primary_key,"");
      if ( isset( $db->models[$table] ) ) {
        $f = array();
        foreach ($db->models[$table]->field_array as $field=>$data_type) {
          $f[$field] = "";
        }
        $db->set_attributes( $this, $f );
      }
    }
    trigger_after( 'Record', $this, $db );
  }

  /**
   * Field Names
   * 
   * get a list of Record attributes
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @return string[]
   */
  function field_names() {
    $arr = array();
    foreach ( array_keys( $this->attributes ) as $field ) {
      if ($field != $this->primary_key) {
        $arr[] = $field;
      }
    }
    return $arr;
  }

  /**
   * Set Value
   * 
   * change a Record attribute value, and
   * register the change in the database
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string field_name
   * @param string value
   */
  function set_value($field,$value) {
    $db =& db_object();
    trigger_before( 'set_value', $this, $db );
    if (!(isset($this->attributes[$this->primary_key]))) {
      $pkfield = $this->primary_key;
      $this->attributes[$pkfield] = "";
      $this->$pkfield =& $this->attributes[$pkfield];
    }
    if ($this->validate_field($field,$value)) {
      if ($db->models[$this->table]->is_blob($field) && is_array($value))
        $value = $value['tmp_name'];
      $this->attributes[$field] = $value;
      if ( !( isset( $this->$field ) ) )
        $this->$field =& $this->attributes[$field];
      $this->modified_fields[] = $field;
    } else {
      trigger_error("the new value for $field is invalid", E_USER_ERROR );
    }
    trigger_after( 'set_value', $this, $db );
  }

  /**
   * Save Changes
   * 
   * Save attributes changed via ->set_value( field, new_value )
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   */
  function save_changes() {
    $db =& db_object();
    $result = $db->save_record($this);
    if ($result)
      $this->exists = true;
    return $result;
  }
  
  /**
   * Save
   * 
   * Save all attributes into the database
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   */
  function save() {
    $db =& db_object();
    foreach ( array_keys( $this->attributes ) as $field ) {
      $this->modified_fields[] = $field;
    }
    $result = $db->save_record($this);
    if ($result)
      $this->exists = true;
    return $result;
  }
  
  /**
   * First Child
   * 
   * get the first Record returned from a related table
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string table
   * @return Record
   */  
  function FirstChild( $table=NULL ) {
    $db =& db_object();
    if (!(isset($db->models[$table]))) return false;
    $rs =& $db->recordsets[$this->table];
    if (!$rs) return false;
    if (!($this->ChildCount( $table ) > 0)) {
      return $db->get_record( $table );
    }
    if ( isset( $rs->relations[$this->attributes[$this->primary_key]][$table] ) )
      return $rs->FirstChild( $this->attributes[$this->primary_key], $table );
    return false;
  }

  /**
   * Next Child
   * 
   * Iterate to the next Record returned from a related table
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string table
   * @return Record
   */
  function NextChild( $table=NULL ) {
    $db =& db_object();
    $rs =& $db->recordsets[$this->table];
    if (!$rs) return false;
    if ( isset( $rs->relations[$this->attributes[$this->primary_key]][$table] ) )
      return $rs->NextChild( $this->attributes[$this->primary_key], $table );
    return false;
  }

  /**
   * Child Count
   * 
   * Count the number of related records from a specific table
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string table
   * @return Record
   */    
  function ChildCount( $table ) {
    if ( isset( $this->children[$table] ) )
      return count( $this->children[$table] );
    return 0;
  }

  /**
   * Has and Belongs To Many
   * 
   * set a 'child-many' relationship
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string relstring
   */
  function has_and_belongs_to_many( $relstring ) {
    $this->relationships[$relstring] = 'child-many';
  }

  /**
   * Belongs To
   * 
   * set a 'child-one' relationship
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string relstring
   */
  function belongs_to( $relstring ) {
    $this->relationships[$relstring] = 'child-one';
  }

  /**
   * Has Many
   * 
   * set a 'parent-many' relationship
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string relstring
   */
  function has_many( $relstring ) {
    $this->relationships[$relstring] = 'parent-many';
  }

  /**
   * Has One
   * 
   * set a 'parent-one' relationship
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string relstring
   */
  function has_one( $relstring ) {
    $this->relationships[$relstring] = 'parent-one';
  }

  /**
   * Is Skeleton
   * 
   * Set the skeleton flag on a record
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   */
  function is_skeleton() {
    $this->skeleton = true;
  }

  /**
   * Validate Field
   * 
   * Look for a callback function for this field
   * 
   * @author Brian Hendrickson <hide@address.com>
   * @access public
   * @param string field_name
   * @param string value
   */
  function validate_field($field,&$value) {
    $function_name = "validate_" . $this->table . "_" . $field;
    if (function_exists($function_name)) {
      return $function_name($value);
    } else {
      return true;
    }
  }

}

?>
Return current item: Dbscript