Mercurial > hg > isophonics-drupal-site
comparison vendor/zendframework/zend-stdlib/src/ArrayUtils.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 /** | |
3 * Zend Framework (http://framework.zend.com/) | |
4 * | |
5 * @link http://github.com/zendframework/zf2 for the canonical source repository | |
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) | |
7 * @license http://framework.zend.com/license/new-bsd New BSD License | |
8 */ | |
9 | |
10 namespace Zend\Stdlib; | |
11 | |
12 use Traversable; | |
13 use Zend\Stdlib\ArrayUtils\MergeRemoveKey; | |
14 use Zend\Stdlib\ArrayUtils\MergeReplaceKeyInterface; | |
15 | |
16 /** | |
17 * Utility class for testing and manipulation of PHP arrays. | |
18 * | |
19 * Declared abstract, as we have no need for instantiation. | |
20 */ | |
21 abstract class ArrayUtils | |
22 { | |
23 /** | |
24 * Compatibility Flag for ArrayUtils::filter | |
25 */ | |
26 const ARRAY_FILTER_USE_BOTH = 1; | |
27 | |
28 /** | |
29 * Compatibility Flag for ArrayUtils::filter | |
30 */ | |
31 const ARRAY_FILTER_USE_KEY = 2; | |
32 | |
33 /** | |
34 * Test whether an array contains one or more string keys | |
35 * | |
36 * @param mixed $value | |
37 * @param bool $allowEmpty Should an empty array() return true | |
38 * @return bool | |
39 */ | |
40 public static function hasStringKeys($value, $allowEmpty = false) | |
41 { | |
42 if (!is_array($value)) { | |
43 return false; | |
44 } | |
45 | |
46 if (!$value) { | |
47 return $allowEmpty; | |
48 } | |
49 | |
50 return count(array_filter(array_keys($value), 'is_string')) > 0; | |
51 } | |
52 | |
53 /** | |
54 * Test whether an array contains one or more integer keys | |
55 * | |
56 * @param mixed $value | |
57 * @param bool $allowEmpty Should an empty array() return true | |
58 * @return bool | |
59 */ | |
60 public static function hasIntegerKeys($value, $allowEmpty = false) | |
61 { | |
62 if (!is_array($value)) { | |
63 return false; | |
64 } | |
65 | |
66 if (!$value) { | |
67 return $allowEmpty; | |
68 } | |
69 | |
70 return count(array_filter(array_keys($value), 'is_int')) > 0; | |
71 } | |
72 | |
73 /** | |
74 * Test whether an array contains one or more numeric keys. | |
75 * | |
76 * A numeric key can be one of the following: | |
77 * - an integer 1, | |
78 * - a string with a number '20' | |
79 * - a string with negative number: '-1000' | |
80 * - a float: 2.2120, -78.150999 | |
81 * - a string with float: '4000.99999', '-10.10' | |
82 * | |
83 * @param mixed $value | |
84 * @param bool $allowEmpty Should an empty array() return true | |
85 * @return bool | |
86 */ | |
87 public static function hasNumericKeys($value, $allowEmpty = false) | |
88 { | |
89 if (!is_array($value)) { | |
90 return false; | |
91 } | |
92 | |
93 if (!$value) { | |
94 return $allowEmpty; | |
95 } | |
96 | |
97 return count(array_filter(array_keys($value), 'is_numeric')) > 0; | |
98 } | |
99 | |
100 /** | |
101 * Test whether an array is a list | |
102 * | |
103 * A list is a collection of values assigned to continuous integer keys | |
104 * starting at 0 and ending at count() - 1. | |
105 * | |
106 * For example: | |
107 * <code> | |
108 * $list = array('a', 'b', 'c', 'd'); | |
109 * $list = array( | |
110 * 0 => 'foo', | |
111 * 1 => 'bar', | |
112 * 2 => array('foo' => 'baz'), | |
113 * ); | |
114 * </code> | |
115 * | |
116 * @param mixed $value | |
117 * @param bool $allowEmpty Is an empty list a valid list? | |
118 * @return bool | |
119 */ | |
120 public static function isList($value, $allowEmpty = false) | |
121 { | |
122 if (!is_array($value)) { | |
123 return false; | |
124 } | |
125 | |
126 if (!$value) { | |
127 return $allowEmpty; | |
128 } | |
129 | |
130 return (array_values($value) === $value); | |
131 } | |
132 | |
133 /** | |
134 * Test whether an array is a hash table. | |
135 * | |
136 * An array is a hash table if: | |
137 * | |
138 * 1. Contains one or more non-integer keys, or | |
139 * 2. Integer keys are non-continuous or misaligned (not starting with 0) | |
140 * | |
141 * For example: | |
142 * <code> | |
143 * $hash = array( | |
144 * 'foo' => 15, | |
145 * 'bar' => false, | |
146 * ); | |
147 * $hash = array( | |
148 * 1995 => 'Birth of PHP', | |
149 * 2009 => 'PHP 5.3.0', | |
150 * 2012 => 'PHP 5.4.0', | |
151 * ); | |
152 * $hash = array( | |
153 * 'formElement, | |
154 * 'options' => array( 'debug' => true ), | |
155 * ); | |
156 * </code> | |
157 * | |
158 * @param mixed $value | |
159 * @param bool $allowEmpty Is an empty array() a valid hash table? | |
160 * @return bool | |
161 */ | |
162 public static function isHashTable($value, $allowEmpty = false) | |
163 { | |
164 if (!is_array($value)) { | |
165 return false; | |
166 } | |
167 | |
168 if (!$value) { | |
169 return $allowEmpty; | |
170 } | |
171 | |
172 return (array_values($value) !== $value); | |
173 } | |
174 | |
175 /** | |
176 * Checks if a value exists in an array. | |
177 * | |
178 * Due to "foo" == 0 === TRUE with in_array when strict = false, an option | |
179 * has been added to prevent this. When $strict = 0/false, the most secure | |
180 * non-strict check is implemented. if $strict = -1, the default in_array | |
181 * non-strict behaviour is used. | |
182 * | |
183 * @param mixed $needle | |
184 * @param array $haystack | |
185 * @param int|bool $strict | |
186 * @return bool | |
187 */ | |
188 public static function inArray($needle, array $haystack, $strict = false) | |
189 { | |
190 if (!$strict) { | |
191 if (is_int($needle) || is_float($needle)) { | |
192 $needle = (string) $needle; | |
193 } | |
194 if (is_string($needle)) { | |
195 foreach ($haystack as &$h) { | |
196 if (is_int($h) || is_float($h)) { | |
197 $h = (string) $h; | |
198 } | |
199 } | |
200 } | |
201 } | |
202 return in_array($needle, $haystack, $strict); | |
203 } | |
204 | |
205 /** | |
206 * Convert an iterator to an array. | |
207 * | |
208 * Converts an iterator to an array. The $recursive flag, on by default, | |
209 * hints whether or not you want to do so recursively. | |
210 * | |
211 * @param array|Traversable $iterator The array or Traversable object to convert | |
212 * @param bool $recursive Recursively check all nested structures | |
213 * @throws Exception\InvalidArgumentException if $iterator is not an array or a Traversable object | |
214 * @return array | |
215 */ | |
216 public static function iteratorToArray($iterator, $recursive = true) | |
217 { | |
218 if (!is_array($iterator) && !$iterator instanceof Traversable) { | |
219 throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable object'); | |
220 } | |
221 | |
222 if (!$recursive) { | |
223 if (is_array($iterator)) { | |
224 return $iterator; | |
225 } | |
226 | |
227 return iterator_to_array($iterator); | |
228 } | |
229 | |
230 if (method_exists($iterator, 'toArray')) { | |
231 return $iterator->toArray(); | |
232 } | |
233 | |
234 $array = []; | |
235 foreach ($iterator as $key => $value) { | |
236 if (is_scalar($value)) { | |
237 $array[$key] = $value; | |
238 continue; | |
239 } | |
240 | |
241 if ($value instanceof Traversable) { | |
242 $array[$key] = static::iteratorToArray($value, $recursive); | |
243 continue; | |
244 } | |
245 | |
246 if (is_array($value)) { | |
247 $array[$key] = static::iteratorToArray($value, $recursive); | |
248 continue; | |
249 } | |
250 | |
251 $array[$key] = $value; | |
252 } | |
253 | |
254 return $array; | |
255 } | |
256 | |
257 /** | |
258 * Merge two arrays together. | |
259 * | |
260 * If an integer key exists in both arrays and preserveNumericKeys is false, the value | |
261 * from the second array will be appended to the first array. If both values are arrays, they | |
262 * are merged together, else the value of the second array overwrites the one of the first array. | |
263 * | |
264 * @param array $a | |
265 * @param array $b | |
266 * @param bool $preserveNumericKeys | |
267 * @return array | |
268 */ | |
269 public static function merge(array $a, array $b, $preserveNumericKeys = false) | |
270 { | |
271 foreach ($b as $key => $value) { | |
272 if ($value instanceof MergeReplaceKeyInterface) { | |
273 $a[$key] = $value->getData(); | |
274 } elseif (isset($a[$key]) || array_key_exists($key, $a)) { | |
275 if ($value instanceof MergeRemoveKey) { | |
276 unset($a[$key]); | |
277 } elseif (!$preserveNumericKeys && is_int($key)) { | |
278 $a[] = $value; | |
279 } elseif (is_array($value) && is_array($a[$key])) { | |
280 $a[$key] = static::merge($a[$key], $value, $preserveNumericKeys); | |
281 } else { | |
282 $a[$key] = $value; | |
283 } | |
284 } else { | |
285 if (!$value instanceof MergeRemoveKey) { | |
286 $a[$key] = $value; | |
287 } | |
288 } | |
289 } | |
290 | |
291 return $a; | |
292 } | |
293 | |
294 /** | |
295 * Compatibility Method for array_filter on <5.6 systems | |
296 * | |
297 * @param array $data | |
298 * @param callable $callback | |
299 * @param null|int $flag | |
300 * @return array | |
301 */ | |
302 public static function filter(array $data, $callback, $flag = null) | |
303 { | |
304 if (! is_callable($callback)) { | |
305 throw new Exception\InvalidArgumentException(sprintf( | |
306 'Second parameter of %s must be callable', | |
307 __METHOD__ | |
308 )); | |
309 } | |
310 | |
311 if (version_compare(PHP_VERSION, '5.6.0') >= 0) { | |
312 return array_filter($data, $callback, $flag); | |
313 } | |
314 | |
315 $output = []; | |
316 foreach ($data as $key => $value) { | |
317 $params = [$value]; | |
318 | |
319 if ($flag === static::ARRAY_FILTER_USE_BOTH) { | |
320 $params[] = $key; | |
321 } | |
322 | |
323 if ($flag === static::ARRAY_FILTER_USE_KEY) { | |
324 $params = [$key]; | |
325 } | |
326 | |
327 $response = call_user_func_array($callback, $params); | |
328 if ($response) { | |
329 $output[$key] = $value; | |
330 } | |
331 } | |
332 | |
333 return $output; | |
334 } | |
335 } |