PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260814
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260814
260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 120213 All 189 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 260814, at src/includes/classes/utils-arrays.inc.php

309 lines 9.6 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 * Forces string values on each array value *(also supports multi-dimensional arrays)*.
165 *
166 * @package s2Member\Utilities
167 * @since 111101
168 *
169 * @param array $array An input array.
170 * @return array Returns the ``$array`` after having forced it to set of string values.
171 */
172 public static function force_strings ($array = FALSE)
173 {
174 $array = (array)$array;
175
176 foreach ($array as &$value)
177 {
178 if (is_array($value) /* Recursive function call here. */)
179 $value = c_ws_plugin__s2member_utils_arrays::force_strings ($value);
180
181 else if (!is_string ($value) /* String? */)
182 $value = (string)$value;
183 }
184 return $array;
185 }
186 /**
187 * Forces integer values on each array value *(also supports multi-dimensional arrays)*.
188 *
189 * @package s2Member\Utilities
190 * @since 111101
191 *
192 * @param array $array An input array.
193 * @return array Returns the ``$array`` after having forced it to set of integer values.
194 */
195 public static function force_integers ($array = array())
196 {
197 $array = (array)$array;
198
199 foreach ($array as &$value)
200 {
201 if (is_array($value) /* Recursive function call here. */)
202 $value = c_ws_plugin__s2member_utils_arrays::force_integers ($value);
203
204 else if (!is_integer ($value) /* Integer? */)
205 $value = (int)$value;
206 }
207 return $array;
208 }
209 /**
210 * Sorts arrays *(also supports multi-dimensional arrays)* by key, low to high.
211 *
212 * @package s2Member\Utilities
213 * @since 111205
214 *
215 * @param array $array An input array.
216 * @param int $flags Optional. Can be used to modify the sorting behavior.
217 * See: {@link http://www.php.net/manual/en/function.ksort.php}
218 * @return Unlike PHP's ``ksort()``, this function returns the array, and does NOT work on a reference.
219 */
220 public static function ksort_deep ($array = FALSE, $flags = SORT_REGULAR)
221 {
222 $array = (array)$array;
223 ksort /* Sort by key. */ ($array, $flags);
224
225 foreach ($array as &$value)
226 if (is_array($value) /* Recursive function call here. */)
227 $value = c_ws_plugin__s2member_utils_arrays::ksort_deep ($value, $flags);
228
229 return /* Now return the array. */ $array;
230 }
231
232 /**
233 * Safely unserializes a value when appropriate.
234 *
235 * @package s2Member\Utilities
236 * @since 250801
237 * @since 260808 Added additional validation before unserializing.
238 *
239 * @param mixed $value The value to be unserialized.
240 * @return mixed The unserialized value, or original if not serialized or blocked.
241 */
242 public static function maybe_unserialize($value) {
243 if (!is_string($value) || !is_serialized($value)) {
244 return $value;
245 }
246
247 $value = trim($value);
248
249 //260808 Reject disallowed serialization types without matching harmless text inside serialized strings.
250 if (self::serialized_contains_disallowed_type($value)) {
251 do_action('ws_plugin__s2member_security_object_detected', $value);
252 return null;
253 }
254
255 if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
256 return @unserialize($value, ['allowed_classes' => false]);
257 }
258
259 return @unserialize($value);
260 }
261
262 /**
263 * Checks serialized data for disallowed serialization types.
264 *
265 * Serialized string payloads are skipped so object-like text inside a
266 * normal string does not produce a false positive.
267 *
268 * @package s2Member\Utilities
269 * @since 260808
270 *
271 * @param string $value Serialized value to inspect.
272 * @return bool True if a disallowed serialization type is present.
273 */
274 private static function serialized_contains_disallowed_type($value) {
275 $length = strlen($value);
276
277 for ($offset = 0; $offset < $length; ++$offset) {
278 $token = $value[$offset];
279
280 //260808 Skip complete serialized strings so harmless text such as "PROMO:" is not mistaken for an object token.
281 if ($token === 's' && isset($value[$offset + 1]) && $value[$offset + 1] === ':') {
282 if (!preg_match('/\Gs:([0-9]+):"/', $value, $match, 0, $offset)) {
283 continue;
284 }
285
286 $string_length = (int)$match[1];
287 $string_start = $offset + strlen($match[0]);
288 $string_end = $string_start + $string_length;
289
290 if ($string_end + 1 >= $length || substr($value, $string_end, 2) !== '";') {
291 return true;
292 }
293
294 $offset = $string_end + 1;
295 continue;
296 }
297
298 //260808 O=object, C=Serializable object, E=enum object, S=noncanonical string, R/r=references that can create cyclic structures.
299 if (($token === 'O' || $token === 'C' || $token === 'E' || $token === 'S' || $token === 'R' || $token === 'r')
300 && isset($value[$offset + 1]) && $value[$offset + 1] === ':') {
301 return true;
302 }
303 }
304
305 return false;
306 }
307 }
308 }
309