PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.6.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.6.9
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 / custom-post-types / quiz.php

quiz.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9, at inc/custom-post-types/quiz.php

503 lines 13.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Quiz_Post_Type
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 4.0.0
8 */
9
10 defined( 'ABSPATH' ) || exit();
11
12 if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
13
14 /**
15 * Class LP_Quiz_Post_Type
16 */
17 final class LP_Quiz_Post_Type extends LP_Abstract_Post_Type {
18
19 /**
20 * @var null
21 */
22 protected static $_instance = null;
23
24 /**
25 * @var array
26 */
27 public static $metaboxes = array();
28
29 /**
30 * @var string
31 */
32 protected $_post_type = LP_QUIZ_CPT;
33
34 /**
35 * LP_Quiz_Post_Type constructor.
36 *
37 * @param $post_type
38 * @param mixed
39 */
40 public function __construct() {
41
42 //$this->add_map_method( 'before_delete', 'before_delete_quiz' );
43
44 add_action( 'learn-press/admin/after-enqueue-scripts', array( $this, 'data_quiz_editor' ) );
45
46 add_filter( 'views_edit-' . LP_QUIZ_CPT, array( $this, 'views_pages' ), 10 );
47 add_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 );
48
49 parent::__construct();
50 }
51
52 /**
53 * Add filters to lesson view.
54 *
55 * @since 3.0.0
56 *
57 * @param array $views
58 *
59 * @return array
60 */
61 public function views_pages( array $views ): array {
62 $count_unassigned_quiz = LP_Course_DB::getInstance()->get_total_item_unassigned( LP_QUIZ_CPT );
63
64 if ( $count_unassigned_quiz > 0 ) {
65 $views['unassigned'] = sprintf(
66 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
67 admin_url( 'edit.php?post_type=' . LP_QUIZ_CPT . '&unassigned=yes' ),
68 isset( $_GET['unassigned'] ) ? 'current' : '',
69 __( 'Unassigned', 'learnpress' ),
70 $count_unassigned_quiz
71 );
72 }
73
74 return $views;
75 }
76
77 /**
78 * Register quiz post type.
79 */
80 public function args_register_post_type(): array {
81 $args = apply_filters(
82 'lp_quiz_post_type_args',
83 array(
84 'labels' => array(
85 'name' => esc_html__( 'Quizzes', 'learnpress' ),
86 'menu_name' => esc_html__( 'Quizzes', 'learnpress' ),
87 'singular_name' => esc_html__( 'Quiz', 'learnpress' ),
88 'add_new_item' => esc_html__( 'Add New Quiz', 'learnpress' ),
89 'edit_item' => esc_html__( 'Edit Quiz', 'learnpress' ),
90 'all_items' => esc_html__( 'Quizzes', 'learnpress' ),
91 'view_item' => esc_html__( 'View Quiz', 'learnpress' ),
92 'add_new' => esc_html__( 'New Quiz', 'learnpress' ),
93 'update_item' => esc_html__( 'Update Quiz', 'learnpress' ),
94 'search_items' => esc_html__( 'Search Quizzes', 'learnpress' ),
95 'not_found' => sprintf( __( 'You haven\'t had any quizzes yet. Click <a href="%s">Add new</a> to start', 'learnpress' ), admin_url( 'post-new.php?post_type=lp_quiz' ) ),
96 'not_found_in_trash' => esc_html__( 'No quiz found in Trash', 'learnpress' ),
97 ),
98 'public' => true,
99 'publicly_queryable' => true,
100 'show_ui' => true,
101 'has_archive' => false,
102 'capability_type' => LP_LESSON_CPT,
103 'map_meta_cap' => true,
104 'show_in_menu' => 'learn_press',
105 'show_in_rest' => true,
106 'show_in_admin_bar' => true,
107 'show_in_nav_menus' => true,
108 'supports' => array(
109 'title',
110 'editor',
111 'revisions',
112 ),
113 'hierarchical' => true,
114 'rewrite' => array(
115 'slug' => 'quizzes',
116 'hierarchical' => true,
117 'with_front' => false,
118 ),
119 )
120 );
121
122 return $args;
123 }
124
125 /**
126 * Load data for quiz editor.
127 *
128 * @since 3.0.0
129 */
130 public function data_quiz_editor() {
131 if ( LP_QUIZ_CPT !== get_post_type() ) {
132 return;
133 }
134
135 global $post;
136
137 $quiz = LP_Quiz::get_quiz( $post->ID );
138
139 $user_id = get_current_user_id();
140 $default_new_question_type = get_user_meta( $user_id, '_learn_press_memorize_question_types', true ) ? get_user_meta( $user_id, '_learn_press_memorize_question_types', true ) : 'true_or_false';
141
142 $hidden_questions = get_post_meta( $post->ID, '_lp_hidden_questions', true );
143 $hidden_questions_settings = get_post_meta( $post->ID, '_hidden_questions_settings', true );
144
145 wp_localize_script(
146 'learn-press-admin-quiz-editor',
147 'lp_quiz_editor',
148 apply_filters(
149 'learn-press/admin-localize-quiz-editor',
150 array(
151 'root' => array(
152 'quiz_id' => $post->ID,
153 'ajax' => admin_url( '' ),
154 'action' => 'admin_quiz_editor',
155 'nonce' => wp_create_nonce( 'learnpress_admin_quiz_editor' ),
156 'types' => LP_Question::get_types(),
157 'default_new' => $default_new_question_type,
158 ),
159 'chooseItems' => array(
160 'open' => false,
161 'addedItems' => array(),
162 'items' => array(),
163 ),
164 'i18n' => apply_filters(
165 'learn-press/quiz-editor/i18n',
166 array(
167 'option' => esc_html__( 'Option', 'learnpress' ),
168 'unique' => learn_press_uniqid(),
169 'back' => esc_html__( 'Back', 'learnpress' ),
170 'selected_items' => esc_html__( 'Selected items', 'learnpress' ),
171 'new_option' => esc_html__( 'New Option', 'learnpress' ),
172 'confirm_trash_question' => esc_html__( 'Do you want to move question "{{QUESTION_NAME}}" to trash?', 'learnpress' ),
173 'question_labels' => array(
174 'singular' => esc_html__( 'Question', 'learnpress' ),
175 'plural' => esc_html__( 'Questions', 'learnpress' ),
176 ),
177 'confirm_remove_blanks' => esc_html__( 'Are you sure to remove all blanks?', 'learnpress' ),
178 )
179 ),
180 'listQuestions' => array(
181 'questions' => $quiz->quiz_editor_get_questions(),
182 'hidden_questions' => ! empty( $hidden_questions ) ? $hidden_questions : array(),
183 'hidden_questions_settings' => $hidden_questions_settings ? $hidden_questions_settings : array(),
184 'disableUpdateList' => false,
185 'supportAnswerOptions' => learn_press_get_question_support_answer_options(),
186 ),
187 )
188 )
189 );
190 }
191
192 /**
193 * Delete all questions assign to quiz.
194 *
195 * @since 3.0.0
196 *
197 * @param $post_id
198 */
199 public function before_delete_quiz( $post_id ) {
200 if ( get_post_type( $post_id ) !== LP_QUIZ_CPT ) {
201 return;
202 }
203
204 $curd = new LP_Quiz_CURD();
205 // remove question from course items
206 $curd->delete( $post_id );
207 }
208
209 /**
210 * Admin editor
211 *
212 * @since 3.3.0
213 *
214 * @return bool|string
215 */
216 public function admin_editor() {
217 $quiz = LP_Quiz::get_quiz();
218
219 echo learn_press_admin_view_content( 'quiz/editor' );
220 }
221
222 /**
223 * Add columns to admin manage quiz page
224 *
225 * @param array $columns
226 *
227 * @return array
228 */
229 public function columns_head( $columns ) {
230 $pos = array_search( 'title', array_keys( $columns ) );
231
232 if ( false !== $pos && ! array_key_exists( LP_COURSE_CPT, $columns ) ) {
233 $columns = array_merge(
234 array_slice( $columns, 0, $pos + 1 ),
235 array(
236 'instructor' => esc_html__( 'Author', 'learnpress' ),
237 LP_COURSE_CPT => esc_html__( 'Course', 'learnpress' ),
238 'num_of_question' => esc_html__( 'Questions', 'learnpress' ),
239 'duration' => esc_html__( 'Duration', 'learnpress' ),
240 ),
241 array_slice( $columns, $pos + 1 )
242 );
243 }
244
245 unset( $columns['taxonomy-lesson-tag'] );
246 $user = wp_get_current_user();
247
248 if ( in_array( 'lp_teacher', $user->roles ) ) {
249 unset( $columns['instructor'] );
250 }
251
252 if ( ! empty( $columns['author'] ) ) {
253 unset( $columns['author'] );
254 }
255
256 return $columns;
257 }
258
259 /**
260 * Display content for custom column
261 *
262 * @param string $name
263 * @param int $post_id
264 */
265 public function columns_content( $name, $post_id = 0 ) {
266 global $post;
267
268 switch ( $name ) {
269 case 'instructor':
270 $this->column_instructor( $post_id );
271 break;
272 case 'lp_course':
273 $this->_get_item_course( $post_id );
274 break;
275 case 'num_of_question':
276 if ( property_exists( $post, 'question_count' ) ) {
277 $count = $post->question_count;
278 } else {
279 $quiz = LP_Quiz::get_quiz( $post_id );
280 $questions = $quiz->get_questions();
281 $count = sizeof( $questions );
282 }
283
284 printf(
285 '<span class="lp-label-counter' . ( ! $count ? ' disabled' : '' ) . '" title="%s">%s</span>',
286 ( $count ) ? sprintf( _n( '%d question', '%d questions', $count, 'learnpress' ), $count ) : __( 'This quiz has no questions', 'learnpress' ),
287 $count
288 );
289 break;
290 case 'duration':
291 $duration_str = get_post_meta( $post_id, '_lp_duration', true );
292 $duration = (int) $duration_str;
293
294 if ( $duration > 0 ) {
295 $duration_str .= 's';
296 $duration_str_arr = explode( ' ', $duration_str );
297 $type_time = '';
298 switch ( $duration_str_arr[1] ) {
299 case 'hours':
300 $type_time = __( 'hours', 'learnpress' );
301 break;
302 case 'minutes':
303 $type_time = __( 'minutes', 'learnpress' );
304 break;
305 case 'days':
306 $type_time = __( 'days', 'learnpress' );
307 break;
308 case 'weeks':
309 $type_time = __( 'weeks', 'learnpress' );
310 break;
311 }
312
313 $duration_str = sprintf( '%1$s %2$s', $duration_str_arr[0], $type_time );
314 } else {
315 $duration_str = '--';
316 }
317
318 echo esc_html( $duration_str );
319 break;
320 case 'preview':
321 printf(
322 '<input type="checkbox" class="learn-press-checkbox learn-press-toggle-item-preview" %s value="%s" data-nonce="%s" />',
323 get_post_meta( $post_id, '_lp_preview', true ) == 'yes' ? ' checked="checked"' : '',
324 $post_id,
325 wp_create_nonce( 'learn-press-toggle-item-preview' )
326 );
327 break;
328 default:
329 break;
330
331 }
332 }
333
334 /**
335 * @param $fields
336 *
337 * @return string
338 */
339 public function posts_fields( $fields ): string {
340 global $wpdb;
341
342 if ( ! $this->is_page_list_posts_on_backend() ) {
343 return $fields;
344 }
345
346 $fields = ' DISTINCT ' . $fields;
347
348 if ( $this->get_order_by() == 'question-count' ) {
349 $fields .= ", (SELECT count(*) FROM {$wpdb->prefix}learnpress_quiz_questions qq WHERE {$wpdb->posts}.ID = qq.quiz_id ) as question_count";
350 }
351
352 return $fields;
353 }
354
355 /**
356 * @param $join
357 *
358 * @return string
359 */
360 public function posts_join_paged( $join ): string {
361 if ( ! $this->is_page_list_posts_on_backend() ) {
362 return $join;
363 }
364
365 return $join;
366 }
367
368 /**
369 * @param $where
370 *
371 * @return mixed|string
372 */
373 public function posts_where_paged( $where ) {
374 if ( ! $this->is_page_list_posts_on_backend() ) {
375 return $where;
376 }
377
378 global $wpdb;
379
380 if ( 'yes' === LP_Request::get( 'unassigned' ) ) {
381 $where .= $wpdb->prepare(
382 "
383 AND {$wpdb->posts}.ID NOT IN(
384 SELECT si.item_id
385 FROM {$wpdb->learnpress_section_items} si
386 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
387 WHERE p.post_type = %s
388 )
389 ",
390 LP_QUIZ_CPT
391 );
392 }
393
394 return $where;
395 }
396
397 /**
398 * @param $order_by_statement
399 *
400 * @return string
401 */
402 public function posts_orderby( $order_by_statement ) {
403 global $wpdb;
404
405 if ( ! $this->is_page_list_posts_on_backend() ) {
406 return $order_by_statement;
407 }
408
409 $orderby = $this->get_order_by();
410 $order = $this->get_order_sort();
411
412 if ( $order && $orderby ) {
413 switch ( $orderby ) {
414 case 'course-name':
415 $order_by_statement = "post_title {$order}";
416 break;
417 case 'question-count':
418 $order_by_statement = "question_count {$order}";
419 break;
420 default:
421 $order_by_statement = "{$wpdb->posts}.post_title {$order}";
422 }
423 }
424
425 return $order_by_statement;
426 }
427
428 /**
429 * @param $columns
430 *
431 * @return mixed
432 */
433 public function sortable_columns( $columns ) {
434 $columns['instructor'] = 'author';
435 $columns[ LP_COURSE_CPT ] = 'course-name';
436 $columns['num_of_question'] = 'question-count';
437
438 return $columns;
439 }
440
441 /**
442 * Quiz assigned view.
443 *
444 * @since 3.0.0
445 */
446 // public static function quiz_assigned() {
447 // learn_press_admin_view( 'meta-boxes/course/assigned.php' );
448 // }
449
450 public function meta_boxes() {
451 return array(
452 'quiz_assigned' => array(
453 'title' => esc_html__( 'Assigned', 'learnpress' ),
454 'callback' => function( $post ) {
455 learn_press_admin_view( 'meta-boxes/course/assigned.php' );
456 },
457 'context' => 'side',
458 'priority' => 'high',
459 ),
460 'quiz-editor' => array(
461 'title' => esc_html__( 'Questions', 'learnpress' ),
462 'callback' => array( $this, 'admin_editor' ),
463 'context' => 'normal',
464 'priority' => 'high',
465 ),
466 );
467 }
468
469 /**
470 * @return LP_Quiz_Post_Type|null
471 */
472 public static function instance() {
473 if ( ! self::$_instance ) {
474 self::$_instance = new self();
475 }
476
477 return self::$_instance;
478 }
479
480 /**
481 * Save Post type Quiz
482 *
483 * @author tungnx
484 * @version 1.0.0
485 * @since 4.0.0
486 */
487 public function save( int $post_id, WP_Post $post ) {
488 $lp_quiz_cache = LP_Quiz_Cache::instance();
489
490 // Clear cache get question_ids of quiz
491 $lp_quiz_cache->clear( "$post_id/question_ids" );
492 }
493 }
494
495 // LP_Quiz_Post_Type
496 $quiz_post_type = LP_Quiz_Post_Type::instance();
497
498 //Todo: Nhamdv see to rewrite
499 // $quiz_post_type
500 // ->add_meta_box( 'lesson_assigned', esc_html__( 'Assigned', 'learnpress' ), 'quiz_assigned', 'side', 'high' )
501 // ->add_meta_box( 'quiz-editor', esc_html__( 'Questions', 'learnpress' ), 'admin_editor', 'normal', 'high' );
502 }
503