1: <?php
2: /**
3: * This file contains the array utility class.
4: *
5: * @package Core
6: * @subpackage Util
7: * @version SVN Revision $Rev:$
8: *
9: * @author Murat Purc <murat@purc.de>
10: * @copyright four for business AG <www.4fb.de>
11: * @license http://www.contenido.org/license/LIZENZ.txt
12: * @link http://www.4fb.de
13: * @link http://www.contenido.org
14: */
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: /**
19: * Array helper class.
20: *
21: * @package Core
22: * @subpackage Util
23: */
24: class cArray {
25:
26: /**
27: * Strip whitespaces (or other characters) from the beginning and end of
28: * each item in array.
29: * Similar to trim() function.
30: *
31: * @param array $arr Array of strings that will be trimmed.
32: * @param string $charlist Optionally, the stripped characters can also be
33: * specified using the charlist parameter. Simply list all characters
34: * that you want to be stripped. With .. you can specify a range of
35: * characters.
36: * @return array Array of trimmed strings.
37: */
38: public static function trim(array $arr, $charlist = NULL) {
39: foreach ($arr as $key => $value) {
40: $arr[$key] = trim($value, $charlist);
41: }
42:
43: return $arr;
44: }
45:
46: /**
47: * Search for given value in given array and return key of its first
48: * occurance.
49: *
50: * If value wasn't found at all false will be returned. If given array
51: * contains subarrays, these will be searched too. If value is found in
52: * subarray the returned key is that of the subarray.
53: *
54: * Usually the values are tested for equality with the given $search. If the
55: * flag $partial is not false values are tested to contain $search.
56: * Otherwise, if $strict equals true values are tested for identity with
57: * $search. Otherwise (which is the default) values are tested for equality.
58: *
59: * Be carefull when searching by equality in arrays containing values that
60: * are no strings! The same is true for searching by equality for values
61: * that are no strings. PHPs behaviour is quite weird concerning comparision
62: * of different data types. E.g. '0' equals '0.0', 'foo' equals 0, 'foo'
63: * equals 0.0, NULL equals '' and false equals '0'! When dealing with
64: * nonstrings consider to use the strict mode!
65: *
66: * Another caveat is when searching for an empty string when using the
67: * partial mode. This would lead to an error and is considered a bug!
68: *
69: * @param array $arr array to search
70: * @param mixed $search value to search for
71: * @param bool $partial if values are tested to contain $search
72: * @param bool $strict if values are tested for identity
73: * @return mixed key of the array containing the searched value or false
74: * @todo There should be only one flag for $partial and $strict in order to
75: * avoid ambiguities (imagine $partial=true & $strict=true).
76: */
77: public static function searchRecursive(array $arr, $search, $partial = false, $strict = false) {
78: foreach ($arr as $key => $value) {
79: if (is_array($value)) {
80: $ret = self::searchRecursive($value, $search, $partial, $strict);
81: if ($ret !== false) {
82: return $ret;
83: }
84: } else {
85: if ($partial !== false) {
86: // search partial
87: $found = false !== strpos($value, $search);
88: } else if ($strict == true) {
89: // search by identity
90: $found = $value === $search;
91: } else {
92: // search by equality
93: $found = $value == $search;
94: }
95: if ($found) {
96: // echo "\nfound key $key:\nvalue "; var_dump($value);
97: // echo "search "; var_dump($search); echo "\n";
98: return $key;
99: }
100: }
101: }
102:
103: return false;
104: }
105:
106: /**
107: * Sorts an array by changing the locale temporary to passed value.
108: *
109: * @param array $arr The array to sort
110: * @param string $locale The locale to change before sorting
111: * @return array Sorted array
112: */
113: public static function sortWithLocale(array $arr, $locale) {
114: $oldlocale = setlocale(LC_COLLATE, 0);
115: setlocale(LC_COLLATE, $locale);
116:
117: uasort($arr, 'strcoll');
118:
119: setlocale(LC_COLLATE, $oldlocale);
120:
121: return $arr;
122: }
123:
124: /**
125: * Very cool algorithm for sorting multi-dimensional arrays.
126: *
127: * Found at http://us2.php.net/manual/en/function.array-multisort.php
128: *
129: * Syntax:
130: * <pre>
131: * $new_array = cArray::csort($array [, 'col1' [, SORT_FLAG [,
132: * SORT_FLAG]]]...);
133: * </pre>
134: *
135: * Explanation:
136: * - $array is the array you want to sort
137: * - 'col1' is the name of the column you want to sort
138: * - SORT_FLAGS are: SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC,
139: * SORT_STRING
140: *
141: * You can repeat the 'col', FLAG, FLAG as often as you want. The highest
142: * prioritiy is given to the first - so the array is sorted by the last
143: * given column first, then the one before ...
144: *
145: * Example:
146: * <pre>
147: * $array = cArray::csort($array, 'town', 'age', SORT_DESC, 'name');
148: * </pre>
149: *
150: * @return array
151: */
152: public static function csort() {
153: $args = func_get_args();
154: $marray = array_shift($args);
155: $msortline = "return(array_multisort(";
156: $i = 0;
157: foreach ($args as $arg) {
158: $i++;
159: if (is_string($arg)) {
160: foreach ($marray as $row) {
161: $a = strtoupper($row[$arg]);
162: $sortarr[$i][] = $a;
163: }
164: } else {
165: $sortarr[$i] = $arg;
166: }
167: $msortline .= "\$sortarr[" . $i . "],";
168: }
169: $msortline .= "\$marray));";
170: @eval($msortline);
171: return $marray;
172: }
173:
174: /**
175: * Ensures that the passed array has the key, sets it by using the value.
176: *
177: * @param array $aArray
178: * @param string $sKey
179: * @param mixed $mDefault
180: * @return boolean
181: */
182: public static function initializeKey(&$aArray, $sKey, $mDefault = '') {
183: if (!is_array($aArray)) {
184: if (isset($aArray)) {
185: return false;
186: }
187: $aArray = array();
188: }
189:
190: if (!array_key_exists($sKey, $aArray)) {
191: $aArray[$sKey] = $mDefault;
192: }
193: }
194: }
195: