PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 3.8.1
WooCommerce Square v3.8.1
5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Framework / Square_Helper.php
woocommerce-square / includes / Framework Last commit date
Addresses 3 years ago Api 3 years ago Compatibility 3 years ago PaymentGateway 3 years ago Utilities 3 years ago Admin_Message_Handler.php 3 years ago Admin_Notice_Handler.php 3 years ago Lifecycle.php 3 years ago Plugin.php 3 years ago Plugin_Compatibility.php 3 years ago Plugin_Dependencies.php 3 years ago Square_Helper.php 4 years ago
Square_Helper.php
408 lines
1 <?php
2
3 namespace WooCommerce\Square\Framework;
4 use WooCommerce\Square\Framework\Plugin_Compatibility;
5
6 defined( 'ABSPATH' ) or exit;
7
8 /**
9 * Square Helper Class
10 *
11 * The purpose of this class is to centralize common utility functions.
12 *
13 * @since 3.0.0
14 */
15 class Square_Helper {
16
17
18 /** encoding used for mb_*() string functions */
19 const MB_ENCODING = 'UTF-8';
20
21
22 /** String manipulation functions (all multi-byte safe) ***************/
23
24 /**
25 * Returns true if the haystack string starts with needle
26 *
27 * Note: case-sensitive
28 *
29 * @since 3.0.0
30 * @param string $haystack
31 * @param string $needle
32 * @return bool
33 */
34 public static function str_starts_with( $haystack, $needle ) {
35
36 if ( self::multibyte_loaded() ) {
37
38 if ( '' === $needle ) {
39 return true;
40 }
41
42 return 0 === mb_strpos( $haystack, $needle, 0, self::MB_ENCODING );
43
44 } else {
45
46 $needle = self::str_to_ascii( $needle );
47
48 if ( '' === $needle ) {
49 return true;
50 }
51
52 return 0 === strpos( self::str_to_ascii( $haystack ), self::str_to_ascii( $needle ) );
53 }
54 }
55
56 /**
57 * Returns true if the needle exists in haystack
58 *
59 * Note: case-sensitive
60 *
61 * @since 3.0.0
62 * @param string $haystack
63 * @param string $needle
64 * @return bool
65 */
66 public static function str_exists( $haystack, $needle ) {
67
68 if ( self::multibyte_loaded() ) {
69
70 if ( '' === $needle ) {
71 return false;
72 }
73
74 return false !== mb_strpos( $haystack, $needle, 0, self::MB_ENCODING );
75
76 } else {
77
78 $needle = self::str_to_ascii( $needle );
79
80 if ( '' === $needle ) {
81 return false;
82 }
83
84 return false !== strpos( self::str_to_ascii( $haystack ), self::str_to_ascii( $needle ) );
85 }
86 }
87
88 /**
89 * Returns a string with all non-ASCII characters removed. This is useful
90 * for any string functions that expect only ASCII chars and can't
91 * safely handle UTF-8. Note this only allows ASCII chars in the range
92 * 33-126 (newlines/carriage returns are stripped)
93 *
94 * @since 3.0.0
95 * @param string $string string to make ASCII
96 * @return string
97 */
98 public static function str_to_ascii( $string ) {
99
100 // strip ASCII chars 32 and under
101 $string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW );
102
103 // strip ASCII chars 127 and higher
104 return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );
105 }
106
107 /**
108 * Truncates a given $string after a given $length if string is longer than
109 * $length. The last characters will be replaced with the $omission string
110 * for a total length not exceeding $length
111 *
112 * @since 3.0.0
113 * @param string $string text to truncate
114 * @param int $length total desired length of string, including omission
115 * @param string $omission omission text, defaults to '...'
116 * @return string
117 */
118 public static function str_truncate( $string, $length, $omission = '...' ) {
119
120 if ( self::multibyte_loaded() ) {
121
122 // bail if string doesn't need to be truncated
123 if ( mb_strlen( $string, self::MB_ENCODING ) <= $length ) {
124 return $string;
125 }
126
127 $length -= mb_strlen( $omission, self::MB_ENCODING );
128
129 return mb_substr( $string, 0, $length, self::MB_ENCODING ) . $omission;
130
131 } else {
132
133 $string = self::str_to_ascii( $string );
134
135 // bail if string doesn't need to be truncated
136 if ( strlen( $string ) <= $length ) {
137 return $string;
138 }
139
140 $length -= strlen( $omission );
141
142 return substr( $string, 0, $length ) . $omission;
143 }
144 }
145
146 /**
147 * Helper method to check if the multibyte extension is loaded, which
148 * indicates it's safe to use the mb_*() string methods
149 *
150 * @since 3.0.0
151 * @return bool
152 */
153 protected static function multibyte_loaded() {
154
155 return extension_loaded( 'mbstring' );
156 }
157
158
159 /** Array functions ***************************************************/
160
161
162 /**
163 * Insert the given element after the given key in the array
164 *
165 * Sample usage:
166 *
167 * given
168 *
169 * array( 'item_1' => 'foo', 'item_2' => 'bar' )
170 *
171 * array_insert_after( $array, 'item_1', array( 'item_1.5' => 'w00t' ) )
172 *
173 * becomes
174 *
175 * array( 'item_1' => 'foo', 'item_1.5' => 'w00t', 'item_2' => 'bar' )
176 *
177 * @since 3.0.0
178 * @param array $array array to insert the given element into
179 * @param string $insert_key key to insert given element after
180 * @param array $element element to insert into array
181 * @return array
182 */
183 public static function array_insert_after( Array $array, $insert_key, Array $element ) {
184
185 $new_array = array();
186
187 foreach ( $array as $key => $value ) {
188
189 $new_array[ $key ] = $value;
190
191 if ( $insert_key == $key ) {
192
193 foreach ( $element as $k => $v ) {
194 $new_array[ $k ] = $v;
195 }
196 }
197 }
198
199 return $new_array;
200 }
201
202 /**
203 * Lists an array as text.
204 *
205 * Takes an array and returns a list like "one, two, three, and four"
206 * with a (mandatory) oxford comma.
207 *
208 * @since 3.0.0
209 *
210 * @param array $items items to list
211 * @param string|null $conjunction coordinating conjunction, like "or" or "and"
212 * @param string $separator list separator, like a comma
213 * @return string
214 */
215 public static function list_array_items( array $items, $conjunction = null, $separator = '' ) {
216
217 if ( ! is_string( $conjunction ) ) {
218 $conjunction = _x( 'and', 'coordinating conjunction for a list of items: a, b, and c', 'woocommerce-square' );
219 }
220
221 // append the conjunction to the last item
222 if ( count( $items ) > 1 ) {
223
224 $last_item = array_pop( $items );
225
226 array_push( $items, trim( "{$conjunction} {$last_item}" ) );
227
228 // only use a comma if needed and no separator was passed
229 if ( count( $items ) < 3 ) {
230 $separator = ' ';
231 } elseif ( ! is_string( $separator ) || '' === $separator ) {
232 $separator = ', ';
233 }
234 }
235
236 return implode( $separator, $items );
237 }
238
239
240 /** Number helper functions *******************************************/
241
242
243 /**
244 * Format a number with 2 decimal points, using a period for the decimal
245 * separator and no thousands separator.
246 *
247 * Commonly used for payment gateways which require amounts in this format.
248 *
249 * @since 3.0.0
250 * @param float $number
251 * @return string
252 */
253 public static function number_format( $number ) {
254
255 return number_format( (float) $number, 2, '.', '' );
256 }
257
258 /**
259 * Determines if an order contains only virtual products.
260 *
261 * @since 3.0.0
262 * @param \WC_Order $order the order object
263 * @return bool
264 */
265 public static function is_order_virtual( \WC_Order $order ) {
266
267 $is_virtual = true;
268
269 foreach ( $order->get_items() as $item ) {
270 $product = $item->get_product();
271
272 // once we've found one non-virtual product we know we're done, break out of the loop
273 if ( $product && ! $product->is_virtual() ) {
274 $is_virtual = false;
275 break;
276 }
277 }
278
279 return $is_virtual;
280 }
281
282
283 /**
284 * Safely get and trim data from $_POST
285 *
286 * @since 3.0.0
287 * @param string $key array key to get from $_POST array
288 * @return string value from $_POST or blank string if $_POST[ $key ] is not set
289 */
290 public static function get_post( $key ) {
291
292 if ( isset( $_POST[ $key ] ) ) {
293 return trim( $_POST[ $key ] );
294 }
295
296 return '';
297 }
298
299
300 /**
301 * Safely get and trim data from $_REQUEST
302 *
303 * @since 3.0.0
304 * @param string $key array key to get from $_REQUEST array
305 * @return string value from $_REQUEST or blank string if $_REQUEST[ $key ] is not set
306 */
307 public static function get_request( $key ) {
308
309 if ( isset( $_REQUEST[ $key ] ) ) {
310 return trim( $_REQUEST[ $key ] );
311 }
312
313 return '';
314 }
315
316 /**
317 * Add and store a notice.
318 *
319 * WC notice functions are not available in the admin
320 *
321 * @since 3.0.0
322 * @param string $message The text to display in the notice.
323 * @param string $notice_type The singular name of the notice type - either error, success or notice. [optional]
324 */
325 public static function wc_add_notice( $message, $notice_type = 'success' ) {
326
327 if ( function_exists( 'wc_add_notice' ) ) {
328 wc_add_notice( $message, $notice_type );
329 }
330 }
331
332 /**
333 * Gets the full URL to the log file for a given $handle
334 *
335 * @since 3.0.0
336 * @param string $handle log handle
337 * @return string URL to the WC log file identified by $handle
338 */
339 public static function get_wc_log_file_url( $handle ) {
340 return admin_url( sprintf( 'admin.php?page=wc-status&tab=logs&log_file=%s-%s-log', $handle, sanitize_file_name( wp_hash( $handle ) ) ) );
341 }
342
343
344 /**
345 * Gets the current WordPress site name.
346 *
347 * This is helpful for retrieving the actual site name instead of the
348 * network name on multisite installations.
349 *
350 * @since 3.0.0
351 * @return string
352 */
353 public static function get_site_name() {
354 return ( is_multisite() ) ? get_blog_details()->blogname : get_bloginfo( 'name' );
355 }
356
357 /**
358 * Displays a notice if the provided hook has not yet run.
359 *
360 * @since 3.0.0
361 *
362 * @param string $hook action hook to check
363 * @param string $method method/function name
364 * @param string $version version the notice was added
365 */
366 public static function maybe_doing_it_early( $hook, $method, $version ) {
367
368 if ( ! did_action( $hook ) ) {
369 Plugin_Compatibility::wc_doing_it_wrong( $method, "This should only be called after '{$hook}'", $version );
370 }
371 }
372
373 /**
374 * Triggers a PHP error.
375 *
376 * This wrapper method ensures AJAX isn't broken in the process.
377 *
378 * @since 3.0.0
379 * @param string $message the error message
380 * @param int $type Optional. The error type. Defaults to E_USER_NOTICE
381 */
382 public static function trigger_error( $message, $type = E_USER_NOTICE ) {
383
384 if ( wp_doing_ajax() ) {
385
386 switch ( $type ) {
387
388 case E_USER_NOTICE:
389 $prefix = 'Notice: ';
390 break;
391
392 case E_USER_WARNING:
393 $prefix = 'Warning: ';
394 break;
395
396 default:
397 $prefix = '';
398 }
399
400 error_log( $prefix . $message );
401
402 } else {
403
404 trigger_error( $message, $type );
405 }
406 }
407 }
408