Class TActiveRecord

Description

Base class for active records.

An active record creates an object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.

Active record objects are stateful, this is main difference between the TActiveRecord implementation and the TTableGateway implementation.

The essence of an Active Record is an object model of the domain (e.g. products, items) that incorporates both behavior and data in which the classes match very closely the record structure of an underlying database. Each Active Record is responsible for saving and loading to the database and also for any domain logic that acts on the data.

The Active Record provides methods that do the following:

  1. Construct an instance of the Active Record from a SQL result set row.
  2. Construct a new instance for later insertion into the table.
  3. Finder methods to wrap commonly used SQL queries and return Active Record objects.
  4. Update the database and insert into it the data in the Active Record.
Example:
  1.  class UserRecord extends TActiveRecord
  2.  {
  3.      const TABLE='users'//optional table name.
  4.  
  5.      public $username//corresponds to the fieldname in the table
  6.      public $email;
  7.  
  8.      //returns active record finder instance
  9.      public static function finder($className=__CLASS__)
  10.      {
  11.          return parent::finder($className);
  12.      }
  13.  }
  14.  
  15.  //create a connection and give it to the ActiveRecord manager.
  16.  $dsn 'pgsql:host=localhost;dbname=test';
  17.  $conn new TDbConnection($dsn'dbuser','dbpass');
  18.  TActiveRecordManager::getInstance()->setDbConnection($conn);
  19.  
  20.  //load the user record with username (primary key) 'admin'.
  21.  $user UserRecord::finder()->findByPk('admin');
  22.  $user->email 'admin@example.org';
  23.  $user->save()//update the 'admin' record.

Since v3.1.1, TActiveRecord starts to support column mapping. The physical column names (defined in database) can be mapped to logical column names (defined in active classes as public properties.) To use this feature, declare a static class variable COLUMN_MAPPING like the following:

  1.  class UserRecord extends TActiveRecord
  2.  {
  3.      const TABLE='users';
  4.      public static $COLUMN_MAPPING=array
  5.      (
  6.          'user_id'=>'username',
  7.          'email_address'=>'email',
  8.      );
  9.      public $username;
  10.      public $email;
  11.  }
In the above, the 'users' table consists of 'user_id' and 'email_address' columns, while the UserRecord class declares 'username' and 'email' properties. By using column mapping, we can regularize the naming convention of column names in active record.

Since v3.1.2, TActiveRecord enhanced its support to access of foreign objects. By declaring a public static variable RELATIONS like the following, one can access the corresponding foreign objects easily:

  1.  class UserRecord extends TActiveRecord
  2.  {
  3.      const TABLE='users';
  4.      public static $RELATIONS=array
  5.      (
  6.          'department'=>array(self::BELONGS_TO'DepartmentRecord''department_id'),
  7.          'contacts'=>array(self::HAS_MANY'ContactRecord''user_id'),
  8.      );
  9.  }
In the above, the users table is related with departments table (represented by DepartmentRecord) and contacts table (represented by ContactRecord). Now, given a UserRecord instance $user, one can access its department and contacts simply by: $user->department and $user->contacts. No explicit data fetching is needed. Internally, the foreign objects are fetched in a lazy way, which avoids unnecessary overhead if the foreign objects are not accessed at all.

Since v3.1.2, new events OnInsert, OnUpdate and OnDelete are available. The event OnInsert, OnUpdate and OnDelete methods are executed before inserting, updating, and deleting the current record, respectively. You may override these methods; a TActiveRecordChangeEventParameter parameter is passed to these methods. The property TActiveRecordChangeEventParameter::setIsValid of the parameter can be set to false to prevent the change action to be executed. This can be used, for example, to validate the record before the action is executed. For example, in the following the password property is hashed before a new record is inserted.

  1.  class UserRecord extends TActiveRecord
  2.  {
  3.       function OnInsert($param)
  4.       {
  5.           //parent method should be called to raise the event
  6.           parent::OnInsert($param);
  7.           $this->nounce md5(time());
  8.           $this->password md5($this->password.$this->nounce);
  9.       }
  10.  }

