Flourish PHP Unframework

fRecordSet

class, implements IteratorAggregate ArrayAccess Countable , v1.0.0b47

A lightweight, iterable set of fActiveRecord-based objects

Changes:
1.0.0b47Fixed the new version of precount() to work with tables having an explicit schema 9/21/12
1,0,0b46Fixed a bug with precount() not working for self-joining tables 9/16/12
1.0.0b45Added support for the starts with like, ^~, and ends with like, $~, operators to both build() and filter() 6/20/11
1.0.0b44Backwards Compatibility Break - sort() and sortByCallback() now return a new fRecordSet instead of sorting the record set in place 6/20/11
1.0.0b43Added the ability to pass SQL and values to buildFromSQL(), added the ability to manually pass the $limit and $page to buildFromArray() and buildFromSQL(), changed slice() to remember $limit and $page if possible when $remember_original_count is TRUE 1/11/11
1.0.0b42Updated class to use fORM::getRelatedClass() 11/24/10
1.0.0b41Added support for PHP 5.3 namespaced fActiveRecord classes 11/11/10
1.0.0b40Added the tally() method 9/28/10
1.0.0b39Backwards Compatibility Break - removed the methods fetchRecord(), http://www.php.net/current, http://www.php.net/key, http://www.php.net/next, http://www.php.net/rewind and valid() and the Iterator interface - and the $pointer parameter for callbacks registered via fORM::registerRecordSetMethod() was replaced with the $method_name parameter - added the methods getIterator(), getLimit(), getPage(), getPages(), getRecord(), offsetExists(), offsetGet(), offsetSet() and offsetUnset() and the IteratorAggregate and ArrayAccess interfaces 9/28/10
1.0.0b38Updated code to work with the new fORM API 8/6/10
1.0.0b37Fixed a typo/bug in reduce() 6/30/10
1.0.0b36Replaced create_function() with a private method call 6/8/10
1.0.0b35Added the chunk() and split() methods 5/20/10
1.0.0b34Added an integer cast to count() to fix issues with the dblib MSSQL driver 4/9/10
1.0.0b33Updated the class to force configure classes before peforming actions with them 3/30/10
1.0.0b32Fixed a column aliasing issue with SQLite 1/25/10
1.0.0b31Added the ability to compare columns in build() with the =:, !:, <:, <=:, >: and >=: operators 12/8/09
1.0.0b30Fixed a bug affecting where conditions with columns that are not null but have a default value 11/3/09
1.0.0b29Updated code for the new fORMDatabase and fORMSchema APIs 10/28/09
1.0.0b28Fixed prebuild() and precount() to work across all databases, changed SQL statements to use value placeholders, identifier escaping and schema support 10/22/09
1.0.0b27Changed fRecordSet::build() to fix bad $page numbers instead of throwing an fProgrammerException 10/5/09
1.0.0b26Updated the documentation for build() and filter() to reflect new functionality 9/21/09
1.0.0b25Fixed map() to work with string-style static method callbacks in PHP 5.1 9/18/09
1.0.0b24Backwards Compatibility Break - renamed buildFromRecords() to buildFromArray(). Added buildFromCall(), buildFromMap() and ::build{RelatedRecords}() 9/16/09
1.0.0b23Added an extra parameter to diff(), filter(), intersect(), slice() and unique() to save the number of records in the current set as the non-limited count for the new set 9/15/09
1.0.0b22Changed __construct() to accept any Iterator instead of just an fResult object 8/12/09
1.0.0b21Added performance tweaks to prebuild() and precreate() 7/31/09
1.0.0b20Changed the class to implement Countable, making the count() function work 7/29/09
1.0.0b19Fixed bugs with diff() and intersect() and empty record sets 7/29/09
1.0.0b18Added method chaining support to prebuild, precount and precreate methods 7/15/09
1.0.0b17Changed __call() to pass the parameters to the callback 7/14/09
1.0.0b16Updated documentation for the intersection operator >< 7/13/09
1.0.0b15Added the methods diff() and intersect() 7/13/09
1.0.0b14Added the methods contains() and unique() 7/9/09
1.0.0b13Added documentation to build() about the intersection operator >< 7/9/09
1.0.0b12Added documentation to build() about the AND LIKE operator &~ 7/9/09
1.0.0b11Added documentation to build() about the NOT LIKE operator !~ 7/8/09
1.0.0b10Moved the private method checkConditions() to fActiveRecord::checkConditions() 7/8/09
1.0.0b9Changed build() to only fall back to ordering by primary keys if one exists 6/26/09
1.0.0b8Updated merge() to accept arrays of fActiveRecords or a single fActiveRecord in addition to an fRecordSet 6/2/09
1.0.0b7Backwards Compatibility Break - Removed flagAssociate() and isFlaggedForAssociation(), callbacks registered via fORM::registerRecordSetMethod() no longer receive the $associate parameter 6/2/09
1.0.0b6Changed tossIfEmpty() to return the record set to allow for method chaining 5/18/09
1.0.0b5build() now allows NULL for $where_conditions and $order_bys, added a check to the SQL passed to buildFromSQL() 5/3/09
1.0.0b4__call() was changed to prevent exceptions coming from fGrammar when an unknown method is called 3/27/09
1.0.0b3sort() and sortByCallback() now return the record set to allow for method chaining 3/23/09
1.0.0b2Added support for != and <> to build() and filter() 12/4/08
1.0.0bThe initial implementation 8/4/07

