PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.7
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 / TemplateHooks / CourseBuilder / Quiz / BuilderEditQuizTemplate.php

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

605 lines 20.1 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.0
6 * @version 1.0.0
7 */
8
9 namespace LearnPress\TemplateHooks\CourseBuilder\Quiz;
10
11 use Exception;
12 use LearnPress\CourseBuilder\CourseBuilderAccessPolicy;
13 use LearnPress\Models\UserModel;
14 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
15 use LearnPress\CourseBuilder\CourseBuilder;
16 use LearnPress\Helpers\Singleton;
17 use LearnPress\Helpers\Template;
18 use LearnPress\Models\PostModel;
19 use LearnPress\Models\QuizPostModel;
20 use LearnPress\TemplateHooks\Admin\AdminEditQizTemplate;
21 use LearnPress\TemplateHooks\Admin\AdminTemplate;
22 use LearnPress\TemplateHooks\Course\AdminEditCurriculumTemplate;
23 use LearnPress\TemplateHooks\TemplateAJAX;
24 use LP_Settings;
25 use LP_WP_Filesystem;
26 use Throwable;
27 use WP_User;
28
29 class BuilderEditQuizTemplate {
30 use Singleton;
31
32 public function init() {
33 add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
34 }
35
36 /**
37 * Display layout edit/create quiz.
38 *
39 * @param array $data [ 'userModel' => UserModel, 'item_id' => int|string ]
40 *
41 * @throws Exception
42 */
43 public function layout( array $data = [] ) {
44 try {
45 $userModel = $data['userModel'] ?? false;
46 if ( ! $userModel || ! $userModel->is_instructor() ) {
47 throw new Exception( __( 'You do not have permission to create or edit quizzes', 'learnpress' ) );
48 }
49
50 $item_id = $data['item_id'] ?? '';
51 if ( empty( $item_id ) ) {
52 throw new Exception( __( 'Invalid quiz ID', 'learnpress' ) );
53 }
54
55 if ( ! CourseBuilderAccessPolicy::can_access_tab_post( 'quizzes', $item_id ) ) {
56 throw new Exception( __( "Sorry, you don't have permission to access this content", 'learnpress' ) );
57 }
58
59 $is_create_new = $item_id === CourseBuilder::POST_NEW;
60 $quizModel = false;
61
62 if ( ! $is_create_new ) {
63 $quizModel = QuizPostModel::find( (int) $item_id, true );
64 if ( ! $quizModel ) {
65 throw new Exception( __( 'Quiz not found', 'learnpress' ) );
66 }
67
68 if ( $quizModel->post_status === PostModel::STATUS_TRASH ) {
69 throw new Exception(
70 __(
71 'You cannot edit this item because it is in the Trash. Please restore it and try again.',
72 'learnpress'
73 )
74 );
75 }
76 }
77
78 $data['quizModel'] = $quizModel;
79
80 $section = [
81 'wrap' => sprintf(
82 '<div class="lp-cb-content" data-post-id="%1$s">',
83 esc_attr( $item_id )
84 ),
85 'header' => $this->html_header( $data ),
86 'tabs' => $this->html_tabs( $data ),
87 'wrap_end' => '</div>',
88 ];
89
90 echo Template::combine_components( $section );
91
92 } catch ( Throwable $e ) {
93 Template::print_message( $e->getMessage(), 'error' );
94 }
95 }
96
97 public function html_header( array $data = [] ): string {
98 $userModel = $data['userModel'] ?? false;
99 if ( ! $userModel instanceof UserModel ) {
100 return '';
101 }
102
103 $quizModel = $data['quizModel'] ?? false;
104 $hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
105 $more_actions_icon = LP_WP_Filesystem::get_icon_svg( 'ico-cb-more.svg' );
106 $title = $quizModel ? $quizModel->get_the_title() : __( 'Add New Quiz', 'learnpress' );
107 $status = $quizModel ? $quizModel->post_status : '';
108 $status_label = 'future' === $status ? __( 'scheduled', 'learnpress' ) : $status;
109 $main_action_status = in_array( $status, [ 'publish', 'draft', 'pending', 'future', 'private' ], true ) ? $status : 'publish';
110 $wp_user = new WP_User( $userModel );
111 $hide_wp_edit_link = $hide_instructor_access_admin_screen && user_can( $wp_user, UserModel::ROLE_INSTRUCTOR );
112
113 $section = [
114 'header_wrap' => '<div class="lp-cb-header">',
115 'header_left' => '<div class="lp-cb-header__left">',
116 'title' => sprintf(
117 '<h1 class="lp-cb-header__title">%s</h1>',
118 esc_html( $title )
119 ),
120 'status_badge' => $quizModel && $status ? sprintf(
121 '<span class="quiz-status %1$s">%2$s</span>',
122 esc_attr( $status ),
123 esc_html( $status_label )
124 ) : '',
125 'link_edit_on_wp' => $quizModel && ! $hide_wp_edit_link ? sprintf(
126 '<a href="%1$s" class="lp-cb-admin-link" target="_blank" title="%2$s"%3$s>
127 <span class="dashicons dashicons-wordpress"></span>
128 <span>%2$s</span>
129 </a>',
130 esc_url( admin_url( 'post.php?post=' . $quizModel->get_id() . '&action=edit' ) ),
131 esc_attr__( 'Edit with WordPress', 'learnpress' ),
132 'trash' === $status ? ' style="display:none"' : ''
133 ) : '',
134 'header_left_end' => '</div>',
135 'header_actions' => '<div class="lp-cb-header__actions">',
136 'dropdown_wrap' => '<div class="cb-header-actions-dropdown cb-header-actions-dropdown--single">',
137 'update_btn' => sprintf(
138 '<div class="cb-btn-update lp-button cb-btn-primary cb-btn-main-action"
139 data-status="%1$s"
140 data-title-update="%2$s"
141 data-title-publish="%3$s"
142 data-title-draft="%4$s">%5$s</div>',
143 esc_attr( $main_action_status ),
144 esc_attr__( 'Update', 'learnpress' ),
145 esc_attr__( 'Publish', 'learnpress' ),
146 esc_attr__( 'Save Draft', 'learnpress' ),
147 esc_html__( 'Update', 'learnpress' )
148 ),
149 'dropdown_wrap_end' => '</div>',
150 'expanded_actions' => $quizModel ? sprintf(
151 '<div class="cb-header-action-expanded">
152 <button type="button" class="lp-button course-action-expanded" aria-haspopup="true" aria-expanded="false" aria-label="%1$s">
153 %2$s
154 </button>
155 <div class="cb-header-action-expanded__items">
156 <div class="cb-header-action-expanded__duplicate lp-button cb-btn-duplicate-quiz"
157 data-title="%3$s"
158 data-content="%4$s">
159 <span class="dashicons dashicons-admin-page"></span>
160 %5$s
161 </div>
162 <div class="cb-header-action-expanded__trash lp-button cb-btn-trash">
163 <span class="dashicons dashicons-trash"></span>
164 %6$s
165 </div>
166 </div>
167 </div>',
168 esc_attr__( 'More actions', 'learnpress' ),
169 $more_actions_icon,
170 esc_attr__( 'Are you sure?', 'learnpress' ),
171 esc_attr__( 'Are you sure you want to duplicate this quiz?', 'learnpress' ),
172 esc_html__( 'Duplicate', 'learnpress' ),
173 esc_html__( 'Move to Trash', 'learnpress' )
174 ) : '',
175 'header_actions_end' => '</div>',
176 'header_end' => '</div>',
177 ];
178
179 return Template::combine_components( $section );
180 }
181
182 public function html_tabs( array $data = [] ): string {
183 $section_tab = [
184 'tabs_wrap' => '<div class="lp-cb-tabs">',
185 'tabs' => '',
186 'tabs_end' => '</div>',
187 ];
188
189 $section_content = [
190 'wrap' => '<div class="lp-cb-tab-content">',
191 'content' => '',
192 'wrap-end' => '</div>',
193 ];
194
195 $tabs = apply_filters(
196 'learn-press/course-builder/quizzes/edit/tabs',
197 [
198 'overview' => [
199 'title' => esc_html__( 'Overview', 'learnpress' ),
200 'html' => $this->html_tab_overview( $data ),
201 ],
202 'question' => [
203 'title' => esc_html__( 'Question', 'learnpress' ),
204 'html' => $this->html_tab_question( $data ),
205 ],
206 'settings' => [
207 'title' => esc_html__( 'Settings', 'learnpress' ),
208 'html' => $this->html_tab_settings( $data ),
209 ],
210 ],
211 $data
212 );
213
214 $tab_sections = [];
215 foreach ( $tabs as $key => $tab ) {
216 $tab_sections[ $key ] = $tab['slug'] ?? $key;
217 }
218
219 $tab_active = (string) reset( $tab_sections );
220 if ( isset( $_GET['tab'] ) ) {
221 $requested_tab = sanitize_key( wp_unslash( $_GET['tab'] ) );
222 if ( in_array( $requested_tab, $tab_sections, true ) ) {
223 $tab_active = $requested_tab;
224 }
225 }
226
227 foreach ( $tabs as $key => $tab ) {
228 $tab_section = $tab_sections[ $key ];
229 $is_active = $tab_section === $tab_active;
230
231 $section_tab['tabs'] .= sprintf(
232 '<a href="#" class="lp-cb-tabs__item %s" data-tab-section="%s">%s</a>',
233 $is_active ? 'is-active' : '',
234 esc_attr( $tab_section ),
235 esc_html( $tab['title'] ?? '' )
236 );
237
238 /**
239 * @uses html_tab_overview
240 * @uses html_tab_question
241 * @uses html_tab_settings
242 */
243 $section_content['content'] .= sprintf(
244 '<div class="lp-cb-tab-panel %s" data-section="%s">%s</div>',
245 $is_active ? '' : 'lp-hidden',
246 esc_attr( $tab_section ),
247 $tab['html'] ?? ''
248 );
249 }
250
251 return Template::combine_components(
252 [
253 'tabs' => Template::combine_components( $section_tab ),
254 'contents' => Template::combine_components( $section_content ),
255 ]
256 );
257 }
258
259 public function html_tab_overview( array $data = [] ): string {
260 wp_enqueue_script( 'lp-course-builder' );
261
262 $quiz_model = $data['quizModel'] ?? false;
263 $quiz_id = $data['item_id'] ?? ( $quiz_model ? $quiz_model->get_id() : CourseBuilder::POST_NEW );
264
265 if ( absint( $quiz_id ) && ! $quiz_model ) {
266 $quiz_model = QuizPostModel::find( absint( $quiz_id ), true );
267 if ( empty( $quiz_model ) ) {
268 return '';
269 }
270 }
271
272 $html_assigned = $this->assigned_course( $quiz_model );
273 $html_edit_title = $this->edit_title( $quiz_model );
274 $html_permalink = $this->edit_permalink( $quiz_model );
275 $html_publish = $this->edit_publish( $quiz_model );
276 $html_edit_desc = $this->edit_desc( $quiz_model );
277 $section = [
278 'wrapper' => sprintf( '<div class="cb-section__quiz-edit" data-quiz-id="%s">', $quiz_id ),
279 'content_wrapper' => '<div class="cb-item-edit-content">',
280 'left_column' => '<div class="cb-item-edit-column cb-item-edit-column--left">',
281 'edit_title' => $html_edit_title,
282 'assigned_course' => $html_assigned,
283 'edit_permalink' => $html_permalink,
284 'edit_publish' => $html_publish,
285 'left_column_end' => '</div>',
286 'right_column' => '<div class="cb-item-edit-column cb-item-edit-column--right">',
287 'edit_desc' => $html_edit_desc,
288 'right_column_end' => '</div>',
289 'content_wrapper_end' => '</div>',
290 'wrapper_end' => '</div>',
291 ];
292
293 return Template::combine_components( $section );
294 }
295
296 public function html_tab_question( array $data = [] ): string {
297 wp_enqueue_style( 'lp-edit-quiz' );
298
299 $quiz_model = $data['quizModel'] ?? false;
300 $quiz_id = $data['item_id'] ?? ( $quiz_model ? $quiz_model->get_id() : CourseBuilder::POST_NEW );
301
302 if ( $quiz_id === CourseBuilder::POST_NEW || absint( $quiz_id ) <= 0 ) {
303 return sprintf( '<span class="lp-message lp-message--info">%s</span>', __( 'Please save Quiz before add question', 'learnpress' ) );
304 }
305
306 if ( ! $quiz_model ) {
307 $quiz_model = QuizPostModel::find( absint( $quiz_id ), true );
308 if ( empty( $quiz_model ) ) {
309 return '';
310 }
311 }
312
313 $args = [
314 'id_url' => 'edit-quiz',
315 'quiz_id' => $quiz_model->ID,
316 ];
317 $call_back = [
318 'class' => AdminEditQizTemplate::class,
319 'method' => 'render_edit_quiz',
320 ];
321
322 return TemplateAJAX::load_content_via_ajax( $args, $call_back );
323 }
324
325 public function html_tab_settings( array $data = [] ): string {
326 wp_enqueue_script( 'lp-cb-edit-curriculum' );
327 wp_enqueue_script( 'lp-tom-select' );
328 wp_enqueue_style( 'lp-cb-edit-curriculum' );
329 wp_enqueue_script( 'lp-cb-learnpress' );
330
331 $quiz_model = $data['quizModel'] ?? false;
332 $quiz_id = $data['item_id'] ?? ( $quiz_model ? $quiz_model->get_id() : CourseBuilder::POST_NEW );
333
334 if ( $quiz_id === CourseBuilder::POST_NEW || absint( $quiz_id ) <= 0 ) {
335 return sprintf( '<span class="lp-message lp-message--info">%s</span>', __( 'Please save Quiz before setting quiz', 'learnpress' ) );
336 }
337
338 if ( ! $quiz_model ) {
339 $quiz_model = QuizPostModel::find( absint( $quiz_id ), true );
340 if ( empty( $quiz_model ) ) {
341 return '';
342 }
343 }
344
345 if ( ! class_exists( 'LP_Meta_Box_Quiz' ) ) {
346 require_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/quiz/settings.php';
347 }
348
349 $metabox = new \LP_Meta_Box_Quiz();
350 ob_start();
351 $metabox->output( $quiz_model );
352 $settings = ob_get_clean();
353
354 $output = [
355 'wrapper' => sprintf( '<div class="cb-section__quiz-edit" data-quiz-id="%s">', $quiz_id ),
356 'form_setting' => '<form name="lp-form-setting-quiz" class="lp-form-setting-quiz" method="post" enctype="multipart/form-data">',
357 'settings' => $settings,
358 'form_setting_end' => '</form>',
359 'wrapper_end' => '</div>',
360 ];
361
362 return Template::combine_components( $output );
363 }
364
365 /**
366 * Allow callback for AJAX.
367 * @use self::render_edit_course_curriculum
368 * @use self::render_html
369 *
370 * @param array $callbacks
371 *
372 * @return array
373 */
374 public function allow_callback( array $callbacks ): array {
375 $callbacks[] = AdminEditCurriculumTemplate::class . ':render_edit_course_curriculum';
376
377 return $callbacks;
378 }
379
380 public function assigned_course( $quiz_model ) {
381 $assign_course = ! empty( $quiz_model ) ? $this->get_assigned( $quiz_model->get_id() ) : '';
382 $html_courses = '';
383 $assigned = sprintf( '<span class="quiz-not-assigned">%s</span>', __( 'Not assigned yet', 'learnpress' ) );
384 if ( ! empty( $assign_course ) ) {
385 $courses = is_array( $assign_course ) && isset( $assign_course['id'] )
386 ? array( $assign_course )
387 : $assign_course;
388
389 $course_htmls = array();
390 foreach ( $courses as $course ) {
391 $course_id = $course['id'] ?? 0;
392 $course_title = $course['title'] ?? '';
393
394 if ( $course_id && $course_title ) {
395 $course_link = BuilderCourseTemplate::instance()->get_link_edit( $course_id );
396 $course_htmls[] = sprintf(
397 '<a href="%s" target="_blank">%s</a>',
398 esc_url( $course_link ),
399 esc_html( $course_title )
400 );
401 }
402 }
403
404 if ( ! empty( $course_htmls ) ) {
405 $assigned = implode( ', ', $course_htmls );
406 }
407 }
408
409 $html_courses = sprintf(
410 '<div class="cb-item-edit-assigned quiz-assigned-courses"><span class="label">%s</span> %s</div>',
411 __( 'Assigned', 'learnpress' ),
412 $assigned
413 );
414
415 return $html_courses;
416 }
417
418
419 public function edit_title( $quiz_model ) {
420 $title = ! empty( $quiz_model ) ? $quiz_model->get_the_title() : '';
421 $edit = [
422 'wrapper' => '<div class="cb-quiz-edit-title">',
423 'label' => sprintf( '<label for="title" class="cb-quiz-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
424 'input' => sprintf( '<input type="text" name="quiz_title" size="30" value="%s" id="title" class="cb-quiz-edit-title__input">', $title ),
425 'wrapper_end' => '</div>',
426 ];
427
428 return Template::combine_components( $edit );
429 }
430
431 public function edit_desc( $quiz_model ) {
432 $desc = ! empty( $quiz_model ) ? $quiz_model->get_the_content() : '';
433 $editor_id = 'quiz_description_editor';
434 $editor_settings = array(
435 'textarea_name' => 'quiz_description',
436 'textarea_rows' => 10,
437 'teeny' => false,
438 'media_buttons' => true,
439 'tinymce' => array(
440 'content_style' => "body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; font-size: 14px; line-height: 1.6; color: #1e1e1e; }",
441 'toolbar1' => 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,spellchecker,wp_adv',
442 'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help',
443 ),
444 'quicktags' => true,
445 );
446
447 $edit = [
448 'wrapper' => '<div class="cb-quiz-edit-desc">',
449 'label' => sprintf( '<label for="quiz_description" class="cb-quiz-edit-desc__label">%s</label>', __( 'Description', 'learnpress' ) ),
450 'edit' => AdminTemplate::editor_tinymce(
451 $desc,
452 $editor_id,
453 $editor_settings
454 ),
455 'wrapper_end' => '</div>',
456 ];
457
458 return Template::combine_components( $edit );
459 }
460
461 public function edit_permalink( $quiz_model ): string {
462 $post_id = ! empty( $quiz_model ) ? absint( $quiz_model->get_id() ) : 0;
463 $post = $post_id ? get_post( $post_id ) : null;
464 $post_name = $post && ! empty( $post->post_name ) ? (string) $post->post_name : '';
465 $full_url = '';
466 $base_url = '';
467 $display_classes = 'cb-permalink-display';
468 $placeholder_class = 'cb-item-edit-permalink__placeholder';
469 $notice_no_link = __(
470 'Permalink is only available if the item is already assigned to a course.',
471 'learnpress'
472 );
473 $placeholder_text = __( 'Permalink will be available after saving.', 'learnpress' );
474 $show_unavailable = true;
475
476 if ( $post_id ) {
477 $current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : '';
478 if ( 'draft' !== $current_status ) {
479 $course_id_of_item = \LP_Course_DB::getInstance()->get_course_by_item_id( $post_id );
480 if ( $course_id_of_item ) {
481 $course = learn_press_get_course( $course_id_of_item );
482 if ( $course ) {
483 $full_url = urldecode( $course->get_item_link( $post_id ) );
484 $base_url = $full_url;
485 $show_unavailable = false;
486
487 if ( ! empty( $post_name ) ) {
488 $base_url = trailingslashit( preg_replace( '/' . preg_quote( $post_name, '/' ) . '\/?$/', '', $full_url ) );
489 }
490 }
491 }
492 }
493 }
494
495 if ( $show_unavailable && $post_id ) {
496 $placeholder_text = $notice_no_link;
497 }
498
499 if ( $show_unavailable ) {
500 $display_classes .= ' lp-hidden';
501 } else {
502 $placeholder_class .= ' lp-hidden';
503 }
504
505 $state_a = sprintf(
506 '<span class="cb-item-edit-permalink__label">%s</span>
507 <div class="%s">
508 <a href="%s" target="_blank" class="cb-permalink-url">%s</a>
509 <button type="button" class="cb-permalink-edit-btn" title="%s">
510 <span class="dashicons dashicons-edit"></span>
511 </button>
512 </div>',
513 __( 'Permalink', 'learnpress' ),
514 esc_attr( $display_classes ),
515 esc_url( $full_url ),
516 esc_html( $full_url ),
517 __( 'Edit', 'learnpress' )
518 );
519
520 $state_b = sprintf(
521 '<div class="cb-permalink-editor lp-hidden">
522 <span class="cb-permalink-prefix">%s</span>
523 <div class="cb-permalink-input-row">
524 <input type="text" name="quiz_permalink" id="quiz_permalink" value="%s" class="cb-permalink-slug-input" placeholder="%s">
525 <div class="cb-permalink-actions">
526 <button type="button" class="cb-permalink-ok-btn">%s</button>
527 <button type="button" class="cb-permalink-cancel-btn">%s</button>
528 </div>
529 </div>
530 </div>',
531 esc_html( $base_url ),
532 esc_attr( $post_name ),
533 esc_attr__( 'your-slug', 'learnpress' ),
534 __( 'OK', 'learnpress' ),
535 __( 'Cancel', 'learnpress' )
536 );
537
538 $hidden_base = sprintf(
539 '<input type="hidden" id="cb-permalink-base-url" value="%s">',
540 esc_attr( $base_url )
541 );
542
543 $placeholder = sprintf(
544 '<span class="%s">%s</span>',
545 esc_attr( $placeholder_class ),
546 esc_html( $placeholder_text )
547 );
548
549 $view = [
550 'wrapper' => '<div class="cb-item-edit-permalink cb-course-edit-permalink">',
551 'state_a' => $state_a,
552 'state_b' => $state_b,
553 'hidden_base' => $hidden_base,
554 'placeholder' => $placeholder,
555 'wrapper_end' => '</div>',
556 ];
557
558 return Template::combine_components( $view );
559 }
560
561 public function edit_publish( $quiz_model ): string {
562 $post_id = ! empty( $quiz_model ) ? absint( $quiz_model->get_id() ) : 0;
563 $post = $post_id ? get_post( $post_id ) : null;
564 $current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : 'draft';
565 $status_value = 'draft' === $current_status ? 'draft' : 'publish';
566
567 $status_options_html = sprintf(
568 '<option value="publish" %1$s>%2$s</option><option value="draft" %3$s>%4$s</option>',
569 selected( $status_value, 'publish', false ),
570 esc_html__( 'Published', 'learnpress' ),
571 selected( $status_value, 'draft', false ),
572 esc_html__( 'Draft', 'learnpress' )
573 );
574
575 $publish = [
576 'wrapper' => '<div class="cb-item-edit-publish">',
577 'title' => sprintf( '<h3 class="cb-item-edit-publish__title">%s</h3>', esc_html__( 'Publish', 'learnpress' ) ),
578 'status_row' => sprintf(
579 '<div class="cb-item-edit-publish__row">
580 <label for="cb-quiz-publish-status" class="cb-item-edit-publish__label">%1$s</label>
581 <select id="cb-quiz-publish-status" name="cb_quiz_publish_status" class="cb-item-edit-publish__control">%2$s</select>
582 </div>',
583 esc_html__( 'Status', 'learnpress' ),
584 $status_options_html
585 ),
586 'wrapper_end' => '</div>',
587 ];
588
589 return Template::combine_components( $publish );
590 }
591
592 public function get_assigned( $id ) {
593 $courses = learn_press_get_item_courses( $id );
594
595 if ( empty( $courses ) ) {
596 return array();
597 }
598
599 return array(
600 'id' => $courses[0]->ID,
601 'title' => $courses[0]->post_title ?? '',
602 );
603 }
604 }
605