Since v3.1.3 you can also define a method that returns the table name.

  1.  class UserRecord extends TActiveRecord
  2.  {
  3.      public function table()
  4.      {
  5.           return 'users';
  6.      }
  7.  
  8.  }

  • author: Wei Zhuo <weizho[at]gmail[dot]com>
  • version: $Id: TActiveRecord.php 3004 2011-06-26 09:56:56Z ctrlaltca@gmail.com $
  • abstract:
  • since: 3.1

Located in /Data/ActiveRecord/TActiveRecord.php (line 149)

TComponent
   |
   --TActiveRecord
Class Constant Summary
 BELONGS_TO = 'BELONGS_TO'
 HAS_MANY = 'HAS_MANY'
 HAS_ONE = 'HAS_ONE'
 MANY_TO_MANY = 'MANY_TO_MANY'
 STATE_NEW = 0
Variable Summary
Method Summary
static TActiveRecord createRecord (string $type, array $data)
static TActiveRecord finder ([string $className = __CLASS__])
static void getActiveDbConnection ()
TActiveRecord __construct ([array $data = array()], [TDbConnection $connection = null])
void copyFrom ( $data)
int count ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
boolean delete ()
int deleteAll ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
void deleteAllByPks ( $keys)
int deleteByPk (mixed $keys)
boolean equals (TActiveRecord $record, [boolean $strict = false])
boolean fetchResultsFor (string $property)
TActiveRecord find (string|TActiveRecordCriteria $criteria, [mixed $parameters = array()])
array findAll ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
array findAllByIndex (TActiveRecordCriteria $criteria, array $fields, array $values)
array findAllByPks (mixed $keys)
array findAllBySql (string $sql, [array $parameters = array()])
TActiveRecord. findByPk (mixed $keys)
TActiveRecord, findBySql (string $sql, [array $parameters = array()])
mixed getColumnValue (string $columnName)
TSqlCriteria getRecordCriteria (string|TSqlCriteria $criteria, mixed $parameters, [array $args = array()])
array getRecordRelation (string $property)
TActiveRecordRelation, getRelationHandler (string $name, [array $args = array()])
boolean hasRecordRelation (string $property)
TActiveRecord populateObject (array $data)
array populateObjects (TDbDataReader $reader)
boolean save ()
void setColumnValue (string $columnName, mixed $value)
void setDbConnection (TDbConnection $connection)
mixed __call ( $method,  $args)
mixed __get (string $name)
void __set (string $name, mixed $value)
void __sleep ()
void __wakeup ()
Variables
static array $COLUMN_MAPPING = array() (line 174)

This static variable defines the column mapping.

The keys are physical column names as defined in database, and the values are logical column names as defined as public variable/property names for the corresponding active record class.

  • var: column mapping. Keys: physical column names, values: logical column names.
  • since: 3.1.1
  • access: public
static array $RELATIONS = array() (line 184)

This static variable defines the relationships.

The keys are public variable/property names defined in the AR class. Each value is an array, e.g. array(self::HAS_MANY, 'PlayerRecord').

  • var: relationship.
  • since: 3.1.1
  • access: public
TDbConnection $_connection (line 190)
  • var: database connection object.
  • access: protected
TActiveRecordInvalidFinderResult $_invalidFinderResult = null (line 199)

Defaults to 'null'

  • since: 3.1.5
  • access: protected
integer $_recordState (line 164)
  • var: record state: 0 = new, 1 = loaded, 2 = deleted.
  • since: 3.1.2
  • access: protected
Methods
static method createRecord (line 552)

Create an AR instance specified by the AR class name and initial data.

If the initial data is empty, the AR object will not be created and null will be returned. (You should use the "new" operator to create the AR instance in that case.)

  • return: the initialized AR object. Null if the initial data is empty.
  • since: 3.1.2
  • access: public
static TActiveRecord createRecord (string $type, array $data)
  • string $type: the AR class name
  • array $data: initial data to be populated into the AR object.
static method finder (line 385)

Returns the instance of a active record finder for a particular class.

The finder objects are static instances for each ActiveRecord class. This means that event handlers bound to these finder instances are class wide. Create a new instance of the ActiveRecord class if you wish to bound the event handlers to object instance.

  • return: active record finder instance.
  • access: public
