fActiveRecordabstract classv1.0.0b56

An active record pattern base class

This class uses fORMSchema to inspect your database and provides an OO interface to a single database table. The class dynamically handles method calls for getting, setting and other operations on columns. It also dynamically handles retrieving and storing related records.

Changes:
1.0.0b56Fixed $force_cascade in delete() to work even when the restricted relationship is once-removed through an unrestricted relationship 3/9/10
1.0.0b55Fixed load() to that related records are cleared, requiring them to be loaded from the database 3/4/10
1.0.0b54Fixed detection of route name for one-to-one relationships in delete() 3/3/10
1.0.0b53Fixed a bug where related records with a primary key that contained a foreign key with an on update cascade clause would be deleted when changing the value of the column referenced by the foreign key 12/17/09
1.0.0b52Backwards Compatibility Break - Added the $force_cascade parameter to delete() and store() - enabled calling prepare() and encode() for non-column get methods, added ::has{RelatedRecords}() methods 12/16/09
1.0.0b51Made changed() properly recognize that a blank string and NULL are equivalent due to the way that set() casts values 11/14/09
1.0.0b50Fixed a bug with trying to load by a multi-column primary key where one of the columns was not specified 11/13/09
1.0.0b49Fixed a bug affecting where conditions with columns that are not null but have a default value 11/3/09
1.0.0b48Updated code for the new fORMDatabase and fORMSchema APIs 10/28/09
1.0.0b47Changed ::associate{RelatedRecords}(), ::link{RelatedRecords}() and ::populate{RelatedRecords}() to allow for method chaining 10/22/09
1.0.0b46Changed SQL statements to use value placeholders and identifier escaping 10/22/09
1.0.0b45Added support for !~, &~, >< and OR comparisons to checkConditions(), made object handling in checkConditions() more robust 9/21/09
1.0.0b44Updated code for new fValidationException API 9/18/09
1.0.0b43Updated code for new fRecordSet API 9/16/09
1.0.0b42Corrected a grammar bug in hash() 9/9/09
1.0.0b41Fixed a bug in the last version that would cause issues with classes containing a custom class to table mapping 9/1/09
1.0.0b40Added a check to the configuration part of __construct() to ensure modelled tables have primary keys 8/26/09
1.0.0b39Changed set{ColumnName}() methods to return the record for method chaining, fixed a bug with loading by multi-column unique constraints, fixed a bug with load() 8/26/09
1.0.0b38Updated changed() to do a strict comparison when at least one value is NULL 8/17/09
1.0.0b37Changed __construct() to allow any Iterator object instead of just fResult 8/12/09
1.0.0b36Fixed a bug with setting NULL values from v1.0.0b33 8/10/09
1.0.0b35Fixed a bug with unescaping data in loadFromResult() from v1.0.0b33 8/10/09
1.0.0b34Added the ability to compare fActiveRecord objects in checkConditions() 8/7/09
1.0.0b33Performance enhancements to __call() and __construct() 8/7/09
1.0.0b32Changed delete() to remove auto-incrementing primary keys after the post::delete() hook 7/29/09
1.0.0b31Fixed a bug with loading a record by a multi-column primary key, fixed one-to-one relationship API 7/21/09
1.0.0b30Updated reflect() for new fORM::callReflectCallbacks() API 7/13/09
1.0.0b29Updated to use new fORM::callInspectCallbacks() method 7/13/09
1.0.0b28Fixed a bug where records would break the identity map at the end of store() 7/9/09
1.0.0b27Changed hash() from a protected method to a static public/internal method that requires the class name for non-fActiveRecord values 7/9/09
1.0.0b26Added checkConditions() from fRecordSet 7/8/09
1.0.0b25Updated validate() to use new fORMValidation API, including new message search/replace functionality 7/1/09
1.0.0b24Changed validate() to remove duplicate validation messages 6/30/09
1.0.0b23Updated code for new fORMValidation::validateRelated() API 6/26/09
1.0.0b22Added support for the $formatting parameter to encode methods on char, text and varchar columns 6/19/09
1.0.0b21Performance tweaks and updates for fORM and fORMRelated API changes 6/15/09
1.0.0b20Changed replacement values in preg_replace() calls to be properly escaped 6/11/09
1.0.0b19Added list{RelatedRecords}() methods, updated code for new fORMRelated API 6/2/09
1.0.0b18Changed store() to use new fORMRelated::store() method 6/2/09
1.0.0b17Added some missing parameter information to reflect() 6/1/09
1.0.0b16Fixed bugs in __clone() and replicate() related to recursive relationships 5/20/09
1.0.0b15Fixed an incorrect variable reference in store() 5/6/09
1.0.0b14store() no longer tries to get an auto-incrementing ID from the database if a value was set 5/2/09
1.0.0b13delete(), load(), populate() and store() now return the record to allow for method chaining 3/23/09
1.0.0b12set() now removes commas from integers and floats to prevent validation issues 3/22/09
1.0.0b11encode() no longer adds commas to floats 3/22/09
1.0.0b10__wakeup() no longer registers the record as the definitive copy in the identity map 3/22/09
1.0.0b9Changed __construct() to populate database default values when a non-existing record is instantiated 1/12/09
1.0.0b8Fixed exists() to properly detect cases when an existing record has one or more NULL values in the primary key 1/11/09
1.0.0b7Fixed __construct() to not trigger the post::__construct() hook when force-configured 12/30/08
1.0.0b6__construct() now accepts an associative array matching any unique key or primary key, fixed the post::__construct() hook to be called once for each record 12/26/08
1.0.0b5Fixed replicate() to use plural record names for related records 12/12/08
1.0.0b4Added replicate() to allow cloning along with related records 12/12/08
1.0.0b3Changed __clone() to clone objects contains in the values and cache arrays 12/11/08
1.0.0b2Added the __clone() method to properly duplicate a record 12/4/08
1.0.0bThe initial implementation 8/4/07