Static Methods

::build() public

Creates an fRecordSet by specifying the class to create plus the where conditions and order by rules

The where conditions array can contain key => value entries in any of the following formats:

'column='                    => VALUE,                       // column = VALUE
'column!'                    => VALUE                        // column <> VALUE
'column!='                   => VALUE                        // column <> VALUE
'column<>'                   => VALUE                        // column <> VALUE
'column~'                    => VALUE                        // column LIKE '%VALUE%'
'column^~'                   => VALUE                        // column LIKE 'VALUE%'
'column$~'                   => VALUE                        // column LIKE '%VALUE'
'column!~'                   => VALUE                        // column NOT LIKE '%VALUE%'
'column<'                    => VALUE                        // column < VALUE
'column<='                   => VALUE                        // column <= VALUE
'column>'                    => VALUE                        // column > VALUE
'column>='                   => VALUE                        // column >= VALUE
'column=:'                   => 'other_column'               // column = other_column
'column!:'                   => 'other_column'               // column <> other_column
'column!=:'                  => 'other_column'               // column <> other_column
'column<>:'                  => 'other_column'               // column <> other_column
'column<:'                   => 'other_column'               // column < other_column
'column<=:'                  => 'other_column'               // column <= other_column
'column>:'                   => 'other_column'               // column > other_column
'column>=:'                  => 'other_column'               // column >= other_column
'column='                    => array(VALUE, VALUE2, ... )   // column IN (VALUE, VALUE2, ... )
'column!'                    => array(VALUE, VALUE2, ... )   // column NOT IN (VALUE, VALUE2, ... )
'column!='                   => array(VALUE, VALUE2, ... )   // column NOT IN (VALUE, VALUE2, ... )
'column<>'                   => array(VALUE, VALUE2, ... )   // column NOT IN (VALUE, VALUE2, ... )
'column~'                    => array(VALUE, VALUE2, ... )   // (column LIKE '%VALUE%' OR column LIKE '%VALUE2%' OR column ... )
'column^~'                   => array(VALUE, VALUE2, ... )   // (column LIKE 'VALUE%' OR column LIKE 'VALUE2%' OR column ... )
'column$~'                   => array(VALUE, VALUE2, ... )   // (column LIKE '%VALUE' OR column LIKE '%VALUE2' OR column ... )
'column&~'                   => array(VALUE, VALUE2, ... )   // (column LIKE '%VALUE%' AND column LIKE '%VALUE2%' AND column ... )
'column!~'                   => array(VALUE, VALUE2, ... )   // (column NOT LIKE '%VALUE%' AND column NOT LIKE '%VALUE2%' AND column ... )
'column!|column2<|column3='  => array(VALUE, VALUE2, VALUE3) // (column <> '%VALUE%' OR column2 < '%VALUE2%' OR column3 = '%VALUE3%')
'column|column2><'           => array(VALUE, VALUE2)         // WHEN VALUE === NULL: ((column2 IS NULL AND column = VALUE) OR (column2 IS NOT NULL AND column <= VALUE AND column2 >= VALUE))
                                                             // WHEN VALUE !== NULL: ((column <= VALUE AND column2 >= VALUE) OR (column >= VALUE AND column <= VALUE2))