static TActiveRecord finder ([string $className = __CLASS__])
  • string $className: active record class name.
static method getActiveDbConnection (line 313)
  • access: public
static void getActiveDbConnection ()
static method getRecordManager (line 401)

Gets the record manager for this object, the default is to call TActiveRecordManager::getInstance().

  • return: default active record manager.
  • access: public
static TActiveRecordManager getRecordManager ()
Constructor __construct (line 225)

Create a new instance of an active record with given $data. The record can be saved to the database specified by the $connection object.

  • access: public
TActiveRecord __construct ([array $data = array()], [TDbConnection $connection = null])
  • array $data: optional name value pair record data.
  • TDbConnection $connection: optional database connection this object record use.
copyFrom (line 302)

Copies data from an array or another object.

  • throws: TActiveRecordException if data is not array or not object.
  • access: public
void copyFrom ( $data)
  • $data
count (line 705)

Find the number of records.

  • return: number of records.
  • access: public
int count ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
  • string|TActiveRecordCriteria $criteria: SQL condition or criteria object.
  • mixed $parameters: parameter values.
createRelationContext (line 740)

Gets a static copy of the relationship context for given property (a key in $RELATIONS), returns null if invalid relationship. Keeps a null reference to all invalid relations called.

  • return: object containing information on the active record relationships for given property, null if invalid relationship
  • since: 3.1.2
  • access: protected
TActiveRecordRelationContext createRelationContext (string $name)
  • string $name: relationship/property name corresponding to keys in $RELATION array.
delete (line 448)

Deletes the current record from the database. Once deleted, this object can not be saved again in the same instance.

  • return: true if the record was deleted successfully, false otherwise.
  • access: public
boolean delete ()
deleteAll (line 512)

Delete multiple records using a criteria.

  • return: number of records deleted.
  • access: public
int deleteAll ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
  • string|TActiveRecordCriteria $criteria: SQL condition or criteria object.
  • mixed $parameters: parameter values.
deleteAllByPks (line 500)

Alias for deleteByPk()

  • access: public
void deleteAllByPks ( $keys)
  • $keys
deleteByPk (line 490)

Delete records by primary key. Usage:

  1.  $finder->deleteByPk($primaryKey)//delete 1 record
  2.  $finder->deleteByPk($key1,$key2,...)//delete multiple records
  3.  $finder->deleteByPk(array($key1,$key2,...))//delete multiple records

For composite primary keys (determined from the table definitions):

  1.  $finder->deleteByPk(array($key1,$key2))//delete 1 record
  2.  
  3.  //delete multiple records
  4.  $finder->deleteByPk(array($key1,$key2)array($key3,$key4),...);
  5.  
  6.  //delete multiple records
  7.  $finder->deleteByPk(arrayarray($key1,$key2)array($key3,$key4).. ));

  • return: number of records deleted.
  • access: public
int deleteByPk (mixed $keys)
  • mixed $keys: primary key values.
equals (line 356)

Compare two records using their primary key values (all column values if table does not defined primary keys). The default uses simple == for comparison of their values. Set $strict=true for identity comparison (===).

  • return: true if $record equals, false otherwise.
  • access: public
boolean equals (TActiveRecord $record, [boolean $strict = false])
  • TActiveRecord $record: another record to compare with.
  • boolean $strict: true to perform strict identity comparison
fetchResultsFor (line 786)

Tries to load the relationship results for the given property. The $property value should correspond to an entry key in the $RELATION array.

This method can be used to lazy load relationships.

  1.  class TeamRecord extends TActiveRecord
  2.  {
  3.      ...
  4.  
  5.      private $_players;
  6.      public static $RELATION=array
  7.      (
  8.          'players' => array(self::HAS_MANY'PlayerRecord'),
  9.      );
  10.  
  11.      public function setPlayers($array)
  12.      {
  13.          $this->_players=$array;
  14.      }
  15.  
  16.      public function getPlayers()
  17.      {
  18.          if($this->_players===null)
  19.              $this->fetchResultsFor('players');
  20.          return $this->_players;
  21.      }
  22.  }
  23.  Usage example:
  24.  $team TeamRecord::finder()->findByPk(1);
  25.  var_dump($team->players)//uses lazy load to fetch 'players' relation

  • return: true if relationship exists, false otherwise.
  • since: 3.1.2
  • access: protected
