PluginProbe
HivePress – Business Directory, Listings & Classified Ads Plugin / trunk
HivePress – Business Directory, Listings & Classified Ads Plugin vtrunk
1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 All 98 releases
hivepress / includes / helpers.php

helpers.php in HivePress – Business Directory, Listings & Classified Ads Plugin trunk, at includes/helpers.php

604 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Helper functions.
4 *
5 * @package HivePress
6 */
7
8 namespace HivePress\Helpers;
9
10 // Exit if accessed directly.
11 defined( 'ABSPATH' ) || exit;
12
13 /**
14 * Adds HivePress prefix.
15 *
16 * @param mixed $names Names to prefix.
17 * @return mixed
18 */
19 function prefix( $names ) {
20 $prefixed = '';
21
22 if ( is_array( $names ) ) {
23 $prefixed = array_map(
24 function( $name ) {
25 return 'hp_' . $name;
26 },
27 $names
28 );
29 } else {
30 $prefixed = 'hp_' . $names;
31 }
32
33 return $prefixed;
34 }
35
36 /**
37 * Removes HivePress prefix.
38 *
39 * @param mixed $names Names to unprefix.
40 * @return mixed
41 */
42 function unprefix( $names ) {
43 $unprefixed = '';
44
45 if ( is_array( $names ) ) {
46 $unprefixed = array_map(
47 function( $name ) {
48 return preg_replace( '/^hp_/', '', $name );
49 },
50 $names
51 );
52 } else {
53 $unprefixed = preg_replace( '/^hp_/', '', $names );
54 }
55
56 return $unprefixed;
57 }
58
59 /**
60 * Gets array item value by key.
61 *
62 * @param array $array Source array.
63 * @param string $key Key to search.
64 * @param mixed $default Default value.
65 * @return mixed
66 */
67 function get_array_value( $array, $key, $default = null ) {
68 $value = $default;
69
70 if ( is_array( $array ) && isset( $array[ $key ] ) ) {
71 $value = $array[ $key ];
72 }
73
74 return $value;
75 }
76
77 /**
78 * Gets first array item value.
79 *
80 * @since 1.3.1
81 * @param array $array Source array.
82 * @param mixed $default Default value.
83 * @return mixed
84 */
85 function get_first_array_value( $array, $default = null ) {
86 $value = $default;
87
88 if ( is_array( $array ) && $array ) {
89 $value = reset( $array );
90 }
91
92 return $value;
93 }
94
95 /**
96 * Gets last array item value.
97 *
98 * @since 1.3.1
99 * @param array $array Source array.
100 * @param mixed $default Default value.
101 * @return mixed
102 */
103 function get_last_array_value( $array, $default = null ) {
104 $value = $default;
105
106 if ( is_array( $array ) && $array ) {
107 $value = end( $array );
108 }
109
110 return $value;
111 }
112
113 /**
114 * Searches array item value by keys.
115 *
116 * @deprecated since version 1.6.13.
117 * @param array $array Source array.
118 * @param mixed $keys Keys to search.
119 * @return mixed
120 */
121 function search_array_value( $array, $keys ) {
122 $keys = (array) $keys;
123
124 foreach ( $keys as $key ) {
125 if ( isset( $array[ $key ] ) ) {
126 if ( get_last_array_value( $keys ) === $key ) {
127 return $array[ $key ];
128 } elseif ( is_array( $array[ $key ] ) ) {
129 $array = $array[ $key ];
130 }
131 } else {
132 foreach ( $array as $subarray ) {
133 if ( is_array( $subarray ) ) {
134 $value = search_array_value( $subarray, $keys );
135
136 if ( ! is_null( $value ) ) {
137 return $value;
138 }
139 }
140 }
141
142 break;
143 }
144 }
145 }
146
147 /**
148 * Merges arrays with mixed values.
149 *
150 * @return array
151 */
152 function merge_arrays() {
153 $merged = [];
154
155 foreach ( func_get_args() as $array ) {
156 foreach ( $array as $key => $value ) {
157 if ( ! isset( $merged[ $key ] ) || ( ! is_array( $merged[ $key ] ) || ! is_array( $value ) ) ) {
158 if ( is_numeric( $key ) ) {
159 $merged[] = $value;
160 } else {
161 $merged[ $key ] = $value;
162 }
163 } else {
164 $merged[ $key ] = merge_arrays( $merged[ $key ], $value );
165 }
166 }
167 }
168
169 return $merged;
170 }
171
172 /**
173 * Merges trees with mixed values.
174 *
175 * @deprecated since version 1.6.13.
176 * @param array $parent_tree Parent tree.
177 * @param array $child_tree Child tree.
178 * @param string $tree_key Tree key.
179 * @param string $node_key Node key.
180 * @return array
181 */
182 function merge_trees( $parent_tree, $child_tree, $tree_key = null, $node_key = null ) {
183 if ( is_null( $tree_key ) ) {
184 if ( $parent_tree ) {
185 $tree_key = get_first_array_value( array_keys( $parent_tree ) );
186 } elseif ( $child_tree ) {
187 $tree_key = get_first_array_value( array_keys( $child_tree ) );
188 }
189 }
190
191 if ( isset( $parent_tree[ $tree_key ] ) ) {
192 foreach ( $parent_tree[ $tree_key ] as $parent_node_key => $parent_node ) {
193 $parent_tree[ $tree_key ][ $parent_node_key ] = merge_trees( $parent_node, $child_tree, $tree_key, $parent_node_key );
194 }
195 }
196
197 if ( is_null( $node_key ) ) {
198 unset( $child_tree[ $tree_key ] );
199
200 $parent_tree = merge_arrays( $parent_tree, $child_tree );
201 } else {
202 $child_node = search_array_value( $child_tree, [ $tree_key, $node_key ] );
203
204 if ( ! is_null( $child_node ) ) {
205 $parent_tree = merge_arrays( $parent_tree, $child_node );
206 }
207 }
208
209 return $parent_tree;
210 }
211
212 /**
213 * Sorts array by a custom order.
214 *
215 * @param array $array Source array.
216 * @return array
217 */
218 function sort_array( $array ) {
219 foreach ( $array as $key => $value ) {
220 if ( is_array( $value ) ) {
221
222 // @deprecated since version 1.3.0.
223 if ( isset( $value['order'] ) && is_int( $value['order'] ) ) {
224 $array[ $key ]['_order'] = $value['order'];
225 } elseif ( ! isset( $value['_order'] ) ) {
226 $array[ $key ]['_order'] = 0;
227 }
228 }
229 }
230
231 return wp_list_sort( $array, '_order', 'ASC', true );
232 }
233
234 /**
235 * Gets a short class name.
236 *
237 * @param string $class Class name.
238 * @return string
239 */
240 function get_class_name( $class ) {
241 return strtolower( ( new \ReflectionClass( $class ) )->getShortName() );
242 }
243
244 /**
245 * Gets parent classes including a child.
246 *
247 * @param string $class Class name.
248 * @return array
249 */
250 function get_class_parents( $class ) {
251 return array_reverse( array_merge( [ $class ], class_parents( $class ) ) );
252 }
253
254 /**
255 * Checks if object is a class instance.
256 *
257 * @param object $object Class object.
258 * @param string $class Class name.
259 * @return bool
260 */
261 function is_class_instance( $object, $class ) {
262 return is_object( $object ) && strtolower( get_class( $object ) ) === ltrim( strtolower( $class ), '\\' );
263 }
264
265 /**
266 * Checks if object is a namespace instance.
267 *
268 * @param object $object Class object.
269 * @param string $namespace Namespace name.
270 * @return bool
271 */
272 function is_namespace_instance( $object, $namespace ) {
273 return is_object( $object ) && stripos( get_class( $object ), 'HivePress\\' . $namespace . '\\' ) === 0;
274 }
275
276 /**
277 * Creates a class instance.
278 *
279 * @param string $class Class name.
280 * @param array $args Instance arguments.
281 * @return object
282 */
283 function create_class_instance( $class, $args = [] ) {
284 if ( class_exists( $class ) && ! ( new \ReflectionClass( $class ) )->isAbstract() ) {
285 $instance = null;
286
287 if ( empty( $args ) ) {
288 $instance = new $class();
289 } else {
290 $instance = new $class( ...$args );
291 }
292
293 return $instance;
294 }
295 }
296
297 /**
298 * Calls a class method.
299 *
300 * @param string $class Class name.
301 * @param string $method Method name.
302 * @param array $args Method arguments.
303 * @return mixed
304 */
305 function call_class_method( $class, $method, $args = [] ) {
306 if ( class_exists( $class ) && method_exists( $class, $method ) ) {
307 return call_user_func_array( [ $class, $method ], $args );
308 }
309 }
310
311 /**
312 * Replaces tokens with values.
313 *
314 * @param array $tokens Array of tokens.
315 * @param string $text Text to be processed.
316 * @param bool $format Format values?
317 * @return string
318 */
319 function replace_tokens( $tokens, $text, $format = false ) {
320 $fallback = get_option( 'hp_installed_time' ) < strtotime( '2024-07-08' );
321
322 foreach ( $tokens as $token_name => $token_value ) {
323 $is_model = is_namespace_instance( $token_value, 'models' );
324
325 // Get matches.
326 $regex = '/%' . $token_name;
327
328 if ( $is_model ) {
329 $regex .= '\.([a-z0-9_]+)';
330 }
331
332 $regex .= '(\s*\|[^%]+)?%/';
333
334 preg_match_all( $regex, $text, $matches );
335
336 $matches = array_unique( get_first_array_value( $matches ) );
337
338 foreach ( $matches as $match ) {
339
340 // Get name.
341 $match_name = trim( $match, '%' );
342
343 // Get default.
344 $match_default = '';
345
346 $parts = explode( '|', $match_name, 2 );
347
348 if ( count( $parts ) > 1 ) {
349 $match_name = trim( get_first_array_value( $parts ) );
350
351 $match_default = trim( get_last_array_value( $parts ) );
352 }
353
354 // Get value.
355 $match_value = null;
356
357 if ( $is_model ) {
358 $field_name = get_last_array_value( explode( '.', $match_name ) );
359
360 if ( 'id' === $field_name ) {
361 $match_value = $token_value->get_id();
362 } else {
363 $field = get_array_value( $token_value->_get_fields(), $field_name );
364
365 if ( $field ) {
366
367 // @todo remove date check in the next major version.
368 if ( $format || $fallback ) {
369 $match_value = $field->display();
370 } else {
371 $match_value = $field->get_display_value();
372 }
373 } elseif ( method_exists( $token_value, 'display_' . $field_name ) ) {
374 $match_value = call_user_func( [ $token_value, 'display_' . $field_name ] );
375 }
376 }
377 } elseif ( ! is_array( $token_value ) ) {
378 $match_value = $token_value;
379 }
380
381 // Replace match.
382 $text = str_replace( $match, is_null( $match_value ) ? $match_default : $match_value, $text );
383 }
384 }
385
386 return $text;
387 }
388
389 /**
390 * Renders HTML attributes.
391 *
392 * @param array $attributes Array of attributes.
393 * @return string
394 */
395 function html_attributes( $attributes ) {
396 $output = '';
397
398 if ( is_array( $attributes ) ) {
399 foreach ( $attributes as $name => $value ) {
400 if ( true === $value ) {
401 $value = $name;
402 } elseif ( is_array( $value ) ) {
403 $value = implode( ' ', $value );
404 }
405
406 $output .= esc_attr( $name ) . '="' . esc_attr( $value ) . '" ';
407 }
408 }
409
410 return rtrim( $output );
411 }
412
413 /**
414 * Escapes JSON.
415 *
416 * @param string $json JSON string.
417 * @param bool $html Contains HTML?
418 * @return string
419 */
420 function esc_json( $json, $html = false ) {
421 return _wp_specialchars(
422 $json,
423 $html ? ENT_NOQUOTES : ENT_QUOTES,
424 'UTF-8',
425 true
426 );
427 }
428
429 /**
430 * Sanitizes HTML.
431 *
432 * @param string $html HTML to sanitize.
433 * @param array $tags Allowed HTML tags.
434 * @return string
435 */
436 function sanitize_html( $html, $tags = [] ) {
437 if ( empty( $tags ) ) {
438 $tags = [
439 'strong' => [],
440 'a' => [
441 'href' => [],
442 'target' => [],
443 'class' => [],
444 ],
445 'i' => [
446 'class' => [],
447 ],
448 ];
449 } elseif ( true === $tags ) {
450 $tags = 'post';
451 }
452
453 return wp_kses( $html, $tags );
454 }
455
456 /**
457 * Sanitizes slug.
458 *
459 * @param string $text Text to sanitize.
460 * @return string
461 */
462 function sanitize_slug( $text ) {
463 return str_replace( '_', '-', \sanitize_key( $text ) );
464 }
465
466 /**
467 * Sanitizes key.
468 *
469 * @param string $text Text to sanitize.
470 * @return string
471 */
472 function sanitize_key( $text ) {
473 $key = $text;
474
475 if ( function_exists( 'transliterator_transliterate' ) ) {
476 $key = transliterator_transliterate( 'Any-Latin; Latin-ASCII; Lower()', $key );
477 } else {
478 $key = strtolower( $key );
479 }
480
481 $key = preg_replace( '/[^a-z0-9]+/', '_', $key );
482 $key = ltrim( trim( $key, '_' ), '0..9' );
483
484 if ( empty( $key ) ) {
485 $key = 'a' . substr( md5( $text ), 0, 31 );
486 }
487
488 return $key;
489 }
490
491 /**
492 * Formats number.
493 *
494 * @param float $number Number.
495 * @param int $decimals Precision.
496 * @return string
497 */
498 function format_number( $number, $decimals = null ) {
499 if ( is_null( $decimals ) ) {
500 $decimals = strlen( substr( strrchr( (string) $number, '.' ), 1 ) );
501 }
502
503 return number_format_i18n( $number, $decimals );
504 }
505
506 /**
507 * Checks plugin status.
508 *
509 * @param string $name Plugin name.
510 * @return bool
511 */
512 function is_plugin_active( $name ) {
513 return class_exists( $name ) || function_exists( $name );
514 }
515
516 /**
517 * Checks if the current request is REST.
518 *
519 * @return bool
520 */
521 function is_rest() {
522 return defined( 'REST_REQUEST' ) && REST_REQUEST;
523 }
524
525 /**
526 * Creates a REST API response.
527 *
528 * @param int $code Error code.
529 * @param array $data Response data.
530 * @return WP_Rest_Response
531 */
532 function rest_response( $code, $data = null ) {
533 $response = new \WP_Rest_Response( (object) [], $code );
534
535 if ( ! is_null( $data ) ) {
536 $response = new \WP_Rest_Response(
537 [
538 'data' => $data,
539 ],
540 $code
541 );
542 }
543
544 return $response;
545 }
546
547 /**
548 * Creates a REST API error.
549 *
550 * @param int $code Error code.
551 * @param array $errors Error messages.
552 * @return WP_Rest_Response
553 */
554 function rest_error( $code, $errors = [] ) {
555 $error = [
556 'code' => $code,
557 ];
558
559 if ( $errors ) {
560 $error['errors'] = array_map(
561 function( $error ) {
562 return [
563 'message' => $error,
564 ];
565 },
566 (array) $errors
567 );
568 }
569
570 return new \WP_Rest_Response(
571 [
572 'error' => $error,
573 ],
574 $code
575 );
576 }
577
578 /**
579 * Gets the number of columns out of 12.
580 *
581 * @param int $number Columns number.
582 * @return int
583 */
584 function get_column_width( $number ) {
585 $number = absint( $number );
586 $width = 12;
587
588 if ( $number > 0 && $number <= 12 ) {
589 $width = round( $width / $number );
590 }
591
592 return $width;
593 }
594
595 /**
596 * Checks if text contains shortcodes.
597 *
598 * @param string $text Text to be checked.
599 * @return bool
600 */
601 function has_shortcode( $text ) {
602 return strpos( $text, '[' ) !== false && preg_match( '/\[[a-z0-9_-]+(\]| )/i', $text );
603 }
604