PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.2.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.2.0
4.4.10 4.4.9.1 4.4.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 All 142 releases
learnpress / inc / custom-post-types / quiz.php

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

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