boolean fetchResultsFor (string $property)
  • string $property: relationship/property name corresponding to keys in $RELATION array.
find (line 578)

Find one single record that matches the criteria.

Usage:

  1.  $finder->find('username = :name AND password = :pass',
  2.                      array(':name'=>$name':pass'=>$pass));
  3.  $finder->find('username = ? AND password = ?'array($name$pass));
  4.  $finder->find('username = ? AND password = ?'$name$pass);
  5.  //$criteria is of TActiveRecordCriteria
  6.  $finder->find($criteria)//the 2nd parameter for find() is ignored.

  • return: matching record object. Null if no result is found.
  • access: public
TActiveRecord find (string|TActiveRecordCriteria $criteria, [mixed $parameters = array()])
  • string|TActiveRecordCriteria $criteria: SQL condition or criteria object.
  • mixed $parameters: parameter values.
findAll (line 594)

Same as find() but returns an array of objects.

  • return: matching record objects. Empty array if no result is found.
  • access: public
array findAll ([string|TActiveRecordCriteria $criteria = null], [mixed $parameters = array()])
  • string|TActiveRecordCriteria $criteria: SQL condition or criteria object.
  • mixed $parameters: parameter values.
findAllByIndex (line 693)

Fetches records using the sql clause "(fields) IN (values)", where fields is an array of column names and values is an array of values that the columns must have.

This method is to be used by the relationship handler.

  • return: matching active records. Empty array is returned if no result is found.
  • access: public
array findAllByIndex (TActiveRecordCriteria $criteria, array $fields, array $values)
  • TActiveRecordCriteria $criteria: additional criteria
  • array $fields: field names to match with "(fields) IN (values)" sql clause.
  • array $values: matching field values.
findAllByPks (line 640)

Find multiple records matching a list of primary or composite keys.

For scalar primary keys:

  1.  $finder->findAllByPk($key1$key2...);
  2.  $finder->findAllByPk(array($key1$key2...));

For composite keys:

  1.  $finder->findAllByPk(array($key1$key2)array($key3$key4)...);
  2.  $finder->findAllByPk(array(array($key1$key2)array($key3$key4)...));

  • return: matching ActiveRecords. Empty array is returned if no result is found.
  • access: public
array findAllByPks (mixed $keys)
  • mixed $keys: primary keys
findAllBySql (line 673)

Find records using full SQL, returns corresponding record object.

The names of the column retrieved must be defined in your Active Record class.

  • return: matching active records. Empty array is returned if no result is found.
  • access: public
array findAllBySql (string $sql, [array $parameters = array()])
  • array $parameters
  • string $sql: select SQL
findByPk (line 615)

Find one record using only the primary key or composite primary keys. Usage:

  1.  $finder->findByPk($primaryKey);
  2.  $finder->findByPk($key1$key2...);
  3.  $finder->findByPk(array($key1,$key2,...));

  • return: Null if no result is found.
  • access: public
TActiveRecord. findByPk (mixed $keys)
  • mixed $keys: primary keys
findBySql (line 656)

Find records using full SQL, returns corresponding record object.

The names of the column retrieved must be defined in your Active Record class.

  • return: null if no result is returned.
  • access: public
TActiveRecord, findBySql (string $sql, [array $parameters = array()])
  • array $parameters
  • string $sql: select SQL
getColumnValue (line 975)

Retrieves the column value according to column name.

This method is used internally.

  • return: the corresponding column value
  • since: 3.1.1
  • access: public
mixed getColumnValue (string $columnName)
  • string $columnName: the column name (as defined in database schema)
getDbConnection (line 325)

Gets the current Db connection, the connection object is obtained from the TActiveRecordManager if connection is currently null.

  • return: current db connection for this object.
  • access: public