'column|column2|column3~'    => VALUE                        // (column LIKE '%VALUE%' OR column2 LIKE '%VALUE%' OR column3 LIKE '%VALUE%')
'column|column2|column3~'    => array(VALUE, VALUE2, ... )   // ((column LIKE '%VALUE%' OR column2 LIKE '%VALUE%' OR column3 LIKE '%VALUE%') AND (column LIKE '%VALUE2%' OR column2 LIKE '%VALUE2%' OR column3 LIKE '%VALUE2%') AND ... )

When creating a condition in the form column|column2|column3~, if the value for the condition is a single string that contains spaces, the string will be parsed for search terms. The search term parsing will handle quoted phrases and normal words and will strip punctuation and stop words (such as "the" and "a").

The order bys array can contain key => value entries in any of the following formats:

'column'     => 'asc'      // 'first_name' => 'asc'
'column'     => 'desc'     // 'last_name'  => 'desc'
'expression' => 'asc'      // "CASE first_name WHEN 'smith' THEN 1 ELSE 2 END" => 'asc'
'expression' => 'desc'     // "CASE first_name WHEN 'smith' THEN 1 ELSE 2 END" => 'desc'

The column in both the where conditions and order bys can be in any of the formats:

'column'                                                         // e.g. 'first_name'
'current_table.column'                                           // e.g. 'users.first_name'
'related_table.column'                                           // e.g. 'user_groups.name'
'related_table{route}.column'                                    // e.g. 'user_groups{user_group_id}.name'
'related_table=>once_removed_related_table.column'               // e.g. 'user_groups=>permissions.level'
'related_table{route}=>once_removed_related_table.column'        // e.g. 'user_groups{user_group_id}=>permissions.level'
'related_table=>once_removed_related_table{route}.column'        // e.g. 'user_groups=>permissions{read}.level'
'related_table{route}=>once_removed_related_table{route}.column' // e.g. 'user_groups{user_group_id}=>permissions{read}.level'
'column||other_column'                                           // e.g. 'first_name||last_name' - this concatenates the column values

In addition to using plain column names for where conditions, it is also possible to pass an aggregate function wrapped around a column in place of a column name, but only for certain comparison types. Note that for column comparisons, the function may be placed on either column or both.

'function(column)='   => VALUE,                       // function(column) = VALUE
'function(column)!'   => VALUE                        // function(column) <> VALUE
'function(column)!=   => VALUE                        // function(column) <> VALUE
'function(column)<>'  => VALUE                        // function(column) <> VALUE
'function(column)~'   => VALUE                        // function(column) LIKE '%VALUE%'
'function(column)^~'  => VALUE                        // function(column) LIKE 'VALUE%'
'function(column)$~'  => VALUE                        // function(column) LIKE '%VALUE'
'function(column)!~'  => VALUE                        // function(column) NOT LIKE '%VALUE%'
'function(column)<'   => VALUE                        // function(column) < VALUE
'function(column)<='  => VALUE                        // function(column) <= VALUE
'function(column)>'   => VALUE                        // function(column) > VALUE
'function(column)>='  => VALUE                        // function(column) >= VALUE
'function(column)=:'  => 'other_column'               // function(column) = other_column
'function(column)!:'  => 'other_column'               // function(column) <> other_column
'function(column)!=:' => 'other_column'               // function(column) <> other_column
'function(column)<>:' => 'other_column'               // function(column) <> other_column
'function(column)<:'  => 'other_column'               // function(column) < other_column
'function(column)<=:' => 'other_column'               // function(column) <= other_column
'function(column)>:'  => 'other_column'               // function(column) > other_column
'function(column)>=:' => 'other_column'               // function(column) >= other_column
'function(column)='   => array(VALUE, VALUE2, ... )   // function(column) IN (VALUE, VALUE2, ... )
'function(column)!'   => array(VALUE, VALUE2, ... )   // function(column) NOT IN (VALUE, VALUE2, ... )
'function(column)!='  => array(VALUE, VALUE2, ... )   // function(column) NOT IN (VALUE, VALUE2, ... )
'function(column)<>'  => array(VALUE, VALUE2, ... )   // function(column) NOT IN (VALUE, VALUE2, ... )

