PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
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 4.1.7.3.1 4.1.7.3.2 All 140 releases
← All changes | inc/custom-post-types/question.php +189 -142 4.1.7.3.1 → 4.4.9 View file →
@@ -6,8 +6,14 @@
6 6 * @package LearnPress/Classes
7 7 * @version 4.0.0
8 8 */
9 9
10 +use LearnPress\Databases\PostDB;
11 +use LearnPress\Filters\QuestionPostFilter;
12 +use LearnPress\Models\PostModel;
13 +use LearnPress\Models\Question\QuestionPostModel;
14 +use LearnPress\Models\WPTables\QuestionsTable;
15 +
10 16 defined( 'ABSPATH' ) || exit();
11 17
12 18 if ( ! class_exists( 'LP_Question_Post_Type' ) ) {
13 19
@@ -25,8 +31,13 @@
25 31 */
26 32 protected $_post_type = LP_QUESTION_CPT;
27 33
28 34 /**
35 + * @var string
36 + */
37 + protected $_screen_list = 'edit-' . LP_QUESTION_CPT;
38 +
39 + /**
29 40 * LP_Question_Post_Type constructor.
30 41 *
31 42 * @param $post_type
32 43 * @param mixed
@@ -31,14 +42,15 @@
31 42 * @param $post_type
32 43 * @param mixed
33 44 */
34 45 public function __construct() {
35 - add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
46 + //add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
36 47 add_action( 'admin_head', array( $this, 'init' ) );
37 48 add_action( 'learn-press/admin/after-enqueue-scripts', array( $this, 'data_question_editor' ) );
38 49
39 50 add_filter( 'views_edit-' . LP_QUESTION_CPT, array( $this, 'views_pages' ), 11 );
40 - add_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 );
51 + add_action( 'posts_pre_query', array( $this, 'posts_pre_query' ), 999, 2 );
52 + // add_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 );
41 53
42 54 // $this->add_map_method( 'before_delete', 'before_delete_question' );
43 55
44 56 parent::__construct();
@@ -44,8 +56,25 @@
44 56 parent::__construct();
45 57 }
46 58
47 59 /**
60 + * Declare class name of table list questions.
61 + *
62 + * @param string $class_name
63 + * @param array $args
64 + *
65 + * @return string
66 + * @since 4.2.9.5
67 + */
68 + public function wp_list_table_class_name( $class_name, $args ) {
69 + if ( $this->check_class_name_handle_table( $args['screen'] ) ) {
70 + $class_name = QuestionsTable::class;
71 + }
72 +
73 + return $class_name;
74 + }
75 +
76 + /**
48 77 * Add question types support answer options
49 78 *
50 79 * @since 3.3.0
51 80 */
@@ -188,9 +217,9 @@
188 217 ),
189 218 'public' => true,
190 219 'hierarchical' => false,
191 220 'show_ui' => true,
192 - 'show_admin_column' => 'true',
221 + 'show_admin_column' => false,
193 222 'show_in_nav_menus' => true,
194 223 'rewrite' => array(
195 224 'slug' => 'question-tag',
196 225 'hierarchical' => false,
@@ -200,9 +229,9 @@
200 229 );
201 230 add_post_type_support( 'question', 'comments' );
202 231
203 232 return array(
204 - 'labels' => array(
233 + 'labels' => array(
205 234 'name' => esc_html__( 'Question Bank', 'learnpress' ),
206 235 'menu_name' => esc_html__( 'Question Bank', 'learnpress' ),
207 236 'singular_name' => esc_html__( 'Question', 'learnpress' ),
208 237 'all_items' => esc_html__( 'Questions', 'learnpress' ),
@@ -214,25 +243,26 @@
214 243 'search_items' => esc_html__( 'Search Questions', 'learnpress' ),
215 244 'not_found' => esc_html__( 'No questions found', 'learnpress' ),
216 245 'not_found_in_trash' => esc_html__( 'There was no questions found in the trash', 'learnpress' ),
217 246 ),
218 - 'public' => true,
219 - 'publicly_queryable' => true,
220 - 'show_ui' => true,
221 - 'has_archive' => false,
222 - 'capability_type' => LP_LESSON_CPT,
223 - 'map_meta_cap' => true,
224 - 'show_in_menu' => 'learn_press',
225 - 'show_in_admin_bar' => true,
226 - 'show_in_nav_menus' => true,
227 - 'show_in_rest' => learn_press_user_maybe_is_a_teacher(),
228 - 'supports' => array( 'title', 'editor', 'revisions' ),
229 - 'hierarchical' => false,
230 - 'rewrite' => array(
247 + 'public' => true,
248 + 'publicly_queryable' => true,
249 + 'show_ui' => true,
250 + 'has_archive' => false,
251 + 'capability_type' => LP_LESSON_CPT,
252 + 'map_meta_cap' => true,
253 + 'show_in_menu' => 'learn_press',
254 + 'show_in_admin_bar' => true,
255 + 'show_in_nav_menus' => true,
256 + 'show_in_rest' => learn_press_user_maybe_is_a_teacher(),
257 + 'supports' => array( 'title', 'editor', 'revisions' ),
258 + 'hierarchical' => false,
259 + 'rewrite' => array(
231 260 'slug' => 'questions',
232 261 'hierarchical' => true,
233 262 'with_front' => false,
234 263 ),
264 + 'exclude_from_search' => true,
235 265 );
236 266 }
237 267
238 268 /**
@@ -261,31 +291,23 @@
261 291 $curd->delete( $question_id );
262 292 }
263 293
264 294 /**
265 - * Add default answer when save new question action.
295 + * Handle when save post.
266 296 *
267 - * @param int $post_id
268 - * @param WP_Post $post
269 - * @since 3.0.0
297 + * @param int $post_id
298 + * @param WP_Post|null $post
299 + * @param bool $is_update
300 + *
301 + * @return void
302 + * @since 4.2.7.6
303 + * @version 1.0.0
270 304 */
271 - public function save( int $post_id, WP_Post $post ) {
272 - /*$question_id = $post_id;
273 -
274 - $question_type = LP_Helper::sanitize_params_submitted( $_REQUEST['question-type'] ?? '' );
275 -
276 - if ( empty( $question_type ) ) {
277 - $types = array_keys( LP_Question::get_types() );
278 - $question_type = reset( $types );
279 - }
280 -
281 - update_post_meta( $question_id, '_lp_type', $question_type );
282 -
283 - $question = LP_Question::get_question( $question_id );
284 -
285 - if ( $question->is_support( 'answer-options' ) ) {
286 - $question->create_default_answers();
287 - }*/
305 + public function save_post( int $post_id, ?WP_Post $post = null, bool $is_update = false ) {
306 + // Clear cache get question by id
307 + $lpCache = new LP_Cache();
308 + $lpCache->clear( "questionPostModel/find/{$post_id}" );
309 + $lpCache->clear( "questionModel/find/{$post_id}" );
288 310 }
289 311
290 312 /**
291 313 * Admin editor
@@ -291,99 +313,151 @@
291 313 * Admin editor
292 314 *
293 315 * @since 3.3.0
294 316 *
295 - * @return bool|string
317 + * @return void
296 318 */
297 319 public function admin_editor() {
298 - $question = LP_Question::get_question();
320 + global $post;
299 321
300 - //if ( $question->is_support( 'answer-options' ) ) {
301 - echo learn_press_admin_view_content( 'question/editor' );
302 - //}
322 + $question_id = $post->ID;
323 + $questionPostModel = QuestionPostModel::find( $question_id, true );
324 + if ( ! $questionPostModel instanceof QuestionPostModel ) {
325 + return;
326 + }
303 327
304 - ob_start();
305 - do_action( 'learn-press/question-admin-editor', $question );
306 - echo ob_get_clean();
328 + do_action( 'learn-press/admin/edit-question/layout', $questionPostModel );
307 329 }
308 330
309 331 /**
310 - * Add columns to admin manage question page
332 + * Query lp questions in admin via Post DB
311 333 *
312 - * @param array $columns
334 + * @param array $posts
335 + * @param WP_Query $wp_query
313 336 *
314 - * @return array
337 + * @return array|WP_Query
338 + * @since 4.4.8
339 + * @version 1.0.0
315 340 */
316 - public function columns_head( $columns ) {
317 - $pos = array_search( 'title', array_keys( $columns ) );
318 - $new_columns = array(
319 - 'instructor' => esc_html__( 'Author', 'learnpress' ),
320 - LP_QUIZ_CPT => esc_html__( 'Quiz', 'learnpress' ),
321 - 'type' => esc_html__( 'Type', 'learnpress' ),
322 - );
341 + public function posts_pre_query( $posts, $wp_query ) {
342 + try {
343 + if ( ! is_admin() ) {
344 + return $posts;
345 + }
323 346
324 - if ( false !== $pos && ! array_key_exists( LP_QUIZ_CPT, $columns ) ) {
325 - $columns = array_merge(
326 - array_slice( $columns, 0, $pos + 1 ),
327 - $new_columns,
328 - array_slice( $columns, $pos + 1 )
347 + // Check screen
348 + if ( ! function_exists( 'get_current_screen' ) ) {
349 + return $posts;
350 + }
351 +
352 + $curren_screen = get_current_screen();
353 + if ( ! $curren_screen || $curren_screen->id !== 'edit-' . LP_QUESTION_CPT ) {
354 + return $posts;
355 + }
356 +
357 + $post_type = $wp_query->get( 'post_type' );
358 +
359 + if ( empty( $post_type ) || $post_type !== LP_QUESTION_CPT ) {
360 + return $posts;
361 + }
362 +
363 + $posts_per_page = get_user_option( "edit_{$post_type}_per_page", get_current_user_id() );
364 + if ( empty( $posts_per_page ) ) {
365 + $posts_per_page = 20;
366 + }
367 +
368 + $paged = max( 1, get_query_var( 'paged' ) );
369 + $author = $wp_query->get( 'author' );
370 + $status = $wp_query->get( 'post_status' );
371 + $search = $wp_query->get( 's' );
372 + $month = $wp_query->get( 'm' );
373 + $orderby = LP_Request::get_param( 'orderby', '', 'key' );
374 + $order = LP_Request::get_param( 'order', '', 'key' );
375 + $quiz_id = LP_Request::get_param( 'filter_quiz' );
376 +
377 + $filter = new QuestionPostFilter();
378 + $filter->page = $paged;
379 + $filter->limit = $posts_per_page;
380 + $filter->only_fields = array_map(
381 + function ( $field ) {
382 + return "p.{$field}";
383 + },
384 + $filter->all_fields
329 385 );
330 - }
386 + $filter->field_count = 'p.ID';
387 + $post_db = PostDB::getInstance();
331 388
332 - $user = wp_get_current_user();
389 + if ( ! empty( $status ) ) {
390 + $filter->post_status = array( $status );
391 + }
333 392
334 - if ( in_array( LP_TEACHER_ROLE, $user->roles ) ) {
335 - unset( $columns['instructor'] );
336 - }
393 + if ( ! empty( $author ) ) {
394 + $filter->post_author = absint( $author );
395 + }
337 396
338 - if ( ! empty( $columns['author'] ) ) {
339 - unset( $columns['author'] );
340 - }
397 + if ( ! empty( $search ) ) {
398 + $filter->post_title = sanitize_text_field( wp_unslash( $search ) );
399 + }
341 400
342 - return $columns;
343 - }
401 + if ( ! empty( $month ) && is_numeric( $month ) && strlen( (string) $month ) === 6 ) {
402 + $filter->where[] = $post_db->wpdb->prepare(
403 + 'AND YEAR(p.post_date) = %d AND MONTH(p.post_date) = %d',
404 + substr( $month, 0, 4 ),
405 + substr( $month, 4, 2 )
406 + );
407 + }
344 408
345 - /**
346 - * Displaying the content of extra columns
347 - *
348 - * @param $name
349 - * @param $post_id
350 - */
351 - public function columns_content( $name, $post_id = 0 ) {
352 - switch ( $name ) {
353 - case 'instructor':
354 - $this->column_instructor( $post_id );
355 - break;
356 - case 'lp_quiz':
357 - $curd = new LP_Question_CURD();
358 - // get quiz
359 - $quiz = $curd->get_quiz( $post_id );
409 + // Exclude status auto-draft
410 + $filter->where[] = $post_db->wpdb->prepare( 'AND p.post_status != %s', PostModel::STATUS_AUTO_DRAFT );
360 411
361 - if ( $quiz ) {
362 - echo '<div><a href="' . esc_url_raw( add_query_arg( array( 'filter_quiz' => $quiz->ID ) ) ) . '">' . get_the_title( $quiz->ID ) . '</a>';
363 - echo '<div class="row-actions">';
364 - printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $quiz->ID ) ), esc_html__( 'Edit', 'learnpress' ) );
365 - echo '&nbsp;|&nbsp;';
366 - printf( '<a href="%s">%s</a>', get_the_permalink( $quiz->ID ), esc_html__( 'View', 'learnpress' ) );
367 - echo '</div></div>';
368 - } else {
369 - esc_html_e( 'Not assigned yet', 'learnpress' );
370 - }
371 - break;
372 - case 'type':
373 - echo learn_press_question_name_from_slug( get_post_meta( $post_id, '_lp_type', true ) );
374 - break;
412 + // Join quiz questions when needed
413 + if ( $quiz_id || $orderby === 'quiz-name' ) {
414 + $filter->join[] = "LEFT JOIN {$post_db->wpdb->prefix}learnpress_quiz_questions qq ON p.ID = qq.question_id";
415 + $filter->join[] = "LEFT JOIN {$post_db->wpdb->posts} qz ON qz.ID = qq.quiz_id";
416 + }
417 +
418 + // Filter by quiz
419 + if ( $quiz_id ) {
420 + $filter->where[] = $post_db->wpdb->prepare( 'AND qz.ID = %d', $quiz_id );
421 + }
422 +
423 + // Filter unassigned
424 + if ( 'yes' === LP_Request::get_param( 'unassigned', '', 'key' ) ) {
425 + $filter->where[] = "AND p.ID NOT IN(
426 + SELECT qq_un.question_id
427 + FROM {$post_db->wpdb->learnpress_quiz_questions} qq_un
428 + )";
429 + }
430 +
431 + if ( $orderby === 'quiz-name' ) {
432 + $filter->order_by = 'qz.post_title';
433 + } elseif ( $orderby === 'title' ) {
434 + $filter->order_by = 'p.post_title';
435 + } elseif ( $orderby === 'author' ) {
436 + $filter->order_by = 'p.post_author';
437 + } elseif ( $orderby === 'date' ) {
438 + $filter->order_by = 'p.post_date';
439 + } else {
440 + $filter->order_by = 'p.menu_order';
441 + }
442 +
443 + $filter->order = strtolower( $order ) === 'asc' ? 'ASC' : 'DESC';
444 +
445 + // Get lp questions
446 + $total_rows = 0;
447 + $lp_questions = $post_db->get_posts( $filter, $total_rows );
448 +
449 + $wp_query->post_count = count( $lp_questions );
450 + $wp_query->found_posts = $total_rows;
451 + $posts = $lp_questions;
452 + } catch ( Throwable $e ) {
453 + LP_Debug::error_log( $e );
375 454 }
455 +
456 + return $posts;
376 457 }
377 458
378 - /**
379 - * Posts_join_paged.
380 - *
381 - * @param $join
382 - *
383 - * @return string
384 - */
385 - public function posts_join_paged( $join ): string {
459 + /*public function posts_join_paged( $join ): string {
386 460 if ( ! $this->is_page_list_posts_on_backend() ) {
387 461 return $join;
388 462 }
389 463
@@ -397,13 +471,8 @@
397 471
398 472 return $join;
399 473 }
400 474
401 - /**
402 - * @param $where
403 - *
404 - * @return mixed|string
405 - */
406 475 public function posts_where_paged( $where ) {
407 476 static $posts_where_paged = false;
408 477
409 478 if ( $posts_where_paged || ! $this->is_page_list_posts_on_backend() ) {
@@ -419,22 +488,17 @@
419 488
420 489 if ( 'yes' === LP_Request::get( 'unassigned' ) ) {
421 490 global $wpdb;
422 491 $where .= " AND {$wpdb->posts}.ID NOT IN(
423 - SELECT qq.question_id
424 - FROM {$wpdb->learnpress_quiz_questions} qq
425 - )
426 - ";
492 + SELECT qq.question_id
493 + FROM {$wpdb->learnpress_quiz_questions} qq
494 + )
495 + ";
427 496 }
428 497
429 498 return $where;
430 499 }
431 500
432 - /**
433 - * @param $order_by_statement
434 - *
435 - * @return string
436 - */
437 501 public function posts_orderby( $order_by_statement ): string {
438 502 if ( ! $this->is_page_list_posts_on_backend() ) {
439 503 return $order_by_statement;
440 504 }
@@ -453,23 +517,11 @@
453 517 }
454 518 }
455 519
456 520 return $order_by_statement;
457 - }
521 + }*/
458 522
459 523 /**
460 - * @param $columns
461 - *
462 - * @return mixed
463 - */
464 - public function sortable_columns( $columns ) {
465 - $columns['author'] = 'author';
466 - $columns[ LP_QUIZ_CPT ] = 'quiz-name';
467 -
468 - return $columns;
469 - }
470 -
471 - /**
472 524 * @return bool|int
473 525 */
474 526 private function _filter_quiz() {
475 527 return LP_Request::get_int( 'filter_quiz' );
@@ -487,9 +539,9 @@
487 539 public function meta_boxes() {
488 540 return array(
489 541 'question_assigned' => array(
490 542 'title' => esc_html__( 'Assigned', 'learnpress' ),
491 - 'callback' => function( $post ) {
543 + 'callback' => function ( $post ) {
492 544 learn_press_admin_view( 'meta-boxes/quiz/assigned.php' );
493 545 },
494 546 'context' => 'side',
495 547 'priority' => 'high',
@@ -494,9 +546,9 @@
494 546 'context' => 'side',
495 547 'priority' => 'high',
496 548 ),
497 549 'question-editor' => array(
498 - 'title' => esc_html__( 'Answer Options', 'learnpress' ),
550 + 'title' => esc_html__( 'Questions Options', 'learnpress' ),
499 551 'callback' => array( $this, 'admin_editor' ),
500 552 'context' => 'normal',
501 553 'priority' => 'high',
502 554 ),
@@ -524,10 +576,5 @@
524 576 }
525 577 }
526 578
527 579 $question_post_type = LP_Question_Post_Type::instance();
528 -
529 - // Todo: Nhamdv see to rewrite
530 - // $question_post_type
531 - // ->add_meta_box( 'lesson_assigned', esc_html__( 'Assigned', 'learnpress' ), 'question_assigned', 'side', 'high' )
532 - // ->add_meta_box( 'question-editor', esc_html__( 'Answer Options', 'learnpress' ), 'admin_editor', 'normal', 'high', 1 );
533 580 }