TDbConnection getDbConnection ()
getInvalidFinderResult (line 859)
  • return: Defaults to 'Null'.
  • see: TActiveRecordManager::getInvalidFinderResult
  • since: 3.1.5
  • access: public
TActiveRecordInvalidFinderResult getInvalidFinderResult ()
getRecordCriteria (line 891)

Create a new TSqlCriteria object from a string $criteria. The $args are additional parameters and are used in place of the $parameters if $parameters is not an array and $args is an arrary.

  • return: criteria object.
  • access: protected
TSqlCriteria getRecordCriteria (string|TSqlCriteria $criteria, mixed $parameters, [array $args = array()])
  • string|TSqlCriteria $criteria: sql criteria
  • mixed $parameters: parameters passed by the user.
  • array $args: additional parameters obtained from function_get_args().
getRecordGateway (line 409)
  • return: record table gateway.
  • access: public
TActiveRecordGateway getRecordGateway ()
getRecordRelation (line 1003)
  • return: relation definition for the specified property
  • since: 3.1.2
  • access: public
array getRecordRelation (string $property)
  • string $property: relation property name
getRecordRelations (line 1014)
  • return: all relation definitions declared in the AR class
  • since: 3.1.2
  • access: public
array getRecordRelations ()
getRecordTableInfo (line 343)
  • return: the meta information of the table associated with this AR class.
  • access: public
TDbTableInfo getRecordTableInfo ()
getRelationHandler (line 720)

Returns the active record relationship handler for $RELATION with key value equal to the $property value.

  • return: null if the context or the handler doesn't exist
  • access: protected
TActiveRecordRelation, getRelationHandler (string $name, [array $args = array()])
  • string $name: relationship/property name corresponding to keys in $RELATION array.
  • array $args: method call arguments.
hasRecordRelation (line 1024)
  • return: whether a relation is declared for the specified AR property
  • since: 3.1.2
  • access: public
boolean hasRecordRelation (string $property)
  • string $property: AR property name
onCreateCommand (line 916)

Raised when a command is prepared and parameter binding is completed.

The parameter object is TDataGatewayEventParameter of which the TDataGatewayEventParameter::getCommand property can be inspected to obtain the sql query to be executed.

Note well that the finder objects obtained from ActiveRecord::finder() method are static objects. This means that the event handlers are bound to a static finder object and not to each distinct active record object.

  • access: public
void onCreateCommand (TDataGatewayEventParameter $param)
onDelete (line 953)

Raised before the record attempt to delete its data from the database.

To prevent the delete operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false.

  • access: public
void onDelete (TActiveRecordChangeEventParameter $param)
onExecuteCommand (line 933)

Raised when a command is executed and the result from the database was returned.

The parameter object is TDataGatewayResultEventParameter of which the TDataGatewayEventParameter::getResult property contains the data return from the database. The data returned can be changed by setting the TDataGatewayEventParameter::setResult property.

Note well that the finder objects obtained from ActiveRecord::finder() method are static objects. This means that the event handlers are bound to a static finder object and not to each distinct active record object.

  • access: public
void onExecuteCommand (TDataGatewayResultEventParameter $param)
onInsert (line 943)

Raised before the record attempt to insert its data into the database.

To prevent the insert operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false.

  • access: public
void onInsert (TActiveRecordChangeEventParameter $param)
onUpdate (line 963)

Raised before the record attempt to update its data in the database.

To prevent the update operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false.

  • access: public
void onUpdate (TActiveRecordChangeEventParameter $param)
populateObject (line 525)

Populates a new record with the query result.

This is a wrapper of createRecord.

  • return: object record, null if data is empty.
  • access: protected
TActiveRecord populateObject (array $data)
  • array $data: name value pair of record data
populateObjects (line 535)
  • return: the AR objects populated by the query result
  • since: 3.1.2
  • access: protected
array populateObjects (TDbDataReader $reader)
save (line 418)

Saves the current record to the database, insert or update is automatically determined.

  • return: true if record was saved successfully, false otherwise.
  • access: public
boolean save ()
setColumnValue (line 990)

Sets the column value according to column name.

This method is used internally.

  • since: 3.1.1
  • access: public
