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
learnpress / inc / TemplateHooks / CourseBuilder / Question / BuilderEditQuestionTemplate.php

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

621 lines 20.9 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\Question;
10
11 use Exception;
12 use LearnPress\CourseBuilder\CourseBuilder;
13 use LearnPress\CourseBuilder\CourseBuilderAccessPolicy;
14 use LearnPress\Helpers\Singleton;
15 use LearnPress\Helpers\Template;
16 use LearnPress\Models\PostModel;
17 use LearnPress\Models\Question\QuestionPostModel;
18 use LearnPress\Models\UserModel;
19 use LearnPress\TemplateHooks\Admin\AdminEditQuestionTemplate;
20 use LearnPress\TemplateHooks\Admin\AdminTemplate;
21 use LearnPress\TemplateHooks\Course\AdminEditCurriculumTemplate;
22 use LearnPress\TemplateHooks\CourseBuilder\Quiz\BuilderQuizTemplate;
23 use LP_Question_CURD;
24 use LP_Settings;
25 use LP_WP_Filesystem;
26 use Throwable;
27 use WP_User;
28
29 class BuilderEditQuestionTemplate {
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 question.
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 questions', 'learnpress' ) );
48 }
49
50 $item_id = $data['item_id'] ?? '';
51 if ( empty( $item_id ) ) {
52 throw new Exception( __( 'Invalid question ID', 'learnpress' ) );
53 }
54
55 /*if ( ! CourseBuilderAccessPolicy::can_access_tab_post( 'questions', $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 $questionModel = false;
61
62 if ( ! $is_create_new ) {
63 $questionModel = QuestionPostModel::find( (int) $item_id, true );
64 if ( ! $questionModel ) {
65 throw new Exception( __( 'Question not found', 'learnpress' ) );
66 }
67
68 $questionModel->check_capabilities_update_item_course();
69
70 if ( $questionModel->post_status === PostModel::STATUS_TRASH ) {
71 throw new Exception(
72 __(
73 'You cannot edit this item because it is in the Trash. Please restore it and try again.',
74 'learnpress'
75 )
76 );
77 }
78 } else {
79 $questionModelNew = new QuestionPostModel();
80 $questionModelNew->check_capabilities_create_item_course();
81 }
82
83 $data['questionModel'] = $questionModel;
84
85 $section = [
86 'wrap' => sprintf(
87 '<div class="lp-cb-content" data-post-id="%1$s">',
88 esc_attr( $item_id )
89 ),
90 'header' => $this->html_header( $data ),
91 'tabs' => $this->html_tabs( $data ),
92 'wrap_end' => '</div>',
93 ];
94
95 echo Template::combine_components( $section );
96
97 } catch ( Throwable $e ) {
98 Template::print_message( $e->getMessage(), 'error' );
99 }
100 }
101
102 public function html_header( array $data = [] ): string {
103 $userModel = $data['userModel'] ?? false;
104 if ( ! $userModel instanceof UserModel ) {
105 return '';
106 }
107
108 $questionModel = $data['questionModel'] ?? false;
109 $hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
110 $more_actions_icon = LP_WP_Filesystem::get_icon_svg( 'ico-cb-more.svg' );
111 $title = $questionModel ? $questionModel->get_the_title() : __( 'Add New Question', 'learnpress' );
112 $status = $questionModel ? $questionModel->post_status : '';
113 $status_label = 'future' === $status ? __( 'scheduled', 'learnpress' ) : $status;
114 $main_action_status = in_array( $status, [ 'publish', 'draft', 'pending', 'future', 'private' ], true ) ? $status : 'publish';
115 $wp_user = new WP_User( $userModel );
116 $hide_wp_edit_link = $hide_instructor_access_admin_screen && user_can( $wp_user, UserModel::ROLE_INSTRUCTOR );
117
118 $section = [
119 'header_wrap' => '<div class="lp-cb-header">',
120 'header_left' => '<div class="lp-cb-header__left">',
121 'title' => sprintf(
122 '<h1 class="lp-cb-header__title">%s</h1>',
123 esc_html( $title )
124 ),
125 'status_badge' => $questionModel && $status ? sprintf(
126 '<span class="question-status %1$s">%2$s</span>',
127 esc_attr( $status ),
128 esc_html( $status_label )
129 ) : '',
130 'link_edit_on_wp' => $questionModel && ! $hide_wp_edit_link ? sprintf(
131 '<a href="%1$s" class="lp-cb-admin-link" target="_blank" title="%2$s"%3$s>
132 <span class="dashicons dashicons-wordpress"></span>
133 <span>%2$s</span>
134 </a>',
135 esc_url( admin_url( 'post.php?post=' . $questionModel->get_id() . '&action=edit' ) ),
136 esc_attr__( 'Edit with WordPress', 'learnpress' ),
137 'trash' === $status ? ' style="display:none"' : ''
138 ) : '',
139 'header_left_end' => '</div>',
140 'header_actions' => '<div class="lp-cb-header__actions">',
141 'dropdown_wrap' => '<div class="cb-header-actions-dropdown cb-header-actions-dropdown--single">',
142 'update_btn' => sprintf(
143 '<div class="cb-btn-update lp-button cb-btn-primary cb-btn-main-action"
144 data-status="%1$s"
145 data-title-update="%2$s"
146 data-title-publish="%3$s"
147 data-title-draft="%4$s">%5$s</div>',
148 esc_attr( $main_action_status ),
149 esc_attr__( 'Update', 'learnpress' ),
150 esc_attr__( 'Publish', 'learnpress' ),
151 esc_attr__( 'Save Draft', 'learnpress' ),
152 esc_html__( 'Update', 'learnpress' )
153 ),
154 'dropdown_wrap_end' => '</div>',
155 'expanded_actions' => $questionModel ? sprintf(
156 '<div class="cb-header-action-expanded">
157 <button type="button" class="lp-button course-action-expanded" aria-haspopup="true" aria-expanded="false" aria-label="%1$s">
158 %2$s
159 </button>
160 <div class="cb-header-action-expanded__items">
161 <div class="cb-header-action-expanded__duplicate lp-button cb-btn-duplicate-question"
162 data-title="%3$s"
163 data-content="%4$s">
164 <span class="dashicons dashicons-admin-page"></span>
165 %5$s
166 </div>
167 <div class="cb-header-action-expanded__trash lp-button cb-btn-trash">
168 <span class="dashicons dashicons-trash"></span>
169 %6$s
170 </div>
171 </div>
172 </div>',
173 esc_attr__( 'More actions', 'learnpress' ),
174 $more_actions_icon,
175 esc_attr__( 'Are you sure?', 'learnpress' ),
176 esc_attr__( 'Are you sure you want to duplicate this question?', 'learnpress' ),
177 esc_html__( 'Duplicate', 'learnpress' ),
178 esc_html__( 'Move to Trash', 'learnpress' )
179 ) : '',
180 'header_actions_end' => '</div>',
181 'header_end' => '</div>',
182 ];
183
184 return Template::combine_components( $section );
185 }
186
187 public function html_tabs( array $data = [] ): string {
188 $section_tab = [
189 'tabs_wrap' => '<div class="lp-cb-tabs">',
190 'tabs' => '',
191 'tabs_end' => '</div>',
192 ];
193
194 $section_content = [
195 'wrap' => '<div class="lp-cb-tab-content">',
196 'content' => '',
197 'wrap-end' => '</div>',
198 ];
199
200 $tabs = apply_filters(
201 'learn-press/course-builder/questions/edit/tabs',
202 [
203 'overview' => [
204 'title' => esc_html__( 'Overview', 'learnpress' ),
205 'html' => $this->html_tab_overview( $data ),
206 ],
207 'settings' => [
208 'title' => esc_html__( 'Settings', 'learnpress' ),
209 'html' => $this->html_tab_settings( $data ),
210 ],
211 ],
212 $data
213 );
214
215 $tab_sections = [];
216 foreach ( $tabs as $key => $tab ) {
217 $tab_sections[ $key ] = $tab['slug'] ?? $key;
218 }
219
220 $tab_active = (string) reset( $tab_sections );
221 if ( isset( $_GET['tab'] ) ) {
222 $requested_tab = sanitize_key( wp_unslash( $_GET['tab'] ) );
223 if ( in_array( $requested_tab, $tab_sections, true ) ) {
224 $tab_active = $requested_tab;
225 }
226 }
227
228 foreach ( $tabs as $key => $tab ) {
229 $tab_section = $tab_sections[ $key ];
230 $is_active = $tab_section === $tab_active;
231
232 $section_tab['tabs'] .= sprintf(
233 '<a href="#" class="lp-cb-tabs__item %s" data-tab-section="%s">%s</a>',
234 $is_active ? 'is-active' : '',
235 esc_attr( $tab_section ),
236 esc_html( $tab['title'] ?? '' )
237 );
238
239 /**
240 * @uses html_tab_overview
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 $question_model = $data['questionModel'] ?? false;
263 $question_id = $data['item_id'] ?? ( $question_model ? $question_model->get_id() : CourseBuilder::POST_NEW );
264
265 if ( absint( $question_id ) && ! $question_model ) {
266 $question_model = QuestionPostModel::find( absint( $question_id ), true );
267 if ( empty( $question_model ) ) {
268 return '';
269 }
270 }
271
272 $html_assigned = $this->assigned_quiz( $question_model );
273 $html_edit_title = $this->edit_title( $question_model );
274 $html_permalink = $this->edit_permalink( $question_model );
275 $html_publish = $this->edit_publish( $question_model );
276 $html_edit_desc = $this->edit_desc( $question_model );
277 $section = [
278 'wrapper' => sprintf( '<div class="cb-section__question-edit" data-question-id="%s">', $question_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_quiz' => $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_settings( array $data = [] ): string {
297 wp_enqueue_style( 'lp-edit-question' );
298
299 $question_model = $data['questionModel'] ?? false;
300 $question_id = $data['item_id'] ?? ( $question_model ? $question_model->get_id() : CourseBuilder::POST_NEW );
301
302 if ( $question_id === CourseBuilder::POST_NEW || absint( $question_id ) <= 0 ) {
303 return sprintf( '<span class="lp-message lp-message--info">%s</span>', __( 'Please save Question before setting question', 'learnpress' ) );
304 }
305
306 if ( ! $question_model ) {
307 $question_model = QuestionPostModel::find( absint( $question_id ), true );
308 if ( empty( $question_model ) ) {
309 return '';
310 }
311 }
312
313 $settings = AdminEditQuestionTemplate::instance()->html_edit_question( $question_model );
314
315 $output = [
316 'wrapper' => sprintf( '<div class="cb-section__question-edit" data-question-id="%s">', $question_id ),
317 'form_setting' => '<form name="lp-form-setting-question" class="lp-form-setting-question" method="post" enctype="multipart/form-data">',
318 'settings' => $settings,
319 'form_setting_end' => '</form>',
320 'wrapper_end' => '</div>',
321 ];
322
323 return Template::combine_components( $output );
324 }
325
326 /**
327 * Allow callback for AJAX.
328 * @use self::render_edit_course_curriculum
329 * @use self::render_html
330 *
331 * @param array $callbacks
332 *
333 * @return array
334 */
335 public function allow_callback( array $callbacks ): array {
336 $callbacks[] = AdminEditCurriculumTemplate::class . ':render_edit_course_curriculum';
337
338 return $callbacks;
339 }
340
341 public function assigned_quiz( $question_model ) {
342 $assign_question = ! empty( $question_model ) ? $this->get_assigned_question( $question_model->get_id() ) : '';
343 $html_quizzes = '';
344 $assigned = sprintf( '<span class="question-not-assigned">%s</span>', __( 'Not assigned yet', 'learnpress' ) );
345 if ( ! empty( $assign_question ) ) {
346 $quizzes = is_array( $assign_question ) && isset( $assign_question['id'] )
347 ? array( $assign_question )
348 : $assign_question;
349
350 $quiz_htmls = array();
351 foreach ( $quizzes as $quiz ) {
352 $quiz_id = $quiz['id'] ?? 0;
353 $quiz_title = $quiz['title'] ?? '';
354
355 if ( $quiz_id && $quiz_title ) {
356 $quiz_link = BuilderQuizTemplate::instance()->get_link_edit( $quiz_id );
357 $quiz_htmls[] = sprintf(
358 '<a href="%s">%s</a>',
359 esc_url( $quiz_link ),
360 esc_html( $quiz_title )
361 );
362 }
363 }
364
365 if ( ! empty( $quiz_htmls ) ) {
366 $assigned = implode( ', ', $quiz_htmls );
367 }
368 }
369
370 $html_quizzes = sprintf(
371 '<div class="cb-item-edit-assigned question-assigned-quizzes"><span class="label">%s</span> %s</div>',
372 __( 'Assigned', 'learnpress' ),
373 $assigned
374 );
375
376 return $html_quizzes;
377 }
378
379
380 public function edit_title( $question_model ) {
381 $title = ! empty( $question_model ) ? $question_model->get_the_title() : '';
382 $edit = [
383 'wrapper' => '<div class="cb-question-edit-title">',
384 'label' => sprintf( '<label for="title" class="cb-question-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
385 'input' => sprintf( '<input type="text" name="question_title" size="30" value="%s" id="title" class="cb-question-edit-title__input">', esc_attr( $title ) ),
386 'wrapper_end' => '</div>',
387 ];
388
389 return Template::combine_components( $edit );
390 }
391
392 /**
393 * @param QuestionPostModel|false $question_model
394 * @return string
395 */
396 public function edit_desc( $question_model ) {
397 $desc = ! empty( $question_model ) ? $question_model->post_content : '';
398 $editor_id = 'question_description_editor';
399 $editor_settings = array(
400 'textarea_name' => 'question_description',
401 'textarea_rows' => 10,
402 'teeny' => false,
403 'media_buttons' => true,
404 'tinymce' => array(
405 '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; }",
406 'toolbar1' => 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,spellchecker,wp_adv',
407 'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help',
408 ),
409 'quicktags' => true,
410 );
411
412 $edit = [
413 'wrapper' => '<div class="cb-question-edit-desc">',
414 'label' => sprintf( '<label for="question_description" class="cb-question-edit-desc__label">%s</label>', __( 'Description', 'learnpress' ) ),
415 'edit' => AdminTemplate::editor_tinymce(
416 $desc,
417 $editor_id,
418 $editor_settings
419 ),
420 'wrapper_end' => '</div>',
421 ];
422
423 return Template::combine_components( $edit );
424 }
425
426 public function edit_permalink( $question_model ): string {
427 $post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
428
429 if ( ! $post_id ) {
430 return Template::combine_components(
431 [
432 'wrapper' => '<div class="cb-item-edit-permalink">',
433 'label' => sprintf( '<span class="cb-item-edit-permalink__label">%s</span>', __( 'Permalink', 'learnpress' ) ),
434 'content' => sprintf(
435 '<span class="cb-item-edit-permalink__placeholder">%s</span>',
436 __( 'Permalink will be available after saving.', 'learnpress' )
437 ),
438 'wrapper_end' => '</div>',
439 ]
440 );
441 }
442
443 $post = get_post( $post_id );
444 $post_name = $post ? $post->post_name : '';
445 $full_url = urldecode( (string) get_permalink( $post_id ) );
446 $display_data = $this->get_question_display_permalink_data( $post_id, (string) $post_name );
447 $display_url = (string) ( $display_data['url'] ?? '' );
448 $editor_slug = (string) ( $display_data['slug'] ?? '' );
449
450 if ( empty( $display_url ) ) {
451 $display_url = $full_url;
452 }
453
454 if ( empty( $full_url ) ) {
455 $full_url = $display_url;
456 }
457
458 if ( empty( $editor_slug ) ) {
459 $editor_slug = (string) $post_name;
460 }
461
462 if ( empty( $editor_slug ) && ! empty( $display_url ) ) {
463 $display_path = parse_url( $display_url, PHP_URL_PATH );
464 if ( is_string( $display_path ) && '' !== $display_path ) {
465 $editor_slug = basename( untrailingslashit( $display_path ) );
466 }
467 }
468
469 if ( empty( $full_url ) ) {
470 return Template::combine_components(
471 [
472 'wrapper' => '<div class="cb-item-edit-permalink">',
473 'label' => sprintf( '<span class="cb-item-edit-permalink__label">%s</span>', __( 'Permalink', 'learnpress' ) ),
474 'content' => sprintf(
475 '<span class="cb-item-edit-permalink__placeholder">%s</span>',
476 __( 'Permalink is not available for this question.', 'learnpress' )
477 ),
478 'wrapper_end' => '</div>',
479 ]
480 );
481 }
482
483 $base_url = $display_url;
484 if (
485 ! empty( $editor_slug ) &&
486 false === strpos( $display_url, '?p=' ) &&
487 false === strpos( $display_url, '&p=' ) &&
488 false === strpos( $display_url, '?lp_question=' ) &&
489 false === strpos( $display_url, '&lp_question=' )
490 ) {
491 $base_url = trailingslashit( preg_replace( '/' . preg_quote( $editor_slug, '/' ) . '\/?$/', '', $display_url ) );
492 }
493
494 $state_a = sprintf(
495 '<span class="cb-item-edit-permalink__label">%s</span>
496 <div class="cb-permalink-display">
497 <a href="%s" target="_blank" class="cb-permalink-url">%s</a>
498 <button type="button" class="cb-permalink-edit-btn" title="%s">
499 <span class="dashicons dashicons-edit"></span>
500 </button>
501 </div>',
502 __( 'Permalink', 'learnpress' ),
503 esc_url( $full_url ),
504 esc_html( $display_url ),
505 __( 'Edit', 'learnpress' )
506 );
507
508 $state_b = sprintf(
509 '<div class="cb-permalink-editor lp-hidden">
510 <span class="cb-permalink-prefix">%s</span>
511 <div class="cb-permalink-input-row">
512 <input type="text" name="question_permalink" id="question_permalink" value="%s" class="cb-permalink-slug-input" placeholder="%s">
513 <div class="cb-permalink-actions">
514 <button type="button" class="cb-permalink-ok-btn">%s</button>
515 <button type="button" class="cb-permalink-cancel-btn">%s</button>
516 </div>
517 </div>
518 </div>',
519 esc_html( $base_url ),
520 esc_attr( $editor_slug ),
521 esc_attr__( 'your-slug', 'learnpress' ),
522 __( 'OK', 'learnpress' ),
523 __( 'Cancel', 'learnpress' )
524 );
525
526 $hidden_base = sprintf(
527 '<input type="hidden" id="cb-permalink-base-url" value="%s">',
528 esc_attr( $base_url )
529 );
530
531 $view = [
532 'wrapper' => '<div class="cb-item-edit-permalink cb-course-edit-permalink">',
533 'state_a' => $state_a,
534 'state_b' => $state_b,
535 'hidden_base' => $hidden_base,
536 'wrapper_end' => '</div>',
537 ];
538
539 return Template::combine_components( $view );
540 }
541
542 /**
543 * Get permalink display URL in publish-style format for editing slug.
544 *
545 * @param int $post_id
546 * @param string $post_name
547 *
548 * @return array<string, string>
549 */
550 private function get_question_display_permalink_data( int $post_id, string $post_name = '' ): array {
551 $display_url = urldecode( (string) get_permalink( $post_id ) );
552 $sample_slug = $post_name;
553
554 if ( ! function_exists( 'get_sample_permalink' ) ) {
555 require_once ABSPATH . 'wp-admin/includes/post.php';
556 }
557
558 if ( function_exists( 'get_sample_permalink' ) ) {
559 $sample_permalink = get_sample_permalink( $post_id );
560 if ( is_array( $sample_permalink ) && ! empty( $sample_permalink[0] ) ) {
561 $sample_slug = ! empty( $sample_permalink[1] ) ? (string) $sample_permalink[1] : $sample_slug;
562 $display_url = str_replace(
563 [ '%postname%', '%pagename%' ],
564 $sample_slug,
565 (string) $sample_permalink[0]
566 );
567 }
568 }
569
570 return [
571 'url' => urldecode( $display_url ),
572 'slug' => urldecode( (string) $sample_slug ),
573 ];
574 }
575
576 public function edit_publish( $question_model ): string {
577 $post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
578 $post = $post_id ? get_post( $post_id ) : null;
579 $current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : 'draft';
580 $status_value = 'draft' === $current_status ? 'draft' : 'publish';
581
582 $status_options_html = sprintf(
583 '<option value="publish" %1$s>%2$s</option><option value="draft" %3$s>%4$s</option>',
584 selected( $status_value, 'publish', false ),
585 esc_html__( 'Published', 'learnpress' ),
586 selected( $status_value, 'draft', false ),
587 esc_html__( 'Draft', 'learnpress' )
588 );
589
590 $publish = [
591 'wrapper' => '<div class="cb-item-edit-publish">',
592 'title' => sprintf( '<h3 class="cb-item-edit-publish__title">%s</h3>', esc_html__( 'Publish', 'learnpress' ) ),
593 'status_row' => sprintf(
594 '<div class="cb-item-edit-publish__row">
595 <label for="cb-question-publish-status" class="cb-item-edit-publish__label">%1$s</label>
596 <select id="cb-question-publish-status" name="cb_question_publish_status" class="cb-item-edit-publish__control">%2$s</select>
597 </div>',
598 esc_html__( 'Status', 'learnpress' ),
599 $status_options_html
600 ),
601 'wrapper_end' => '</div>',
602 ];
603
604 return Template::combine_components( $publish );
605 }
606
607 public function get_assigned_question( $id ) {
608 $curd = new LP_Question_CURD();
609 $quiz = $curd->get_quiz( $id );
610
611 if ( $quiz ) {
612 return array(
613 'id' => $quiz->ID,
614 'title' => $quiz->post_title ?? '',
615 );
616 }
617
618 return false;
619 }
620 }
621