Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Old Collection Class
<?php
/**
*
* A collection of Cfs_Model_Base_Record records.
* @package Cfs_Model
*
*/
class Cfs_Model_Base_Collection extends Solar_Sql_Model_Collection {
/**
*
* A list of valid php comparison operators.
*
* @var array A list of valid php comparison operators.
*
*/
private static $_php_operators = array('==', '===', '!=', '<>', '!==', '<', '>', '<=', '>=');
/**
*
* Get 2 character locale code (e.g. en, fr) for the currently selected locale
* in a web app extending Cfs_App_Base.
*
* @return string 2 character locale code (e.g. en, fr) for the currently selected
* locale in a web app extending Cfs_App_Base.
*
* @see Cfs_Model_Base::get_Lang()
*
*/
public static function get_Lang(){ return Cfs_Model_Base::get_Lang(); }
/**
*
* Get 2 character locale code (e.g. en, fr) for the currently selected locale
* in a web app extending Cfs_App_Base.
*
* @return string 2 character locale code (e.g. en, fr) for the currently selected
* locale in a web app extending Cfs_App_Base.
*
* @see Cfs_Model_Base_Collection::get_Lang()
*
*/
public function getLang(){ return self::get_Lang(); }
/**
*
* Returns reference to the internal array being used to store data in this collection.
*
* Please use carefully! We are dealing with references here and we don't want to get burned!
*
* @return array A reference to the internal array being used to store data in
* this collection.
*
*/
public function &getRefToInternalArray(){ return $this->_data; }
// Support methods taken from Solar Beta
/**
*
* Removes one record from the collection but <strong>does not</strong> delete it from the database.
*
* @param mixed $spec If a Solar_Sql_Model_Record, looks up the record in
* the collection and deletes it. Otherwise, is treated as an offset
* value (**not** a record primary key value) and that record is removed.
*
* @return void
*
* @see Cfs_Model_Base_Collection::getRecordOffset()
*
*/
public function removeOne($spec) {
if ($spec instanceof Solar_Sql_Model_Record) {
$key = $this->getRecordOffset($spec);
if ($key === false) {
throw $this->_exception(
'ERR_NOT_IN_COLLECTION',
$spec->toArray()
);
}
} else {
$key = $spec;
}
unset($this->_data[$key]);
}
/**
*
* Given a record object, looks up its offset value in the collection.
*
* For this to work, the record primary key must exist in the collection,
* **and** the record looked up in the collection must have the same
* primary key and be of the same class.
*
* Note that the returned offset may be zero, indicating the first element
* in the collection. As such, you should check the return for boolean
* false to indicate failure.
*
* @param Solar_Sql_Model_Record $record The record to find in the collection.
*
*
* @return mixed The record offset (which may be zero), or boolean false
* if the same record was not found in the collection.
*
*/
public function getRecordOffset($record) {
// the primary value of the record
$val = $record->getPrimaryVal();
// mapping of primary-key values to offset values
$map = array_flip($this->getAllPrimaryOrOtherColsVals());
// does the record primary value exist in the collection?
// use array_key_exists() instead of empty() so we can honor zeroes.
if (! array_key_exists($val, $map)) {
return false;
}
// retain the offset value
$offset = $map[$val];
// look up the record inside the collection
$lookup = $this->__get($offset);
// the primary keys are already known to be the same from above.
// if the classes match as well, consider records to be "the same".
if (get_class($lookup) === get_class($record)) {
return $offset;
} else {
return false;
}
}
// End Support methods taken from Solar Beta
/**
*
* Fetch one or more record(s) from a collection whose value(s) match the value(s)
* of the column(s) and value(s) specified.
*
* If count($cols) != count($vals) a null value will be returned by this method.
*
* <br />
* **Usage:**
*
* - $this->_findRecordByCols( array( 'col_1_name', 'col_2_name' ), array( 'col_1_val', 'col_2_val' ), true, array(), false, false )
*
* **SQL Equivalent:** Select * from table where col_1_name = 'col_1_val' and col_2_name = 'col_2_val'
*
* <br />
* - $this->_findRecordByCols( 'col_1_name', 'col_1_val', true, array(), false, false )
*
* **SQL Equivalent:** Select * from table where col_1_name = 'col_1_val'
*
* <br />
* - $this->_findRecordByCols( array( 'col_1_name', 'col_2_name' ), array( 'col_1_val', 'col_2_val' ), true, array( 'col_1_name'=>'!=' ), false, false )
*
* **SQL Equivalent:** Select * from table where col_1_name <> 'col_1_val' and col_2_name = 'col_2_val'
*
* <br />
* - $this->_findRecordByCols( array( 'col_1_name', 'col_2_name' ), array( 'col_1_val', 'col_2_val' ), true, array( 'col_1_name'=>'!=', 'col_2_name'=>'<=' ), false, false )
*
* **SQL Equivalent:** Select * from table where col_1_name <> 'col_1_val' and col_2_name <= 'col_2_val'
*
*
* @param mixed $cols (string | array) An array of column/field name(s) or a single
* column/field name (string) to be checked in each record.
*
* @param mixed $vals (int | double | string | array) A list of corresponding value(s)
* or single value for the field(s) specified in $cols.
*
* @param boolean $return_all_matching_records **False** to determine if only the
* first matching record should be returned (default behaviour), or **True** if all matching
* records should be returned.
*
* @param array $comparision_operators_per_col An array of column_name=>php_comparison_operator
* pairs for the columns we are searching by (The php_comparison_operator should be a string
* containing one of the valid php comparison operators specified
* <a href="http://php.net/manual/en/language.operators.comparison.php">here</a>).
*
* @param boolean $return_cloned_records **False**, if the matching records in the collection
* should be directly returned (default behaviour) or **True** if a clone of each matching record
* should be returned.
*
* @param boolean $remove_matched_records_from_collection **True** if matched record(s) should be
* removed from the collection (**$this**) or **False** if not.
*
*
* @return mixed (Cfs_Model_Base_Record | Cfs_Model_Base_Collection | null) First matching record
* or a collection of all matching records. Null is returned if there are no matching record(s).
*
*/
protected function _findRecordByCols($cols, $vals, $return_all_matching_records=false, $comparision_operators_per_col=array(), $return_cloned_records=false, $remove_matched_records_from_collection=false) {
$result = null;
$curr_rec_2_b_returned = 0;
$collection_keys_4_matched_records = array();
if($return_all_matching_records){ $result = Solar::factory(get_class($this)); }
if(is_string($cols)){ $cols = array($cols); }
if(is_string($vals) || is_numeric($vals)){ $vals = array($vals); }
if(!(count($cols) < count($vals) ||count($cols) > count($vals))){
$num_records = count($this);
$num_fields = count($cols);
$keys_2_dis_cllctn = array_keys($this->_data);
for($curr_record=0; $curr_record<$num_records; $curr_record++) {
$record = $this[$keys_2_dis_cllctn[$curr_record]];
$matched = true;
for($curr_field_index=0; $curr_field_index < $num_fields && $matched; $curr_field_index++){
$specified_cols_name = $cols[$curr_field_index];
$specified_cols_value = $vals[$curr_field_index];
if(empty($comparision_operators_per_col)){
//use default comparison technique
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}else{
if(array_key_exists($specified_cols_name, $comparision_operators_per_col)){
if(in_array($comparision_operators_per_col[$specified_cols_name], self::$_php_operators)){
//we have a valid comparison operator for the current column
$matched = $matched && $this->_doComparison($comparision_operators_per_col[$specified_cols_name], $record[$specified_cols_name], $specified_cols_value);
}else{
//use default comparison technique
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}
}else{
//use default comparison technique
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}
}
}
if($matched){
$curr_records_key_in_collection = $keys_2_dis_cllctn[$curr_record];
$collection_keys_4_matched_records[] = $curr_records_key_in_collection;
if($return_all_matching_records){
//don't remove record from collection here if $remove_matched_records_from_collection
//is True, because we are still in the loop and keys will get messed up.
$result[$curr_rec_2_b_returned++] = ($return_cloned_records)? clone $record: $record;
}else{
//Remove record from collection here if $remove_matched_records_from_collection
//is True, because we are returning result anyways and exiting this method in
//this else block.
if($remove_matched_records_from_collection){
unset($this->_data[$curr_records_key_in_collection]);
}
return ($return_cloned_records)? clone $record: $record;
}
}
}
}
if(count($collection_keys_4_matched_records) > 0 && $remove_matched_records_from_collection){
foreach($collection_keys_4_matched_records as $key){
unset($this->_data[$key]);
}
}
if(count($result)== 0){ $result = null; }
return $result;
}
/**
*
* Tests the equality of two values.
* Does regular ( == ) comparison if the values are both numeric.
*
* Otherwise, does a strict ( === ) comparison of the values casted to strings
* (i.e. ( (string) $value1 ) === ( (string) $value2 ) ).
*
* @param mixed $value1 A value to be compared with the second value.
*
* @param mixed $value2 A value to be compared with the first value.
*
*
* @return boolean True if both parameters are equal in value, else False.
*
*/
private function _doNormalOrStrictEqualityComparison($value1, $value2){
$both_numeric = is_numeric($value1)
&& is_numeric($value2);
if ($both_numeric) {
// use normal inequality
return ($value1 == $value2);
}else{
// use strict inequality
return (((string)$value1) === ((string)$value2));
}
}
/**
*
* Fetch first record in a collection whose value(s) for the specified cols ($cols),
* match the specified value(s) ($vals).
*
* If count( $cols ) != count( $vals ) a null value will be returned by this method.
*
* <br />
* **Usage:**
*
* - $this->_findOneRecordByCols( array( 'col_1_name', 'col_2_name' ), array( 'col_1_val', 'col_2_val' ) )
*
* **SQL Equivalent:** SELECT * FROM table WHERE col_1_name = 'col_1_val' AND col_2_name = 'col_2_val' LIMIT 1
*
* <br />
* - $this->_findOneRecordByCols( 'col_1_name', 'col_1_val' )
*
* **SQL Equivalent:** SELECT * FROM table WHERE col_1_name = 'col_1_val' LIMIT 1
*
* @param mixed $cols (string | array) A list of column / field name(s) to be
* checked in each record.
*
* @param mixed $vals (int | double | string | array) A list of corresponding value(s) for the
* field(s) specified in $cols.
*
* @param boolean $return_cloned_record **False** if the first matching record in the collection
* should be directly returned (default behaviour), else **True** if a **clone** of the first
* matching record should be returned.
*
*
* @return mixed (Cfs_Model_Base_Record | null) First record in this collection whose value(s)
* for the specified cols ($cols), match the specified value(s) ($vals), or null if there is no
* matching record.
*
*/
protected function _findOneRecordByCols($cols, $vals, $return_cloned_record = false) {
$result = null;
$curr_rec_2_b_returned = 0;
if(is_string($cols)){ $cols = array($cols); }
if(is_string($vals) || is_numeric($vals)){ $vals = array($vals); }
if(!(count($cols) < count($vals) ||count($cols) > count($vals))){
$num_records = $this->count();
if($num_records > 0){
$num_fields = count($cols);
$keys_2_dis_cllctn = array_keys($this->_data);
//only one record, no need to loop
if($num_records == 1){
$record = $this->firstItem();
$matched = true;
for($curr_field_index=0; $curr_field_index < $num_fields && $matched; $curr_field_index++){
$specified_cols_name = $cols[$curr_field_index];
$specified_cols_value = $vals[$curr_field_index];
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}
if($matched){
return ($return_cloned_record)? clone $record : $record;
}
}else{
//start from the middle to the first element
$start = floor($num_records/2);
for($curr_record_index = $start; $curr_record_index >=0; $curr_record_index--){
$record = $this[$keys_2_dis_cllctn[$curr_record_index]];
$matched = true;
for($curr_field_index=0; $curr_field_index < $num_fields && $matched; $curr_field_index++){
$specified_cols_name = $cols[$curr_field_index];
$specified_cols_value = $vals[$curr_field_index];
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}
if($matched){
return ($return_cloned_record)? clone $record : $record;
}
}
//start from the middle + 1 to the last element
$start = (floor($num_records/2)) + 1;
for($curr_record_index = $start; $curr_record_index < $num_records; $curr_record_index++){
$record = $this[$keys_2_dis_cllctn[$curr_record_index]];
$matched = true;
for($curr_field_index=0; $curr_field_index < $num_fields && $matched; $curr_field_index++){
$specified_cols_name = $cols[$curr_field_index];
$specified_cols_value = $vals[$curr_field_index];
$matched = $matched && $this->_doNormalOrStrictEqualityComparison($record[$specified_cols_name], $specified_cols_value);
}
if($matched){
return ($return_cloned_record)? clone $record : $record;
}
}
}
}
}
return $result;
}
/**
*
* Fetch first record in a collection whose value(s) for the specified cols ($cols),
* match the specified value(s) ($vals).
*
* If count($cols) != count($vals) a null value will be returned by this method.
*
* @param mixed $cols (string | array) A list of column / field name(s) to be checked in each
* record.
*
* @param mixed $vals (int | double | string | array) A list of corresponding value(s) for the
* field(s) specified in $cols.
*
* @param boolean $return_cloned_record **False** if the first matching record in the collection
* should be directly returned (default behaviour), else **True** if a clone of the first matching
* record should be returned.
*
*
* @return mixed (Cfs_Model_Base_Record | null) First record in this collection whose value(s)
* for the specified cols ($cols), match the specified value(s) ($vals), or null if there is no
* matching record.
*
* @see Cfs_Model_Base_Collection::_findOneRecordByCols()
*
*/
public function findRecordByCols($cols, $vals, $return_cloned_record=false) {
return $this->_findOneRecordByCols($cols, $vals, $return_cloned_record);
}
/**
*
* Fetch one or more record(s) from a collection whose value(s) match the value(s) of the
* column(s) and value(s) specified.
*
* If count( $cols ) != count( $vals ) a null value will be returned by this method.
*
* @param mixed $cols (string | array) An array of column/field name(s) or a single
* column/field name (string) to be checked in each record.
*
* @param mixed $vals (int | double | string | array) A list of corresponding value(s) or
* single value for the field(s) specified in $cols.
*
* @param array $comparision_operators_per_col An array of column_name=>php_comparison_operator
* pairs for the columns we are searching by (The php_comparison_operator should be a string
* containing one of the valid php comparison operators specified
* <a href="http://php.net/manual/en/language.operators.comparison.php">here</a>).
*
* @param boolean $return_cloned_records **False**, if the matching records in the collection
* should be directly returned (default behaviour) or **True** if a clone of each matching
* record should be returned.
*
* @param boolean $remove_matched_records_from_collection **True** if matched record(s) should
* be removed from the collection (**$this**) or **False** if not.
*
*
* @return mixed (Cfs_Model_Base_Collection | null) Collection of all matching record(s). Null
* is returned if there are no matching record(s).
*
* @see Cfs_Model_Base_Collection::_findRecordByCols()
*
*/
public function findRecordsByCols($cols, $vals, $comparision_operators_per_col=array(), $return_cloned_records=false, $remove_matched_records_from_collection=false) {
return $this->_findRecordByCols($cols, $vals, true, $comparision_operators_per_col, $return_cloned_records, $remove_matched_records_from_collection);
}
/**
*
* Sorts this collection by one or more specified columns (including calculate_cols) in
* the Model associated with the records in this collection.
*
* **Usage:**
*
* - $this->orderByCols( 'column_to_sort_by', true )
*
* **SQL Equivalent:** Select * from table **Order By column_to_sort_by ASC**
*
* <br />
* - $this->orderByCols( array( '1st_column_to_sort_by', '2nd_column_to_sort_by' ), array( true, false ) )
*
* **SQL Equivalent:** Select * from table **Order By 1st_column_to_sort_by ASC, 2nd_column_to_sort_by DESC**
*
* @param mixed $col_names (array | string) Specified column(s) we are sorting by.
*
* @param mixed $sort_asc_cols An array of booleans or a single boolean indicating whether or
* not the corresponding column(s) in $col_names should be sorted in ascending order. True to
* sort corresponding column in ascending order or false to sort in descending order. Default
* is sort ascending if the flag is not supplied for a column by the caller of this method.
*
*
* @return void
*
*/
public function orderByCols($col_names, $sort_asc_cols=array(true)){
$num_recs_in_dis_cllctn = count($this);
if($num_recs_in_dis_cllctn > 0){
if(is_string($col_names)){
$col_names = array($col_names);
}else if(!is_array($col_names)){
throw new Exception('Invalid first parameter ['.print_r($col_names, true).'] supplied to '.__CLASS__.'::'.__FUNCTION__.' array of strings or single string excpected');
}
if(is_bool($sort_asc_cols)){
$sort_asc_cols = array($sort_asc_cols);
}else if(!is_array($sort_asc_cols)){
throw new Exception('Invalid second parameter ['.print_r($sort_asc_cols, true).'] supplied to '.__CLASS__.'::'.__FUNCTION__.' array of booleans or a single boolean excpected');
}
$num_cols = count($col_names);
$num_sort_flags = count($sort_asc_cols);
$sort_params = array();
for($i=0; $i < $num_cols; $i++){
if($i < $num_sort_flags){
if((((boolean)$sort_asc_cols[$i]))){
$sort_params[] = array('column'=>$col_names[$i]);
}else{
$sort_params[] = array('column'=>$col_names[$i],'order_desc'=>true);
}
}else{
//default to sort ASC
$sort_params[] = array('column'=>$col_names[$i]);
}
}
$array_to_sort = array();
$keys_2_dis_cllctn = array_keys($this->_data);
for ($curr_record = 0; $curr_record < $num_recs_in_dis_cllctn; $curr_record++) {
$record = $this[$keys_2_dis_cllctn[$curr_record]];
//I use a url as key since no valid database column can be named using the
//url scheme there by avoiding collision with a column name to sort by
$sortable_entry = array('http://Cfs_Model_Base_Record'=>$record);
for($i=0; $i < $num_cols; $i++){
$sortable_entry[$col_names[$i]] = $record[$col_names[$i]];
}
$array_to_sort[] = $sortable_entry;
}
//do the sort
Cfs_Lib_Array::orderAssocArrayByKeys($array_to_sort, $sort_params);
$sorted_array_of_records = array();
$num_recs_in_collection = count($array_to_sort);
for($i=0; $i < $num_recs_in_collection; $i++){
$sorted_array_of_records[] = $array_to_sort[$i]['http://Cfs_Model_Base_Record'];
}
//reorder this collection
$this->load($sorted_array_of_records);
}
}
/**
*
* Adds a new column to the collection or overwrites all existing values of an existing column
* with the value in the $default_val parameter if the $overwrite_existing_col parameter has a
* value of true.
*
* @param string $col_name Name of column to be added to the collection or existing column whose
* values are to be overwritten.
*
* @param mixed $default_val Default value of new column or value to overwite existing values in
* an already existent column.
*
* @param boolean $overwrite_existing_col Flag to allow overwriting the values of an existing
* column if the specified $col_name already exists.
*
*
* @return void
*
* @throws Exception This happens if you are trying to add a column that already exists and
* $overwrite_existing_col is false.
*
*/
public function addColumn($col_name, $default_val='', $overwrite_existing_col=false){
//Error: $col_name already exists in the collection
if(!$overwrite_existing_col
&& $this->getModel() instanceof Cfs_Model_Base
&& array_key_exists($col_name, $this->getModel()->getTableCols())){
throw new Exception(__CLASS__."::".__FUNCTION__.": Column $col_name cannot be added to the collection, it already exists in the table ".$this->getModel()->getTableName());
}
if(!empty($col_name)){
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
$record[$col_name] = $default_val;
}
}
}
/**
*
* Retrieves distinct values from a column in a collection.
*
* Similar to **Select Distinct ColumnName** in SQL.
*
* @param string $col_name Name of column in the collection from which distinct values are to
* be retreived.
*
* @param boolean $allow_empty_or_null_vals **True** if empty or null values should be returned
* in the result, else **False** to omit empty or null values in the result (default behaviour).
* 0, '0', false and array() are treated as non-empty values by this method.
*
*
* @return array An array of distinct values from the specified column in the collection.
*
*/
public function distinct($col_name, $allow_empty_or_null_vals=false){
$distinct_vals = array();
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
if(!in_array($record[$col_name], $distinct_vals)) {
if ( empty($record[$col_name]) && $allow_empty_or_null_vals ){
$distinct_vals[] = $record[$col_name];
}elseif(
!empty($record[$col_name])
|| $record[$col_name] === false //treat false as non-empty
|| is_array($record[$col_name]) //treat the value: array() as non-empty
|| $record[$col_name] === 0 //treat 0 as non-empty
|| $record[$col_name] === '0' //treat '0' as non-empty
){
$distinct_vals[] = $record[$col_name];
}
}
}
sort($distinct_vals);
return $distinct_vals;
}
/**
*
* Retrieves values from a column in a collection.
*
* Similar to **Select ColumnName** in SQL.
*
* <br />
* The keys to the array of values returned are the same as the keys the records
* containing the selected values have in the collection (**$this**). The returned values still
* maintain this key association even when $sort_vals == true.
*
* @param string $col_name Name of column in the collection from which values are to
* be retreived. If omitted, the primary key column is used.
*
* @param boolean $allow_empty_or_null_vals Flag to indicate whether or not empty or
* null values should be returned in the result (these values are omitted by default).
* 0, '0', false and array() are treated as non-empty values by this method.
*
* @param boolean $sort_vals Flag to indicate whether or not the returned values should
* be sorted (**true** to sort, **false** not to sort [default behaviour]).
*
*
* @return array An array of values from the specified column in the collection.
*
*/
public function getAllPrimaryOrOtherColsVals($col_name=null, $allow_empty_or_null_vals=false, $sort_vals=false){
// what key to look for?
$col_name = (empty($col_name))? $this->_model->primary_col : $col_name;
$results = array();
for($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
$key = $this->key();
if( (empty($record[$col_name]) ) && $allow_empty_or_null_vals ) {
$results[$key] = $record[$col_name];
}elseif(
!empty($record[$col_name])
|| $record[$col_name] === false //treat false as non-empty
|| is_array($record[$col_name]) //treat the value: array() as non-empty
|| $record[$col_name] === 0 //treat 0 as non-empty
|| $record[$col_name] === '0' //treat '0' as non-empty
){
$results[$key] = $record[$col_name];
}
}
if($sort_vals){
asort($results);
}
return $results;
}
/**
*
* Calculates the average of all the values of the specified column in each record
* in this collection.
* Synonymous to **AVG( column_name )** in ANSII SQL.
*
* @param string $col_name The name of a column **(containing only numeric values)** in
* the table whose records are contained in this collection.
*
*
* @return mixed (float | int) The average of all the values of the specified column in
* each record in this collection.
*
*/
public function averageColumnValue($col_name){
return ($this->sumColumnValues($col_name) / $this->count());
}
/**
*
* Finds the maximum numeric value in the specified column in all the records in this
* collection.
* Synonymous to **MAX( column_name )** in ANSII SQL.
*
* @param string $col_name The name of a column **(containing only numeric values)**
* in the table whose records are contained in this collection.
*
*
* @return mixed (float|int) The maximum numeric value in the specified column in all
* the records in this collection.
*
*/
public function maxColumnValue($col_name){
$keys = array_keys($this->_data);
$max = ($this->count() > 0) ? $this[$keys[0]][$col_name] : null;
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
if(!empty($col_name)){
if(is_numeric($record[$col_name]) && is_numeric($max) && $record[$col_name] > $max){
$max = $record[$col_name];
}else if(!is_numeric($max) && is_numeric($record[$col_name])){
$max = $record[$col_name];
}
}
}
return (!is_numeric($max))? $max : ($max * 1);//multiply by 1 to make it a truly numeric (float|int) data type rather than a string with a numeric value
}
/**
*
* Finds the minimum numeric value in the specified column in all the records in this
* collection.
* Synonymous to **MIN( column_name )** in ANSII SQL.
*
* @param string $col_name The name of a column **(containing only numeric values)**
* in the table whose records are contained in this collection.
*
*
* @return mixed (float|int) The minimum numeric value in the specified column in all
* the records in this collection.
*
*/
public function minColumnValue($col_name){
$keys = array_keys($this->_data);
$min = ($this->count() > 0) ? $this[$keys[0]][$col_name] : null;
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
if(!empty($col_name)){
if(is_numeric($record[$col_name]) && is_numeric($min) && $record[$col_name] < $min){
$min = $record[$col_name];
}else if(!is_numeric($min) && is_numeric($record[$col_name]) ){
$min = $record[$col_name];
}
}
}
return (!is_numeric($min))? $min : ($min * 1);//multiply by 1 to make it a truly numeric (float|int) data type rather than a string with a numeric value
}
/**
*
* Calculates the sum of all the values of the specified column in each record in this
* collection.
* Synonymous to **SUM( column_name )** in ANSII SQL.
*
* @param string $col_name The name of a column **(containing only numeric values)** in
* the table whose records are contained in this collection.
*
*
* @return mixed (float|int) The sum of all the values of the specified column in each
* record in this collection.
*
*/
public function sumColumnValues($col_name){
$sum = 0;
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
if(!empty($col_name)){
if(is_numeric($record[$col_name])){
$sum += $record[$col_name];
}
}
}
return $sum;
}
/**
*
* Divides a collection of records into an array of smaller collections based on the
* supplied list of columns ($col_names) to group by.
*
* **NOTE:** The collection is first grouped by the first column in $col_names, then
* each of the groups obtained via grouping by the first column in $col_names are then
* further grouped by the second column in $col_names... (this process continues until
* all the entries in $col_names have been used for grouping).
*
* <br />
* **NOTE:** This method does the same thing as a basic SQL **GROUP BY**, but returns
* all the records for each group instead of one record per group (in the case of SQL's
* **GROUP BY**).
*
* <br />
* **NOTE:** Records with a **NULL** or **empty string** value for any of the columns being
* grouped by, are grouped together. As oppossed to having one group for records with one or
* more group by column(s) having a **NULL** value and another group for records with one or
* group by column(s) having an **empty string** value.
*
* <br />
* **Usage:**
*
* <pre>
* $this->groupByReturnAllRecordsPerGroup (
* array('first_col_to_group_by', 'second_col_to_group_by'),
* array('col_1_name'=>'summed_col_1_value'),
* array('col_1_name'=>'min_col_1_value'),
* array('col_1_name'=>'max_col_1_value'),
* array('col_1_name'=>'avg_col_1_value')
* );
* </pre>
*
* Similar to
*
* <pre>
* SELECT table.*,
* SUM(col_1_name) AS summed_col_1_value,
* MIN(col_1_name) AS min_col_1_value,
* MAX(col_1_name) AS max_col_1_value,
* AVG(col_1_name) AS avg_col_1_value
* FROM table
* GROUP BY first_col_to_group_by, second_col_to_group_by
* </pre>
*
* in SQL (but all the records in each group are returned as opposed to the first
* record in each group).
*
* @param array $col_names An array of column names (calculate cols and other special
* cols can be included) that we want to group by.
*
* @param array $sum_cols Associative array. Array keys are the column name(s) whose
* values are to be summed in each group of the final result and the corresponding
* values are the desired alias column name(s) for the summed value(s).
* Example **array('col_1_name'=>'summed_col_1_value')** equivalent to
* **SUM(col_1_name) AS summed_col_1_value** in SQL.
*
* @param array $min_cols Associative array. Array keys are the column name(s) whose
* min value(s) are to be found in each group of the final result and the corresponding
* values are the desired alias column name(s) for the min value(s).
* Example **array('col_1_name'=>'min_col_1_value')** equivalent to
* **MIN(col_1_name) AS min_col_1_value** in SQL.
*
* @param array $max_cols Associative array. Array keys are the column name(s) whose
* max value(s) are to be found in each group of the final result and the corresponding
* values are the desired alias column name(s) for the max value(s).
* Example **array('col_1_name'=>'max_col_1_value')** equivalent to
* **MAX(col_1_name) AS max_col_1_value** in SQL.
*
* @param array $avg_cols Associative array. Array keys are the column name(s) whose
* average value(s) are to be found in each group of the final result and the corresponding
* values are the desired alias column name(s) for the averaged value(s).
* Example **array('col_1_name'=>'avg_col_1_value')** equivalent to
* **AVG(col_1_name) AS avg_col_1_value** in SQL.
*
*
* @return array An array of collections (Cfs_Model_Base_Collection). Each collection
* contains records that have the same distinct values for the columns in $col_names.
*
*/
public function groupByReturnAllRecordsPerGroup($col_names,
$sum_cols=array(),
$min_cols=array(),
$max_cols=array(),
$avg_cols=array()) {
$groups = array();
$col_names = (array)$col_names;
//get the column we are going to group by
$col_name = array_shift($col_names);
$grouping_array = array();//holds an array of arrays where the
//each array element's key is a distinct
//value of the grouping column $col_name
//loop thru all the records in this collection
//and group them by $col_name
for ($this->rewind(); $this->valid(); $this->next()) {
$record = $this->current();
if(!array_key_exists($record[$col_name], $grouping_array)){
$grouping_array[$record[$col_name]] = array();
}
//group
$grouping_array[$record[$col_name]][] = $record;
}
ksort($grouping_array);
$groups_4_this_iteration = array();//holds each group in collection form
reset($grouping_array);
while(list(, $items_in_group) = each($grouping_array)){
//convert array of records in the current group
//to a collection of records
$current_group_4_key = Solar::factory(get_class($this));
$current_group_4_key->load($items_in_group);
$groups_4_this_iteration[] = $current_group_4_key;
}
if(count($col_names) > 0){
//we still have more column names to further group by
reset($groups_4_this_iteration);
while(list(, $group_4_this_iteration) = each($groups_4_this_iteration)){
$returned_groups_4_current_group =
$group_4_this_iteration
->groupByReturnAllRecordsPerGroup($col_names,
$sum_cols,
$min_cols,
$max_cols,
$avg_cols);
reset($returned_groups_4_current_group);
while(list(, $sub_group) = each($returned_groups_4_current_group)){
//store the sub-groups
$groups[] = $sub_group;
}
}
}else{
//we have reached the last col_name in the list of
//column names initially passed to this method
//caluculate the SUM
self::_executeAggregateSqlFunctionForGroupBy('sumColumnValues',
$sum_cols,
$groups_4_this_iteration);
//caluculate the MIN
self::_executeAggregateSqlFunctionForGroupBy('minColumnValue',
$min_cols,
$groups_4_this_iteration);
//caluculate the MAX
self::_executeAggregateSqlFunctionForGroupBy('maxColumnValue',
$max_cols,
$groups_4_this_iteration);
//caluculate the AVG COLS
self::_executeAggregateSqlFunctionForGroupBy('averageColumnValue',
$avg_cols,
$groups_4_this_iteration);
return $groups_4_this_iteration;
}
//finally return merged sub-groups
return $groups;
}
/**
*
* Divides a collection of records into smaller collections based on the supplied
* list of columns ($col_names) to group by and then returns a collection containing
* the first record in each group.
*
* **NOTE:** The collection is first grouped by the first column in $col_names,
* then each of the groups obtained via grouping by the first column in $col_names
* are then further grouped by the second column in $col_names... (this process
* continues until all the entries in $col_names have been used for grouping).
*
* <br />
* **NOTE:** This method does the same thing as a basic SQL **GROUP BY**.
*
* <br />
* **NOTE:** Records with a **NULL** or **empty string** value for any of the columns being
* grouped by, are grouped together. As oppossed to having one group for records with one or
* more group by column(s) having a **NULL** value and another group for records with one or
* group by column(s) having an **empty string** value.
*
* <br />
* **Usage:**
*
* <pre>
* $this->groupByReturnOneRecordPerGroup (
* array('first_col_to_group_by', 'second_col_to_group_by'),
* array('col_1_name'=>'summed_col_1_value'),
* array('col_1_name'=>'min_col_1_value'),
* array('col_1_name'=>'max_col_1_value'),
* array('col_1_name'=>'avg_col_1_value')
* );
* </pre>
*
* Identical to
*
* <pre>
* SELECT table.*,
* SUM(col_1_name) AS summed_col_1_value,
* MIN(col_1_name) AS min_col_1_value,
* MAX(col_1_name) AS max_col_1_value,
* AVG(col_1_name) AS avg_col_1_value
* FROM table
* GROUP BY first_col_to_group_by, second_col_to_group_by
* </pre>
*
* in SQL.
*
* @param array $col_names An array of column names (calculate cols and other special
* cols can be included) that we want to group by.
*
* @param array $sum_cols Associative array. Array keys are the column name(s) whose
* values are to be summed in each group of the final result and the corresponding
* values are desired alias column name(s) for the summed value(s).
* Example **array('col_1_name'=>'summed_col_1_value')** equivalent to
* **SUM(col_1_name) AS summed_col_1_value** in SQL.
*
* @param array $min_cols Associative array. Array keys are the column name(s) whose
* min value(s) are to be found in each group of the final result and the corresponding
* values are desired alias column name(s) for the min value(s).
* Example **array('col_1_name'=>'min_col_1_value')** equivalent to
* **MIN(col_1_name) AS min_col_1_value** in SQL.
*
* @param array $max_cols Associative array. Array keys are the column name(s) whose
* max value(s) are to be found in each group of the final result and the corresponding
* values are desired alias column name(s) for the max value(s).
* Example **array('col_1_name'=>'max_col_1_value')** equivalent to
* **MAX(col_1_name) AS max_col_1_value** in SQL.
*
* @param array $avg_cols Associative array. Array keys are the column name(s) whose
* average value(s) are to be found in each group of the final result and the corresponding
* values are desired alias column name(s) for the averaged value(s).
* Example **array('col_1_name'=>'avg_col_1_value')** equivalent to
* **AVG(col_1_name) AS avg_col_1_value** in SQL.
*
*
* @return Cfs_Model_Base_Collection A collection of records with unique values for all the
* columns in $col_names. Same as running an SQL GROUP BY on the original
* collection ($this).
*
*/
public function groupByReturnOneRecordPerGroup($col_names,
$sum_cols=array(),
$min_cols=array(),
$max_cols=array(),
$avg_cols=array()) {
$groups = $this->groupByReturnAllRecordsPerGroup($col_names, $sum_cols, $min_cols, $max_cols, $avg_cols);
$first_record_per_group = array();
reset($groups);
while (list(, $group) = each($groups)) {
$first_record_per_group[] = $group->firstItem();
}
$collection = Solar::factory(get_class($this));
$collection->load($first_record_per_group);
return $collection;
}
/**
*
* Performs a comparison between the two specified operands using the specified
* comparison operator.
*
* @param string $operator A comparison operator. The specified comparison operator
* should be a string containing one of the valid php comparison operators specified
* <a href="http://php.net/manual/en/language.operators.comparison.php">here</a>.
*
* @param mixed $operand1s_value The value to be compared with the value of $operand2s_value
*
* @param mixed $operand2s_value The value to be compared with the value of $operand1s_value
*
*
* @return boolean True or false based on the specified comparison operator. For example,
* true will be returned if the operator is '==' and the operands are equivalent in value.
*
*/
private function _doComparison($operator, $operand1s_value, $operand2s_value){
$result = false;
$operator = $this->_extractComparisonOperatorFromStr($operator);
if(!empty ($operator)){
switch ($operator) {
case '==':
$result = ($operand1s_value == $operand2s_value);
break;
case '===':
$result = ($operand1s_value === $operand2s_value);
break;
case '!=':
$result = ($operand1s_value != $operand2s_value);
break;
case '<>':
$result = ($operand1s_value <> $operand2s_value);
break;
case '!==':
$result = ($operand1s_value !== $operand2s_value);
break;
case '<':
$result = ($operand1s_value < $operand2s_value);
break;
case '>':
$result = ($operand1s_value > $operand2s_value);
break;
case '<=':
$result = ($operand1s_value <= $operand2s_value);
break;
case '>=':
$result = ($operand1s_value >= $operand2s_value);
break;
default:
//do nothing
}
}
return $result;
}
/**
*
* Tries to extract a valid comparison operator from the specified string.
*
* @param string $potential_operator A string from which a valid comparison operator
* is to be extracted.
* See <a href="http://php.net/manual/en/language.operators.comparison.php">here</a>
* for list of valid comparison operators.
*
*
* @return string The extracted valid math operator. E.g. <=, !=, e.t.c.
* An empty string is returned if there is no valid math operator in $potential_operator.
*
*/
private function _extractComparisonOperatorFromStr($potential_operator){
$operator = '';
$php_operator_parts = array('<','>', '=', '!');
if(!empty($potential_operator) && is_string($potential_operator)){
$len = strlen($potential_operator);
for($i=0; $i<$len; $i++){
$char = $potential_operator[$i];
if(in_array($char, $php_operator_parts)){
$operator .= $char;
}
}
if(!in_array($operator, self::$_php_operators)){
//the extracted operator is not a standard php comparison operator
//http://ca.php.net/manual/en/language.operators.comparison.php
$operator = '';
}
}
return $operator;
}
/**
*
* A helper method used by Cfs_Model_Base_Collection::groupByReturnAllRecordsPerGroup() to call
* Cfs_Model_Base_Collection::sumColumnValues(), Cfs_Model_Base_Collection::minColumnValue(),
* Cfs_Model_Base_Collection::maxColumnValue() or Cfs_Model_Base_Collection::averageColumnValue().
*
* @param string $function_alias_name Name of function to be executed ( sumColumnValues(),
* minColumnValue(), maxColumnValue(), averageColumnValue() ).
*
* @param array $columns_2_b_operated_on An array of column names (each of which is a
* parameter to be passed to the function represented by $function_alias_name). If an
* empty array is supplied this method will do nothing.
*
* @param array $array_of_collections An array of collections (Cfs_Model_Base_Collection).
*
*
* @return void
*
*/
private static function _executeAggregateSqlFunctionForGroupBy( $function_alias_name,
$columns_2_b_operated_on,
&$array_of_collections){
if(!empty($columns_2_b_operated_on)){
$columns_2_b_operated_on = ((array)$columns_2_b_operated_on);
reset($columns_2_b_operated_on);
while (list($key) = each($columns_2_b_operated_on)) {
$results_col_name = $columns_2_b_operated_on[$key];
//assume that the name of the column to be operated on
//is the current key for the current array element
$col_name_to_be_operated_on = $key;
if(is_numeric($key)){
//The key is numeric and as a result cannot be the
//name of the column whose values are to be summed
$col_name_to_be_operated_on = $results_col_name;
}
reset($array_of_collections);
while (list($collection_key) = each($array_of_collections)) {
$result = $array_of_collections[$collection_key]->$function_alias_name($col_name_to_be_operated_on);
$array_of_collections[$collection_key]->addColumn($results_col_name, $result, true);
}
}
}
}
/**
*
* Retrieves and returns the first record in this collection.
*
* @return Cfs_Model_Base_Record The first record in this collection or null if
* collection is empty.
*
*/
public function firstItem(){
$keys = array_keys($this->_data);
return ($this->count() > 0) ? $this[$keys[0]] : null;
}
/**
*
* Retrieves and returns the last record in this collection.
*
* @return Cfs_Model_Base_Record The last record in this collection or null if
* collection is empty.
*
*/
public function lastItem(){
$keys = array_keys($this->_data);
$keys = array_reverse($keys);
return ($this->count() > 0) ? $this[$keys[0]] : null;
}
/**
*
* Left joins two collections (Cfs_Model_Base_Collection).
*
* If you are strictly using the Solar_Sql_Model for data access in your
* application, this method will allow you to do a left join between two
* different models (for this version of Solar (1.0.0alpha2), there is no
* left join implementation in the Solar_Sql_Model package. Inner joins
* are already taken care of by relationships in this version of Solar).
* Simply fetch collections of all the records you are interested in from
* both models and use this method to left join the two collections. All
* the records in the left hand side collection (i.e. the collection with
* which you are using to call this method) are always returned just like
* in SQL's Left Join where all records in the left table are always returned.
*
* <br />
* **$this** is the left hand side collection and **$other_collection** is
* the right hand side collection.
*
* <br />
* **Usage 1:**
*
* <pre>
* $this->leftJoin (
* $other_collection,
* array('column_1', 'column_2'),
* array('column_3', 'column_4'),
* array('column_3'=>'NONE', 'column_4'=>'NONE'),
* array('column_x'=>array('foreign_key_to_tlefts_column_x'=>'=='))
* );
* </pre>
*
* Assuming **$this** maps to a database table called **tleft** and
* **$other_collection** maps to another database table called **tright**.
* The SQL equivalent of this method would be:
*
* <pre>
* SELECT tleft.column_1, tleft.column_2, tright.column_3, tright.column_4
* FROM tleft
* LEFT JOIN tright
* ON tleft.column_x = tright.foreign_key_to_tlefts_column_x
* </pre>
*
* **Usage 2:**
*
* <pre>
* $this->leftJoin (
* $other_collection,
* array('column_1'=>'alias_1', 'column_2'=>'alias_2'),
* array('column_3'=>'alias_3', 'column_4'=>'alias_4'),
* array(),
* array('column_x'=>array('foreign_key_to_tlefts_column_x'=>'=='))
* );
* </pre>
*
* Assuming **$this** maps to a database table called **tleft** and
* **$other_collection** maps to another database table called **tright**.
* The SQL equivalent of this method would be:
*
* <pre>
* SELECT tleft.column_1 AS alias_1, tleft.column_2 AS alias_2,
* tright.column_3 AS alias_3, tright.column_4 AS alias_4
* FROM tleft
* LEFT JOIN tright
* ON tleft.column_x = tright.foreign_key_to_tlefts_column_x
* </pre>
*
* **NOTE:** You can supply default values for the columns you want in the
* result from **$other_collection** (the right hand side collection) via
* **$return_default_values_4_right_collection_columns**. These values will
* be used to populate the **$other_collection**'s columns in records in the
* result that do not have a matching right hand side collection record. This
* can be seen in the first usage example above where **'column_3'** and
* **'column_4'** from **$other_collection** records are assigned a default
* value of 'NONE' in the result where no record in **$other_collection**
* matches a record in **this** (the left hand side collection).
* Usually in SQL such values will be set to NULL, this method will set these columns
* to an empty string value if **$return_default_values_4_right_collection_columns**
* is an empty array (as can be seen in the second usage example above).
*
* @param Cfs_Model_Base_Collection $other_collection the right hand side collection to be joined to $this.
*
* @param array $return_column_names_4_left_collection Names of the columns in the
* records in **$this** that should be returned in the result of the left join. You
* can use this format: **array('column_name_1'=>'column_name_1_alias', ...)**
* (the **column_name_#**'s values will be accessed via **column_name_#_alias**
* in each record of the result. **column_name_#** is just a placeholder for a
* column name).
* **array('column_name_1',...)** is also a valid format (the **column_name_#**'s
* values will be accessed via **column_name_#** in each record of the result.
* **column_name_#** is also just a placeholder for a column name).
*
* @param array $return_column_names_4_right_collection Names of the columns in the
* records in **$other_collection** that should be returned in the result of the left
* join. You can use this format: **array('column_name_1'=>'column_name_1_alias', ...)**
* (the **column_name_#**'s values will be accessed via **column_name_#_alias** in each
* record of the result. **column_name_#** is just a placeholder for a column name).
* **array('column_name_1',...)** is also a valid format (the **column_name_#**'s
* values will be accessed via **column_name_#** in each record of the result.
* **column_name_#** is also just a placeholder for a column name).
*
* @param array $return_default_values_4_right_collection_columns An array of default values
* for **$other_collection**'s columns in the left join result. These value(s) will be applied
* to record(s) in the result where a record in **$this** (the left hand hand side collection)
* does not have a matching record in **$other_collection** (the right hand side collection).
* The key(s) in this array are the column names in **$other_collection** and the corresponding
* value(s) are the default value(s) for the respective columns.
*
* @param array $join_cols_map_with_comparison_operators An array of the left join criteria. It
* has the following structure:
* <br/>
* <code>
* array(
* <br/>
* 'join_col_1_in_left' => array( 'join_col_1_in_right' => 'comparison_operator_1' ),
* <br/>
* .......,
* <br/>
* .......,
* <br/>
* 'join_col_N_in_left' => array( 'join_col_N_in_right' => 'comparison_operator_N' ),
* <br/>
* );
* </code>
* <br/>
* The key ( e.g. 'join_col_1_in_left',....,'join_col_N_in_left' ) to each element in this array
* is the name of a column in the left collection that will be part of the comparison check for
* the join. Each element in this array is an array containing only one element whose key ( e.g.
* 'join_col_1_in_right', .... ,'join_col_N_in_right' ) is the name of a column in the right
* collection that will be compared to the corresponding specified column in the left collection
* mentioned above. The value of this single element sub-array is a string containing a comparison
* operator (e.g. '<=' ) specified
* <a href="http://php.net/manual/en/language.operators.comparison.php">here</a>.
*
* @return Cfs_Model_Base_Collection A collection of records (the result of the left join operation).
* Uses the same logic / algorithm as the SQL LEFT JOIN operation. An empty collection will be returned
* if one or more of $this, $other_collection, $return_column_names_4_left_collection,
* $return_column_names_4_right_collection or $join_cols_map_with_comparison_operators
* is empty.
*
*/
public function leftJoin(Cfs_Model_Base_Collection $other_collection,
array $return_column_names_4_left_collection,
array $return_column_names_4_right_collection,
array $return_default_values_4_right_collection_columns,
array $join_cols_map_with_comparison_operators) {
$records_to_be_returned = Solar::factory(get_class($this));
$curr_key_in_collctn_2_b_returned = 0;
if($this->count() > 0
&& $other_collection->count() > 0
&& count($return_column_names_4_left_collection) > 0
&& count($return_column_names_4_right_collection) > 0
&& count($join_cols_map_with_comparison_operators) > 0){
//generate params to be passed to findRecordsByCols
//for the $other_collection
$find_cols = array();
$operators = array();
reset($join_cols_map_with_comparison_operators);
while(list($current_left_collection_join_col) = each($join_cols_map_with_comparison_operators)){
list($right_col_4_filtering, $operator) =
each($join_cols_map_with_comparison_operators[$current_left_collection_join_col]);
$find_cols[] = $right_col_4_filtering;
$operators[$right_col_4_filtering] = $operator;
}
$current_left_collection_join_col ='';//reset
$all_left_collections_join_cols = array_keys($join_cols_map_with_comparison_operators);
for($this->rewind(); $this->valid(); $this->next()) {
$left_collections_record = $this->current();
//generate params to be passed to findRecordsByCols
//for the $other_collection
$find_vals = array();
reset($all_left_collections_join_cols);
while(list($key) = each($all_left_collections_join_cols)){
$current_left_collection_join_col = $all_left_collections_join_cols[$key];
$find_vals[] = $left_collections_record[$current_left_collection_join_col];
}
//get the matching right records
$matching_right_collection_records =
$other_collection
->findRecordsByCols($find_cols, $find_vals, $operators);
//since this a left join, we always need to return a record
//containing the details of the current left collection's
//record whether or not we find any matching right collection
//record(s)
//create a new record
$db_rec = Solar::factory('Solar_Struct');
//fill record to be returned with values from
//the current left collection's record
reset($return_column_names_4_left_collection);
while(list($potential_left_col_name) = each($return_column_names_4_left_collection)){
$left_col_name_alias = $return_column_names_4_left_collection[$potential_left_col_name];
//user just supplied an array of column names and not a
//key value pair array of column_name=>column_name_alias
if(is_numeric($potential_left_col_name)){
$potential_left_col_name = $left_col_name_alias;
}
$db_rec[$left_col_name_alias] = $left_collections_record[$potential_left_col_name];
}
if($matching_right_collection_records != null){
$keys_2_matching_right_collection = array_keys($matching_right_collection_records->getRefToInternalArray());
$num_matching_records = count($keys_2_matching_right_collection);
for($curr_index_2_key_map=0; $curr_index_2_key_map < $num_matching_records; $curr_index_2_key_map++){
$right_collections_record =
$matching_right_collection_records[$keys_2_matching_right_collection[$curr_index_2_key_map]];
$current_record_2_b_returned = clone $db_rec;
//fill record to be returned with the approriate
//matching right collection record's values
reset($return_column_names_4_right_collection);
while(list($potential_right_col_name) = each($return_column_names_4_right_collection)){
$right_col_name_alias = $return_column_names_4_right_collection[$potential_right_col_name];
if(is_numeric($potential_right_col_name)){
//user just supplied an array of column names and not a
//key value pair array of column_name=>column_name_alias
$potential_right_col_name = $right_col_name_alias;
}
$current_record_2_b_returned[$right_col_name_alias] = $right_collections_record[$potential_right_col_name];
}
$records_to_be_returned[$curr_key_in_collctn_2_b_returned++] = $current_record_2_b_returned;
}
}else{
$current_record_2_b_returned = clone $db_rec;
//fill record to be returned with default / empty values
//for the right collections return columns since there
//are no matching right collection records
reset($return_column_names_4_right_collection);
while(list($potential_right_col_name) = each($return_column_names_4_right_collection)){
$right_col_name_alias = $return_column_names_4_right_collection[$potential_right_col_name];
if(is_numeric($potential_right_col_name)){
//user just supplied an array of column names and not a
//key value pair array of column_name=>column_name_alias
$potential_right_col_name = $right_col_name_alias;
}
if(array_key_exists($potential_right_col_name, $return_default_values_4_right_collection_columns)){
//default value was specified for the current right column, so use it
$current_record_2_b_returned[$right_col_name_alias] = $return_default_values_4_right_collection_columns[$potential_right_col_name];
}else{
//no default value was specified for the current right column,
//so set it to an empty string
$current_record_2_b_returned[$right_col_name_alias] = '';
}
}
$records_to_be_returned[$curr_key_in_collctn_2_b_returned++] = $current_record_2_b_returned;
}
}
}
return $records_to_be_returned;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.