void setColumnValue (string $columnName, mixed $value)
  • string $columnName: the column name (as defined in database schema)
  • mixed $value: the corresponding column value
setDbConnection (line 335)
  • access: public
void setDbConnection (TDbConnection $connection)
  • TDbConnection $connection: db connection object for this record.
setInvalidFinderResult (line 874)

Define the way an active record finder react if an invalid magic-finder invoked

  • see: TActiveRecordManager::setInvalidFinderResult
  • since: 3.1.5
  • access: public
void setInvalidFinderResult (TActiveRecordInvalidFinderResult|null $value)
__call (line 823)

Dynamic find method using parts of method name as search criteria.

Method name starting with "findBy" only returns 1 record. Method name starting with "findAllBy" returns 0 or more records. Method name starting with "deleteBy" deletes records by the trail criteria. The condition is taken as part of the method name after "findBy", "findAllBy" or "deleteBy".

The following are equivalent:

  1.  $finder->findByName($name)
  2.  $finder->find('Name = ?'$name);
  1.  $finder->findByUsernameAndPassword($name,$pass)// OR may be used
  2.  $finder->findBy_Username_And_Password($name,$pass)// _OR_ may be used
  3.  $finder->find('Username = ? AND Password = ?'$name$pass);
  1.  $finder->findAllByAge($age);
  2.  $finder->findAll('Age = ?'$age);
  1.  $finder->deleteAll('Name = ?'$name);
  2.  $finder->deleteByName($name);

  • return: single record if method name starts with "findBy", 0 or more records if method name starts with "findAllBy"
  • access: public
mixed __call ( $method,  $args)
  • $method
  • $args

Redefinition of:
TComponent::__call()
Calls a method.
__get (line 243)

Magic method for reading properties.

This method is overriden to provide read access to the foreign objects via the key names declared in the RELATIONS array.

  • return: property value.
  • since: 3.1.2
  • access: public
mixed __get (string $name)
  • string $name: property name

Redefinition of:
TComponent::__get()
Returns a property value or an event handler list by property or event name.
__set (line 261)

Magic method for writing properties.

This method is overriden to provide write access to the foreign objects via the key names declared in the RELATIONS array.

  • since: 3.1.2
  • access: public
void __set (string $name, mixed $value)
  • string $name: property name
  • mixed $value: property value.

Redefinition of:
TComponent::__set()
Sets value of a component property.
__sleep (line 204)

Prevent __call() method creating __sleep() when serializing.

  • access: public
void __sleep ()

Redefinition of:
TComponent::__sleep()
Returns an array with the names of all variables of that object that should be serialized.
__wakeup (line 212)

Prevent __call() method creating __wakeup() when unserializing.

  • access: public
void __wakeup ()

Redefinition of:
TComponent::__wakeup()
Do not call this method. This is a PHP magic method that will be called automatically after any unserialization; it can perform reinitialization tasks on the object.

Inherited Methods

Inherited From TComponent

TComponent::addParsedObject()
TComponent::attachEventHandler()
TComponent::canGetProperty()
TComponent::canSetProperty()
TComponent::createdOnTemplate()
TComponent::detachEventHandler()
TComponent::evaluateExpression()
TComponent::evaluateStatements()
TComponent::getEventHandlers()
TComponent::getSubProperty()
TComponent::hasEvent()
TComponent::hasEventHandler()
TComponent::hasProperty()
TComponent::raiseEvent()
TComponent::setSubProperty()
TComponent::__call()
TComponent::__get()
TComponent::__set()
TComponent::__sleep()
TComponent::__wakeup()
Class Constants
BELONGS_TO = 'BELONGS_TO' (line 151)
HAS_MANY = 'HAS_MANY' (line 153)
HAS_ONE = 'HAS_ONE' (line 152)
MANY_TO_MANY = 'MANY_TO_MANY' (line 154)
STATE_DELETED = 2 (line 158)
STATE_LOADED = 1 (line 157)
STATE_NEW = 0 (line 156)

Documentation generated on Mon, 25 Jun 2012 14:37:11 +0200 by phpDocumentor 1.4.3