Static Variables

::$callback_cacheprotected

Caches callbacks for methods

Type

array

::$configuredprotected

An array of flags indicating a class has been configured

Type

array

::$identity_mapprotected

Maps objects via their primary key

Type

array

::$method_name_cacheprotected

Caches method name parsings

Type

array

::$replicate_levelprotected

Keeps track of the recursive call level of replication so we can clear the map

Type

integer

::$replicate_mapprotected

Keeps a list of records that have been replicated

Type

array

::$unescape_mapprotected

Contains a list of what columns in each class need to be unescaped and what data type they are

Type

array

Variables

->cacheprotected

A data store for caching data related to a record, the structure of this is completely up to the developer using it

Type

array

->old_valuesprotected

The old values for this record

Column names are the keys, but a column key will only be present if a value has changed. The value associated with each key is an array of old values with the first entry being the oldest value. The static methods assign(), changed(), hasOld() and retrieveOld() are the best way to interact with this array.

Type

array

Records that are related to the current record via some relationship

This array is used to cache related records so that a database query is not required each time related records are accessed. The fORMRelated class handles most of the interaction with this array.

Type

array

->valuesprotected

The values for this record

This array always contains every column in the database table as a key with the value being the current value.

Type

array

Static Methods

::assign() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Sets a value to the $values array, preserving the old value in $old_values

Signatures

void assign( string $column, mixed $value )

void assign( array $values, array $old_values )

Parameters

array &$values The current values
array &$old_values The old values
string $column The column to set
mixed $value The value to set

::changed() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Checks to see if a value has changed

Signatures

boolean changed( string $column )

boolean changed( array $values, array $old_values )

Parameters

array &$values The current values
array &$old_values The old values
string $column The column to check

Returns

If the value for the column specified has changed

::checkConditions() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Checks to see if a record matches all of the conditions

Signature

boolean checkConditions( fActiveRecord $record, array $conditions )

Parameters

fActiveRecord $record The record to check
array $conditions The conditions to check - see fRecordSet::filter() for format details

Returns

If the record meets all conditions

::compose() protected

Composes text using fText if loaded

Signature

string compose( string $message, mixed $component )

Parameters

string $message The message to compose
mixed $component [, ... ] A string or number to insert into the message

Returns

The composed and possible translated message

::forceConfigure() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Ensures that configure() has been called for the class

Signature

void forceConfigure( string $class )

Parameters

string $class The class to configure

::hash() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Takes a row of data or a primary key and makes a hash from the primary key

Signature

string|NULL hash( fActiveRecord|array|string|int $record, string $class=NULL )

Parameters

fActiveRecord|array|string|int $record An fActiveRecord object, an array of the records data, an array of primary key data or a scalar primary key value
string $class The class name, if $record isn't an fActiveRecord

Returns

A hash of the record's primary key value or NULL if the record doesn't exist yet

::hasOld() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Checks to see if an old value exists for a column

Signatures

boolean hasOld( string $column )

