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_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 ); parent::__construct(); } /** * 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' => true, '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 ); } /** * Add columns to admin manage quiz page * * @param array $columns * * @return array */ public function columns_head( $columns ) { $pos = array_search( 'title', array_keys( $columns ) ); if ( false !== $pos && ! array_key_exists( LP_COURSE_CPT, $columns ) ) { $columns = array_merge( array_slice( $columns, 0, $pos + 1 ), array( 'instructor' => esc_html__( 'Author', 'learnpress' ), LP_COURSE_CPT => esc_html__( 'Course', 'learnpress' ), 'num_of_question' => esc_html__( 'Questions', 'learnpress' ), 'duration' => esc_html__( 'Duration', 'learnpress' ), ), array_slice( $columns, $pos + 1 ) ); } unset( $columns['taxonomy-lesson-tag'] ); $user = wp_get_current_user(); if ( in_array( 'lp_teacher', $user->roles ) ) { unset( $columns['instructor'] ); } if ( ! empty( $columns['author'] ) ) { unset( $columns['author'] ); } return $columns; } /** * Display content for custom column * * @param string $name * @param int $post_id */ public function columns_content( $name, $post_id = 0 ) { $quizPostModel = QuizPostModel::find( $post_id, true ); if ( ! $quizPostModel ) { return; } switch ( $name ) { case 'instructor': $this->column_instructor( $post_id ); break; case 'lp_course': $this->_get_item_course( $post_id ); break; case 'num_of_question': $count = $quizPostModel->count_questions(); printf( '%s', ! $count ? 'disabled' : '', $count ? sprintf( _n( '%d question', '%d questions', $count, 'learnpress' ), $count ) : __( 'This quiz has no questions', 'learnpress' ), $count ); break; case 'duration': $duration_str = $quizPostModel->get_duration(); $duration_arr = explode( ' ', $duration_str ); $duration = $duration_arr[0]; $duration_type = $duration_arr[1]; if ( $duration > 0 ) { $duration_str = LP_Datetime::get_string_plural_duration( $duration, $duration_type ); } else { $duration_str = __( 'Unlimited', 'learnpress' ); } echo esc_html( $duration_str ); break; case 'preview': printf( '', get_post_meta( $post_id, '_lp_preview', true ) == 'yes' ? ' checked="checked"' : '', $post_id, wp_create_nonce( 'learn-press-toggle-item-preview' ) ); break; default: break; } } /** * @param $fields * * @return string */ 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; } /** * @param $join * * @return string */ public function posts_join_paged( $join ): string { if ( ! $this->is_page_list_posts_on_backend() ) { return $join; } return $join; } /** * @param $where * * @return mixed|string */ 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; } /** * @param $order_by_statement * * @return string */ 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; } /** * @param $columns * * @return mixed */ public function sortable_columns( $columns ) { $columns['instructor'] = 'author'; $columns[ LP_COURSE_CPT ] = 'course-name'; $columns['num_of_question'] = 'question-count'; return $columns; } /** * 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(); }