PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.9
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 / TemplateHooks / CourseBuilder / CourseBuilderTemplate.php

CourseBuilderTemplate.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.9, at inc/TemplateHooks/CourseBuilder/CourseBuilderTemplate.php

772 lines 22.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Template hooks Course Builder.
4 *
5 * @since 4.3.x
6 * @version 1.0.0
7 */
8
9 namespace LearnPress\TemplateHooks\CourseBuilder;
10
11 use Exception;
12 use LearnPress\CourseBuilder\CourseBuilder;
13 use LearnPress\Helpers\Singleton;
14 use LearnPress\Helpers\Template;
15 use LearnPress\Models\UserModel;
16 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
17 use LearnPress\TemplateHooks\TemplateAJAX;
18 use LP_Profile;
19 use LP_Settings;
20 use LP_WP_Filesystem;
21 use Throwable;
22 use WP_User;
23
24 class CourseBuilderTemplate {
25 use Singleton;
26
27 const MENU_COURSES = 'courses';
28 const MENU_LESSONS = 'lessons';
29 const MENU_QUIZZES = 'quizzes';
30 const MENU_QUESTIONS = 'questions';
31 const MENU_SETTINGS = 'settings';
32
33 public function init() {
34 //add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
35 add_action( 'learn-press/course-builder/layout', [ $this, 'layout' ] );
36 // Show link to Course Builder in admin bar
37 add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 80 );
38 // Hide admin bar for instructor (not admin)
39 add_filter( 'show_admin_bar', [ $this, 'hide_admin_bar_for_instructor' ] );
40 // Dequeue theme styles on Course Builder page (must run during wp_head, not after)
41 //add_action( 'wp_enqueue_scripts', [ $this, 'dequeue_theme_styles' ], 9999 );
42 }
43
44 /**
45 * Hide admin bar for instructor users (not administrators).
46 *
47 * @param bool $show_admin_bar
48 *
49 * @return bool
50 * @since 4.3.0
51 */
52 public function hide_admin_bar_for_instructor( bool $show_admin_bar ): bool {
53 // Check enable hide admin bar for instructor
54 if ( ! LP_Settings::get_option( 'hide_admin_bar_for_instructor', 'no' ) ) {
55 return $show_admin_bar;
56 }
57
58 return $show_admin_bar;
59 }
60
61 /**
62 * Allow callback for AJAX.
63 * @use self::render_html_comments
64 *
65 * @param array $callbacks
66 *
67 * @return array
68 */
69 /*public function allow_callback( array $callbacks ): array {
70 $callbacks[] = get_class( $this ) . ':sidebar';
71
72 return $callbacks;
73 }*/
74
75 /**
76 * Layout for Course Builder.
77 *
78 * @since 4.3.6
79 * @version 1.0.0
80 */
81 public function layout() {
82 try {
83 // Enqueue assets(js,css) for Course Builder
84 //$this->enqueue_assets();
85
86 // Check permission
87 $user_id = get_current_user_id();
88 $userModel = UserModel::find( $user_id, true );
89 if ( ! $userModel || ! $userModel->is_instructor() ) {
90 throw new Exception( __( "Sorry, you don't have permission to access Course Builder", 'learnpress' ) );
91 }
92
93 $data = [
94 'userModel' => $userModel,
95 ];
96
97 $layout = [
98 'wrapper' => '<div class="learn-press-course-builder">',
99 'header' => $this->html_header( $data ),
100 'body' => '<div class="lp-cb-body">',
101 'sidebar' => $this->html_sidebar( $data ),
102 'content' => $this->html_content( $data ),
103 'body_end' => '</div>',
104 'wrapper_end' => '</div>',
105 ];
106
107 echo Template::combine_components( $layout );
108 } catch ( Throwable $e ) {
109 Template::print_message(
110 wp_kses_post( $e->getMessage() ),
111 'error'
112 );
113 }
114 }
115
116 /**
117 * Enqueue scripts, styles and localize data for Course Builder.
118 *
119 * @since 4.3.x
120 * @version 1.0.0
121 */
122 protected function enqueue_assets() {}
123
124 /**
125 * Auto-detect and dequeue all theme/child-theme stylesheets.
126 * Prevents theme CSS from interfering with Course Builder styles.
127 *
128 * Hooked to `wp_enqueue_scripts` at priority 9999 so it runs DURING wp_head(),
129 * after themes have enqueued their styles but before they are printed.
130 *
131 * Only removes styles whose source URL is within the theme or child-theme directory.
132 * WP core styles, plugin styles, and other assets remain untouched.
133 *
134 * @since 4.3.0
135 * @version 1.0.0
136 */
137 /*public function dequeue_theme_styles() {
138 global $wp_styles, $wp_scripts;
139
140 if ( ! LP_Page_Controller::is_page_course_builder() ) {
141 return;
142 }
143
144 $allowed_styles = apply_filters(
145 'learn-press/course-builder/allowed-styles',
146 [
147 'dashicons',
148 'admin-bar',
149 'buttons',
150 'media-views',
151 'wp-components',
152 'wp-block-library',
153 'wp-editor',
154 'wp-edit-post',
155 'wp-block-editor',
156 'wp-components',
157 'wp-editor',
158 'wp-nux',
159 'wp-notices',
160 ]
161 );
162
163 $allowed_scripts = apply_filters(
164 'learn-press/course-builder/allowed-scripts',
165 [
166 'jquery',
167 'jquery-core',
168 'jquery-migrate',
169 'jquery-ui-core',
170 'jquery-ui-widget',
171 'wp-api-fetch',
172 'wp-i18n',
173 'wp-components',
174 'wp-element',
175 'react',
176 'react-dom',
177 'wp-polyfill',
178 'wp-hooks',
179 'lodash',
180 'moment',
181 'heartbeat',
182 'wp-data',
183 'wp-core-data',
184 'wp-url',
185 'wp-api',
186 'wp-block-editor',
187 'wp-blocks',
188 'wp-media-utils',
189 'wp-compose',
190 'regenerator-runtime',
191 'wp-a11y',
192 ]
193 );
194
195 if ( ! empty( $wp_styles->queue ) ) {
196 foreach ( $wp_styles->queue as $handle ) {
197 if ( ! in_array( $handle, $allowed_styles ) && strpos( $handle, 'lp-' ) !== 0 && strpos( $handle, 'learn-press' ) !== 0 && strpos( $handle, 'learnpress' ) !== 0 ) {
198 wp_dequeue_style( $handle );
199 }
200 }
201 }
202
203 if ( ! empty( $wp_scripts->queue ) ) {
204 foreach ( $wp_scripts->queue as $handle ) {
205 if ( ! in_array( $handle, $allowed_scripts ) && strpos( $handle, 'lp-' ) !== 0 && strpos( $handle, 'learn-press' ) !== 0 && strpos( $handle, 'learnpress' ) !== 0 ) {
206 wp_dequeue_script( $handle );
207 }
208 }
209 }
210 }*/
211
212 /**
213 * Header with logo and user profile
214 *
215 * @param array $data
216 *
217 * @return string
218 * @throws Exception
219 * @version 1.0.0
220 * @since 4.3.6
221 */
222 protected function html_header( array $data = [] ): string {
223 /** @var UserModel $userModel */
224 $userModel = $data['userModel'] ?? false;
225 if ( ! $userModel ) {
226 return '';
227 }
228
229 $avatar = $userModel->get_avatar_url();
230 $display_name = $userModel->get_display_name();
231 $profile = LP_Profile::instance( $userModel->get_id() );
232 $profile_url = $profile->get_tab_link();
233 $logout_url = wp_logout_url( home_url() );
234 $logo_id = absint( LP_Settings::get_option( 'course_builder_logo_id', 0 ) );
235
236 if ( $logo_id ) {
237 $custom_logo = wp_get_attachment_image(
238 $logo_id,
239 'full',
240 false,
241 [
242 'class' => 'lp-cb-top-header__logo-image',
243 'alt' => __( 'Course Builder', 'learnpress' ),
244 'loading' => 'eager',
245 'decoding' => 'async',
246 ]
247 );
248 }
249
250 $header = [
251 'wrapper' => '<header class="lp-cb-top-header">',
252 'logo' => sprintf(
253 '<div class="lp-cb-top-header__logo">
254 <a href="%s">%s</a>
255 </div>',
256 esc_url( CourseBuilder::get_link_course_builder() ),
257 $custom_logo ?? LP_WP_Filesystem::get_icon_svg( 'ico-logo-course-builder.svg' ),
258 ),
259 'user' => sprintf(
260 '<div class="lp-cb-top-header__user">
261 <div class="lp-cb-top-header__user-avatar">
262 <img src="%s" class="lp-cb-top-header__user-avatar-image">
263 <span class="lp-cb-top-header__online-dot"></span>
264 </div>
265 <div class="lp-cb-top-header__user-info">
266 <span class="lp-cb-top-header__user-name">%s</span>
267 <a href="%s" class="lp-cb-top-header__user-link" target="_blank">%s</a>
268 </div>
269 <a href="%s" class="lp-cb-top-header__logout" title="%s">
270 %s
271 </a>
272 </div>',
273 $avatar,
274 esc_html( $display_name ),
275 esc_url( $profile_url ),
276 __( 'View Profile', 'learnpress' ),
277 esc_url( $logout_url ),
278 __( 'Logout', 'learnpress' ),
279 LP_WP_Filesystem::get_icon_svg( 'ico-logout.svg' ),
280 ),
281 'wrapper_end' => '</header>',
282 ];
283
284 return Template::combine_components( $header );
285 }
286
287 /**
288 * HTML Sidebar
289 *
290 * @param array $data
291 *
292 * @return string
293 */
294 public function html_sidebar( array $data = [] ): string {
295 $userModel = $data['userModel'] ?? false;
296 if ( ! $userModel ) {
297 return '';
298 }
299
300 $tabs = CourseBuilder::get_menus_arr();
301 $nav_content = '';
302 $is_admin = current_user_can( ADMIN_ROLE );
303
304 $tabs = array_filter(
305 $tabs,
306 static function ( array $tab ) use ( $is_admin ): bool {
307 if ( ! empty( $tab['admin_only'] ) && ! $is_admin ) {
308 return false;
309 }
310
311 return true;
312 }
313 );
314
315 usort(
316 $tabs,
317 static function ( array $a, array $b ): int {
318 $a_priority = isset( $a['priority'] ) && is_numeric( $a['priority'] ) ? (int) $a['priority'] : PHP_INT_MAX;
319 $b_priority = isset( $b['priority'] ) && is_numeric( $b['priority'] ) ? (int) $b['priority'] : PHP_INT_MAX;
320
321 return $a_priority <=> $b_priority;
322 }
323 );
324
325 foreach ( $tabs as $tab ) {
326 $slug = $tab['slug'];
327 $nav_item = $this->html_nav_item_main( $slug, $tab );
328 $nav_content .= $nav_item;
329 }
330
331 $nav = [
332 'wrapper' => '<ul class="lp-cb-sidebar__nav">',
333 'content' => $nav_content,
334 'wrapper_end' => '</ul>',
335 ];
336
337 $sidebar_toggle_icon = LP_WP_Filesystem::get_icon_svg( 'ico-cb-sidebar-toggle.svg' );
338 $toggle = sprintf(
339 '<button type="button" class="lp-cb-sidebar__toggle" aria-label="%s" title="%s">
340 %s
341 </button>',
342 esc_attr__( 'Toggle Sidebar', 'learnpress' ),
343 esc_attr__( 'Toggle Sidebar', 'learnpress' ),
344 $sidebar_toggle_icon
345 );
346
347 $sidebar = [
348 'wrapper' => '<aside id="lp-course-builder-sidebar" class="lp-cb-sidebar">',
349 'nav' => Template::combine_components( $nav ),
350 'toggle' => $toggle,
351 'footer' => $this->sidebar_footer( $data ),
352 'wrapper_end' => '</aside>',
353 ];
354
355 return Template::combine_components( $sidebar );
356 }
357
358 /**
359 * HTML main content area
360 *
361 * @param array $data
362 *
363 * @return string
364 * @throws Exception
365 * @version 1.0.1
366 * @since 4.3.6
367 */
368 public function html_content( array $data = [] ): string {
369 $userModel = $data['userModel'] ?? false;
370 if ( ! $userModel ) {
371 return '';
372 }
373
374 $menu_current = CourseBuilder::get_menu_current();
375
376 //Switch layout display by menu, via model, @since 4.3.7
377 switch ( $menu_current ) {
378 case self::MENU_COURSES:
379 $content = BuilderCourseTemplate::instance()->layout( $data );
380 break;
381 default:
382 if ( has_action( "learn-press/course-builder/{$menu_current}/layout" ) ) {
383 // Hook old @since 4.3.6.
384 ob_start();
385 do_action( "learn-press/course-builder/{$menu_current}/layout", $data );
386 $content = ob_get_clean();
387 } else {
388 // Hook new @since 4.3.7.
389 $content = apply_filters( 'learn-press/course-builder/content/layout', '', $menu_current, $data );
390 }
391 break;
392 }
393
394 $output = [
395 'wrapper' => '<div id="lp-course-builder-content" class="lp-cb-main">',
396 'content' => $content,
397 'wrapper_end' => '</div>',
398 ];
399
400 return Template::combine_components( $output );
401 }
402
403 /**
404 * Sidebar footer with "Back to Dashboard" link
405 *
406 * @param array $data
407 *
408 * @return string
409 * @since 4.3.0
410 */
411 protected function sidebar_footer( array $data = [] ): string {
412 $userModel = $data['userModel'] ?? false;
413 if ( ! $userModel instanceof UserModel ) {
414 return '';
415 }
416
417 $hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
418 $wp_user = new WP_User( $userModel );
419 $is_instructor = user_can( $wp_user, UserModel::ROLE_INSTRUCTOR );
420 $dashboard_url = admin_url();
421
422 $footer = [
423 'wrapper' => '<div class="lp-cb-sidebar__footer">',
424 ];
425
426 // Hide "Back to WordPress" for instructors when CB admin mode is on
427 // Admins always see this link
428 $hide_back_link = $hide_instructor_access_admin_screen && $is_instructor;
429
430 if ( ! $hide_back_link ) {
431 $back_to_wp_text = __( 'Back to WordPress', 'learnpress' );
432
433 $footer['back'] = sprintf(
434 '<a href="%s" class="lp-cb-sidebar__item lp-cb-sidebar__back" title="%s" aria-label="%s">
435 <span class="dashicons dashicons-wordpress"></span>
436 <span class="lp-cb-sidebar__item-title">%s</span>
437 </a>',
438 esc_url( $dashboard_url ),
439 esc_attr( $back_to_wp_text ),
440 esc_attr( $back_to_wp_text ),
441 esc_html( $back_to_wp_text )
442 );
443 }
444
445 $footer['wrapper_end'] = '</div>';
446
447 return Template::combine_components( $footer );
448 }
449
450 /**
451 * Render main navigation item (persistent sidebar)
452 *
453 * @param string $slug
454 * @param array $tab_data
455 *
456 * @return string
457 * @since 4..0
458 */
459 protected function html_nav_item_main( $slug, $tab_data ) {
460 $tab_current = CourseBuilder::get_menu_current();
461 $sub_menu_items = $this->get_nav_item_sub_menu_items( $slug, $tab_data );
462 $has_sub_menu = ! empty( $sub_menu_items );
463 $has_active_submenu = $has_sub_menu && ! empty(
464 array_filter(
465 $sub_menu_items,
466 static function ( array $item ): bool {
467 return ! empty( $item['is_active'] );
468 }
469 )
470 );
471 $is_active = $slug === $tab_current || ! empty( $has_active_submenu );
472 $classes = [ 'lp-cb-sidebar__item', $slug ];
473
474 if ( $has_sub_menu ) {
475 $classes[] = 'has-sub-menu';
476 }
477
478 if ( $is_active ) {
479 $classes[] = 'is-active';
480 }
481
482 if ( $has_sub_menu && $is_active ) {
483 $classes[] = 'is-expanded';
484 }
485
486 $icon = isset( $tab_data['icon'] ) ? $tab_data['icon'] : '';
487 $title = $tab_data['title'];
488 $link = CourseBuilder::get_tab_link( $slug );
489 $sub_menu_id = 'lp-cb-sidebar-sub-menu-' . sanitize_html_class( $slug );
490 $aria_current = $is_active && empty( $has_active_submenu ) ? ' aria-current="page"' : '';
491
492 if ( $has_sub_menu ) {
493 $content = sprintf(
494 '<div class="lp-cb-sidebar__item-control">
495 <a href="%1$s" class="lp-cb-sidebar__item-link" title="%2$s" aria-label="%2$s"%3$s>
496 %4$s
497 <span class="lp-cb-sidebar__item-title">%5$s</span>
498 </a>
499 <button type="button" class="lp-cb-sidebar__sub-menu-toggle" aria-label="%6$s" aria-expanded="%7$s" aria-controls="%8$s">
500 <span class="dashicons dashicons-arrow-down-alt2" aria-hidden="true"></span>
501 </button>
502 </div>',
503 esc_url( $link ),
504 esc_attr( $title ),
505 $aria_current,
506 $icon,
507 esc_html( $title ),
508 esc_attr( sprintf( __( 'Toggle %s submenu', 'learnpress' ), $title ) ),
509 $is_active ? 'true' : 'false',
510 esc_attr( $sub_menu_id )
511 );
512 } else {
513 $content = sprintf(
514 '<a href="%1$s" class="lp-cb-sidebar__item-link" title="%2$s" aria-label="%2$s"%3$s>
515 %4$s
516 <span class="lp-cb-sidebar__item-title">%5$s</span>
517 </a>',
518 esc_url( $link ),
519 esc_attr( $title ),
520 $aria_current,
521 $icon,
522 esc_html( $title )
523 );
524 }
525
526 $item = [
527 'wrapper' => sprintf( '<li class="%s">', implode( ' ', $classes ) ),
528 'content' => $content,
529 'wrapper_end' => '</li>',
530 ];
531
532 if ( $has_sub_menu ) {
533 $item['content'] .= $this->html_nav_item_sub_menu( $sub_menu_items, $sub_menu_id, $title );
534 }
535
536 return Template::combine_components( $item );
537 }
538
539 protected function get_nav_item_sub_menu_items( string $parent_slug, array $tab_data ): array {
540 $items = [];
541 if ( ! empty( $tab_data['sub_menu'] ) && is_array( $tab_data['sub_menu'] ) ) {
542 $items = $this->normalize_nav_sub_menu_items( $parent_slug, $tab_data['sub_menu'] );
543 }
544
545 return $items;
546 }
547
548 protected function normalize_nav_sub_menu_items( string $parent_slug, array $sub_menu ): array {
549 $is_admin = current_user_can( ADMIN_ROLE );
550 $items = [];
551
552 foreach ( $sub_menu as $key => $item ) {
553 if ( ! is_array( $item ) || ( ! empty( $item['admin_only'] ) && ! $is_admin ) ) {
554 continue;
555 }
556
557 $title = $item['title'] ?? '';
558 if ( '' === $title ) {
559 continue;
560 }
561
562 $slug = ! empty( $item['slug'] ) ? (string) $item['slug'] : ( is_string( $key ) ? $key : sanitize_title( $title ) );
563 if ( '' === $slug ) {
564 continue;
565 }
566
567 $url = $item['url'] ?? '';
568 if ( '' === $url ) {
569 $url = CourseBuilder::get_tab_link( $parent_slug, $slug );
570 }
571
572 if ( '' === $url ) {
573 continue;
574 }
575
576 $is_active = false;
577 if ( $parent_slug === CourseBuilder::get_menu_current() ) {
578 $is_active = $slug === (string) CourseBuilder::get_item_id();
579 }
580
581 $items[] = [
582 'class' => is_string( $key ) ? $key : sanitize_title( $title ),
583 'icon' => $item['icon'] ?? '',
584 'is_active' => $is_active,
585 'rel' => ! empty( $item['target'] ) && '_blank' === $item['target'] ? 'noopener noreferrer' : '',
586 'slug' => $slug,
587 'target' => $item['target'] ?? '',
588 'title' => $title,
589 'url' => $url,
590 ];
591 }
592
593 return $items;
594 }
595
596 protected function html_nav_item_sub_menu( array $sub_menu_items, string $sub_menu_id, string $parent_title = '' ): string {
597 if ( empty( $sub_menu_items ) ) {
598 return '';
599 }
600
601 $content = '';
602
603 foreach ( $sub_menu_items as $item ) {
604 $target = '' !== $item['target'] ? sprintf( ' target="%s"', esc_attr( $item['target'] ) ) : '';
605 $rel = '' !== $item['rel'] ? sprintf( ' rel="%s"', esc_attr( $item['rel'] ) ) : '';
606 $active_class = ! empty( $item['is_active'] ) ? ' is-active' : '';
607 $aria_current = ! empty( $item['is_active'] ) ? ' aria-current="page"' : '';
608
609 $content .= sprintf(
610 '<li class="lp-cb-sidebar__sub-menu-item %1$s%2$s"><a href="%3$s" class="lp-cb-sidebar__sub-menu-link"%4$s%5$s%6$s>%7$s<span class="lp-cb-sidebar__sub-menu-title">%8$s</span></a></li>',
611 esc_attr( sanitize_html_class( $item['class'] ) ),
612 esc_attr( $active_class ),
613 esc_url( $item['url'] ),
614 $target,
615 $rel,
616 $aria_current,
617 $item['icon'],
618 esc_html( $item['title'] )
619 );
620 }
621
622 if ( '' === $content ) {
623 return '';
624 }
625
626 return sprintf(
627 '<ul id="%1$s" class="lp-cb-sidebar__sub-menu" aria-label="%2$s">%3$s</ul>',
628 esc_attr( $sub_menu_id ),
629 esc_attr( sprintf( __( '%s submenu', 'learnpress' ), $parent_title ) ),
630 $content
631 );
632 }
633
634 public function html_btn_add_new() {
635 $tab_current = CourseBuilder::get_menu_current();
636 $map_title = [
637 'courses' => __( 'Course', 'learnpress' ),
638 'lessons' => __( 'Lesson', 'learnpress' ),
639 'quizzes' => __( 'Quiz', 'learnpress' ),
640 'questions' => __( 'Question', 'learnpress' ),
641 ];
642
643 $map_type = [
644 'lessons' => 'lesson',
645 'quizzes' => 'quiz',
646 'questions' => 'question',
647 ];
648
649 $title = isset( $map_title[ $tab_current ] ) ? $map_title[ $tab_current ] : '';
650 $type = isset( $map_type[ $tab_current ] ) ? $map_type[ $tab_current ] : '';
651 $add_new = 'data-add-new-' . esc_attr( $type );
652 $template_html = '';
653 $template_attr = '';
654
655 $btn_add_new = sprintf( '<button %s class="lp-button cb-btn-add-new">', $add_new );
656 $btn_close = '</button>';
657
658 if ( 'lessons' === $tab_current ) {
659 $template_id = 'lp-tmpl-builder-popup-lesson-tab-new';
660 $template_attr = sprintf(
661 ' data-template="#%1$s" data-popup-type="lesson" data-popup-id="0"',
662 esc_attr( $template_id )
663 );
664 $template_html = sprintf(
665 '<script type="text/template" id="%1$s"><div class="lp-builder-popup-overlay"></div><div class="lp-builder-popup lp-builder-popup--loading">%2$s</div></script>',
666 esc_attr( $template_id ),
667 TemplateAJAX::load_content_via_ajax(
668 [
669 'id_url' => 'builder-popup-lesson-tab-new',
670 'lesson_id' => 0,
671 'html_no_load_ajax_first' => sprintf(
672 '<div class="lp-builder-popup__loader"><div class="lp-loading-circle"></div><span>%s</span></div>',
673 esc_html__( 'Loading...', 'learnpress' )
674 ),
675 ],
676 [
677 'class' => BuilderPopupTemplate::class,
678 'method' => 'render_lesson_popup',
679 ]
680 )
681 );
682 }
683
684 if ( 'courses' === $tab_current ) {
685 $btn_add_new = sprintf(
686 '<a href="%s" class="lp-button cb-btn-add-new">',
687 esc_url( CourseBuilder::get_link_add_new( 'courses' ) )
688 );
689 $btn_close = '</a>';
690 }
691
692 if ( 'quizzes' === $tab_current ) {
693 $btn_add_new = sprintf(
694 '<a href="%s" class="lp-button cb-btn-add-new">',
695 esc_url( CourseBuilder::get_link_add_new( 'quizzes' ) )
696 );
697 $btn_close = '</a>';
698 }
699
700 if ( 'questions' === $tab_current ) {
701 $btn_add_new = sprintf(
702 '<a href="%s" class="lp-button cb-btn-add-new">',
703 esc_url( CourseBuilder::get_link_add_new( 'questions' ) )
704 );
705 $btn_close = '</a>';
706 }
707
708 $btn = [
709 'wrapper' => str_replace( '>', $template_attr . '>', $btn_add_new ),
710 'content' => sprintf( '%s %s', __( 'Add New', 'learnpress' ), $title ),
711 'wrapper_end' => $btn_close,
712 'template' => $template_html,
713 ];
714 $btn = apply_filters( 'learn-press/course-builder/button-add-new', $btn, $tab_current, $type );
715
716 return Template::combine_components( $btn );
717 }
718
719 /**
720 * Show link to Course Builder in admin bar
721 */
722 public function add_admin_bar_menu( $wp_admin_bar ) {
723 $href = CourseBuilder::get_link_course_builder();
724 $title = esc_html__( 'Course Builder', 'learnpress' );
725
726 // Check if on frontend single course page
727 if ( is_singular( LP_COURSE_CPT ) && get_the_ID() ) {
728 $title = esc_html__( 'Edit with Course Builder', 'learnpress' );
729 $href = BuilderCourseTemplate::instance()->get_link_edit( get_the_ID() );
730 }
731
732 // Check if on admin edit course page (post.php or post-new.php)
733 if ( is_admin() ) {
734 global $post, $pagenow;
735 if ( in_array( $pagenow, array( 'post.php', 'post-new.php' ), true ) ) {
736 $post_type = '';
737 if ( isset( $_GET['post_type'] ) ) {
738 $post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) );
739 } elseif ( isset( $_GET['post'] ) ) {
740 $post_id = absint( $_GET['post'] );
741 $post_type = get_post_type( $post_id );
742 } elseif ( $post && isset( $post->post_type ) ) {
743 $post_type = $post->post_type;
744 }
745
746 if ( LP_COURSE_CPT === $post_type ) {
747 $title = esc_html__( 'Edit with Course Builder', 'learnpress' );
748 if ( isset( $_GET['post'] ) ) {
749 $href = BuilderCourseTemplate::instance()->get_link_edit( $_GET['post'] );
750 } else {
751 $href = CourseBuilder::get_link_add_new( 'courses' );
752 }
753 }
754 }
755 }
756
757 $admin_bar_icon = LP_WP_Filesystem::get_icon_svg( 'ico-cb-admin-bar.svg' );
758
759 $wp_admin_bar->add_node(
760 array(
761 'id' => 'lp-course-builder',
762 'title' => sprintf(
763 '<span class="lp-cb-admin-bar-icon">%1$s</span><span class="ab-label">%2$s</span>',
764 $admin_bar_icon,
765 $title
766 ),
767 'href' => $href,
768 )
769 );
770 }
771 }
772