public static function sortBy($array, $sortByKeys, $sorters, $orders = [])
	{
		if( is_string($sortByKeys) )
		{
			$sortByKeys = explode('.', $sortByKeys);
		}

		$sortByKeys = array_values((array)$sortByKeys);
		$sorters = array_values((array)$sorters);

		uasort($array, function($a, $b) use ($sortByKeys, $sorters, $orders) {

			$return = 0;

			foreach( $sortByKeys as $key => $sortBy ) 
			{
				// call callback or get attribute
				if( is_callable($sortBy) )
				{
					$aSort = call_user_func($sortBy, $a);
					$bSort = call_user_func($sortBy, $b);
				}
				else 
				{
					$aSort = u\def($a, $sortBy);
					$bSort = u\def($b, $sortBy);
				}

				$method = isset($sorters[$key]) ? $sorters[$key] : $sorters[ ( count($sorters) - 1 ) ];

				// make sure Sort class from pisc\arrr namespace is used
				if( is_string($method) && substr($method, 0, 4) === 'Sort' ) $method = __NAMESPACE__ .'\\' . $method;

				$order = u\def($orders, $key, 'desc');

				// call compare function
				$return = call_user_func($method, $aSort, $bSort);

				// reverse return value
				if( $order !== 'desc' )
				{
					$return *= -1;
				}

				// return if the items compared are not the same
				if( $return !== 0 )
				{
					return $return;
				}
			}

			return 0;
		});

		return $array;
	}
public static function sortBy($array, $sortByKeys, $sorters, $orders = [])
	{
		if( is_string($sortByKeys) )
		{
			$sortByKeys = explode('.', $sortByKeys);
		}

		$sortByKeys = array_values((array)$sortByKeys);
		$sorters = array_values((array)$sorters);

		uasort($array, function($a, $b) use ($sortByKeys, $sorters, $orders) {

			$return = 0;

			foreach( $sortByKeys as $key => $sortBy ) 
			{
				// call callback or get attribute
				if( is_callable($sortBy) )
				{
					$aSort = call_user_func($sortBy, $a);
					$bSort = call_user_func($sortBy, $b);
				}
				else 
				{
					$aSort = u\def($a, $sortBy);
					$bSort = u\def($b, $sortBy);
				}

				$method = isset($sorters[$key]) ? $sorters[$key] : $sorters[ ( count($sorters) - 1 ) ];

				// make sure Sort class from pisc\arrr namespace is used
				if( is_string($method) && substr($method, 0, 4) === 'Sort' ) $method = __NAMESPACE__ .'\\' . $method;

				$order = u\def($orders, $key, 'desc');

				// call compare function
				$return = call_user_func($method, $aSort, $bSort);

				// reverse return value
				if( $order !== 'desc' )
				{
					$return *= -1;
				}

				// return if the items compared are not the same
				if( $return !== 0 )
				{
					return $return;
				}
			}

			return 0;
		});

		return $array;
	}
public static function sortBy ( $ array , $ sortByKeys , $ sorters , $ orders = [ ] ) { if ( is_string ( $ sortByKeys ) ) { $ sortByKeys = explode ( '.' , $ sortByKeys ) ; } $ sortByKeys = array_values ( ( array ) $ sortByKeys ) ; $ sorters = array_values ( ( array ) $ sorters ) ; uasort ( $ array , function ( $ a , $ b ) use ( $ sortByKeys , $ sorters , $ orders ) { $ return = 0 ; foreach ( $ sortByKeys as $ key => $ sortBy ) { // call callback or get attribute if ( is_callable ( $ sortBy ) ) { $ aSort = call_user_func ( $ sortBy , $ a ) ; $ bSort = call_user_func ( $ sortBy , $ b ) ; } else { $ aSort = u \ def ( $ a , $ sortBy ) ; $ bSort = u \ def ( $ b , $ sortBy ) ; } $ method = isset ( $ sorters [ $ key ] ) ? $ sorters [ $ key ] : $ sorters [ ( count ( $ sorters ) - 1 ) ] ; // make sure Sort class from pisc\arrr namespace is used if ( is_string ( $ method ) && substr ( $ method , 0 , 4 ) === 'Sort' ) $ method = __NAMESPACE__ . '\\' . $ method ; $ order = u \ def ( $ orders , $ key , 'desc' ) ; // call compare function $ return = call_user_func ( $ method , $ aSort , $ bSort ) ; // reverse return value if ( $ order !== 'desc' ) { $ return *= - 1 ; } // return if the items compared are not the same if ( $ return !== 0 ) { return $ return ; } } return 0 ; } ) ; return $ array ; }
Sort by multiple keys

Usages:

String of attributes
Ar::sortBy($array, 'created_at.firstName', [ 'Sort::byDateTime', 'Sort::byString' ], [ 'asc', 'desc' ]);

Array
Ar::sortBy($array, [ 'created_at', function($i) { return strtolower($i->firstName); } ], [ 'Sort::byDateTime', 'Sort::byString' ], [ 'asc', 'desc' ])

@param  array           $array    Array of values
@param  string/array    $sortBy   String with dots seperating keys or array of keys/functions
@param  array/callable  $sorters  Array of compare sorters or one method
@param  array           $orders   Array of order (desc/asc)
@return array                     Sorted array
Sort by multiple keys