PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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
← All changes | inc/Helpers/Template.php +547 -547 4.3.9.14.4.8 View file →
@@ -1,547 +1,547 @@
1 -<?php
2 -
3 -namespace LearnPress\Helpers;
4 -
5 -use LP_Breadcrumb;
6 -use LP_Debug;
7 -use Throwable;
8 -
9 -/**
10 - * Class Template
11 - *
12 - * @package LearnPress\Helpers
13 - * @since 1.0.0
14 - * @version 1.0.2
15 - */
16 -class Template {
17 - /**
18 - * @var bool
19 - */
20 - protected $include;
21 -
22 - protected function __construct() {
23 - }
24 -
25 - /**
26 - * Set 1 for include file, 0 for not
27 - * Set 1 for separate template is block, 0 for not | use "wp_is_block_theme" function
28 - *
29 - * @param bool $has_include
30 - *
31 - * @return self
32 - */
33 - public static function instance( bool $has_include = true ): Template {
34 - $self = new self();
35 - $self->include = $has_include;
36 -
37 - return $self;
38 - }
39 -
40 - /**
41 - * Get template admin file
42 - *
43 - * @param string $file_name
44 - * @param array $args
45 - *
46 - * @return void|string
47 - * @since 1.0.0
48 - * @version 1.0.0
49 - */
50 - public function get_admin_template( string $file_name = '', array $args = array() ) {
51 - $file_name = str_replace( '.php', '', $file_name );
52 - $path_file = LP_PLUGIN_PATH . "inc/admin/views/{$file_name}.php";
53 -
54 - $template = $this->get_template( $path_file, $args );
55 -
56 - if ( ! $this->include ) {
57 - return $template;
58 - }
59 - }
60 -
61 - /**
62 - * Get template frontend file
63 - *
64 - * @param string $file_name
65 - * @param array $args
66 - *
67 - * @return void|string
68 - * @since 4.2.0
69 - * @version 1.0.0
70 - */
71 - public function get_frontend_template( string $file_name = '', array $args = array() ) {
72 - $default_path = LP_PLUGIN_PATH . "templates/{$file_name}";
73 - $folder_name_rewrite = learn_press_template_path();
74 - $file_name = sanitize_text_field( $file_name );
75 - $from_child_theme_path = sprintf(
76 - '%s/%s/%s',
77 - get_stylesheet_directory(),
78 - $folder_name_rewrite,
79 - $file_name
80 - );
81 - $from_theme_path = sprintf(
82 - '%s/%s/%s',
83 - get_template_directory(),
84 - $folder_name_rewrite,
85 - $file_name
86 - );
87 -
88 - $path_load = $default_path;
89 - if ( file_exists( $from_child_theme_path ) ) {
90 - $path_load = $from_child_theme_path;
91 - } elseif ( file_exists( $from_theme_path ) ) {
92 - $path_load = $from_theme_path;
93 - }
94 -
95 - $template = '';
96 - if ( realpath( $path_load ) ) {
97 - $template = $this->get_template( $path_load, $args );
98 - }
99 -
100 - if ( ! $this->include ) {
101 - return $template;
102 - }
103 - }
104 -
105 - /**
106 - * @param array $file_names
107 - * @param array $args
108 - *
109 - * @return void
110 - */
111 - public function get_frontend_templates( array $file_names = array(), array $args = array() ) {
112 - foreach ( $file_names as $file_name ) {
113 - $search_extension = strrpos( $file_name, '.php' );
114 - if ( ! $search_extension ) {
115 - $file_name .= '.php';
116 - }
117 -
118 - $this->get_frontend_template( $file_name, $args );
119 - }
120 - }
121 -
122 - /**
123 - * Include path file
124 - *
125 - * @param string $path_file
126 - * @param array $args
127 - *
128 - * @return string|void
129 - * @since 1.0.0
130 - * @version 1.0.1
131 - */
132 - public function get_template( string $path_file, array $args = array() ) {
133 - try {
134 - //extract( $args );
135 -
136 - // Remove any '..' from the path to prevent directory traversal attacks
137 - $path_file = preg_replace( '/\.\.+/', '', $path_file );
138 -
139 - if ( file_exists( $path_file ) ) {
140 - if ( $this->include ) {
141 - // Extract args
142 - foreach ( $args as $key => $value ) {
143 - $$key = $value;
144 - }
145 - unset( $key, $value ); // Clean up
146 -
147 - include $path_file;
148 - } else {
149 - return $path_file;
150 - }
151 - } else {
152 - printf( esc_html__( 'Path file %s not exists', 'learnpress' ), $path_file );
153 - echo '<br>';
154 - }
155 - } catch ( Throwable $e ) {
156 - LP_Debug::error_log( $e );
157 - }
158 - }
159 -
160 - /**
161 - * Get frontend template block file
162 - *
163 - * @param string $file_name
164 - * @param array $args
165 - *
166 - * @return string|void
167 - */
168 - public function get_frontend_template_type_block( string $file_name = '', array $args = array() ) {
169 - $file_name = "block/{$file_name}";
170 - $template = $this->get_frontend_template( $file_name, $args );
171 -
172 - if ( ! $this->include ) {
173 - return $template;
174 - }
175 - }
176 -
177 - /**
178 - * Check file template is overwritten
179 - *
180 - * @param string $file_name
181 - *
182 - * @return bool|string return false if not, path file if yes
183 - * @since 4.2.6
184 - * @version 1.0.0
185 - */
186 - public static function check_template_is_override( string $file_name = '' ) {
187 - $default_path = LP_PLUGIN_PATH . "templates/{$file_name}";
188 - $folder_name_rewrite = learn_press_template_path();
189 - $from_child_theme_path = sprintf(
190 - '%s/%s/%s',
191 - get_stylesheet_directory(),
192 - $folder_name_rewrite,
193 - $file_name
194 - );
195 - $from_theme_path = sprintf(
196 - '%s/%s/%s',
197 - get_template_directory(),
198 - $folder_name_rewrite,
199 - $file_name
200 - );
201 -
202 - if ( file_exists( $from_child_theme_path ) ) {
203 - return $from_child_theme_path;
204 - } elseif ( file_exists( $from_theme_path ) ) {
205 - return $from_theme_path;
206 - }
207 -
208 - return false;
209 - }
210 -
211 - /**
212 - * Nest elements by tags
213 - *
214 - * @param array $els [ 'html_tag_open' => 'html_tag_close' ]
215 - * @param string $main_content
216 - *
217 - * @return string
218 - */
219 - public function nest_elements( array $els = [], string $main_content = '' ): string {
220 - $html = '';
221 - foreach ( $els as $tag_open => $tag_close ) {
222 - $html .= $tag_open;
223 - }
224 -
225 - $html .= $main_content;
226 -
227 - foreach ( array_reverse( $els, true ) as $tag_close ) {
228 - $html .= $tag_close;
229 - }
230 -
231 - return $html;
232 - }
233 -
234 - /**
235 - * Display sections
236 - *
237 - * @param array $sections
238 - * ['name_section' => [ 'text_html' => '<span>example</span>' ]]
239 - * ['name_section' => [ 'link_templates' => 'path_template' ]]
240 - *
241 - * @return void
242 - */
243 - public function print_sections( array $sections = [], array $args = [] ) {
244 - foreach ( $sections as $section ) {
245 - if ( ! is_array( $section ) ) {
246 - continue;
247 - }
248 -
249 - foreach ( $section as $type => $val ) {
250 - switch ( $type ) {
251 - case 'link_templates':
252 - $this->get_frontend_template( $val, $args );
253 - break;
254 - default:
255 - if ( is_string( $val ) ) {
256 - //$allow_tag = wp_kses_allowed_html( 'post' );
257 - //echo wp_kses( $section, $allow_tag );
258 - echo $val;
259 - }
260 - break;
261 - }
262 - }
263 - }
264 - }
265 -
266 - /**
267 - * Combine html elements
268 - *
269 - * @param array $elms
270 - *
271 - * @return string
272 - * @since 4.2.6.9
273 - */
274 - public static function combine_components( array $elms = [] ): string {
275 - $html = '';
276 - foreach ( $elms as $tag => $val ) {
277 - $html .= $val;
278 - }
279 -
280 - return $html;
281 - }
282 -
283 - /**
284 - * Insert new key to a position of array
285 - *
286 - * @param array $old_array
287 - * @param string $position after/before
288 - * @param string $key_compare key to compare
289 - * @param string $key_add
290 - * @param string $value
291 - *
292 - * @return array
293 - * @since 4.2.7.2
294 - * @version 1.0.1
295 - */
296 - public static function insert_value_to_position_array(
297 - array $old_array,
298 - string $position,
299 - string $key_compare,
300 - string $key_add,
301 - string $value
302 - ): array {
303 - $new_array = [];
304 -
305 - foreach ( $old_array as $k => $v ) {
306 - if ( $position === 'after' ) {
307 - $new_array[ $k ] = $v;
308 - }
309 - if ( $key_compare === $k ) {
310 - $new_array[ $key_add ] = $value;
311 - }
312 - if ( $position === 'before' ) {
313 - $new_array[ $k ] = $v;
314 - }
315 - }
316 -
317 - return $new_array;
318 - }
319 -
320 - /**
321 - * Print message
322 - *
323 - * @param string $message
324 - * @param string $status 'success', 'warning', 'error, 'info'
325 - * @param bool $has_print since 4.2.7.6, true for print, false for return
326 - *
327 - * @return void|string
328 - * @since 4.2.6.9.3
329 - * @version 1.0.2
330 - */
331 - public static function print_message( string $message, string $status = 'success', bool $has_print = true ) {
332 - if ( empty( $message ) ) {
333 - if ( $has_print ) {
334 - return;
335 - } else {
336 - return '';
337 - }
338 - }
339 -
340 - $section = [
341 - 'wrapper' => sprintf( '<div class="learn-press-message %s">', esc_attr( $status ) ),
342 - 'content' => wp_kses_post( $message ),
343 - 'wrapper_end' => '</div>',
344 - ];
345 -
346 - if ( $has_print ) {
347 - echo Template::combine_components( $section );
348 - } else {
349 - return Template::combine_components( $section );
350 - }
351 - }
352 -
353 - /**
354 - * Generate HTML for pagination.
355 - *
356 - * @param array $data [ 'total_pages' => int, 'paged' => int, 'base' => string ]
357 - *
358 - * @return string HTML for pagination.
359 - * @since 4.2.8.7.4
360 - * @version 1.0.1
361 - */
362 - public function html_pagination( array $data = [] ): string {
363 - $total_pages = $data['total_pages'] ?? 0;
364 - $paged = $data['paged'] ?? 1;
365 - if ( $total_pages <= 1 ) {
366 - return '';
367 - }
368 -
369 - $html_wrapper = $data['wrapper'] ?? [
370 - '<nav class="learn-press-pagination navigation pagination">' => '</nav>',
371 - ];
372 -
373 - $pagination = paginate_links(
374 - apply_filters(
375 - 'learn_press_pagination_args',
376 - array(
377 - 'base' => $data['base'] ?? add_query_arg( 'paged', '%#%', '' ),
378 - 'format' => $data['format'] ?? '?paged=%#%',
379 - 'add_args' => $data['add_args'] ?? '',
380 - 'current' => max( 1, $paged ),
381 - 'total' => $total_pages,
382 - 'prev_text' => '<i class="lp-icon-arrow-left"></i>',
383 - 'next_text' => '<i class="lp-icon-arrow-right"></i>',
384 - 'type' => 'list',
385 - 'end_size' => 3,
386 - 'mid_size' => 3,
387 - )
388 - )
389 - );
390 -
391 - return Template::instance()->nest_elements( $html_wrapper, $pagination );
392 - }
393 -
394 - /**
395 - * Convert data to JSON string
396 - *
397 - * @param array|object|mixed $data
398 - *
399 - * @return string
400 - * @since 4.2.9
401 - * @version 1.0.0
402 - */
403 - public static function convert_data_to_json( $data ): string {
404 - return esc_attr(
405 - htmlentities2(
406 - wp_json_encode(
407 - $data,
408 - JSON_HEX_QUOT |
409 - JSON_HEX_TAG |
410 - JSON_HEX_AMP |
411 - JSON_HEX_APOS |
412 - JSON_UNESCAPED_UNICODE |
413 - JSON_UNESCAPED_SLASHES
414 - )
415 - )
416 - );
417 - }
418 -
419 - /**
420 - * Sanitize HTML content by allowing specific tags and attributes.
421 - *
422 - * @param string $content
423 - *
424 - * @return string
425 - * @since 4.2.9
426 - * @version 1.0.0
427 - */
428 - public static function sanitize_html_content( string $content = '' ): string {
429 - $allowed_tags = wp_kses_allowed_html( 'post' );
430 -
431 - $extra_tag = array(
432 - 'iframe' => [
433 - 'src' => true,
434 - 'width' => true,
435 - 'height' => true,
436 - 'frameborder' => true,
437 - 'allowfullscreen' => true,
438 - 'allow' => true,
439 - ],
440 - 'audio' => array(
441 - 'autoplay' => true,
442 - 'controls' => true,
443 - 'loop' => true,
444 - 'muted' => true,
445 - 'preload' => true,
446 - 'src' => true,
447 - 'aria-controls' => true,
448 - 'aria-current' => true,
449 - 'aria-describedby' => true,
450 - 'aria-details' => true,
451 - 'aria-expanded' => true,
452 - 'aria-hidden' => true,
453 - 'aria-label' => true,
454 - 'aria-labelledby' => true,
455 - 'aria-live' => true,
456 - 'class' => true,
457 - 'data-*' => true,
458 - 'dir' => true,
459 - 'hidden' => true,
460 - 'id' => true,
461 - 'lang' => true,
462 - 'style' => true,
463 - 'title' => true,
464 - 'role' => true,
465 - 'xml:lang' => true,
466 - 'controlslist' => true,
467 - 'crossorigin' => true,
468 - 'poster' => true,
469 - ),
470 - 'source' => array(
471 - 'src' => true,
472 - 'type' => true,
473 - 'media' => true,
474 - ),
475 - );
476 -
477 - $allowed_tags = array_merge( $allowed_tags, $extra_tag );
478 -
479 - return wp_kses( $content, $allowed_tags );
480 - }
481 -
482 - /**
483 - * Generate breadcrumb HTML.
484 - *
485 - * @param array $args
486 - *
487 - * @return string
488 - * @since 4.3.2.6
489 - * @version 1.0.0
490 - */
491 - public static function html_breadcrumb( array $args = [] ): string {
492 - $args = wp_parse_args(
493 - $args,
494 - apply_filters(
495 - 'learn_press_breadcrumb_defaults',
496 - array(
497 - 'delimiter' => '<li class="breadcrumb-delimiter"><i class="lp-icon-angle-right"></i></li>',
498 - 'wrap_before' => '<ul class="learn-press-breadcrumb">',
499 - 'wrap_after' => '</ul>',
500 - 'after' => '',
501 - 'home' => _x( 'Home', 'breadcrumb', 'learnpress' ),
502 - )
503 - )
504 - );
505 -
506 - $breadcrumbs = new LP_Breadcrumb();
507 - if ( $args['home'] ) {
508 - $breadcrumbs->add_crumb( $args['home'], apply_filters( 'learn_press_breadcrumb_home_url', home_url() ) );
509 - }
510 -
511 - $args['breadcrumb'] = $breadcrumbs->generate();
512 -
513 - $html_content = '';
514 - foreach ( $args['breadcrumb'] as $key => $crumb ) {
515 - $html_content .= '<li>';
516 - if ( ! empty( $crumb[1] ) ) {
517 - $html_content .= sprintf(
518 - '<a href="%s"><span>%s</span></a>',
519 - esc_url_raw( $crumb[1] ),
520 - esc_html( $crumb[0] )
521 - );
522 - } else {
523 - $html_content .= sprintf(
524 - '<span>%s</span>',
525 - esc_html( $crumb[0] )
526 - );
527 - }
528 -
529 - $html_content .= '</li>';
530 - if ( sizeof( $args['breadcrumb'] ) !== $key + 1 ) {
531 - $html_content .= $args['delimiter'];
532 - }
533 - }
534 -
535 - $section = apply_filters(
536 - 'learn_press/breadcrumb/html-section',
537 - [
538 - 'wrap' => $args['wrap_before'],
539 - 'content' => $html_content,
540 - 'wrap-end' => $args['wrap_after'],
541 - ],
542 - $args
543 - );
544 -
545 - return Template::combine_components( $section );
546 - }
547 -}
1 +<?php
2 +
3 +namespace LearnPress\Helpers;
4 +
5 +use LP_Breadcrumb;
6 +use LP_Debug;
7 +use Throwable;
8 +
9 +/**
10 + * Class Template
11 + *
12 + * @package LearnPress\Helpers
13 + * @since 1.0.0
14 + * @version 1.0.2
15 + */
16 +class Template {
17 + /**
18 + * @var bool
19 + */
20 + protected $include;
21 +
22 + protected function __construct() {
23 + }
24 +
25 + /**
26 + * Set 1 for include file, 0 for not
27 + * Set 1 for separate template is block, 0 for not | use "wp_is_block_theme" function
28 + *
29 + * @param bool $has_include
30 + *
31 + * @return self
32 + */
33 + public static function instance( bool $has_include = true ): Template {
34 + $self = new self();
35 + $self->include = $has_include;
36 +
37 + return $self;
38 + }
39 +
40 + /**
41 + * Get template admin file
42 + *
43 + * @param string $file_name
44 + * @param array $args
45 + *
46 + * @return void|string
47 + * @since 1.0.0
48 + * @version 1.0.0
49 + */
50 + public function get_admin_template( string $file_name = '', array $args = array() ) {
51 + $file_name = str_replace( '.php', '', $file_name );
52 + $path_file = LP_PLUGIN_PATH . "inc/admin/views/{$file_name}.php";
53 +
54 + $template = $this->get_template( $path_file, $args );
55 +
56 + if ( ! $this->include ) {
57 + return $template;
58 + }
59 + }
60 +
61 + /**
62 + * Get template frontend file
63 + *
64 + * @param string $file_name
65 + * @param array $args
66 + *
67 + * @return void|string
68 + * @since 4.2.0
69 + * @version 1.0.0
70 + */
71 + public function get_frontend_template( string $file_name = '', array $args = array() ) {
72 + $default_path = LP_PLUGIN_PATH . "templates/{$file_name}";
73 + $folder_name_rewrite = learn_press_template_path();
74 + $file_name = sanitize_text_field( $file_name );
75 + $from_child_theme_path = sprintf(
76 + '%s/%s/%s',
77 + get_stylesheet_directory(),
78 + $folder_name_rewrite,
79 + $file_name
80 + );
81 + $from_theme_path = sprintf(
82 + '%s/%s/%s',
83 + get_template_directory(),
84 + $folder_name_rewrite,
85 + $file_name
86 + );
87 +
88 + $path_load = $default_path;
89 + if ( file_exists( $from_child_theme_path ) ) {
90 + $path_load = $from_child_theme_path;
91 + } elseif ( file_exists( $from_theme_path ) ) {
92 + $path_load = $from_theme_path;
93 + }
94 +
95 + $template = '';
96 + if ( realpath( $path_load ) ) {
97 + $template = $this->get_template( $path_load, $args );
98 + }
99 +
100 + if ( ! $this->include ) {
101 + return $template;
102 + }
103 + }
104 +
105 + /**
106 + * @param array $file_names
107 + * @param array $args
108 + *
109 + * @return void
110 + */
111 + public function get_frontend_templates( array $file_names = array(), array $args = array() ) {
112 + foreach ( $file_names as $file_name ) {
113 + $search_extension = strrpos( $file_name, '.php' );
114 + if ( ! $search_extension ) {
115 + $file_name .= '.php';
116 + }
117 +
118 + $this->get_frontend_template( $file_name, $args );
119 + }
120 + }
121 +
122 + /**
123 + * Include path file
124 + *
125 + * @param string $path_file
126 + * @param array $args
127 + *
128 + * @return string|void
129 + * @since 1.0.0
130 + * @version 1.0.1
131 + */
132 + public function get_template( string $path_file, array $args = array() ) {
133 + try {
134 + //extract( $args );
135 +
136 + // Remove any '..' from the path to prevent directory traversal attacks
137 + $path_file = preg_replace( '/\.\.+/', '', $path_file );
138 +
139 + if ( file_exists( $path_file ) ) {
140 + if ( $this->include ) {
141 + // Extract args
142 + foreach ( $args as $key => $value ) {
143 + $$key = $value;
144 + }
145 + unset( $key, $value ); // Clean up
146 +
147 + include $path_file;
148 + } else {
149 + return $path_file;
150 + }
151 + } else {
152 + printf( esc_html__( 'Path file %s not exists', 'learnpress' ), $path_file );
153 + echo '<br>';
154 + }
155 + } catch ( Throwable $e ) {
156 + LP_Debug::error_log( $e );
157 + }
158 + }
159 +
160 + /**
161 + * Get frontend template block file
162 + *
163 + * @param string $file_name
164 + * @param array $args
165 + *
166 + * @return string|void
167 + */
168 + public function get_frontend_template_type_block( string $file_name = '', array $args = array() ) {
169 + $file_name = "block/{$file_name}";
170 + $template = $this->get_frontend_template( $file_name, $args );
171 +
172 + if ( ! $this->include ) {
173 + return $template;
174 + }
175 + }
176 +
177 + /**
178 + * Check file template is overwritten
179 + *
180 + * @param string $file_name
181 + *
182 + * @return bool|string return false if not, path file if yes
183 + * @since 4.2.6
184 + * @version 1.0.0
185 + */
186 + public static function check_template_is_override( string $file_name = '' ) {
187 + $default_path = LP_PLUGIN_PATH . "templates/{$file_name}";
188 + $folder_name_rewrite = learn_press_template_path();
189 + $from_child_theme_path = sprintf(
190 + '%s/%s/%s',
191 + get_stylesheet_directory(),
192 + $folder_name_rewrite,
193 + $file_name
194 + );
195 + $from_theme_path = sprintf(
196 + '%s/%s/%s',
197 + get_template_directory(),
198 + $folder_name_rewrite,
199 + $file_name
200 + );
201 +
202 + if ( file_exists( $from_child_theme_path ) ) {
203 + return $from_child_theme_path;
204 + } elseif ( file_exists( $from_theme_path ) ) {
205 + return $from_theme_path;
206 + }
207 +
208 + return false;
209 + }
210 +
211 + /**
212 + * Nest elements by tags
213 + *
214 + * @param array $els [ 'html_tag_open' => 'html_tag_close' ]
215 + * @param string $main_content
216 + *
217 + * @return string
218 + */
219 + public function nest_elements( array $els = [], string $main_content = '' ): string {
220 + $html = '';
221 + foreach ( $els as $tag_open => $tag_close ) {
222 + $html .= $tag_open;
223 + }
224 +
225 + $html .= $main_content;
226 +
227 + foreach ( array_reverse( $els, true ) as $tag_close ) {
228 + $html .= $tag_close;
229 + }
230 +
231 + return $html;
232 + }
233 +
234 + /**
235 + * Display sections
236 + *
237 + * @param array $sections
238 + * ['name_section' => [ 'text_html' => '<span>example</span>' ]]
239 + * ['name_section' => [ 'link_templates' => 'path_template' ]]
240 + *
241 + * @return void
242 + */
243 + public function print_sections( array $sections = [], array $args = [] ) {
244 + foreach ( $sections as $section ) {
245 + if ( ! is_array( $section ) ) {
246 + continue;
247 + }
248 +
249 + foreach ( $section as $type => $val ) {
250 + switch ( $type ) {
251 + case 'link_templates':
252 + $this->get_frontend_template( $val, $args );
253 + break;
254 + default:
255 + if ( is_string( $val ) ) {
256 + //$allow_tag = wp_kses_allowed_html( 'post' );
257 + //echo wp_kses( $section, $allow_tag );
258 + echo $val;
259 + }
260 + break;
261 + }
262 + }
263 + }
264 + }
265 +
266 + /**
267 + * Combine html elements
268 + *
269 + * @param array $elms
270 + *
271 + * @return string
272 + * @since 4.2.6.9
273 + */
274 + public static function combine_components( array $elms = [] ): string {
275 + $html = '';
276 + foreach ( $elms as $tag => $val ) {
277 + $html .= $val;
278 + }
279 +
280 + return $html;
281 + }
282 +
283 + /**
284 + * Insert new key to a position of array
285 + *
286 + * @param array $old_array
287 + * @param string $position after/before
288 + * @param string $key_compare key to compare
289 + * @param string $key_add
290 + * @param string $value
291 + *
292 + * @return array
293 + * @since 4.2.7.2
294 + * @version 1.0.1
295 + */
296 + public static function insert_value_to_position_array(
297 + array $old_array,
298 + string $position,
299 + string $key_compare,
300 + string $key_add,
301 + string $value
302 + ): array {
303 + $new_array = [];
304 +
305 + foreach ( $old_array as $k => $v ) {
306 + if ( $position === 'after' ) {
307 + $new_array[ $k ] = $v;
308 + }
309 + if ( $key_compare === $k ) {
310 + $new_array[ $key_add ] = $value;
311 + }
312 + if ( $position === 'before' ) {
313 + $new_array[ $k ] = $v;
314 + }
315 + }
316 +
317 + return $new_array;
318 + }
319 +
320 + /**
321 + * Print message
322 + *
323 + * @param string $message
324 + * @param string $status 'success', 'warning', 'error, 'info'
325 + * @param bool $has_print since 4.2.7.6, true for print, false for return
326 + *
327 + * @return void|string
328 + * @since 4.2.6.9.3
329 + * @version 1.0.2
330 + */
331 + public static function print_message( string $message, string $status = 'success', bool $has_print = true ) {
332 + if ( empty( $message ) ) {
333 + if ( $has_print ) {
334 + return;
335 + } else {
336 + return '';
337 + }
338 + }
339 +
340 + $section = [
341 + 'wrapper' => sprintf( '<div class="learn-press-message %s">', esc_attr( $status ) ),
342 + 'content' => wp_kses_post( $message ),
343 + 'wrapper_end' => '</div>',
344 + ];
345 +
346 + if ( $has_print ) {
347 + echo Template::combine_components( $section );
348 + } else {
349 + return Template::combine_components( $section );
350 + }
351 + }
352 +
353 + /**
354 + * Generate HTML for pagination.
355 + *
356 + * @param array $data [ 'total_pages' => int, 'paged' => int, 'base' => string ]
357 + *
358 + * @return string HTML for pagination.
359 + * @since 4.2.8.7.4
360 + * @version 1.0.1
361 + */
362 + public function html_pagination( array $data = [] ): string {
363 + $total_pages = $data['total_pages'] ?? 0;
364 + $paged = $data['paged'] ?? 1;
365 + if ( $total_pages <= 1 ) {
366 + return '';
367 + }
368 +
369 + $html_wrapper = $data['wrapper'] ?? [
370 + '<nav class="learn-press-pagination navigation pagination">' => '</nav>',
371 + ];
372 +
373 + $pagination = paginate_links(
374 + apply_filters(
375 + 'learn_press_pagination_args',
376 + array(
377 + 'base' => $data['base'] ?? add_query_arg( 'paged', '%#%', '' ),
378 + 'format' => $data['format'] ?? '?paged=%#%',
379 + 'add_args' => $data['add_args'] ?? '',
380 + 'current' => max( 1, $paged ),
381 + 'total' => $total_pages,
382 + 'prev_text' => '<i class="lp-icon-arrow-left"></i>',
383 + 'next_text' => '<i class="lp-icon-arrow-right"></i>',
384 + 'type' => 'list',
385 + 'end_size' => 3,
386 + 'mid_size' => 3,
387 + )
388 + )
389 + );
390 +
391 + return Template::instance()->nest_elements( $html_wrapper, $pagination );
392 + }
393 +
394 + /**
395 + * Convert data to JSON string
396 + *
397 + * @param array|object|mixed $data
398 + *
399 + * @return string
400 + * @since 4.2.9
401 + * @version 1.0.0
402 + */
403 + public static function convert_data_to_json( $data ): string {
404 + return esc_attr(
405 + htmlentities2(
406 + wp_json_encode(
407 + $data,
408 + JSON_HEX_QUOT |
409 + JSON_HEX_TAG |
410 + JSON_HEX_AMP |
411 + JSON_HEX_APOS |
412 + JSON_UNESCAPED_UNICODE |
413 + JSON_UNESCAPED_SLASHES
414 + )
415 + )
416 + );
417 + }
418 +
419 + /**
420 + * Sanitize HTML content by allowing specific tags and attributes.
421 + *
422 + * @param string $content
423 + *
424 + * @return string
425 + * @since 4.2.9
426 + * @version 1.0.0
427 + */
428 + public static function sanitize_html_content( string $content = '' ): string {
429 + $allowed_tags = wp_kses_allowed_html( 'post' );
430 +
431 + $extra_tag = array(
432 + 'iframe' => [
433 + 'src' => true,
434 + 'width' => true,
435 + 'height' => true,
436 + 'frameborder' => true,
437 + 'allowfullscreen' => true,
438 + 'allow' => true,
439 + ],
440 + 'audio' => array(
441 + 'autoplay' => true,
442 + 'controls' => true,
443 + 'loop' => true,
444 + 'muted' => true,
445 + 'preload' => true,
446 + 'src' => true,
447 + 'aria-controls' => true,
448 + 'aria-current' => true,
449 + 'aria-describedby' => true,
450 + 'aria-details' => true,
451 + 'aria-expanded' => true,
452 + 'aria-hidden' => true,
453 + 'aria-label' => true,
454 + 'aria-labelledby' => true,
455 + 'aria-live' => true,
456 + 'class' => true,
457 + 'data-*' => true,
458 + 'dir' => true,
459 + 'hidden' => true,
460 + 'id' => true,
461 + 'lang' => true,
462 + 'style' => true,
463 + 'title' => true,
464 + 'role' => true,
465 + 'xml:lang' => true,
466 + 'controlslist' => true,
467 + 'crossorigin' => true,
468 + 'poster' => true,
469 + ),
470 + 'source' => array(
471 + 'src' => true,
472 + 'type' => true,
473 + 'media' => true,
474 + ),
475 + );
476 +
477 + $allowed_tags = array_merge( $allowed_tags, $extra_tag );
478 +
479 + return wp_kses( $content, $allowed_tags );
480 + }
481 +
482 + /**
483 + * Generate breadcrumb HTML.
484 + *
485 + * @param array $args
486 + *
487 + * @return string
488 + * @since 4.3.2.6
489 + * @version 1.0.0
490 + */
491 + public static function html_breadcrumb( array $args = [] ): string {
492 + $args = wp_parse_args(
493 + $args,
494 + apply_filters(
495 + 'learn_press_breadcrumb_defaults',
496 + array(
497 + 'delimiter' => '<li class="breadcrumb-delimiter"><i class="lp-icon-angle-right"></i></li>',
498 + 'wrap_before' => '<ul class="learn-press-breadcrumb">',
499 + 'wrap_after' => '</ul>',
500 + 'after' => '',
501 + 'home' => _x( 'Home', 'breadcrumb', 'learnpress' ),
502 + )
503 + )
504 + );
505 +
506 + $breadcrumbs = new LP_Breadcrumb();
507 + if ( $args['home'] ) {
508 + $breadcrumbs->add_crumb( $args['home'], apply_filters( 'learn_press_breadcrumb_home_url', home_url() ) );
509 + }
510 +
511 + $args['breadcrumb'] = $breadcrumbs->generate();
512 +
513 + $html_content = '';
514 + foreach ( $args['breadcrumb'] as $key => $crumb ) {
515 + $html_content .= '<li>';
516 + if ( ! empty( $crumb[1] ) ) {
517 + $html_content .= sprintf(
518 + '<a href="%s"><span>%s</span></a>',
519 + esc_url_raw( $crumb[1] ),
520 + esc_html( $crumb[0] )
521 + );
522 + } else {
523 + $html_content .= sprintf(
524 + '<span>%s</span>',
525 + esc_html( $crumb[0] )
526 + );
527 + }
528 +
529 + $html_content .= '</li>';
530 + if ( sizeof( $args['breadcrumb'] ) !== $key + 1 ) {
531 + $html_content .= $args['delimiter'];
532 + }
533 + }
534 +
535 + $section = apply_filters(
536 + 'learn_press/breadcrumb/html-section',
537 + [
538 + 'wrap' => $args['wrap_before'],
539 + 'content' => $html_content,
540 + 'wrap-end' => $args['wrap_after'],
541 + ],
542 + $args
543 + );
544 +
545 + return Template::combine_components( $section );
546 + }
547 +}