芝麻web文件管理V1.00
编辑当前文件:/home/sditechnicalteam/socialdigivlms.com/wp-content/plugins/tutor/classes/Q_And_A.php
* @link https://themeum.com * @since 1.0.0 */ namespace TUTOR; use Tutor\Helpers\QueryHelper; if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Question answer management * * @since 1.0.0 */ class Q_And_A { /** * Register hooks * * @param boolean $register_hooks true/false to execute the hooks. */ public function __construct( $register_hooks = true ) { if ( ! $register_hooks ) { return; } add_action( 'wp_ajax_tutor_qna_create_update', array( $this, 'tutor_qna_create_update' ) ); /** * Delete question * * @since v.1.6.4 */ add_action( 'wp_ajax_tutor_delete_dashboard_question', array( $this, 'tutor_delete_dashboard_question' ) ); /** * Take action against single qna * * @since v2.0.0 */ add_action( 'wp_ajax_tutor_qna_single_action', array( $this, 'tutor_qna_single_action' ) ); add_action( 'wp_ajax_tutor_qna_bulk_action', array( $this, 'process_bulk_action' ) ); /** * Q & A load more * * @since v2.0.6 */ add_action( 'wp_ajax_tutor_q_and_a_load_more', __CLASS__ . '::load_more' ); } /** * Check user has access to QnA. * * @since 2.6.1 * * @param int $user_id user id. * @param int $course_id course id. * * @return boolean */ public static function has_qna_access( $user_id, $course_id ) { $is_public_course = Course_List::is_public( $course_id ); $has_access = $is_public_course || User::is_admin() || tutor_utils()->is_instructor_of_this_course( $user_id, $course_id ) || tutor_utils()->is_enrolled( $course_id, $user_id ); return $has_access; } /** * Undocumented function * * @since v1.0.0 * * @return void */ public function tutor_qna_create_update() { tutor_utils()->checking_nonce(); $user_id = get_current_user_id(); $course_id = Input::post( 'course_id', 0, Input::TYPE_INT ); if ( ! $this->has_qna_access( $user_id, $course_id ) ) { wp_send_json_error( array( 'message' => tutor_utils()->error_message() ) ); } $qna_text = Input::post( 'answer', '', tutor()->has_pro ? Input::TYPE_KSES_POST : Input::TYPE_TEXTAREA ); if ( ! $qna_text ) { // Content validation. wp_send_json_error( array( 'message' => __( 'Empty Content Not Allowed!', 'tutor' ) ) ); } // Prepare course, question info. $course_id = Input::post( 'course_id', 0, Input::TYPE_INT ); $question_id = Input::post( 'question_id', 0, Input::TYPE_INT ); $context = Input::post( 'context' ); // Prepare user info. $user = get_userdata( $user_id ); $date = gmdate( 'Y-m-d H:i:s', tutor_time() ); $qna_object = new \stdClass(); $qna_object->user_id = $user_id; $qna_object->course_id = $course_id; $qna_object->question_id = $question_id; $qna_object->qna_text = $qna_text; $qna_object->user = $user; $qna_object->date = $date; $question_id = $this->inset_qna( $qna_object ); // Provide the html now. // phpcs:disable WordPress.Security.NonceVerification.Missing ob_start(); tutor_load_template_from_custom_path( tutor()->path . '/views/qna/qna-single.php', array( 'question_id' => $question_id, 'back_url' => isset( $_POST['back_url'] ) ? esc_url_raw( wp_unslash( $_POST['back_url'] ) ) : '', 'context' => $context, ) ); wp_send_json_success( array( 'html' => ob_get_clean(), 'editor_id' => 'tutor_qna_reply_editor_' . $question_id, ) ); } /** * Function to insert Q&A * * @param object $qna_object the object to insert. * @return int */ public function inset_qna( $qna_object ) { $course_id = $qna_object->course_id; $question_id = $qna_object->question_id; $qna_text = $qna_object->qna_text; $user_id = $qna_object->user_id; $user = $qna_object->user; $date = $qna_object->date; // Insert data prepare. $data = apply_filters( 'tutor_qna_insert_data', array( 'comment_post_ID' => $course_id, 'comment_author' => $user->user_login, 'comment_date' => $date, 'comment_date_gmt' => get_gmt_from_date( $date ), 'comment_content' => $qna_text, 'comment_approved' => 'approved', 'comment_agent' => 'TutorLMSPlugin', 'comment_type' => 'tutor_q_and_a', 'comment_parent' => $question_id, 'user_id' => $user_id, ) ); global $wpdb; // Insert new question/answer. $wpdb->insert( $wpdb->comments, $data ); ! $question_id ? $question_id = (int) $wpdb->insert_id : 0; // Mark the question unseen if action made from student. $asker_id = $this->get_asker_id( $question_id ); $self = $asker_id == $user_id; update_comment_meta( $question_id, 'tutor_qna_read' . ( $self ? '' : '_' . $asker_id ), 0 ); do_action( 'tutor_after_asked_question', $data ); // question_id != 0 means it's a reply. $reply_id = Input::post( 'question_id', 0, Input::TYPE_INT ); $answer_id = (int) $wpdb->insert_id; if ( 0 !== $reply_id && ( current_user_can( 'administrator' ) || tutor_utils()->is_instructor_of_this_course( $user_id, $course_id ) ) ) { do_action( 'tutor_after_answer_to_question', $answer_id ); } return $question_id; } /** * Delete question [frontend dashboard] * * @since v.1.6.4 */ public function tutor_delete_dashboard_question() { tutor_utils()->checking_nonce(); $question_id = Input::post( 'question_id', 0, Input::TYPE_INT ); if ( ! $question_id || ! tutor_utils()->can_user_manage( 'qa_question', $question_id ) ) { wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) ); } $this->delete_qna_permanently( array( $question_id ) ); wp_send_json_success(); } /** * Undocumented function * * @param array $question_ids question ids. * * @return void */ public function delete_qna_permanently( $question_ids ) { if ( is_array( $question_ids ) && count( $question_ids ) ) { global $wpdb; // Prepare in clause. $question_ids = QueryHelper::prepare_in_clause( $question_ids ); // Deleting question (comment), child question and question meta (comment meta). $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_ID IN ($question_ids) AND 1 = %d ", 1 ) ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_parent IN ($question_ids) AND 1 = %d ", 1 ) ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->commentmeta} WHERE {$wpdb->commentmeta}.comment_id IN ($question_ids) AND 1 = %d ", 1 ) ); } } /** * Process bulk delete * * @since v1.0.0 * * @return void send wp_json response */ public function process_bulk_action() { tutor_utils()->checking_nonce(); $user_id = get_current_user_id(); $action = Input::post( 'bulk-action' ); switch ( $action ) { case 'delete': $qa_ids = Input::post( 'bulk-ids', '' ); $qa_ids = explode( ',', $qa_ids ); $qa_ids = array_filter( $qa_ids, function ( $id ) use ( $user_id ) { return is_numeric( $id ) && tutor_utils()->can_user_manage( 'qa_question', $id, $user_id ); } ); $this->delete_qna_permanently( $qa_ids ); break; } wp_send_json_success(); } /** * Get user id who asked * * @param int $question_id question id. * * @return string author id */ private function get_asker_id( $question_id ) { global $wpdb; $author_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->comments} WHERE comment_ID = %d ", $question_id ) ); return $author_id; } /** * Update comment meta function * * @return void send wp_json response */ public function tutor_qna_single_action() { tutor_utils()->checking_nonce(); $question_id = Input::post( 'question_id', 0, Input::TYPE_INT ); if ( ! tutor_utils()->can_user_manage( 'qa_question', $question_id ) ) { wp_send_json_error( array( 'message' => __( 'Permission Denied!', 'tutor' ) ) ); } // Get who asked the question. $context = Input::post( 'context', '' ); $user_id = get_current_user_id(); // Get the existing value from meta. $action = Input::post( 'qna_action', '' ); $new_value = $this->trigger_qna_action( $question_id, $action, $context, $user_id ); // Transfer the new status. wp_send_json_success( array( 'new_value' => $new_value ) ); } /** * Function to update Q&A action * * @since 2.6.2 * * @param int $question_id question id. * @param string $action action name. * @param string $context context name. * @param int $user_id user id. * * @return int */ public function trigger_qna_action( $question_id, $action, $context, $user_id ) { $asker_prefix = 'frontend-dashboard-qna-table-student' === $context ? '_' . $user_id : ''; // If current user asker, then make it unread for self. // If it is instructor, then make unread for instructor side. $meta_key = 'tutor_qna_' . $action . $asker_prefix; $current_value = (int) get_comment_meta( $question_id, $meta_key, true ); $new_value = 1 === $current_value ? 0 : 1; // Update the reverted value. update_comment_meta( $question_id, $meta_key, $new_value ); return $new_value; } /** * Available tabs that will visible on the right side of page navbar * * @since v2.0.0 * * @param mixed $asker_id asker id. * * @return array */ public static function tabs_key_value( $asker_id = null ) { $stats = array( 'all' => tutor_utils()->get_qa_questions( 0, 99999, '', null, null, $asker_id, null, true ), 'read' => tutor_utils()->get_qa_questions( 0, 99999, '', null, null, $asker_id, 'read', true ), 'unread' => tutor_utils()->get_qa_questions( 0, 99999, '', null, null, $asker_id, 'unread', true ), 'important' => tutor_utils()->get_qa_questions( 0, 99999, '', null, null, $asker_id, 'important', true ), 'archived' => tutor_utils()->get_qa_questions( 0, 99999, '', null, null, $asker_id, 'archived', true ), ); // Assign value, url etc to the tab array. $tabs = array_map( function ( $tab ) use ( $stats ) { return array( 'key' => $tab, 'title' => tutor_utils()->translate_dynamic_text( $tab ), 'value' => $stats[ $tab ], 'url' => add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) ), ); }, array_keys( $stats ) ); return $tabs; } /** * Load more q & a * * @since v2.0.6 * * @return void send wp_json response */ public static function load_more() { tutor_utils()->checking_nonce(); ob_start(); tutor_load_template( 'single.course.enrolled.question_and_answer' ); $html = ob_get_clean(); wp_send_json_success( array( 'html' => $html ) ); } }