|
/** |
|
* @param unsortedRecords The array that needs to be sorted. This array must be in the typical |
|
* format that our arrays are in after retrieving database data (i.e. array of records). |
|
* @param sortKeys The record keys that we'll be sorting on. |
|
* If this is an array, multi-column sorting will be done. |
|
* @param sortDirections The direction to sort the columns. |
|
* If this is an array, it should match up with the sort_keys array. |
|
* @param sortTypes The type of sorting that should be done (SORT_NUMERIC, SORT_STRING, etc. ) |
|
* If this is an array, it should match up with the sort_keys array. |
|
* @example To sort records by 'last_name' in descending order: |
|
* $sortedArray = multisortRecords( $records, 'last_name', SORT_DESC ) |
|
* @example To sort records by 'last_name' ascending, then 'first_name' descending: |
|
* $sortedArray = multisortRecords( $records, array( 'last_name', 'first_name' ), array( SORT_ASC, SORT_DESC ) ) |
|
* @author - Matthew Hayes <Matthew.Hayes@AllThingsCode.com |
|
*/ |
|
function multisortRecords( &$unsortedRecords, $sortKeys, $sortDirections = SORT_ASC, $sortTypes = null ) |
|
{ |
|
if( ( ! is_array( $unsortedRecords ) ) || ( ! count( $unsortedRecords ) ) ) { |
|
return array(); |
|
} |
|
// Convert params to arrays if they are not already. |
|
if( ! is_array( $sortKeys ) ) { |
|
$_sort_keys = array( $sortKeys ); |
|
} |
|
if( ! is_array( $sortDirections ) ) { |
|
$sortDirections = array_fill( 0, count( $sortKeys ), $sortDirections ); |
|
} |
|
if( ! is_array( $sortTypes ) ) { |
|
$sortTypes = array_fill( 0, count( $sortKeys ), $sortTypes ); |
|
} |
|
|
|
// Convert the sort directions in case they are plain text |
|
foreach( array_keys( $sortDirections ) as $key ) { |
|
switch( $sortDirections[ $key ] ) { |
|
case SORT_ASC: |
|
case SORT_DESC: |
|
break; |
|
case 'DESC': |
|
case 'SORT_DESC': |
|
$sortDirections[ $key ] = SORT_DESC; |
|
break; |
|
case 'ASC': |
|
case 'SORT_ASC': |
|
default: |
|
$sortDirections[ $key ] = SORT_ASC; |
|
} |
|
} |
|
|
|
// Convert the sort types in case they are plain text |
|
foreach( array_keys( $sortTypes ) as $key ) { |
|
switch( $sortTypes[ $key ] ) { |
|
case SORT_NUMERIC: |
|
case SORT_STRING: |
|
break; |
|
case 'NUMERIC': |
|
case 'SORT_NUMERIC': |
|
$sortTypes[ $key ] = SORT_NUMERIC; |
|
break; |
|
case 'STRING': |
|
case 'SORT_STRING': |
|
$sortTypes[ $key ] = SORT_STRING; |
|
break; |
|
default: |
|
$sortTypes[ $key ] = null; |
|
} |
|
} |
|
|
|
// Convert the data we'll be sorting on to column format |
|
$sortColumns = array(); |
|
foreach( $unsortedRecords as $key => $record ) { |
|
$sortColumns['primary_key'][ $key ] = $key; |
|
foreach( $sortKeys as $sortKeyIndex => $sortKeyName ) { |
|
$sortColumns[ $sortKeyName ][ $key ] = $record[ $sortKeyName ]; |
|
} |
|
} |
|
|
|
// Generate parameters for array_multisort() |
|
$arrayMultisortParams = array(); |
|
for( $i = 0; $i < count( $sortKeys ); $i++ ) { |
|
$arrayMultisortParams[] = $sortColumns[ $sortKeys[ $i ] ]; |
|
$arrayMultisortParams[] = $sortDirections[ $i ]; |
|
if( ! is_null( $sortTypes[ $i ] ) ) { |
|
$arrayMultisortParams[] = $sortTypes[ $i ]; |
|
} |
|
} |
|
|
|
// We HAVE to pass in the primary_key column so that we can put it all back together later. |
|
$arrayMultisortParams[] = $sortColumns['primary_key']; |
|
|
|
// This is where the actual sort is done. See Also: http://us.php.net/manual/en/function.array-multisort.php |
|
call_user_func_array( 'array_multisort', $arrayMultisortParams ); |
|
|
|
// Convert back to record format. |
|
// We just build a new sorted array |
|
// using the primary_key column (which is in the correct order now). |
|
$sortedRows = array(); |
|
foreach( $sortColumns['primary_key'] as $key ) { |
|
$sortedRows[ $key ] = $unsortedRecords[ $key ]; |
|
} |
|
|
|
return $sortedRows; |
|
} |