PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / trunk
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions vtrunk
260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 120213 120219 120301 All 187 releases
s2member / src / includes / classes / utils-arrays.inc.php

utils-arrays.inc.php in s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions trunk, at src/includes/classes/utils-arrays.inc.php

331 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // @codingStandardsIgnoreFile
3 /**
4 * Array utilities.
5 *
6 * Copyright: © 2009-2011
7 * {@link http://websharks-inc.com/ WebSharks, Inc.}
8 * (coded in the USA)
9 *
10 * Released under the terms of the GNU General Public License.
11 * You should have received a copy of the GNU General Public License,
12 * along with this software. In the main directory, see: /licensing/
13 * If not, see: {@link http://www.gnu.org/licenses/}.
14 *
15 * @package s2Member\Utilities
16 * @since 3.5
17 */
18 if(!defined('WPINC')) // MUST have WordPress.
19 exit ("Do not access this file directly.");
20
21 if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
22 {
23 /**
24 * Array utilities.
25 *
26 * @package s2Member\Utilities
27 * @since 3.5
28 */
29 class c_ws_plugin__s2member_utils_arrays
30 {
31 /**
32 * Extends ``array_unique()`` to support multi-dimensional arrays.
33 *
34 * @package s2Member\Utilities
35 * @since 3.5
36 *
37 * @param array $array Expects an incoming array.
38 * @return array Returns the ``$array`` after having reduced it to a unique set of values.
39 */
40 public static function array_unique ($array = FALSE)
41 {
42 $array = (array)$array;
43
44 foreach ($array as &$value)
45 $value = serialize ($value);
46
47 $array = array_unique ($array);
48
49 foreach ($array as &$value)
50 $value = unserialize ($value);
51
52 return $array;
53 }
54 /**
55 * Searches an array *(or even a multi-dimensional array)* using a regular expression match against array values.
56 *
57 * @package s2Member\Utilities
58 * @since 3.5
59 *
60 * @param string $regex A regular expression to look for inside the array.
61 * @return bool True if the regular expression matched at least one value in the array, else false.
62 */
63 public static function regex_in_array($regex = FALSE, $array = FALSE)
64 {
65 if (is_string ($regex) && strlen ($regex) && is_array($array))
66 {
67 foreach ($array as $value)
68 {
69 if (is_array($value) /* Recursive function call? */)
70 {
71 if (c_ws_plugin__s2member_utils_arrays::regex_in_array($regex, $value))
72 return true;
73 }
74 else if (is_string ($value) /* Must be a string. */)
75 {
76 if (@preg_match ($regex, $value))
77 return true;
78 }
79 }
80 return false;
81 }
82 else // False.
83 return false;
84 }
85 /**
86 * Searches an array *(or even a multi-dimensional array)* of regular expressions, to match against a string value.
87 *
88 * @package s2Member\Utilities
89 * @since 3.5
90 *
91 * @param string $string A string to test against.
92 * @param array $array An array of regex patterns to match against ``$string``.
93 * @return bool True if at least one regular expression in the ``$array`` matched ``$string``, else false.
94 */
95 public static function in_regex_array($string = FALSE, $array = FALSE)
96 {
97 if (is_string ($string) && strlen ($string) && is_array($array))
98 {
99 foreach ($array as $value)
100 {
101 if (is_array($value) /* Recursive function call. */)
102 {
103 if (c_ws_plugin__s2member_utils_arrays::in_regex_array($string, $value))
104 return true;
105 }
106 else if (is_string ($value) /* Must be a string. */)
107 {
108 if (@preg_match ($value, $string))
109 return true;
110 }
111 }
112 return false;
113 }
114 else // False.
115 return false;
116 }
117 /**
118 * Removes all null values from an array *(or even a multi-dimensional array)*.
119 *
120 * @package s2Member\Utilities
121 * @since 111101
122 *
123 * @param array $array An input array.
124 * @return array Returns the ``$array`` after having reduced its set of values.
125 */
126 public static function remove_nulls ($array = FALSE)
127 {
128 $array = (array)$array;
129
130 foreach ($array as $key => &$value)
131 {
132 if (is_array($value) /* Recursive function call here. */)
133 $value = c_ws_plugin__s2member_utils_arrays::remove_nulls ($value);
134
135 else if (is_null /* Is it null? */ ($value))
136 unset($array[$key]);
137 }
138 return $array;
139 }
140 /**
141 * Removes all 0-byte strings from an array *(or even a multi-dimensional array)*.
142 *
143 * @package s2Member\Utilities
144 * @since 111216
145 *
146 * @param array $array An input array.
147 * @return array Returns the ``$array`` after having reduced its set of values.
148 */
149 public static function remove_0b_strings ($array = FALSE)
150 {
151 $array = (array)$array;
152
153 foreach ($array as $key => &$value)
154 {
155 if (is_array($value) /* Recursive function call here. */)
156 $value = c_ws_plugin__s2member_utils_arrays::remove_0b_strings ($value);
157
158 else if (is_string ($value) && !strlen ($value))
159 unset($array[$key]);
160 }
161 return $array;
162 }
163 /**
164 * Sets specified array elements to an empty string when they are not set according to ``isset()`` (missing or NULL).
165 *
166 * @package s2Member\Utilities
167 * @since 260814
168 *
169 * @param array $array An input array.
170 * @param array $keys Array keys whose unset elements should be set.
171 * @return array Returns the ``$array`` after setting unset elements to empty strings.
172 */
173 public static function set_unset_elements ($array = FALSE, $keys = FALSE)
174 {
175 $array = (array)$array;
176 $keys = (array)$keys;
177
178 //260814 isset() treats both missing keys and null values as unset; initialize either case to an empty string.
179 foreach ($keys as $key)
180 if (!isset($array[$key]))
181 $array[$key] = '';
182
183 return $array;
184 }
185 /**
186 * Forces string values on each array value *(also supports multi-dimensional arrays)*.
187 *
188 * @package s2Member\Utilities
189 * @since 111101
190 *
191 * @param array $array An input array.
192 * @return array Returns the ``$array`` after having forced it to set of string values.
193 */
194 public static function force_strings ($array = FALSE)
195 {
196 $array = (array)$array;
197
198 foreach ($array as &$value)
199 {
200 if (is_array($value) /* Recursive function call here. */)
201 $value = c_ws_plugin__s2member_utils_arrays::force_strings ($value);
202
203 else if (!is_string ($value) /* String? */)
204 $value = (string)$value;
205 }
206 return $array;
207 }
208 /**
209 * Forces integer values on each array value *(also supports multi-dimensional arrays)*.
210 *
211 * @package s2Member\Utilities
212 * @since 111101
213 *
214 * @param array $array An input array.
215 * @return array Returns the ``$array`` after having forced it to set of integer values.
216 */
217 public static function force_integers ($array = array())
218 {
219 $array = (array)$array;
220
221 foreach ($array as &$value)
222 {
223 if (is_array($value) /* Recursive function call here. */)
224 $value = c_ws_plugin__s2member_utils_arrays::force_integers ($value);
225
226 else if (!is_integer ($value) /* Integer? */)
227 $value = (int)$value;
228 }
229 return $array;
230 }
231 /**
232 * Sorts arrays *(also supports multi-dimensional arrays)* by key, low to high.
233 *
234 * @package s2Member\Utilities
235 * @since 111205
236 *
237 * @param array $array An input array.
238 * @param int $flags Optional. Can be used to modify the sorting behavior.
239 * See: {@link http://www.php.net/manual/en/function.ksort.php}
240 * @return Unlike PHP's ``ksort()``, this function returns the array, and does NOT work on a reference.
241 */
242 public static function ksort_deep ($array = FALSE, $flags = SORT_REGULAR)
243 {
244 $array = (array)$array;
245 ksort /* Sort by key. */ ($array, $flags);
246
247 foreach ($array as &$value)
248 if (is_array($value) /* Recursive function call here. */)
249 $value = c_ws_plugin__s2member_utils_arrays::ksort_deep ($value, $flags);
250
251 return /* Now return the array. */ $array;
252 }
253
254 /**
255 * Safely unserializes a value when appropriate.
256 *
257 * @package s2Member\Utilities
258 * @since 250801
259 * @since 260808 Added additional validation before unserializing.
260 *
261 * @param mixed $value The value to be unserialized.
262 * @return mixed The unserialized value, or original if not serialized or blocked.
263 */
264 public static function maybe_unserialize($value) {
265 if (!is_string($value) || !is_serialized($value)) {
266 return $value;
267 }
268
269 $value = trim($value);
270
271 //260808 Reject disallowed serialization types without matching harmless text inside serialized strings.
272 if (self::serialized_contains_disallowed_type($value)) {
273 do_action('ws_plugin__s2member_security_object_detected', $value);
274 return null;
275 }
276
277 if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
278 return @unserialize($value, ['allowed_classes' => false]);
279 }
280
281 return @unserialize($value);
282 }
283
284 /**
285 * Checks serialized data for disallowed serialization types.
286 *
287 * Serialized string payloads are skipped so object-like text inside a
288 * normal string does not produce a false positive.
289 *
290 * @package s2Member\Utilities
291 * @since 260808
292 *
293 * @param string $value Serialized value to inspect.
294 * @return bool True if a disallowed serialization type is present.
295 */
296 private static function serialized_contains_disallowed_type($value) {
297 $length = strlen($value);
298
299 for ($offset = 0; $offset < $length; ++$offset) {
300 $token = $value[$offset];
301
302 //260808 Skip complete serialized strings so harmless text such as "PROMO:" is not mistaken for an object token.
303 if ($token === 's' && isset($value[$offset + 1]) && $value[$offset + 1] === ':') {
304 if (!preg_match('/\Gs:([0-9]+):"/', $value, $match, 0, $offset)) {
305 continue;
306 }
307
308 $string_length = (int)$match[1];
309 $string_start = $offset + strlen($match[0]);
310 $string_end = $string_start + $string_length;
311
312 if ($string_end + 1 >= $length || substr($value, $string_end, 2) !== '";') {
313 return true;
314 }
315
316 $offset = $string_end + 1;
317 continue;
318 }
319
320 //260808 O=object, C=Serializable object, E=enum object, S=noncanonical string, R/r=references that can create cyclic structures.
321 if (($token === 'O' || $token === 'C' || $token === 'E' || $token === 'S' || $token === 'R' || $token === 'r')
322 && isset($value[$offset + 1]) && $value[$offset + 1] === ':') {
323 return true;
324 }
325 }
326
327 return false;
328 }
329 }
330 }
331