/fuel/core/classes/arr.php
PHP | 598 lines | 336 code | 68 blank | 194 comment | 35 complexity | 03740bfc6950602628739d464f47e9d9 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
- <?php
- /**
- * Part of the Fuel framework.
- *
- * @package Fuel
- * @version 1.0
- * @author Fuel Development Team
- * @license MIT License
- * @copyright 2010 - 2011 Fuel Development Team
- * @link http://fuelphp.com
- */
-
- namespace Fuel\Core;
-
- /**
- * The Arr class provides a few nice functions for making
- * dealing with arrays easier
- *
- * @package Fuel
- * @subpackage Core
- */
- class Arr
- {
-
- /**
- * Gets a dot-notated key from an array, with a default value if it does
- * not exist.
- *
- * @param array $array The search array
- * @param mixed $key The dot-notated key or array of keys
- * @param string $default The default value
- * @return mixed
- */
- public static function get($array, $key, $default = null)
- {
- if ( ! is_array($array) and ! $array instanceof \ArrayAccess)
- {
- throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.');
- }
-
- if (is_null($key))
- {
- return $array;
- }
-
- if (is_array($key))
- {
- $return = array();
- foreach ($key as $k)
- {
- $return[$k] = static::get($array, $k, $default);
- }
- return $return;
- }
-
- foreach (explode('.', $key) as $key_part)
- {
- if (($array instanceof \ArrayAccess and isset($array[$key_part])) === false)
- {
- if ( ! is_array($array) or ! array_key_exists($key_part, $array))
- {
- return \Fuel::value($default);
- }
- }
-
- $array = $array[$key_part];
- }
-
- return $array;
- }
-
- /**
- * Set an array item (dot-notated) to the value.
- *
- * @param array $array The array to insert it into
- * @param mixed $key The dot-notated key to set or array of keys
- * @param mixed $value The value
- * @return void
- */
- public static function set(&$array, $key, $value = null)
- {
- if (is_null($key))
- {
- $array = $value;
- return;
- }
-
- if (is_array($key))
- {
- foreach ($key as $k => $v)
- {
- static::set($array, $k, $value);
- }
- }
-
- $keys = explode('.', $key);
-
- while (count($keys) > 1)
- {
- $key = array_shift($keys);
-
- if ( ! isset($array[$key]) or ! is_array($array[$key]))
- {
- $array[$key] = array();
- }
-
- $array =& $array[$key];
- }
-
- $array[array_shift($keys)] = $value;
- }
-
- /**
- * Array_key_exists with a dot-notated key from an array.
- *
- * @param array $array The search array
- * @param mixed $key The dot-notated key or array of keys
- * @return mixed
- */
- public static function key_exists($array, $key)
- {
- foreach (explode('.', $key) as $key_part)
- {
- if ( ! is_array($array) or ! array_key_exists($key_part, $array))
- {
- return false;
- }
-
- $array = $array[$key_part];
- }
-
- return true;
- }
-
- /**
- * Unsets dot-notated key from an array
- *
- * @param array $array The search array
- * @param mixed $key The dot-notated key or array of keys
- * @return mixed
- */
- public static function delete(&$array, $key)
- {
- if (is_null($key))
- {
- return false;
- }
-
- if (is_array($key))
- {
- $return = array();
- foreach ($key as $k)
- {
- $return[$k] = static::delete($array, $k);
- }
- return $return;
- }
-
- $key_parts = explode('.', $key);
-
- if ( ! is_array($array) or ! array_key_exists($key_parts[0], $array))
- {
- return false;
- }
-
- $this_key = array_shift($key_parts);
-
- if ( ! empty($key_parts))
- {
- $key = implode('.', $key_parts);
- return static::delete($array[$this_key], $key);
- }
- else
- {
- unset($array[$this_key]);
- }
-
- return true;
- }
-
- /**
- * Converts a multi-dimensional associative array into an array of key => values with the provided field names
- *
- * @param array the array to convert
- * @param string the field name of the key field
- * @param string the field name of the value field
- * @return array
- */
- public static function assoc_to_keyval($assoc = null, $key_field = null, $val_field = null)
- {
- if(empty($assoc) OR empty($key_field) OR empty($val_field))
- {
- return null;
- }
-
- $output = array();
- foreach($assoc as $row)
- {
- if(isset($row[$key_field]) AND isset($row[$val_field]))
- {
- $output[$row[$key_field]] = $row[$val_field];
- }
- }
-
- return $output;
- }
-
- /**
- * Converts the given 1 dimensional non-associative array to an associative
- * array.
- *
- * The array given must have an even number of elements or null will be returned.
- *
- * Arr::to_assoc(array('foo','bar'));
- *
- * @param string $arr the array to change
- * @return array|null the new array or null
- */
- public static function to_assoc($arr)
- {
- if (($count = count($arr)) % 2 > 0)
- {
- return null;
- }
- $keys = $vals = array();
-
- for ($i = 0; $i < $count - 1; $i += 2)
- {
- $keys[] = array_shift($arr);
- $vals[] = array_shift($arr);
- }
- return array_combine($keys, $vals);
- }
-
- /**
- * Flattens a multi-dimensional associative array down into a 1 dimensional
- * associative array.
- *
- * @param array the array to flatten
- * @param string what to glue the keys together with
- * @param bool whether to reset and start over on a new array
- * @param bool whether to flatten only associative array's, or also indexed ones
- * @return array
- */
- public static function flatten($array, $glue = ':', $reset = true, $indexed = true)
- {
- static $return = array();
- static $curr_key = array();
-
- if ($reset)
- {
- $return = array();
- $curr_key = array();
- }
-
- foreach ($array as $key => $val)
- {
- $curr_key[] = $key;
- if (is_array($val) and ($indexed or array_values($val) !== $val))
- {
- static::flatten_assoc($val, $glue, false);
- }
- else
- {
- $return[implode($glue, $curr_key)] = $val;
- }
- array_pop($curr_key);
- }
- return $return;
- }
-
- /**
- * Flattens a multi-dimensional associative array down into a 1 dimensional
- * associative array.
- *
- * @param array the array to flatten
- * @param string what to glue the keys together with
- * @param bool whether to reset and start over on a new array
- * @return array
- */
- public static function flatten_assoc($array, $glue = ':', $reset = true)
- {
- return static::flatten($array, $glue, $reset, false);
- }
-
- /**
- * Filters an array on prefixed associative keys.
- *
- * @param array the array to filter.
- * @param string prefix to filter on.
- * @param bool whether to remove the prefix.
- * @return array
- */
- public static function filter_prefixed($array, $prefix = 'prefix_', $remove_prefix = true)
- {
- $return = array();
- foreach ($array as $key => $val)
- {
- if(preg_match('/^'.$prefix.'/', $key))
- {
- if($remove_prefix === true)
- {
- $key = preg_replace('/^'.$prefix.'/','',$key);
- }
- $return[$key] = $val;
- }
- }
- return $return;
- }
-
- /**
- * Filters an array by an array of keys
- *
- * @param array the array to filter.
- * @param array the keys to filter
- * @param bool if true, removes the matched elements.
- * @return array
- */
- public static function filter_keys($array, $keys, $remove = false)
- {
- $return = array();
- foreach ($keys as $key)
- {
- if (isset($array[$key]) and ! $remove)
- {
- $return[$key] = $array[$key];
- }
- elseif (isset($array[$key]) and $remove)
- {
- unset($array[$key]);
- }
- }
- return $remove ? $array : $return;
- }
-
- /**
- * Returns the element of the given array or a default if it is not set.
- *
- * @param array the array to fetch from
- * @param mixed the key to fetch from the array
- * @param mixed the value returned when not an array or invalid key
- * @return mixed
- * @deprecated until 1.2
- */
- public static function element($array, $key, $default = false)
- {
- return static::get($array, $key, $default);
- }
-
- /**
- * Returns the elements of the given array or a default if it is not set.
- *
- * @param array the array to fetch from
- * @param array the keys to fetch from the array
- * @param mixed the value returned when not an array or invalid key
- * @return mixed
- * @deprecated until 1.2
- */
- public static function elements($array, $keys, $default = false)
- {
- return static::get($array, $keys, $default);
- }
-
- /**
- * Insert value(s) into an array, mostly an array_splice alias
- * WARNING: original array is edited by reference, only boolean success is returned
- *
- * @param array the original array (by reference)
- * @param array|mixed the value(s) to insert, if you want to insert an array it needs to be in an array itself
- * @param int the numeric position at which to insert, negative to count from the end backwards
- * @return bool false when array shorter then $pos, otherwise true
- */
- public static function insert(array &$original, $value, $pos)
- {
- if (count($original) < abs($pos))
- {
- \Error::notice('Position larger than number of elements in array in which to insert.');
- return false;
- }
-
- array_splice($original, $pos, 0, $value);
- return true;
- }
-
- /**
- * Insert value(s) into an array after a specific key
- * WARNING: original array is edited by reference, only boolean success is returned
- *
- * @param array the original array (by reference)
- * @param array|mixed the value(s) to insert, if you want to insert an array it needs to be in an array itself
- * @param string|int the key after which to insert
- * @return bool false when key isn't found in the array, otherwise true
- */
- public static function insert_after_key(array &$original, $value, $key)
- {
- $pos = array_search($key, array_keys($original));
- if ($pos === false)
- {
- \Error::notice('Unknown key after which to insert the new value into the array.');
- return false;
- }
-
- return static::insert($original, $value, $pos + 1);
- }
-
- /**
- * Insert value(s) into an array after a specific value (first found in array)
- *
- * @param array the original array (by reference)
- * @param array|mixed the value(s) to insert, if you want to insert an array it needs to be in an array itself
- * @param string|int the value after which to insert
- * @return bool false when value isn't found in the array, otherwise true
- */
- public static function insert_after_value(array &$original, $value, $search)
- {
- $key = array_search($search, $original);
- if ($key === false)
- {
- \Error::notice('Unknown value after which to insert the new value into the array.');
- return false;
- }
-
- return static::insert_after_key($original, $value, $key);
- }
-
- /**
- * Sorts a multi-dimensional array by it's values.
- *
- * @access public
- * @param array The array to fetch from
- * @param string The key to sort by
- * @param string The order (asc or desc)
- * @param int The php sort type flag
- * @return array
- */
- public static function sort($array, $key, $order = 'asc', $sort_flags = SORT_REGULAR)
- {
- if ( ! is_array($array))
- {
- throw new \InvalidArgumentException('Arr::sort() - $array must be an array.');
- }
-
- foreach ($array as $k=>$v)
- {
- $b[$k] = static::get($v, $key);
- }
-
- switch ($order)
- {
- case 'asc':
- asort($b, $sort_flags);
- break;
-
- case 'desc':
- arsort($b, $sort_flags);
- break;
-
- default:
- throw new \InvalidArgumentException('Arr::sort() - $order must be asc or desc.');
- break;
- }
-
- foreach ($b as $key=>$val)
- {
- $c[] = $array[$key];
- }
-
- return $c;
- }
-
- /**
- * Find the average of an array
- *
- * @param array the array containing the values
- * @return numeric the average value
- */
- public static function average($array)
- {
- // No arguments passed, lets not divide by 0
- if ( ! ($count = count($array)) > 0)
- {
- return 0;
- }
-
- return (array_sum($array) / $count);
- }
-
- /**
- * Alias for replace_key for backwards compatibility.
- */
- public static function replace_keys($source, $replace, $new_key = null)
- {
- logger(\Fuel::L_WARNING, 'This method is deprecated. Please use a replace_key() instead.', __METHOD__);
- return static::replace_key($source, $replace, $new_key);
- }
-
- /**
- * Replaces key names in an array by names in $replace
- *
- * @param array the array containing the key/value combinations
- * @param array|string key to replace or array containing the replacement keys
- * @param string the replacement key
- * @return array the array with the new keys
- */
- public static function replace_key($source, $replace, $new_key = null)
- {
- if(is_string($replace))
- {
- $replace = array($replace => $new_key);
- }
-
- if ( ! is_array($source) or ! is_array($replace))
- {
- throw new \InvalidArgumentException('Arr::replace_keys() - $source must an array. $replace must be an array or string.');
- }
-
- $result = array();
-
- foreach ($source as $key => $value)
- {
- if (array_key_exists($key, $replace))
- {
- $result[$replace[$key]] = $value;
- }
- else
- {
- $result[$key] = $value;
- }
- }
-
- return $result;
- }
-
- /**
- * Merge 2 arrays recursively, differs in 2 important ways from array_merge_recursive()
- * - When there's 2 different values and not both arrays, the latter value overwrites the earlier
- * instead of merging both into an array
- * - Numeric keys that don't conflict aren't changed, only when a numeric key already exists is the
- * value added using array_push()
- *
- * @param array multiple variables all of which must be arrays
- * @return array
- * @throws \InvalidArgumentException
- */
- public static function merge()
- {
- $array = func_get_arg(0);
- $arrays = array_slice(func_get_args(), 1);
-
- if ( ! is_array($array))
- {
- throw new \InvalidArgumentException('Arr::merge() - all arguments must be arrays.');
- }
-
- foreach ($arrays as $arr)
- {
- if ( ! is_array($arr))
- {
- throw new \InvalidArgumentException('Arr::merge() - all arguments must be arrays.');
- }
-
- foreach ($arr as $k => $v)
- {
- // numeric keys are appended
- if (is_int($k))
- {
- array_key_exists($k, $array) ? array_push($array, $v) : $array[$k] = $v;
- }
- elseif (is_array($v) and array_key_exists($k, $array) and is_array($array[$k]))
- {
- $array[$k] = static::merge($array[$k], $v);
- }
- else
- {
- $array[$k] = $v;
- }
- }
- }
-
- return $array;
- }
-
- /**
- * Prepends a value with an asociative key to an array.
- * Will overwrite if the value exists.
- *
- * @param array $arr the array to prepend to
- * @param string|array $key the key or array of keys and values
- * @param mixed $valye the value to prepend
- */
- public static function prepend(&$arr, $key, $value = null)
- {
- $arr = (is_array($key) ? $key : array($key => $value)) + $arr;
- }
-
- }
-
-