The aggregate functions AVG(), COUNT(), MAX(), MIN() and SUM() are supported across all database types.

Below is an example of using where conditions and order bys. Please note that values should not be escaped for the database, but should just be normal PHP values.

return fRecordSet::build(
    'User',
    array(
        'first_name='      => 'John',
        'status!'          => 'Inactive',
        'groups.group_id=' => 2
    ),
    array(
        'last_name'   => 'asc',
        'date_joined' => 'desc'
    )
);

Signature

fRecordSet build( string $class, array $where_conditions=array(), array $order_bys=array(), integer $limit=NULL, integer $page=NULL )

Parameters

string $class The class to create the fRecordSet of
array $where_conditions The column => value comparisons for the WHERE clause
array $order_bys The column => direction values to use for the ORDER BY clause
integer $limit The number of records to fetch
integer $page The page offset to use when limiting records

Returns

A set of fActiveRecord objects

::buildFromArray() 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 an fRecordSet from an array of records

Signature

fRecordSet buildFromArray( string|array $class, array $records, integer $total_records=NULL, integer $limit=NULL, integer $page=1 )

Parameters

string|array $class The class or classes of the records
array $records The records to create the set from, the order of the record set will be the same as the order of the array.
integer $total_records The total number of records - this should only be provided if the array is a segment of a larger array - this is informational only and does not affect the array
integer $limit The maximum number of records the array was limited to - this is informational only and does not affect the array
integer $page The page of records the array is from - this is informational only and does not affect the array

Returns

A set of fActiveRecord objects

::buildFromSQL() public

Creates an fRecordSet from an SQL statement

The SQL statement should select all columns from a single table with a * pattern since that is what an fActiveRecord models. If any columns are left out or added, strange error may happen when loading or saving records.

Here is an example of an appropriate SQL statement:

SELECT users.* FROM users INNER JOIN groups ON users.group_id = groups.group_id WHERE groups.name = 'Public'

Here is an example of a SQL statement that will cause errors:

SELECT users.*, groups.name FROM users INNER JOIN groups ON users.group_id = groups.group_id WHERE groups.group_id = 2

The $non_limited_count_sql should only be passed when the $sql contains a LIMIT clause and should contain a count of the records when a LIMIT is not imposed.

Here is an example of a $sql statement with a LIMIT clause and a corresponding $non_limited_count_sql:

fRecordSet::buildFromSQL('User', 'SELECT * FROM users LIMIT 5', 'SELECT count(*) FROM users');

The $non_limited_count_sql is used when count() is called with TRUE passed as the parameter.

Both the $sql and $non_limited_count_sql can be passed as a string SQL statement, or an array containing a SQL statement and the values to escape into it:

fRecordSet::buildFromSQL(
    'User',
    array("SELECT * FROM users WHERE date_created > %d LIMIT %i OFFSET %i", $start_date, 10, 10*($page-1)),
    array("SELECT * FROM users WHERE date_created > %d", $start_date),
    10,
    $page
)

Signature

fRecordSet buildFromSQL( string $class, string|array $sql, string|array $non_limited_count_sql=NULL, integer $limit=NULL, integer $page=1 )

Parameters

string $class The class to create the fRecordSet of
string|array $sql The SQL to create the set from, or an array of the SQL statement plus values to escape
string|array $non_limited_count_sql An SQL statement, or an array of the SQL statement plus values to escape, to get the total number of rows that would have been returned if a LIMIT clause had not been used. Should only be passed if a LIMIT clause is used in $sql.
integer $limit The number of records the SQL statement was limited to - this is information only and does not affect the SQL
integer $page The page of records the SQL statement returned - this is information only and does not affect the SQL

Returns

A set of fActiveRecord objects

::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

::tally() public

Counts the number of records that match the conditions specified

Signature

integer tally( string $class, mixed $where_conditions=array() )

Parameters

string $class The class of records to count
mixed $where_conditions An array of where clause parameters in the same format as build()

Returns

The number of records

Methods

->__construct() protected

Sets the contents of the set

