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

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

506 lines 13.5 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
299 if ( is_array( $duration_str_arr ) && ! empty( $duration_str_arr ) && count( $duration_str_arr ) >= 2 ) {
300 switch ( $duration_str_arr[1] ) {
301 case 'hours':
302 $type_time = __( 'hours', 'learnpress' );
303 break;
304 case 'minutes':
305 $type_time = __( 'minutes', 'learnpress' );
306 break;
307 case 'days':
308 $type_time = __( 'days', 'learnpress' );
309 break;
310 case 'weeks':
311 $type_time = __( 'weeks', 'learnpress' );
312 break;
313 }
314
315 $duration_str = sprintf( '%1$s %2$s', $duration_str_arr[0], $type_time );
316 }
317 } else {
318 $duration_str = '--';
319 }
320
321 echo esc_html( $duration_str );
322 break;
323 case 'preview':
324 printf(
325 '<input type="checkbox" class="learn-press-checkbox learn-press-toggle-item-preview" %s value="%s" data-nonce="%s" />',
326 get_post_meta( $post_id, '_lp_preview', true ) == 'yes' ? ' checked="checked"' : '',
327 $post_id,
328 wp_create_nonce( 'learn-press-toggle-item-preview' )
329 );
330 break;
331 default:
332 break;
333
334 }
335 }
336
337 /**
338 * @param $fields
339 *
340 * @return string
341 */
342 public function posts_fields( $fields ): string {
343 global $wpdb;
344
345 if ( ! $this->is_page_list_posts_on_backend() ) {
346 return $fields;
347 }
348
349 $fields = ' DISTINCT ' . $fields;
350
351 if ( $this->get_order_by() == 'question-count' ) {
352 $fields .= ", (SELECT count(*) FROM {$wpdb->prefix}learnpress_quiz_questions qq WHERE {$wpdb->posts}.ID = qq.quiz_id ) as question_count";
353 }
354
355 return $fields;
356 }
357
358 /**
359 * @param $join
360 *
361 * @return string
362 */
363 public function posts_join_paged( $join ): string {
364 if ( ! $this->is_page_list_posts_on_backend() ) {
365 return $join;
366 }
367
368 return $join;
369 }
370
371 /**
372 * @param $where
373 *
374 * @return mixed|string
375 */
376 public function posts_where_paged( $where ) {
377 if ( ! $this->is_page_list_posts_on_backend() ) {
378 return $where;
379 }
380
381 global $wpdb;
382
383 if ( 'yes' === LP_Request::get( 'unassigned' ) ) {
384 $where .= $wpdb->prepare(
385 "
386 AND {$wpdb->posts}.ID NOT IN(
387 SELECT si.item_id
388 FROM {$wpdb->learnpress_section_items} si
389 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
390 WHERE p.post_type = %s
391 )
392 ",
393 LP_QUIZ_CPT
394 );
395 }
396
397 return $where;
398 }
399
400 /**
401 * @param $order_by_statement
402 *
403 * @return string
404 */
405 public function posts_orderby( $order_by_statement ) {
406 global $wpdb;
407
408 if ( ! $this->is_page_list_posts_on_backend() ) {
409 return $order_by_statement;
410 }
411
412 $orderby = $this->get_order_by();
413 $order = $this->get_order_sort();
414
415 if ( $order && $orderby ) {
416 switch ( $orderby ) {
417 case 'course-name':
418 $order_by_statement = "post_title {$order}";
419 break;
420 case 'question-count':
421 $order_by_statement = "question_count {$order}";
422 break;
423 default:
424 $order_by_statement = "{$wpdb->posts}.post_title {$order}";
425 }
426 }
427
428 return $order_by_statement;
429 }
430
431 /**
432 * @param $columns
433 *
434 * @return mixed
435 */
436 public function sortable_columns( $columns ) {
437 $columns['instructor'] = 'author';
438 $columns[ LP_COURSE_CPT ] = 'course-name';
439 $columns['num_of_question'] = 'question-count';
440
441 return $columns;
442 }
443
444 /**
445 * Quiz assigned view.
446 *
447 * @since 3.0.0
448 */
449 // public static function quiz_assigned() {
450 // learn_press_admin_view( 'meta-boxes/course/assigned.php' );
451 // }
452
453 public function meta_boxes() {
454 return array(
455 'quiz_assigned' => array(
456 'title' => esc_html__( 'Assigned', 'learnpress' ),
457 'callback' => function( $post ) {
458 learn_press_admin_view( 'meta-boxes/course/assigned.php' );
459 },
460 'context' => 'side',
461 'priority' => 'high',
462 ),
463 'quiz-editor' => array(
464 'title' => esc_html__( 'Questions', 'learnpress' ),
465 'callback' => array( $this, 'admin_editor' ),
466 'context' => 'normal',
467 'priority' => 'high',
468 ),
469 );
470 }
471
472 /**
473 * @return LP_Quiz_Post_Type|null
474 */
475 public static function instance() {
476 if ( ! self::$_instance ) {
477 self::$_instance = new self();
478 }
479
480 return self::$_instance;
481 }
482
483 /**
484 * Save Post type Quiz
485 *
486 * @author tungnx
487 * @version 1.0.0
488 * @since 4.0.0
489 */
490 public function save( int $post_id, WP_Post $post ) {
491 $lp_quiz_cache = LP_Quiz_Cache::instance();
492
493 // Clear cache get question_ids of quiz
494 $lp_quiz_cache->clear( "$post_id/question_ids" );
495 }
496 }
497
498 // LP_Quiz_Post_Type
499 $quiz_post_type = LP_Quiz_Post_Type::instance();
500
501 //Todo: Nhamdv see to rewrite
502 // $quiz_post_type
503 // ->add_meta_box( 'lesson_assigned', esc_html__( 'Assigned', 'learnpress' ), 'quiz_assigned', 'side', 'high' )
504 // ->add_meta_box( 'quiz-editor', esc_html__( 'Questions', 'learnpress' ), 'admin_editor', 'normal', 'high' );
505 }
506