PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / class-lp-helper.php

class-lp-helper.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.3, at inc/class-lp-helper.php

574 lines 12.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Helper
5 */
6 defined( 'ABSPATH' ) || exit;
7
8 class LP_Helper {
9
10 /**
11 * Wrap function unserialize to fix issues with UTF-8 chars when encoding/decoding
12 * of serialize function.
13 *
14 * @param string $string
15 *
16 * @return mixed
17 */
18 public static function maybe_unserialize( $string ) {
19 if ( is_string( $string ) ) {
20
21 $unserialized = maybe_unserialize( $string );
22 if ( ! $unserialized && strlen( $string ) ) {
23 $string = preg_replace_callback(
24 '!s:(\d+):"(.*?)";!s',
25 array( __CLASS__, '_unserialize_replace_callback' ),
26 $string
27 );
28
29 $unserialized = maybe_unserialize( $string );
30 }
31
32 $string = $unserialized;
33 }
34
35 return $string;
36 }
37
38 public static function _unserialize_replace_callback( $m ) {
39 $len = strlen( $m[2] );
40 $result = "s:$len:\"{$m[2]}\";";
41
42 return $result;
43 }
44
45 /**
46 * Shuffle array and keep the keys
47 *
48 * @param array $array
49 *
50 * @return bool
51 */
52 public static function shuffle_assoc( &$array ) {
53 $keys = array_keys( $array );
54 shuffle( $keys );
55 $new = array();
56 foreach ( $keys as $key ) {
57 $new[ $key ] = $array[ $key ];
58 }
59 $array = $new;
60
61 return true;
62 }
63
64 /**
65 * Sanitize array by removing empty and/or duplicating values.
66 *
67 * @param array $array
68 *
69 * @return array
70 */
71 public static function sanitize_array( $array ) {
72 $array = array_filter( $array );
73 $array = array_unique( $array );
74
75 return $array;
76 }
77
78 /**
79 * MD5 an array.
80 *
81 * @param array $array
82 *
83 * @return string
84 */
85 public static function array_to_md5( $array ) {
86 settype( $array, 'array' );
87 ksort( $array );
88
89 return md5( serialize( $array ) );
90 }
91
92 /**
93 * Load posts from database into cache by ids
94 *
95 * @param array|int $ids
96 * @Todo: tungnx - need to review code
97 * @deprecated 4.1.6.9
98 */
99 public static function cache_posts( $ids ) {
100 //_deprecated_function( __FUNCTION__, '4.1.6.9' );
101 }
102
103 /**
104 * Sort an array by a field.
105 * Having some issue with default PHP usort function.
106 *
107 * @param array $array .
108 * @param string $field .
109 * @param int $default .
110 */
111 public static function sort_by_priority( &$array, $field = 'priority', $default = 10 ) {
112 foreach ( $array as $k => $item ) {
113 if ( ! array_key_exists( $field, $item ) ) {
114 $array[ $k ][ $field ] = $default;
115 }
116 }
117
118 $priority = array_unique( wp_list_pluck( $array, $field ) );
119 sort( $priority );
120 $priority = array_fill_keys( $priority, array() );
121
122 foreach ( $array as $k => $item ) {
123 $priority[ $item[ $field ] ][] = $item;
124 }
125
126 $sorted = array();
127 foreach ( $priority as $item ) {
128 $sorted = array_merge( $sorted, $item );
129 }
130 $array = $sorted;
131 }
132
133 /**
134 * Merge two or more classes into one.
135 *
136 * @return array
137 */
138 public static function merge_class() {
139 if ( func_num_args() == 1 ) {
140 return func_get_arg( 0 );
141 } elseif ( func_num_args() == 0 ) {
142 return null;
143 }
144
145 $classes = array();
146 foreach ( func_get_args() as $class ) {
147 if ( is_string( $class ) ) {
148 $cls = explode( ' ', $class );
149 $classes = array_merge( $classes, $cls );
150 } else {
151 $classes = array_merge( $classes, $class );
152 }
153 }
154
155 $classes = array_filter( $classes );
156 $classes = array_unique( $classes );
157
158 return $classes;
159 }
160
161 /**
162 * Sanitize order statuses.
163 * Add prefix lp- into each status if it is not exists.
164 *
165 * @param $statuses
166 *
167 * @return array|mixed
168 */
169 public static function sanitize_order_status( &$statuses ) {
170 if ( is_array( $statuses ) ) {
171 foreach ( $statuses as $k => $status ) {
172 if ( false === strpos( $status, 'lp-' ) ) {
173 $statuses[ $k ] = "lp-{$status}";
174 }
175 }
176 } else {
177 $statuses = preg_split( '#\s+#', $statuses );
178 self::sanitize_order_status( $statuses );
179 if ( sizeof( $statuses ) == 1 ) {
180 $statuses = reset( $statuses );
181 }
182 }
183
184 return $statuses;
185 }
186
187 /**
188 * Merge two arrays recursive.
189 *
190 * @param array $array1
191 * @param array $array2
192 *
193 * @return array
194 */
195 public static function array_merge_recursive( &$array1, &$array2 ) {
196 $merged = $array1;
197
198 if ( is_array( $array1 ) && is_array( $array2 ) ) {
199 foreach ( $array2 as $key => & $value ) {
200 if ( is_array( $value ) && isset( $merged[ $key ] ) && is_array( $merged[ $key ] ) ) {
201 $merged[ $key ] = self::array_merge_recursive( $merged[ $key ], $value );
202 } elseif ( is_numeric( $key ) ) {
203 if ( ! in_array( $value, $merged ) ) {
204 $merged[] = $value;
205 }
206 } else {
207 $merged[ $key ] = $value;
208 }
209 }
210 } elseif ( is_array( $array2 ) ) {
211 $merged = $array2;
212 }
213
214 return $merged;
215 }
216
217 /**
218 * Encode the object to json format.
219 * Replace number, "false", "true" in couple of quotes with
220 * original value.
221 * Example:
222 * Input: {
223 * number: "1234",
224 * true_value: "true",
225 * false_value: "false"
226 * }
227 * Output: {
228 * number: 1234,
229 * true_value: true,
230 * false_value: false
231 * }
232 *
233 * @param array $data
234 *
235 * @return false|mixed|string
236 */
237 public static function json_encode( $data ) {
238 $data = wp_json_encode( $data );
239 $data = preg_replace_callback(
240 '~:"(([0-9]+)([.,]?)([0-9]?)|true|false)"~',
241 array(
242 __CLASS__,
243 '_valid_json_value',
244 ),
245 $data
246 );
247
248 return $data;
249 }
250
251 /**
252 * Callback function for json_encode method "json_encode".
253 *
254 * @param array $m
255 *
256 * @return string
257 */
258 public static function _valid_json_value( $m ) {
259 return str_replace( array( ':"', '"' ), array( ':', '' ), $m[0] );
260 }
261
262 /**
263 * Create LP static page.
264 *
265 * @param string $name
266 * @param string $assign_to - Optional. Assign to LP page after creating successful.
267 *
268 * @return bool|int|WP_Error
269 */
270 public static function create_page( $name, $assign_to = '' ) {
271 $args = array(
272 'post_type' => 'page',
273 'post_title' => $name,
274 'post_status' => 'publish',
275 );
276
277 $page_id = wp_insert_post( $args );
278
279 if ( ! $page_id ) {
280 return false;
281 }
282
283 update_post_meta( $page_id, '_lp_page', 'yes' );
284
285 if ( $assign_to ) {
286 $pages = learn_press_static_pages();
287
288 if ( ! empty( $pages[ $assign_to ] ) ) {
289 update_option( "learn_press_{$assign_to}_page_id", $page_id );
290
291 // Update cache
292 $page_ids = learn_press_static_page_ids();
293 $page_ids[ $assign_to ] = $page_id;
294 LP_Object_Cache::set( 'static-page-ids', $page_ids, 'learnpress' );
295 }
296 }
297
298 return $page_id;
299 }
300
301 /**
302 * Wrap function ksort of PHP itself and support recursive.
303 *
304 * @param array $array
305 * @param int $sort_flags
306 *
307 * @return bool
308 * @since 3.3.0
309 */
310 public static function ksort( &$array, $sort_flags = SORT_REGULAR ) {
311 if ( ! is_array( $array ) ) {
312 return false;
313 }
314
315 ksort( $array, $sort_flags );
316
317 foreach ( $array as &$arr ) {
318 self::ksort( $arr, $sort_flags );
319 }
320
321 return true;
322 }
323
324 /**
325 * Return new array/object with the keys exists in list of props.
326 *
327 * @param array|string $props
328 * @param array|object $obj
329 *
330 * @return array|object
331 */
332 public function pick( $props, $obj ) {
333 $is_array = is_array( $obj );
334 $new_array = array();
335 settype( $props, 'array' );
336
337 foreach ( $props as $prop ) {
338 if ( $is_array && array_key_exists( $prop, $obj ) ) {
339 $new_array[ $prop ] = $obj[ $prop ];
340 } elseif ( ! $is_array && property_exists( $obj, $prop ) ) {
341 $new_array[ $prop ] = $obj->{$prop};
342 }
343 }
344
345 return $is_array ? $new_array : (object) $new_array;
346 }
347
348 public static function list_pluck( $list, $field, $index_key = null ) {
349 $newlist = array();
350
351 if ( ! $index_key ) {
352 /*
353 * This is simple. Could at some point wrap array_column()
354 * if we knew we had an array of arrays.
355 */
356 foreach ( $list as $key => $value ) {
357 if ( is_callable( array( $value, $field ) ) ) {
358 $newlist[ $key ] = call_user_func( array( $value, $field ) );
359 } elseif ( is_object( $value ) ) {
360 $newlist[ $key ] = $value->$field;
361 } else {
362 $newlist[ $key ] = $value[ $field ];
363 }
364 }
365
366 return $newlist;
367 }
368
369 /*
370 * When index_key is not set for a particular item, push the value
371 * to the end of the stack. This is how array_column() behaves.
372 */
373 foreach ( $list as $value ) {
374 if ( is_callable( array( $value, $field ) ) ) {
375 if ( isset( $value->$index_key ) ) {
376 $newlist[ $value->$index_key ] = call_user_func( array( $value, $field ) );
377 } else {
378 $newlist[] = call_user_func( array( $value, $field ) );
379 }
380 } elseif ( is_object( $value ) ) {
381 if ( isset( $value->$index_key ) ) {
382 $newlist[ $value->$index_key ] = $value->$field;
383 } else {
384 $newlist[] = $value->$field;
385 }
386 } else {
387 if ( isset( $value[ $index_key ] ) ) {
388 $newlist[ $value[ $index_key ] ] = $value[ $field ];
389 } else {
390 $newlist[] = $value[ $field ];
391 }
392 }
393 }
394
395 return $newlist;
396 }
397
398 /**
399 * Get the current url
400 *
401 * @return string
402 * @since 3.2.6.8
403 * @author tungnx
404 */
405 public static function getUrlCurrent(): string {
406 $schema = is_ssl() ? 'https://' : 'http://';
407 $http_host = LP_Helper::sanitize_params_submitted( filter_input( INPUT_SERVER, 'HTTP_HOST' ) ?? '' );
408 $request_uri = LP_Helper::sanitize_params_submitted( filter_input( INPUT_SERVER, 'REQUEST_URI' ) ?? '' );
409
410 return $schema . untrailingslashit( esc_url_raw( $http_host . $request_uri ) );
411 }
412
413 /**
414 * Check request is rest api
415 *
416 * @since 4.1.6.6
417 * @author tungnx
418 * @return bool|int
419 */
420 public static function isRestApiLP() {
421 return strpos( self::getUrlCurrent(), '/wp-json/lp/' );
422 }
423
424 /**
425 * Sanitize string and array
426 *
427 * @param array|string $value
428 * @param string $type_content
429 *
430 * @return array|string
431 * @since 3.2.7.1
432 * @author tungnx
433 */
434 public static function sanitize_params_submitted( $value, string $type_content = 'text' ) {
435 $value = wp_unslash( $value );
436
437 if ( is_string( $value ) ) {
438 switch ( $type_content ) {
439 case 'html':
440 $value = wp_kses_post( $value );
441 break;
442 case 'textarea':
443 $value = sanitize_textarea_field( $value );
444 break;
445 case 'key':
446 $value = sanitize_key( $value );
447 break;
448 case 'int':
449 $value = (int) $value;
450 break;
451 case 'float':
452 $value = (float) $value;
453 break;
454 default:
455 $value = sanitize_text_field( $value );
456 }
457 } elseif ( is_array( $value ) ) {
458 foreach ( $value as $k => $v ) {
459 $value[ $k ] = self::sanitize_params_submitted( $v, $type_content );
460 }
461 }
462
463 return $value;
464 }
465
466 /**
467 * Get wp file system
468 *
469 * @return mixed
470 */
471 public static function get_wp_filesystem() {
472 global $wp_filesystem;
473
474 if ( empty( $wp_filesystem ) ) {
475 require_once( ABSPATH . '/wp-admin/includes/file.php' );
476 WP_Filesystem();
477 }
478
479 return $wp_filesystem;
480 }
481
482 /**
483 * Wrap function $wpdb->prepare(...) to support arguments as
484 * array.
485 *
486 * @param string $query
487 * @param array|mixed $args
488 *
489 * @return string
490 * @example
491 *
492 * $this->prepare($sql, $one, $two, array($three, $four, $file))
493 * => $wpdb->prepare($sql, $one, $two, $three, $four, $file)
494 */
495 public static function prepare( $query, $args ) {
496 global $wpdb;
497
498 $args = func_get_args();
499 array_shift( $args );
500 $new_args = array();
501
502 foreach ( $args as $arg ) {
503 if ( is_array( $arg ) ) {
504 $new_args = array_merge( $new_args, $arg );
505 } else {
506 $new_args[] = $arg;
507 }
508 }
509
510 return $wpdb->prepare( $query, $new_args );
511 }
512
513 public static function db_format_array( array $arr, string $format = '%d' ): string {
514 $arr_formatted = array_fill( 0, sizeof( $arr ), $format );
515
516 return join( ',', $arr_formatted );
517 }
518
519 /**
520 * Calculate percent of progress rows on db
521 *
522 * @param int $offset .
523 * @param int $limit .
524 * @param int $total_row .
525 *
526 * @return float
527 */
528 public static function progress_percent( int $offset, int $limit, int $total_row ): float {
529 if ( $total_row <= 0 ) {
530 return 0;
531 }
532
533 $percent = ( $offset + $limit ) * 100 / $total_row;
534
535 $percent = $percent > 100 ? 100 : $percent;
536
537 return floatval( number_format( $percent, 2 ) );
538 }
539
540 /**
541 * Convert array to string
542 * Ex: array("publish", "pending") to post_status IN(%s, %s)
543 *
544 * @param array $arr
545 *
546 * @return string
547 */
548 public static function format_query_IN( array $arr ): string {
549 $format = array_fill( 0, count( $arr ), '%s' );
550
551 return join( ',', $format );
552 }
553
554 /**
555 * Get link lp checkout page
556 * without cache - because some cache(redis) will cache page with user anonymous
557 */
558 public static function get_link_no_cache( string $link ): string {
559 return esc_url_raw( add_query_arg( 'no-cache', uniqid(), $link ) );
560 }
561
562 /**
563 * Check string is json
564 *
565 * @param string $str
566 *
567 * @return bool
568 */
569 public static function is_json( string $str ): bool {
570 json_decode( $str );
571 return json_last_error() === JSON_ERROR_NONE;
572 }
573 }
574