Signature

fRecordSet __construct( string|array $class, Iterator|array $records=NULL, string|integer $non_limited_count=NULL, integer $limit=NULL, integer $page=1 )

Parameters

string|array $class The type(s) of records the object will contain
Iterator|array $records The Iterator object of the records to create or an array of records
string|integer $non_limited_count An SQL statement to get the total number of records sans a LIMIT clause or a integer of the total number of records
integer $limit The number of records the set was limited to
integer $page The page of records that was built

->__call() public

Allows for preloading various data related to the record set in single database queries, as opposed to one query per record

This method will handle methods in the format verbRelatedRecords() for the verbs build, prebuild, precount and precreate.

build calls create{RelatedClass}() on each record in the set and returns the result as a new record set. The relationship route can be passed as an optional parameter.

prebuild builds *-to-many record sets for all records in the record set. precount will count records in *-to-many record sets for every record in the record set. precreate will create a *-to-one record for every record in the record set.

Signature

void __call( string $method_name, string $parameters )

Parameters

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

->__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

->buildFromCall() public

Calls a specific method on each object, returning an fRecordSet of the results

Signature

fRecordSet buildFromCall( string $method, mixed $parameter [, ... ] )

Parameters

string $method The method to call
mixed $parameter [, ... ] A parameter to pass for each call to the method

Returns

A set of records that resulted from calling the method

->buildFromMap() public

Maps each record in the set to a callback function, returning an fRecordSet of the results

Signature

fRecordSet buildFromMap( callback $callback, mixed $parameter [, ... ] )

Parameters

callback $callback The callback to pass the values to
mixed $parameter [, ... ] The parameter to pass to the callback - see method description for details

Returns

A set of records that resulted from the mapping operation

->call() public

Calls a specific method on each object, returning an array of the results

Signature

array call( string $method, mixed $parameter [, ... ] )

Parameters

string $method The method to call
mixed $parameter [, ... ] A parameter to pass for each call to the method

Returns

An array the size of the record set with one result from each record/method

->chunk() public

Chunks the record set into an array of fRecordSet objects

Each fRecordSet would contain $number records, except for the last, which will contain between 1 and $number records.

Signature

array chunk( integer $number )

Parameters

integer $number The number of fActiveRecord objects to place in each fRecordSet

Returns

An array of fRecordSet objects

->contains() public

Checks if the record set contains the record specified

Signature

boolean contains( fActiveRecord $record )

Parameters

fActiveRecord $record The record to check, must exist in the database

Returns

If the record specified is in this record set

->count() public implements Countable

Returns the number of records in the set

Signature

integer count( boolean $ignore_limit=FALSE )

Parameters

boolean $ignore_limit If set to TRUE, this method will return the number of records that would be in the set if there was no LIMIT clause

Returns

The number of records in the set

->diff() public

Removes all passed records from the current record set

Signature

fRecordSet diff( fRecordSet|array|fActiveRecord $records, boolean $remember_original_count=FALSE )

Parameters

fRecordSet|array|fActiveRecord $records The record set, array of records, or record to remove from the current record set, all instances will be removed
boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to 1 either way

Returns

The records not present in the passed records

->filter() public

Filters the records in the record set via a callback

The $callback parameter can be one of three different forms to filter the records in the set:

  • A callback that accepts a single record and returns FALSE if it should be removed
  • A psuedo-callback in the form '{record}::methodName' to filter out any records where the output of $record->methodName() is equivalent to FALSE
  • A conditions array that will remove any records that don't meet all of the conditions

The conditions array can use one or more of the following key => value syntaxes to perform various comparisons. The array keys are method names followed by a comparison operator.