boolean hasOld( array $old_values )

Parameters

array &$old_values The old values
string $column The column to set

Returns

If an old value for that column exists

::reset() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Resets the configuration of the class

Signature

void reset( )

::retrieveOld() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Retrieves the oldest value for a column or all old values

Signatures

mixed retrieveOld( string $column, mixed $default, boolean $return_all )

mixed retrieveOld( array $old_values )

Parameters

array &$old_values The old values
string $column The column to get
mixed $default The default value to return if no value exists
boolean $return_all Return the array of all old values for this column instead of just the oldest

Returns

The old value for the column

Methods

->__construct() public

Creates a new record or loads one from the database - if a primary key or unique key is provided the record will be loaded

Signature

fActiveRecord __construct( mixed $key=NULL )

Parameters

mixed $key The primary key or unique key value(s) - single column primary keys will accept a scalar value, all others must be an associative array of (string) {column} => (mixed) {value}

Throws

fNotFoundException
When the record specified by $key can not be found in the database

->__call() public

Handles all method calls for columns, related records and hook callbacks

Dynamically handles get, set, prepare, encode and inspect methods for each column in this record. Method names are in the form verbColumName().

This method also handles associate, build, count, has, and link verbs for records in many-to-many relationships; build, count, has and populate verbs for all related records in one-to-many relationships and create, has and populate verbs for all related records in one-to-one relationships, and the create verb for all related records in many-to-one relationships.

Method callbacks registered through fORM::registerActiveRecordMethod() will be delegated via this method.

Signature

mixed __call( string $method_name, array $parameters )

Parameters

string $method_name The name of the method called
array $parameters The parameters passed

Returns

The value returned by the method called

->__clone() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Creates a clone of a record

If the record has an auto incrementing primary key, the primary key will be erased in the clone. If the primary key is not auto incrementing, the primary key will be left as-is in the clone. In either situation the clone will return FALSE from the exists() method until store() is called.

Signature

fActiveRecord __clone( )

->__get() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

All requests that hit this method should be requests for callbacks

Signature

callback __get( string $method )

Parameters

string $method The method to create a callback for

Returns

The callback for the method requested

->__wakeup() internal public

Please note: this method is public, however it is primarily intended for internal use by Flourish and will normally not be useful in site/application code

Configure itself when coming out of the session. Records from the session are NOT hooked into the identity map.

Signature

void __wakeup( )

->configure() protected

Allows the programmer to set features for the class

This method is only called once per page load for each class.

Signature

void configure( )

->constructInsertParams() protected

Creates the fDatabase::translatedQuery() insert statement params

Signature

array constructInsertParams( boolean $new_autoincrementing_record, string $pk_column )

Parameters

boolean $new_autoincrementing_record If the record is new and has an auto-incrementing primary key
string $pk_column The auto-incrementing primary key column for a new record

Returns

The parameters for an fDatabase::translatedQuery() SQL insert statement

->constructUpdateParams() protected

Creates the fDatabase::translatedQuery() update statement params

Signature

array constructUpdateParams( )

Returns

The parameters for an fDatabase::translatedQuery() SQL update statement

->delete() public

Deletes a record from the database, but does not destroy the object

This method will start a database transaction if one is not already active.

Signature

fActiveRecord delete( boolean $force_cascade=FALSE )

Parameters

boolean $force_cascade When TRUE, this will cause all child objects to be deleted, even if the ON DELETE clause is RESTRICT or NO ACTION

Returns

The record object, to allow for method chaining

->encode() protected

Retrieves a value from the record and prepares it for output into an HTML form element.

Below are the transformations performed:

  • varchar, char, text: will run through fHTML::encode(), if TRUE is passed the text will be run through fHTMLconvertNewLinks() and fHTML::makeLinks()
  • float: takes 1 parameter to specify the number of decimal places
  • date, time, timestamp: format() will be called on the fDate/fTime/fTimestamp object with the 1 parameter specified
  • objects: the object will be converted to a string by __toString() or a (string) cast and then will be run through fHTML::encode()
  • all other data types: the value will be run through fHTML::encode()

Signature

string encode( string $column, string $formatting=NULL )

Parameters

string $column The name of the column to retrieve
string $formatting The formatting string

Returns

The encoded value for the column specified

->exists() public

Checks to see if the record exists in the database

Signature

boolean exists( )

Returns

If the record exists in the database

->fetchResultFromUniqueKey() protected

Loads a record from the database based on a UNIQUE key

Signature

