add_map_method( 'before_delete', 'before_delete_quiz' );
add_action( 'learn-press/admin/after-enqueue-scripts', array( $this, 'data_quiz_editor' ) );
add_filter( 'views_edit-' . LP_QUIZ_CPT, array( $this, 'views_pages' ), 10 );
add_action( 'posts_pre_query', array( $this, 'posts_pre_query' ), 999, 2 );
// add_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 );
parent::__construct();
}
/**
* Declare class name of table list quizzes.
*
* @param string $class_name
* @param array $args
*
* @return string
* @since 4.2.9.5
*/
public function wp_list_table_class_name( $class_name, $args ) {
if ( $this->check_class_name_handle_table( $args['screen'] ) ) {
$class_name = QuizzesTable::class;
}
return $class_name;
}
/**
* Add filters to lesson view.
*
* @since 3.0.0
*
* @param array $views
*
* @return array
*/
public function views_pages( array $views ): array {
$count_unassigned_quiz = LP_Course_DB::getInstance()->get_total_item_unassigned( LP_QUIZ_CPT );
if ( $count_unassigned_quiz > 0 ) {
$views['unassigned'] = sprintf(
'%s (%d)',
admin_url( 'edit.php?post_type=' . LP_QUIZ_CPT . '&unassigned=yes' ),
isset( $_GET['unassigned'] ) ? 'current' : '',
__( 'Unassigned', 'learnpress' ),
$count_unassigned_quiz
);
}
return $views;
}
/**
* Register quiz post type.
*/
public function args_register_post_type(): array {
$args = apply_filters(
'lp_quiz_post_type_args',
array(
'labels' => array(
'name' => esc_html__( 'Quizzes', 'learnpress' ),
'menu_name' => esc_html__( 'Quizzes', 'learnpress' ),
'singular_name' => esc_html__( 'Quiz', 'learnpress' ),
'add_new_item' => esc_html__( 'Add A New Quiz', 'learnpress' ),
'edit_item' => esc_html__( 'Edit Quiz', 'learnpress' ),
'all_items' => esc_html__( 'Quizzes', 'learnpress' ),
'view_item' => esc_html__( 'View Quiz', 'learnpress' ),
'add_new' => esc_html__( 'New Quiz', 'learnpress' ),
'update_item' => esc_html__( 'Update Quiz', 'learnpress' ),
'search_items' => esc_html__( 'Search Quizzes', 'learnpress' ),
'not_found' => sprintf( __( 'You haven\'t had any quizzes yet. Click Add new to start', 'learnpress' ), admin_url( 'post-new.php?post_type=lp_quiz' ) ),
'not_found_in_trash' => esc_html__( 'There was no quiz found in the trash', 'learnpress' ),
),
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'has_archive' => false,
'capability_type' => LP_LESSON_CPT,
'map_meta_cap' => true,
'show_in_menu' => 'learn_press',
'show_in_rest' => true,
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'supports' => array(
'title',
'editor',
'revisions',
),
'hierarchical' => false, // Quizzes have no parent-child hierarchy.
'rewrite' => array(
'slug' => 'quizzes',
'hierarchical' => true,
'with_front' => false,
),
'exclude_from_search' => true,
)
);
return $args;
}
/**
* Load data for quiz editor.
*
* @since 3.0.0
*/
public function data_quiz_editor() {
if ( LP_QUIZ_CPT !== get_post_type() ) {
return;
}
global $post;
$quiz = LP_Quiz::get_quiz( $post->ID );
$user_id = get_current_user_id();
$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';
$hidden_questions = get_post_meta( $post->ID, '_lp_hidden_questions', true );
$hidden_questions_settings = get_post_meta( $post->ID, '_hidden_questions_settings', true );
wp_localize_script(
'learn-press-admin-quiz-editor',
'lp_quiz_editor',
apply_filters(
'learn-press/admin-localize-quiz-editor',
array(
'root' => array(
'quiz_id' => $post->ID,
'ajax' => admin_url( '' ),
'action' => 'admin_quiz_editor',
'nonce' => wp_create_nonce( 'learnpress_admin_quiz_editor' ),
'types' => LP_Question::get_types(),
'default_new' => $default_new_question_type,
),
'chooseItems' => array(
'open' => false,
'addedItems' => array(),
'items' => array(),
),
'i18n' => apply_filters(
'learn-press/quiz-editor/i18n',
array(
'option' => esc_html__( 'Option', 'learnpress' ),
'unique' => learn_press_uniqid(),
'back' => esc_html__( 'Back', 'learnpress' ),
'selected_items' => esc_html__( 'Selected items', 'learnpress' ),
'new_option' => esc_html__( 'New Option', 'learnpress' ),
'confirm_trash_question' => esc_html__( 'Do you want to move the "{{QUESTION_NAME}}" question to the trash?', 'learnpress' ),
'question_labels' => array(
'singular' => esc_html__( 'Question', 'learnpress' ),
'plural' => esc_html__( 'Questions', 'learnpress' ),
),
'confirm_remove_blanks' => esc_html__( 'Are you sure to remove all the blanks?', 'learnpress' ),
)
),
'listQuestions' => array(
'questions' => $quiz->quiz_editor_get_questions(),
'hidden_questions' => ! empty( $hidden_questions ) ? $hidden_questions : array(),
'hidden_questions_settings' => $hidden_questions_settings ? $hidden_questions_settings : array(),
'disableUpdateList' => false,
'supportAnswerOptions' => learn_press_get_question_support_answer_options(),
),
)
)
);
}
/**
* Delete all questions assign to quiz.
*
* @since 3.0.0
*
* @param $post_id
*/
public function before_delete_quiz( $post_id ) {
if ( get_post_type( $post_id ) !== LP_QUIZ_CPT ) {
return;
}
$curd = new LP_Quiz_CURD();
// remove question from course items
$curd->delete( $post_id );
}
/**
* Admin editor
*
* @since 3.3.0
* @version 1.0.1
* @return void
*/
public function admin_editor() {
global $post;
$quiz_id = $post->ID;
$quizPostModel = QuizPostModel::find( $quiz_id, true );
if ( ! $quizPostModel instanceof QuizPostModel ) {
return;
}
do_action( 'learn-press/admin/edit-quiz/layout', $quizPostModel );
}
/**
* Query lp quizzes in admin via Post DB
*
* @param array $posts
* @param WP_Query $wp_query
*
* @return array|WP_Query
* @since 4.4.8
* @version 1.0.0
*/
public function posts_pre_query( $posts, $wp_query ) {
try {
if ( ! is_admin() ) {
return $posts;
}
// Check screen
$curren_screen = get_current_screen();
if ( ! $curren_screen || $curren_screen->id !== 'edit-' . LP_QUIZ_CPT ) {
return $posts;
}
$post_type = $wp_query->get( 'post_type' );
if ( empty( $post_type ) || $post_type !== LP_QUIZ_CPT ) {
return $posts;
}
$posts_per_page = get_user_option( "edit_{$post_type}_per_page", get_current_user_id() );
if ( empty( $posts_per_page ) ) {
$posts_per_page = 20;
}
$paged = max( 1, get_query_var( 'paged' ) );
$author = $wp_query->get( 'author' );
$status = $wp_query->get( 'post_status' );
$search = $wp_query->get( 's' );
$month = $wp_query->get( 'm' );
$orderby = LP_Request::get_param( 'orderby', '', 'key' );
$order = LP_Request::get_param( 'order', '', 'key' );
$filter = new QuizPostFilter();
$filter->only_fields = [ 'p.ID', 'p.post_title', 'p.post_author', 'p.post_date', 'p.post_date_gmt' ];
$filter->field_count = 'p.ID';
$filter->page = $paged;
$filter->limit = $posts_per_page;
$post_db = PostDB::getInstance();
if ( ! empty( $status ) ) {
$filter->post_status = array( $status );
}
if ( ! empty( $author ) ) {
$filter->post_author = absint( $author );
}
if ( ! empty( $search ) ) {
$filter->post_title = sanitize_text_field( wp_unslash( $search ) );
}
if ( ! empty( $month ) && is_numeric( $month ) && strlen( (string) $month ) === 6 ) {
$filter->where[] = $post_db->wpdb->prepare(
'AND YEAR(p.post_date) = %d AND MONTH(p.post_date) = %d',
substr( $month, 0, 4 ),
substr( $month, 4, 2 )
);
}
// Exclude status auto-draft
$filter->where[] = $post_db->wpdb->prepare( 'AND p.post_status != %s', PostModel::STATUS_AUTO_DRAFT );
// Add question count field
$filter->only_fields[] = "(SELECT COUNT(*) FROM {$post_db->tb_lp_quiz_questions} qq_count
WHERE qq_count.quiz_id = p.ID) AS question_count";
// Join sections/courses when sorting by course-name
if ( $orderby === 'course-name' ) {
$filter->join[] = "LEFT JOIN {$post_db->wpdb->prefix}learnpress_section_items si ON p.ID = si.item_id";
$filter->join[] = "LEFT JOIN {$post_db->wpdb->prefix}learnpress_sections s ON s.section_id = si.section_id";
$filter->join[] = "LEFT JOIN {$post_db->wpdb->posts} c ON c.ID = s.section_course_id";
}
// Filter unassigned
if ( 'yes' === LP_Request::get_param( 'unassigned', '', 'key' ) ) {
$filter->where[] = "AND p.ID NOT IN(
SELECT si.item_id
FROM {$post_db->wpdb->learnpress_section_items} si
)";
}
if ( $orderby === 'course-name' ) {
$filter->order_by = 'c.post_title';
} elseif ( $orderby === 'question-count' ) {
$filter->order_by = 'question_count';
} elseif ( $orderby === 'title' ) {
$filter->order_by = 'p.post_title';
} elseif ( $orderby === 'author' ) {
$filter->order_by = 'p.post_author';
} elseif ( $orderby === 'date' ) {
$filter->order_by = 'p.post_date';
} else {
$filter->order_by = 'p.menu_order';
}
$filter->order = strtolower( $order ) === 'asc' ? 'ASC' : 'DESC';
// Get lp quizzes
$total_rows = 0;
$lp_quizzes = $post_db->get_posts( $filter, $total_rows );
$wp_query->post_count = count( $lp_quizzes );
$wp_query->found_posts = $total_rows;
$wp_query->max_num_pages = (int) ceil( $total_rows / $posts_per_page );
$posts = $lp_quizzes;
} catch ( Throwable $e ) {
LP_Debug::error_log( $e );
}
return $posts;
}
/*public function posts_fields( $fields ): string {
global $wpdb;
if ( ! $this->is_page_list_posts_on_backend() ) {
return $fields;
}
$fields = ' DISTINCT ' . $fields;
if ( $this->get_order_by() == 'question-count' ) {
$fields .= ", (SELECT count(*) FROM {$wpdb->prefix}learnpress_quiz_questions qq WHERE {$wpdb->posts}.ID = qq.quiz_id ) as question_count";
}
return $fields;
}
public function posts_join_paged( $join ): string {
if ( ! $this->is_page_list_posts_on_backend() ) {
return $join;
}
return $join;
}
public function posts_where_paged( $where ) {
if ( ! $this->is_page_list_posts_on_backend() ) {
return $where;
}
global $wpdb;
if ( 'yes' === LP_Request::get( 'unassigned' ) ) {
$where .= $wpdb->prepare(
"
AND {$wpdb->posts}.ID NOT IN(
SELECT si.item_id
FROM {$wpdb->learnpress_section_items} si
INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
WHERE p.post_type = %s
)
",
LP_QUIZ_CPT
);
}
return $where;
}
public function posts_orderby( $order_by_statement ) {
global $wpdb;
if ( ! $this->is_page_list_posts_on_backend() ) {
return $order_by_statement;
}
$orderby = $this->get_order_by();
$order = $this->get_order_sort();
if ( $order && $orderby ) {
switch ( $orderby ) {
case 'course-name':
$order_by_statement = "post_title {$order}";
break;
case 'question-count':
$order_by_statement = "question_count {$order}";
break;
default:
$order_by_statement = "{$wpdb->posts}.post_title {$order}";
}
}
return $order_by_statement;
}*/
/**
* Quiz assigned view.
*
* @since 3.0.0
*/
// public static function quiz_assigned() {
// learn_press_admin_view( 'meta-boxes/course/assigned.php' );
// }
public function meta_boxes() {
return array(
'quiz_assigned' => array(
'title' => esc_html__( 'Assigned', 'learnpress' ),
'callback' => function ( $post ) {
learn_press_admin_view( 'meta-boxes/course/assigned.php' );
},
'context' => 'side',
'priority' => 'high',
),
'quiz-editor' => array(
'title' => esc_html__( 'Questions', 'learnpress' ),
'callback' => array( $this, 'admin_editor' ),
'context' => 'normal',
'priority' => 'high',
),
);
}
/**
* @return LP_Quiz_Post_Type|null
*/
public static function instance() {
if ( ! self::$_instance ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Handle when save post.
*
* @param int $post_id
* @param WP_Post|null $post
* @param bool $is_update
*
* @return void
* @since 4.2.7.6
* @version 1.0.0
*/
public function save_post( int $post_id = 0, ?WP_Post $post = null, bool $is_update = false ) {
// Clear cache get quiz by id
$lpCache = new LP_Cache();
$lpCache->clear( "quizPostModel/find/{$post_id}" );
$lpCache->clear( "quizModel/find/{$post_id}" );
// Clear cache get question_ids of quiz
$lp_quiz_cache = LP_Quiz_Cache::instance();
$lp_quiz_cache->clear( "$post_id/question_ids" );
}
}
// LP_Quiz_Post_Type
$quiz_post_type = LP_Quiz_Post_Type::instance();
}