PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
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 / Question / BuilderEditQuestionTemplate.php

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

617 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 public function edit_desc( $question_model ) {
393 $desc = ! empty( $question_model ) ? $question_model->get_the_content() : '';
394 $editor_id = 'question_description_editor';
395 $editor_settings = array(
396 'textarea_name' => 'question_description',
397 'textarea_rows' => 10,
398 'teeny' => false,
399 'media_buttons' => true,
400 'tinymce' => array(
401 '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; }",
402 'toolbar1' => 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,spellchecker,wp_adv',
403 'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help',
404 ),
405 'quicktags' => true,
406 );
407
408 $edit = [
409 'wrapper' => '<div class="cb-question-edit-desc">',
410 'label' => sprintf( '<label for="question_description" class="cb-question-edit-desc__label">%s</label>', __( 'Description', 'learnpress' ) ),
411 'edit' => AdminTemplate::editor_tinymce(
412 $desc,
413 $editor_id,
414 $editor_settings
415 ),
416 'wrapper_end' => '</div>',
417 ];
418
419 return Template::combine_components( $edit );
420 }
421
422 public function edit_permalink( $question_model ): string {
423 $post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
424
425 if ( ! $post_id ) {
426 return Template::combine_components(
427 [
428 'wrapper' => '<div class="cb-item-edit-permalink">',
429 'label' => sprintf( '<span class="cb-item-edit-permalink__label">%s</span>', __( 'Permalink', 'learnpress' ) ),
430 'content' => sprintf(
431 '<span class="cb-item-edit-permalink__placeholder">%s</span>',
432 __( 'Permalink will be available after saving.', 'learnpress' )
433 ),
434 'wrapper_end' => '</div>',
435 ]
436 );
437 }
438
439 $post = get_post( $post_id );
440 $post_name = $post ? $post->post_name : '';
441 $full_url = urldecode( (string) get_permalink( $post_id ) );
442 $display_data = $this->get_question_display_permalink_data( $post_id, (string) $post_name );
443 $display_url = (string) ( $display_data['url'] ?? '' );
444 $editor_slug = (string) ( $display_data['slug'] ?? '' );
445
446 if ( empty( $display_url ) ) {
447 $display_url = $full_url;
448 }
449
450 if ( empty( $full_url ) ) {
451 $full_url = $display_url;
452 }
453
454 if ( empty( $editor_slug ) ) {
455 $editor_slug = (string) $post_name;
456 }
457
458 if ( empty( $editor_slug ) && ! empty( $display_url ) ) {
459 $display_path = parse_url( $display_url, PHP_URL_PATH );
460 if ( is_string( $display_path ) && '' !== $display_path ) {
461 $editor_slug = basename( untrailingslashit( $display_path ) );
462 }
463 }
464
465 if ( empty( $full_url ) ) {
466 return Template::combine_components(
467 [
468 'wrapper' => '<div class="cb-item-edit-permalink">',
469 'label' => sprintf( '<span class="cb-item-edit-permalink__label">%s</span>', __( 'Permalink', 'learnpress' ) ),
470 'content' => sprintf(
471 '<span class="cb-item-edit-permalink__placeholder">%s</span>',
472 __( 'Permalink is not available for this question.', 'learnpress' )
473 ),
474 'wrapper_end' => '</div>',
475 ]
476 );
477 }
478
479 $base_url = $display_url;
480 if (
481 ! empty( $editor_slug ) &&
482 false === strpos( $display_url, '?p=' ) &&
483 false === strpos( $display_url, '&p=' ) &&
484 false === strpos( $display_url, '?lp_question=' ) &&
485 false === strpos( $display_url, '&lp_question=' )
486 ) {
487 $base_url = trailingslashit( preg_replace( '/' . preg_quote( $editor_slug, '/' ) . '\/?$/', '', $display_url ) );
488 }
489
490 $state_a = sprintf(
491 '<span class="cb-item-edit-permalink__label">%s</span>
492 <div class="cb-permalink-display">
493 <a href="%s" target="_blank" class="cb-permalink-url">%s</a>
494 <button type="button" class="cb-permalink-edit-btn" title="%s">
495 <span class="dashicons dashicons-edit"></span>
496 </button>
497 </div>',
498 __( 'Permalink', 'learnpress' ),
499 esc_url( $full_url ),
500 esc_html( $display_url ),
501 __( 'Edit', 'learnpress' )
502 );
503
504 $state_b = sprintf(
505 '<div class="cb-permalink-editor lp-hidden">
506 <span class="cb-permalink-prefix">%s</span>
507 <div class="cb-permalink-input-row">
508 <input type="text" name="question_permalink" id="question_permalink" value="%s" class="cb-permalink-slug-input" placeholder="%s">
509 <div class="cb-permalink-actions">
510 <button type="button" class="cb-permalink-ok-btn">%s</button>
511 <button type="button" class="cb-permalink-cancel-btn">%s</button>
512 </div>
513 </div>
514 </div>',
515 esc_html( $base_url ),
516 esc_attr( $editor_slug ),
517 esc_attr__( 'your-slug', 'learnpress' ),
518 __( 'OK', 'learnpress' ),
519 __( 'Cancel', 'learnpress' )
520 );
521
522 $hidden_base = sprintf(
523 '<input type="hidden" id="cb-permalink-base-url" value="%s">',
524 esc_attr( $base_url )
525 );
526
527 $view = [
528 'wrapper' => '<div class="cb-item-edit-permalink cb-course-edit-permalink">',
529 'state_a' => $state_a,
530 'state_b' => $state_b,
531 'hidden_base' => $hidden_base,
532 'wrapper_end' => '</div>',
533 ];
534
535 return Template::combine_components( $view );
536 }
537
538 /**
539 * Get permalink display URL in publish-style format for editing slug.
540 *
541 * @param int $post_id
542 * @param string $post_name
543 *
544 * @return array<string, string>
545 */
546 private function get_question_display_permalink_data( int $post_id, string $post_name = '' ): array {
547 $display_url = urldecode( (string) get_permalink( $post_id ) );
548 $sample_slug = $post_name;
549
550 if ( ! function_exists( 'get_sample_permalink' ) ) {
551 require_once ABSPATH . 'wp-admin/includes/post.php';
552 }
553
554 if ( function_exists( 'get_sample_permalink' ) ) {
555 $sample_permalink = get_sample_permalink( $post_id );
556 if ( is_array( $sample_permalink ) && ! empty( $sample_permalink[0] ) ) {
557 $sample_slug = ! empty( $sample_permalink[1] ) ? (string) $sample_permalink[1] : $sample_slug;
558 $display_url = str_replace(
559 [ '%postname%', '%pagename%' ],
560 $sample_slug,
561 (string) $sample_permalink[0]
562 );
563 }
564 }
565
566 return [
567 'url' => urldecode( $display_url ),
568 'slug' => urldecode( (string) $sample_slug ),
569 ];
570 }
571
572 public function edit_publish( $question_model ): string {
573 $post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
574 $post = $post_id ? get_post( $post_id ) : null;
575 $current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : 'draft';
576 $status_value = 'draft' === $current_status ? 'draft' : 'publish';
577
578 $status_options_html = sprintf(
579 '<option value="publish" %1$s>%2$s</option><option value="draft" %3$s>%4$s</option>',
580 selected( $status_value, 'publish', false ),
581 esc_html__( 'Published', 'learnpress' ),
582 selected( $status_value, 'draft', false ),
583 esc_html__( 'Draft', 'learnpress' )
584 );
585
586 $publish = [
587 'wrapper' => '<div class="cb-item-edit-publish">',
588 'title' => sprintf( '<h3 class="cb-item-edit-publish__title">%s</h3>', esc_html__( 'Publish', 'learnpress' ) ),
589 'status_row' => sprintf(
590 '<div class="cb-item-edit-publish__row">
591 <label for="cb-question-publish-status" class="cb-item-edit-publish__label">%1$s</label>
592 <select id="cb-question-publish-status" name="cb_question_publish_status" class="cb-item-edit-publish__control">%2$s</select>
593 </div>',
594 esc_html__( 'Status', 'learnpress' ),
595 $status_options_html
596 ),
597 'wrapper_end' => '</div>',
598 ];
599
600 return Template::combine_components( $publish );
601 }
602
603 public function get_assigned_question( $id ) {
604 $curd = new LP_Question_CURD();
605 $quiz = $curd->get_quiz( $id );
606
607 if ( $quiz ) {
608 return array(
609 'id' => $quiz->ID,
610 'title' => $quiz->post_title ?? '',
611 );
612 }
613
614 return false;
615 }
616 }
617