// The following forms work for any $value that is not an array
'methodName='                           => $value  // If the output is equal to $value
'methodName!'                           => $value  // If the output is not equal to $value
'methodName!='                          => $value  // If the output is not equal to $value
'methodName<>'                          => $value  // If the output is not equal to $value
'methodName<'                           => $value  // If the output is less than $value
'methodName<='                          => $value  // If the output is less than or equal to $value
'methodName>'                           => $value  // If the output is greater than $value
'methodName>='                          => $value  // If the output is greater than or equal to $value
'methodName~'                           => $value  // If the output contains the $value (case insensitive)
'methodName^~'                          => $value  // If the output starts with the $value (case insensitive)
'methodName$~'                          => $value  // If the output ends with the $value (case insensitive)
'methodName!~'                          => $value  // If the output does not contain the $value (case insensitive)
'methodName|methodName2|methodName3~'   => $value  // Parses $value as a search string and make sure each term is present in at least one output (case insensitive)
// The following forms work for any $array that is an array
'methodName='                           => $array  // If the output is equal to at least one value in $array
'methodName!'                           => $array  // If the output is not equal to any value in $array
'methodName!='                          => $array  // If the output is not equal to any value in $array
'methodName<>'                          => $array  // If the output is not equal to any value in $array
'methodName~'                           => $array  // If the output contains one of the strings in $array (case insensitive)
'methodName^~'                          => $array  // If the output starts with one of the strings in $array (case insensitive)
'methodName$~'                          => $array  // If the output ends with one of the strings in $array (case insensitive)
'methodName!~'                          => $array  // If the output contains none of the strings in $array (case insensitive)
'methodName&~'                          => $array  // If the output contains all of the strings in $array (case insensitive)
'methodName|methodName2|methodName3~'   => $array  // If each value in the array is present in the output of at least one method (case insensitive)
// The following works for an equal number of methods and values in the array
'methodName!|methodName2<|methodName3=' => array($value, $value2, $value3) // An OR statement - one of the method to value comparisons must be TRUE
// The following accepts exactly two methods and two values, although the second value may be NULL
'methodName|methodName2><'              => array($value, $value2) // If the range of values from the methods intersects the range of $value and $value2 - should be dates, times, timestamps or numbers

Signature

fRecordSet filter( callback|string|array $procedure, boolean $remember_original_count=FALSE )

Parameters

callback|string|array $procedure The way in which to filter the records - see method description for possible forms
boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to 1 either way

Returns

A new fRecordSet with the filtered records

->getClass() public

Returns the class name of the record being stored

Signature

string|array getClass( )

Returns

The class name(s) of the records in the set

->getIterator() internal public implements IteratorAggregate

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

Returns an iterator for the record set

This method is required by the IteratorAggregate interface.

Signature

ArrayIterator getIterator( )

Returns

An iterator for the record set

->getLimit() public

Returns the number of records the set was limited to

Signature

integer getLimit( )

Returns

The number of records the set was limited to

->getPage() public

Returns the page of records this set represents

Signature

integer getPage( )

Returns

The page of records this set represents

->getPages() public

Returns the number of pages of records exist for the limit used when creating this set

Signature

integer getPages( )

Returns

The number of pages of records that exist for the limit specified

->getPrimaryKeys() public

Returns the primary keys for all of the records in the set

Signature

array getPrimaryKeys( )

Returns

The primary keys of all the records in the set

->getRecord() public

Returns the record at the zero-based index specified

Signature

fActiveRecord getRecord( integer $index )

Parameters

integer $index The index of the record to return

Returns

The record requested

->getRecords() public

Returns all of the records in the set

Signature

array getRecords( )

Returns

The records in the set

->intersect() public

Returns all records in the current record set that are also present in the passed records

Signature

fRecordSet intersect( fRecordSet|array|fActiveRecord $records, boolean $remember_original_count=FALSE )

Parameters

fRecordSet|array|fActiveRecord $records The record set, array of records, or record to create an intersection of with the current record set
boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to 1 either way

Returns

The records present in the current record set that are also present in the passed records

->map() public

Performs an array_map() on the record in the set

The record will be passed to the callback as the first parameter unless it's position is specified by the placeholder string '{record}'.

Additional parameters can be passed to the callback in one of two different ways:

  • Passing a non-array value will cause it to be passed to the callback
  • Passing an array value will cause the array values to be passed to the callback with their corresponding record

If an array parameter is too long (more items than records in the set) it will be truncated. If an array parameter is too short (less items than records in the set) it will be padded with NULL values.

To allow passing the record as a specific parameter to the callback, a placeholder string '{record}' will be replaced with a the record. It is also possible to specify '{record}::methodName' to cause the output of a method from the record to be passed instead of the whole record.

It is also possible to pass the zero-based record index to the callback by passing a parameter that contains '{index}'.

