Raising Extbase and Fluid to version 1.2.0
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Utility / Arrays.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * The array functions from the good old t3lib_div plus new code.
30 *
31 * @package Extbase
32 * @subpackage Utility
33 * @version $Id: Arrays.php 1992 2010-03-09 21:44:11Z jocrau $
34 (robert) I'm not sure yet if we should use this library statically or as a singleton. The latter might be problematic if we use it from the Core classes.
35 * @api
36 */
37 class Tx_Extbase_Utility_Arrays {
38
39 /**
40 * Explodes a $string delimited by $delimeter and passes each item in the array through intval().
41 * Corresponds to explode(), but with conversion to integers for all values.
42 *
43 * @param string $delimiter Delimiter string to explode with
44 * @param string $string The string to explode
45 * @return array Exploded values, all converted to integers
46 * @api
47 */
48 static public function integerExplode($delimiter, $string) {
49 $chunksArr = explode($delimiter, $string);
50 foreach ($chunksArr as $key => $value) {
51 $chunks[$key] = intval($value);
52 }
53 return $chunks;
54 }
55
56 /**
57 * Explodes a string and trims all values for whitespace in the ends.
58 * If $onlyNonEmptyValues is set, then all blank ('') values are removed.
59 *
60 * @param string $delimiter Delimiter string to explode with
61 * @param string $string The string to explode
62 * @param boolean $onlyNonEmptyValues If set, all empty values (='') will NOT be set in output
63 * @return array Exploded values
64 * @api
65 */
66 static public function trimExplode($delimiter, $string, $onlyNonEmptyValues = FALSE) {
67 $chunksArr = explode($delimiter, $string);
68 $newChunksArr = array();
69 foreach ($chunksArr as $value) {
70 if ($onlyNonEmptyValues === FALSE || strcmp('', trim($value))) {
71 $newChunksArr[] = trim($value);
72 }
73 }
74 reset($newChunksArr);
75 return $newChunksArr;
76 }
77
78 /**
79 * Merges two arrays recursively and "binary safe" (integer keys are overridden as well), overruling similar values in the first array ($firstArray) with the values of the second array ($secondArray)
80 * In case of identical keys, ie. keeping the values of the second.
81 *
82 * @param array First array
83 * @param array Second array, overruling the first array
84 * @param boolean If set, keys that are NOT found in $firstArray (first array) will not be set. Thus only existing value can/will be overruled from second array.
85 * @param boolean If set (which is the default), values from $secondArray will overrule if they are empty (according to PHP's empty() function)
86 * @return array Resulting array where $secondArray values has overruled $firstArray values
87 * @api
88 */
89 static public function arrayMergeRecursiveOverrule(array $firstArray, array $secondArray, $dontAddNewKeys = FALSE, $emptyValuesOverride = TRUE) {
90 foreach ($secondArray as $key => $value) {
91 if (array_key_exists($key, $firstArray) && is_array($firstArray[$key])) {
92 if (is_array($secondArray[$key])) {
93 $firstArray[$key] = self::arrayMergeRecursiveOverrule($firstArray[$key], $secondArray[$key], $dontAddNewKeys, $emptyValuesOverride);
94 }
95 } else {
96 if ($dontAddNewKeys) {
97 if (array_key_exists($key, $firstArray)) {
98 if ($emptyValuesOverride || !empty($value)) {
99 $firstArray[$key] = $value;
100 }
101 }
102 } else {
103 if ($emptyValuesOverride || !empty($value)) {
104 $firstArray[$key] = $value;
105 }
106 }
107 }
108 }
109 reset($firstArray);
110 return $firstArray;
111 }
112
113 /**
114 * Randomizes the order of array values. The array should not be an associative array
115 * as the key-value relations will be lost.
116 *
117 * @param array $array Array to reorder
118 * @return array The array with randomly ordered values
119 * @api
120 */
121 static public function randomizeArrayOrder(array $array) {
122 $reorderedArray = array();
123 if (count($array) > 1) {
124 $keysInRandomOrder = array_rand($array, count($array));
125 foreach ($keysInRandomOrder as $key) {
126 $reorderedArray[] = $array[$key];
127 }
128 } else {
129 $reorderedArray = $array;
130 }
131 return $reorderedArray;
132 }
133
134 /**
135 * Returns TRUE if the given array contains elements of varying types
136 *
137 * @param array $array
138 * @return boolean
139 * @api
140 */
141 static public function containsMultipleTypes(array $array) {
142 if (count($array) > 0) {
143 foreach ($array as $key => $value) {
144 if (!isset($previousType)) {
145 $previousType = gettype($value);
146 } else if ($previousType !== gettype($value)) {
147 return TRUE;
148 }
149 }
150 }
151 return FALSE;
152 }
153
154 /**
155 * Replacement for array_reduce that allows any type for $initial (instead
156 * of only integer)
157 *
158 * @param array $array the array to reduce
159 * @param string $function the reduce function with the same order of parameters as in the native array_reduce (i.e. accumulator first, then current array element)
160 * @param mixed $initial the initial accumulator value
161 * @return mixed
162 * @api
163 */
164 static public function array_reduce(array $array, $function, $initial = NULL) {
165 $accumlator = $initial;
166 foreach($array as $value) {
167 $accumlator = $function($accumlator, $value);
168 }
169 return $accumlator;
170 }
171
172 /**
173 * Returns the value of a nested array by following the specifed path.
174 *
175 * @param array $array The array to traverse
176 * @param array $path The path to follow, ie. a simple array of keys
177 * @return mixed The value found, NULL if the path didn't exist
178 * @api
179 */
180 static public function getValueByPath(array $array, array $path) {
181 $key = array_shift($path);
182 if (isset($array[$key])) {
183 if (count($path) > 0) {
184 return (is_array($array[$key])) ? self::getValueByPath($array[$key], $path) : NULL;
185 } else {
186 return $array[$key];
187 }
188 } else {
189 return NULL;
190 }
191 }
192
193 /**
194 * Sorts multidimensional arrays by recursively calling ksort on its elements.
195 *
196 * @param array $array the array to sort
197 * @param integer $sortFlags may be used to modify the sorting behavior using these values (see http://www.php.net/manual/en/function.sort.php)
198 * @return boolean TRUE on success, FALSE on failure
199 * @see asort()
200 * @api
201 */
202 static public function sortKeysRecursively(array &$array, $sortFlags = NULL) {
203 foreach($array as &$value) {
204 if (is_array($value)) {
205 if (self::sortKeysRecursively($value, $sortFlags) === FALSE) {
206 return FALSE;
207 }
208 }
209 }
210 return ksort($array, $sortFlags);
211 }
212
213 }
214 ?>