void fetchResultFromUniqueKey( array $values )

Parameters

array $values The UNIQUE key values to try and load with

Throws

fNotFoundException

->get() protected

Retrieves a value from the record

Signature

mixed get( string $column )

Parameters

string $column The name of the column to retrieve

Returns

The value for the column specified

->inspect() protected

Retrieves information about a column

Signature

mixed inspect( string $column, string $element=NULL )

Parameters

string $column The name of the column to inspect
string $element The metadata element to retrieve

Returns

The metadata array for the column, or the metadata element specified

->load() public

Loads a record from the database

Signature

fActiveRecord load( )

Returns

The record object, to allow for method chaining

Throws

fNotFoundException
When the record could not be found in the database

->loadFromIdentityMap() protected

Tries to load the object (via references to class vars) from the fORM identity map

Signature

boolean loadFromIdentityMap( array $row, string $hash )

Parameters

array $row The data source for the primary key values
string $hash The unique hash for this record

Returns

If the load was successful

->loadFromResult() protected

Loads a record from the database directly from a result object

Signature

boolean loadFromResult( Iterator $result, boolean $ignore_identity_map=FALSE )

Parameters

Iterator $result The result object to use for loading the current object
boolean $ignore_identity_map If the identity map should be ignored and the values loaded no matter what

Returns

If the record was loaded from the identity map

->populate() public

Sets the values for this record by getting values from the request through the fRequest class

Signature

fActiveRecord populate( )

Returns

The record object, to allow for method chaining

->prepare() protected

Retrieves a value from the record and prepares it for output into html.

Below are the transformations performed:

  • varchar, char, text: will run through fHTML::prepare(), if TRUE is passed the text will be run through fHTMLconvertNewLinks() and fHTML::makeLinks()
  • boolean: will return 'Yes' or 'No'
  • integer: will add thousands/millions/etc. separators
  • float: will add thousands/millions/etc. separators and takes 1 parameter to specify the number of decimal places
  • date, time, timestamp: format() will be called on the fDate/fTime/fTimestamp object with the 1 parameter specified
  • objects: the object will be converted to a string by __toString() or a (string) cast and then will be run through fHTML::prepare()

Signature

string prepare( string $column, mixed $formatting=NULL )

Parameters

string $column The name of the column to retrieve
mixed $formatting The formatting parameter, if applicable

Returns

The formatted value for the column specified

->reflect() public

Generates a pre-formatted block of text containing the method signatures for all methods (including dynamic ones)

Signature

string reflect( boolean $include_doc_comments=FALSE )

Parameters

boolean $include_doc_comments If the doc block comments for each method should be included

Returns

A preformatted block of text with the method signatures and optionally the doc comment

->replicate() public

Generates a clone of the current record, removing any auto incremented primary key value and allowing for replicating related records

This method will accept three different sets of parameters:

  • No parameters: this object will be cloned
  • A single TRUE value: this object plus all many-to-many associations and all child records (recursively) will be cloned
  • Any number of plural related record class names: the many-to-many associations or child records that correspond to the classes specified will be cloned

The class names specified can be a simple class name if there is only a single route between the two corresponding database tables. If there is more than one route between the two tables, the class name should be substituted with a string in the format 'RelatedClass{route}'.

Signature

fActiveRecord replicate( string $related_class=NULL )

Parameters

string $related_class [, ... ] The plural related class to replicate - see method description for details

Returns

The cloned record

->set() protected

Sets a value to the record

Signature

fActiveRecord set( string $column, mixed $value )

Parameters

string $column The column to set the value to
mixed $value The value to set

Returns

This record, to allow for method chaining

->store() public

Stores a record in the database, whether existing or new

This method will start database and filesystem transactions if they have not already been started.

Signature

fActiveRecord store( boolean $force_cascade=FALSE )

Parameters

boolean $force_cascade When storing related records, this will force deleting child records even if they have their own children in a relationship with an RESTRICT or NO ACTION for the ON DELETE clause

Returns

The record object, to allow for method chaining

Throws

fValidationException
When validate() throws an exception

->validate() public

Validates the values of the record against the database and any additional validation rules

Signature

void|array validate( boolean $return_messages=FALSE )

Parameters

boolean $return_messages If an array of validation messages should be returned instead of an exception being thrown

Returns

If $return_messages is TRUE, an array of validation messages will be returned

Throws

fValidationException
When the record, or one of the associated records, violates one of the validation rules for the class or can not be properly stored in the database