Signature

array map( callback $callback, mixed $parameter [, ... ] )

Parameters

callback $callback The callback to pass the values to
mixed $parameter [, ... ] The parameter to pass to the callback - see method description for details

Returns

An array of the results from the callback

->merge() public

Merges the record set with more records

Signature

fRecordSet merge( fRecordSet|array|fActiveRecord $records )

Parameters

fRecordSet|array|fActiveRecord $records The record set, array of records, or record to merge with the current record set, duplicates will not be removed

Returns

The merged record sets

->offsetExists() internal public implements ArrayAccess

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 offset exists

This method is required by the ArrayAccess interface.

Signature

boolean offsetExists( mixed $offset )

Parameters

mixed $offset The offset to check

Returns

If the offset exists

->offsetGet() internal public implements ArrayAccess

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

Returns a record based on the offset

This method is required by the ArrayAccess interface.

Signature

fActiveRecord offsetGet( mixed $offset )

Parameters

mixed $offset The offset of the record to get

Returns

The requested record

Throws

fNoRemainingException
When the offset specified is beyond the last record

->offsetSet() internal public implements ArrayAccess

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

Prevents setting values to the record set

This method is required by the ArrayAccess interface.

Signature

void offsetSet( mixed $offset, mixed $value )

Parameters

mixed $offset The offset to set
mixed $value The value to set to the offset

->offsetUnset() internal public implements ArrayAccess

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

Prevents unsetting values from the record set

This method is required by the ArrayAccess interface.

Signature

void offsetUnset( mixed $offset )

Parameters

mixed $offset The offset to unset

->reduce() public

Reduces the record set to a single value via a callback

The callback should take two parameters and return a single value:

  • The initial value and the first record for the first call
  • The result of the last call plus the next record for the second and subsequent calls
function my_reduce($sum, $record)
{
    return $sum + $record->getQuantity();
)
// For the first record, 0.0 will be passed as the $sum, then subsequent
// calls end up getting the return value of the last call to my_reduce()
$total_quantity = $record_set->reduce('my_reduce', 0.0);

Signature

mixed reduce( callback $callback, mixed $initial_value=NULL )

Parameters

callback $callback The callback to pass the records to - see method description for details
mixed $initial_value The initial value to seed reduce with

Returns

The result of the reduce operation

->slice() public

Slices a section of records from the set and returns a new set containing those

Signature

fRecordSet slice( integer $offset, integer $length=NULL, boolean $remember_original_count=FALSE )

Parameters

integer $offset The index to start at, negative indexes will slice that many records from the end
integer $length The number of records to return, negative values will stop that many records before the end, NULL will return all records to the end of the set - if there are not enough records, less than $length will be returned
boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to 1 either way

Returns

The new slice of records

->sort() public

Sorts the set by the return value of a method from the class created and rewind the interator

This methods uses fUTF8::inatcmp() to perform comparisons.

Signature

fRecordSet sort( string $method, string $direction )

Parameters

string $method The method to call on each object to get the value to sort by
string $direction Either 'asc' or 'desc'

Returns

A new record set object, with the records sorted as requested

->sortByCallback() public

Sorts the set by passing the callback to usort() and rewinds the interator

Signature

fRecordSet sortByCallback( mixed $callback )

Parameters

mixed $callback The function/method to pass to usort()

Returns

A new record set object, with the records sorted as requested

->split() public

Splits the record set into an array of fRecordSet objects

Each fRecordSet would contain ceil(number of records/$number) records, except for the last, which will contain between 1 and ceil(…) records.

Signature

array split( integer $number )

Parameters

integer $number The number of fRecordSet objects to create

Returns

An array of fRecordSet objects

->tossIfEmpty() public

Throws an fEmptySetException if the record set is empty

Signature

fRecordSet tossIfEmpty( string $message=NULL )

Parameters

string $message The message to use for the exception if there are no records in this set

Returns

The record set object, to allow for method chaining

Throws

fEmptySetException
When there are no record in the set

->unique() public

Returns a new fRecordSet containing only unique records in the record set

Signature

fRecordSet unique( boolean $remember_original_count=FALSE )

Parameters

boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to 1 either way

Returns

The new record set with only unique records