PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
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 4.2.1 All 138 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, at inc/class-lp-helper.php

567 lines 12.3 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 * @depecated 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 = $_SERVER['HTTP_HOST'] ?? '';
408
409 return $schema . $http_host . untrailingslashit( esc_url_raw( $_SERVER['REQUEST_URI'] ?? '' ) );
410 }
411
412 /**
413 * Check request is rest api
414 *
415 * @since 4.1.6.6
416 * @author tungnx
417 * @return bool|int
418 */
419 public static function isRestApiLP() {
420 return strpos( self::getUrlCurrent(), '/wp-json/lp/' );
421 }
422
423 /**
424 * Sanitize string and array
425 *
426 * @param array|string $value
427 * @param string $type_content
428 *
429 * @return array|string
430 * @since 3.2.7.1
431 * @author tungnx
432 */
433 public static function sanitize_params_submitted( $value, $type_content = 'text' ) {
434 $value = wp_unslash( $value );
435
436 if ( is_string( $value ) ) {
437 switch ( $type_content ) {
438 case 'html':
439 $value = wp_kses_post( $value );
440 break;
441 case 'textarea':
442 $value = sanitize_textarea_field( $value );
443 break;
444 case 'key':
445 $value = sanitize_key( $value );
446 break;
447 default:
448 $value = sanitize_text_field( $value );
449 }
450 } elseif ( is_array( $value ) ) {
451 foreach ( $value as $k => $v ) {
452 $value[ $k ] = self::sanitize_params_submitted( $v, $type_content );
453 }
454 }
455
456 return $value;
457 }
458
459 /**
460 * Get wp file system
461 *
462 * @return mixed
463 */
464 public static function get_wp_filesystem() {
465 global $wp_filesystem;
466
467 if ( empty( $wp_filesystem ) ) {
468 require_once( ABSPATH . '/wp-admin/includes/file.php' );
469 WP_Filesystem();
470 }
471
472 return $wp_filesystem;
473 }
474
475 /**
476 * Wrap function $wpdb->prepare(...) to support arguments as
477 * array.
478 *
479 * @param string $query
480 * @param array|mixed $args
481 *
482 * @return string
483 * @example
484 *
485 * $this->prepare($sql, $one, $two, array($three, $four, $file))
486 * => $wpdb->prepare($sql, $one, $two, $three, $four, $file)
487 */
488 public static function prepare( $query, $args ) {
489 global $wpdb;
490
491 $args = func_get_args();
492 array_shift( $args );
493 $new_args = array();
494
495 foreach ( $args as $arg ) {
496 if ( is_array( $arg ) ) {
497 $new_args = array_merge( $new_args, $arg );
498 } else {
499 $new_args[] = $arg;
500 }
501 }
502
503 return $wpdb->prepare( $query, $new_args );
504 }
505
506 public static function db_format_array( array $arr, string $format = '%d' ): string {
507 $arr_formatted = array_fill( 0, sizeof( $arr ), $format );
508
509 return join( ',', $arr_formatted );
510 }
511
512 /**
513 * Calculate percent of progress rows on db
514 *
515 * @param int $offset .
516 * @param int $limit .
517 * @param int $total_row .
518 *
519 * @return float
520 */
521 public static function progress_percent( int $offset, int $limit, int $total_row ): float {
522 if ( $total_row <= 0 ) {
523 return 0;
524 }
525
526 $percent = ( $offset + $limit ) * 100 / $total_row;
527
528 $percent = $percent > 100 ? 100 : $percent;
529
530 return floatval( number_format( $percent, 2 ) );
531 }
532
533 /**
534 * Convert array to string
535 * Ex: array("publish", "pending") to post_status IN(%s, %s)
536 *
537 * @param array $arr
538 *
539 * @return string
540 */
541 public static function format_query_IN( array $arr ): string {
542 $format = array_fill( 0, count( $arr ), '%s' );
543
544 return join( ',', $format );
545 }
546
547 /**
548 * Get link lp checkout page
549 * without cache - because some cache(redis) will cache page with user anonymous
550 */
551 public static function get_link_no_cache( string $link ): string {
552 return esc_url_raw( add_query_arg( 'no-cache', uniqid(), $link ) );
553 }
554
555 /**
556 * Check string is json
557 *
558 * @param string $str
559 *
560 * @return bool
561 */
562 public static function is_json( string $str ): bool {
563 json_decode( $str );
564 return json_last_error() === JSON_ERROR_NONE;
565 }
566 }
567