From c9e15d2aa437ac5401965a381e2528de36a4b546 Mon Sep 17 00:00:00 2001 From: "Robert C. Sheets" Date: Thu, 27 Mar 2014 04:10:58 -0700 Subject: [PATCH] Improves doc strings in class CRM_Utils_Array. --- CRM/Utils/Array.php | 452 +++++++++++++++++++++++++++++++++----------- 1 file changed, 345 insertions(+), 107 deletions(-) diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index 575c0e66b8..86b2badd72 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -26,25 +26,30 @@ */ /** + * Provides a ollection of static methods for array manipulation. * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2013 - * $Id$ - * + * @copyright CiviCRM LLC (c) 2004-2014 */ class CRM_Utils_Array { /** - * if the key exists in the list returns the associated value + * Returns $list[$key] if such element exists, or a default value otherwise. + * + * If $list is not actually an array at all, then the default value is + * returned. * * @access public * - * @param string $key the key value - * @param array $list the array to be searched + * @param string $key + * Key value to look up in the array. + * @param array $list + * Array from which to look up a value. * @param mixed $default + * (optional) Value to return $list[$key] does not exist. * - * @return mixed value if exists else $default - * @static + * @return mixed + * Can return any type, since $list might contain anything. */ static function value($key, $list, $default = NULL) { if (is_array($list)) { @@ -54,15 +59,19 @@ class CRM_Utils_Array { } /** - * Given a parameter array and a key to search for, - * search recursively for that key's value. + * Recursively searches an array for a key, returning the first value found. * - * @param array $values The parameter array - * @param string $key The key to search for + * If $params[$key] does not exist and $params contains arrays, descend into + * each array in a depth-first manner, in array iteration order. * - * @return mixed The value of the key, or null. + * @param array $params + * The array to be searched. + * @param string $key + * The key to search for. + * + * @return mixed + * The value of the key, or null if the key is not found. * @access public - * @static */ static function retrieveValueRecursive(&$params, $key) { if (!is_array($params)) { @@ -84,17 +93,21 @@ class CRM_Utils_Array { } /** - * if the value exists in the list returns the associated key + * Wraps and slightly changes the behavior of PHP's array_search(). * - * @access public + * This function reproduces the behavior of array_search() from PHP prior to + * version 4.2.0, which was to return NULL on failure. This function also + * checks that $list is an array before attempting to search it. * - * @param list the array to be searched - * @param value the search value - * - * @return key if exists else null - * @static * @access public * + * @param mixed $value + * The value to search for. + * @param array $list + * The array to be searched. + * + * @return int|string|null + * Returns the key, which could be an int or a string, or NULL on failure. */ static function key($value, &$list) { if (is_array($list)) { @@ -109,6 +122,24 @@ class CRM_Utils_Array { return NULL; } + /** + * Builds an XML fragment representing an array. + * + * Depending on the nature of the keys of the array (and its sub-arrays, + * if any) the XML fragment may not be valid. + * + * @param array $list + * The array to be serialized. + * @param int $depth + * (optional) Indentation depth counter. + * @param string $seperator + * (optional) String to be appended after open/close tags. + * + * @access public + * + * @return string + * XML fragment representing $list. + */ static function &xml(&$list, $depth = 1, $seperator = "\n") { $xml = ''; foreach ($list as $name => $value) { @@ -128,6 +159,18 @@ class CRM_Utils_Array { return $xml; } + /** + * Sanitizes a string for serialization in CRM_Utils_Array::xml(). + * + * Replaces '&', '<', and '>' with their XML escape sequences. Replaces '^A' + * with a comma. + * + * @param string $value + * String to be sanitized. + * + * @return string + * Sanitized version of $value. + */ static function escapeXML($value) { static $src = NULL; static $dst = NULL; @@ -141,12 +184,59 @@ class CRM_Utils_Array { } /** - * Convert an array-tree to a flat array - * - * @param array $list the original, tree-shaped list - * @param array $flat the flat list to which items will be copied + * Converts a nested array to a flat array. + * + * The nested structure is preserved in the string values of the keys of the + * flat array. + * + * Example nested array: + * Array + * ( + * [foo] => Array + * ( + * [0] => bar + * [1] => baz + * [2] => 42 + * ) + * + * [asdf] => Array + * ( + * [merp] => bleep + * [quack] => Array + * ( + * [0] => 1 + * [1] => 2 + * [2] => 3 + * ) + * + * ) + * + * [quux] => 999 + * ) + * + * Corresponding flattened array: + * Array + * ( + * [foo.0] => bar + * [foo.1] => baz + * [foo.2] => 42 + * [asdf.merp] => bleep + * [asdf.quack.0] => 1 + * [asdf.quack.1] => 2 + * [asdf.quack.2] => 3 + * [quux] => 999 + * ) + * + * @param array $list + * Array to be flattened. + * @param array $flat + * Destination array. * @param string $prefix + * (optional) String to prepend to keys. * @param string $seperator + * (optional) String that separates the concatenated keys. + * + * @access public */ static function flatten(&$list, &$flat, $prefix = '', $seperator = ".") { foreach ($list as $name => $value) { @@ -163,12 +253,19 @@ class CRM_Utils_Array { } /** - * Convert an array with path-like keys into a tree of arrays + * Converts an array with path-like keys into a tree of arrays. + * + * This function is the inverse of CRM_Utils_Array::flatten(). + * + * @param string $delim + * A path delimiter + * @param array $arr + * A one-dimensional array indexed by string keys * - * @param $delim A path delimiter - * @param $arr A one-dimensional array indexed by string keys + * @return array + * Array-encoded tree * - * @return array-encoded tree + * @access public */ function unflatten($delim, &$arr) { $result = array(); @@ -190,13 +287,21 @@ class CRM_Utils_Array { } /** - * Funtion to merge to two arrays recursively + * Merges two arrays. + * + * If $a1[foo] and $a2[foo] both exist and are both arrays, the merge + * process recurses into those sub-arrays. If $a1[foo] and $a2[foo] both + * exist but they are not both arrays, the value from $a1 overrides the + * value from $a2 and the value from $a2 is discarded. * * @param array $a1 + * First array to be merged. * @param array $a2 + * Second array to be merged. * - * @return $a3 - * @static + * @return array + * The merged array. + * @access public */ static function crmArrayMerge($a1, $a2) { if (empty($a1)) { @@ -230,6 +335,16 @@ class CRM_Utils_Array { return $a3; } + /** + * Determines whether an array contains any sub-arrays. + * + * @param array $list + * The array to inspect. + * + * @return bool + * True if $list contains at least one sub-array, false otherwise. + * @access public + */ static function isHierarchical(&$list) { foreach ($list as $n => $v) { if (is_array($v)) { @@ -240,15 +355,21 @@ class CRM_Utils_Array { } /** - * Array deep copy + * Recursively copies all values of an array into a new array. + * + * If the recursion depth limit is exceeded, the deep copy appears to + * succeed, but the copy process past the depth limit will be shallow. * - * @params array $array - * @params int $maxdepth - * @params int $depth + * @params array $array + * The array to copy. + * @params int $maxdepth + * (optional) Recursion depth limit. + * @params int $depth + * (optional) Current recursion depth. * - * @return array copy of the array + * @return array + * The new copy of $array. * - * @static * @access public */ static function array_deep_copy(&$array, $maxdepth = 50, $depth = 0) { @@ -268,11 +389,16 @@ class CRM_Utils_Array { } /** + * Makes a shallow copy of a variable, returning the copy by value. + * * In some cases, functions return an array by reference, but we really don't * want to receive a reference. * - * @param $array + * @param $array mixed + * Something to return a copy of. * @return mixed + * The copy. + * @access public */ static function breakReference($array) { $copy = $array; @@ -280,19 +406,28 @@ class CRM_Utils_Array { } /** - * Array splice function that preserves associative keys - * defauly php array_splice function doesnot preserve keys - * So specify start and end of the array that you want to remove + * Removes a portion of an array. * - * @param array $params array to slice - * @param Integer $start - * @param Integer $end + * This function is similar to PHP's array_splice(), with some differences: + * - Array keys that are not removed are preserved. The PHP built-in + * function only preserves values. + * - The portion of the array to remove is specified by start and end + * index rather than offset and length. + * - There is no ability to specify data to replace the removed portion. * - * @return void - * @static + * The behavior given an associative array would probably not be useful. + * + * @param array $params + * Array to manipulate. + * @param int $start + * First index to remove. + * @param int $end + * Last index to remove. + * + * @access public */ static function crmArraySplice(&$params, $start, $end) { - // verify start and end date + // verify start and end index if ($start < 0) { $start = 0; } @@ -312,13 +447,19 @@ class CRM_Utils_Array { } /** - * Function for case insensitive in_array search + * Searches an array recursively in an optionally case-insensitive manner. * - * @param $value value or search string - * @param $params array that need to be searched - * @param $caseInsensitive boolean true or false + * @param string $value + * Value to search for. + * @param array $params + * Array to search within. + * @param bool $caseInsensitive + * (optional) Whether to search in a case-insensitive manner. * - * @static + * @return bool + * True if $value was found, false otherwise. + * + * @access public */ static function crmInArray($value, $params, $caseInsensitive = TRUE) { foreach ($params as $item) { @@ -376,11 +517,21 @@ class CRM_Utils_Array { } /** - * Function to check if give array is empty - * @param array $array array to check for empty condition + * Checks whether an array is empty. + * + * An array is empty if its values consist only of NULL and empty sub-arrays. + * Containing a non-NULL value or non-empty array makes an array non-empty. + * + * If something other than an array is passed, it is considered to be empty. + * + * If nothing is passed at all, the default value provided is empty. + * + * @param array $array + * (optional) Array to be checked for emptiness. * - * @return boolean true is array is empty else false - * @static + * @return boolean + * True if the array is empty. + * @access public */ static function crmIsEmptyArray($array = array()) { if (!is_array($array)) { @@ -400,12 +551,19 @@ class CRM_Utils_Array { } /** - * Function to determine how many levels in array for multidimensional arrays + * Determines the maximum depth of nested arrays in a multidimensional array. + * + * The mechanism for determining depth will be confused if the array + * contains keys or values with the left brace '{' character. This will + * cause the depth to be over-reported. * * @param array $array + * The array to examine. + * + * @return integer + * The maximum nested array depth found. * - * @return integer $levels containing number of levels in array - * @static + * @access public */ static function getLevelsArray($array) { if (!is_array($array)) { @@ -424,13 +582,15 @@ class CRM_Utils_Array { } /** - * Function to sort an associative array of arrays by an attribute using natural string compare + * Sorts an associative array of arrays by an attribute using strnatcmp(). * - * @param array $array Array to be sorted - * @param string $field Name of the attribute you want to sort by + * @param array $array + * Array to be sorted. + * @param string $field + * Name of the attribute used for sorting. * - * @return array $array Sorted array - * @static + * @return array + * Sorted array */ static function crmArraySortByField($array, $field) { $code = "return strnatcmp(\$a['$field'], \$b['$field']);"; @@ -439,12 +599,13 @@ class CRM_Utils_Array { } /** - * Recursively removes duplicate values from an multi-dimensional array. + * Recursively removes duplicate values from a multi-dimensional array. * - * @param array $array The input array possibly containing duplicate values. + * @param array $array + * The input array possibly containing duplicate values. * - * @return array $array The array with duplicate values removed. - * @static + * @return array + * The input array with duplicate values removed. */ static function crmArrayUnique($array) { $result = array_map("unserialize", array_unique(array_map("serialize", $array))); @@ -457,14 +618,18 @@ class CRM_Utils_Array { } /** - * Sort an array and maintain index association, use Collate from the - * PECL "intl" package, if available, for UTF-8 sorting (ex: list of countries). - * On Debian/Ubuntu: apt-get install php5-intl + * Sorts an array and maintains index association (with localization). + * + * Uses Collate from the PECL "intl" package, if available, for UTF-8 + * sorting (e.g. list of countries). Otherwise calls PHP's asort(). * - * @param array $array array of values + * On Debian/Ubuntu: apt-get install php5-intl * - * @return array Sorted array - * @static + * @param array $array + * (optional) Array to be sorted. + * + * @return array + * Sorted array. */ static function asort($array = array()) { $lcMessages = CRM_Utils_System::getUFLocale(); @@ -474,6 +639,7 @@ class CRM_Utils_Array { $collator->asort($array); } else { + // This calls PHP's built-in asort(). asort($array); } @@ -481,14 +647,18 @@ class CRM_Utils_Array { } /** - * Convenient way to unset a bunch of items from an array - * - * @param array $items (reference) - * @param string/int/array $itemN: other params to this function will be treated as keys - * (or arrays of keys) to unset + * Unsets an arbitrary list of array elements from an associative array. + * + * @param array $items + * The array from which to remove items. + * @param string[]|string $key,... + * When passed a string, unsets $items[$key]. + * When passed an array of strings, unsets $items[$k] for each string $k + * in the array. */ static function remove(&$items) { foreach (func_get_args() as $n => $key) { + // Skip argument 0 ($items) by testing $n for truth. if ($n && is_array($key)) { foreach($key as $k) { unset($items[$k]); @@ -501,11 +671,14 @@ class CRM_Utils_Array { } /** - * Build an array-tree which indexes the records in an array + * Builds an array-tree which indexes the records in an array. * - * @param $keys array of string (properties by which to index) - * @param $records array of records (objects or assoc-arrays) - * @return array; multi-dimensional, with one layer for each key + * @param string[] $keys + * Properties by which to index. + * @param object|array $records + * + * @return array + * Multi-dimensional array, with one layer for each key. */ static function index($keys, $records) { $final_key = array_pop($keys); @@ -534,11 +707,15 @@ class CRM_Utils_Array { } /** - * Iterate through a list of records and grab the value of some property + * Iterates over a list of records and returns the value of some property. * * @param string $prop - * @param array $records a list of records (object|array) - * @return array keys are the original keys of $records; values are the $prop values + * Property to retrieve. + * @param array|object $records + * A list of records. + * + * @return array + * Keys are the original keys of $records; values are the $prop values. */ static function collect($prop, $records) { $result = array(); @@ -553,11 +730,17 @@ class CRM_Utils_Array { } /** - * Given a list of key-value pairs, combine thme into a single string - * @param array $pairs e.g. array('a' => '1', 'b' => '2') - * @param string $l1Delim e.g. ',' - * @param string $l2Delim e.g. '=' - * @return string e.g. 'a=1,b=2' + * Generate a string representation of an array. + * + * @param array $pairs + * Array to stringify. + * @param string $l1Delim + * String to use to separate key/value pairs from one another. + * @param string $l2Delim + * String to use to separate keys from values within each key/value pair. + * + * @return string + * Generated string. */ static function implodeKeyValue($l1Delim, $l2Delim, $pairs) { $exprs = array(); @@ -568,11 +751,22 @@ class CRM_Utils_Array { } /** - * Like explode() but assumes that the $value is padded with $delim on left and right + * Trims delimiters from a string and then splits it using explode(). * - * @param mixed $values + * This method works mostly like PHP's built-in explode(), except that + * surrounding delimiters are trimmed before explode() is called. + * + * Also, if an array or NULL is passed as the $values parameter, the value is + * returned unmodified rather than being passed to explode(). + * + * @param array|null|string $values + * The input string (or an array, or NULL). * @param string $delim - * @return array|NULL + * (optional) The boundary string. + * + * @return array|null + * An array of strings produced by explode(), or the unmodified input + * array, or NULL. */ static function explodePadded($values, $delim = CRM_Core_DAO::VALUE_SEPARATOR) { if ($values === NULL) { @@ -586,11 +780,21 @@ class CRM_Utils_Array { } /** - * Like implode() but creates a string that is padded with $delim on left and right + * Joins array elements with a string, adding surrounding delimiters. + * + * This method works mostly like PHP's built-in implode(), but the generated + * string is surrounded by delimiter characters. Also, if NULL is passed as + * the $values parameter, NULL is returned. * * @param mixed $values + * Array to be imploded. If a non-array is passed, it will be cast to an + * array. * @param string $delim + * Delimiter to be used for implode() and which will surround the output + * string. + * * @return string|NULL + * The generated string, or NULL if NULL was passed as $values parameter. */ static function implodePadded($values, $delim = CRM_Core_DAO::VALUE_SEPARATOR) { if ($values === NULL) { @@ -604,14 +808,26 @@ class CRM_Utils_Array { } /** - * Function to modify the key in an array without actually changing the order - * By default when you add an element it is added at the end + * Modifies a key in an array while preserving the key order. + * + * By default when an element is added to an array, it is added to the end. + * This method allows for changing an existing key while preserving its + * position in the array. + * + * The array is both modified in-place and returned. + * + * @param array $elementArray + * Array to manipulate. + * @param string $oldKey + * Old key to be replaced. + * @param string $newKey + * Replacement key string. * - * @param array $elementArray associated array element - * @param string $oldKey old key - * @param string $newKey new key + * @throws Exception + * Throws a generic Exception if $oldKey is not found in $elementArray. * * @return array + * The manipulated array. */ static function crmReplaceKey(&$elementArray, $oldKey, $newKey) { $keys = array_keys($elementArray); @@ -624,8 +840,25 @@ class CRM_Utils_Array { } /* - * function to get value of first matched - * regex key element of an array + * Searches array keys by regex, returning the value of the first match. + * + * Given a regular expression and an array, this method searches the keys + * of the array using the regular expression. The first match is then used + * to index into the array, and the associated value is retrieved and + * returned. If no matches are found, or if something other than an array + * is passed, then a default value is returned. Unless otherwise specified, + * the default value is NULL. + * + * @param string $regexKey + * The regular expression to use when searching for matching keys. + * @param array $list + * The array whose keys will be searched. + * @param mixed $default + * (optional) The default value to return if the regex does not match an + * array key, or if something other than an array is passed. + * + * @return mixed + * The value found. */ static function valueByRegexKey($regexKey, $list, $default = NULL) { if (is_array($list) && $regexKey) { @@ -637,11 +870,16 @@ class CRM_Utils_Array { } /** - * Generate the Cartesian product of zero or more vectors + * Generates the Cartesian product of zero or more vectors. * - * @param array $dimensions list of dimensions to multiply; each key is a dimension name; each value is a vector - * @param array $template a base set of values included in every output - * @return array each item is a distinct combination of values from $dimensions + * @param array $dimensions + * List of dimensions to multiply. + * Each key is a dimension name; each value is a vector. + * @param array $template + * (optional) A base set of values included in every output. + * + * @return array + * Each item is a distinct combination of values from $dimensions. * * For example, the product of * { -- 2.25.1