AnsPress_Ajax()
Description #
Register all ajax callback
Source #
File: includes/ajax-hooks.php
class AnsPress_Ajax { /** * Initialize the plugin by setting localization and loading public scripts * and styles. */ public static function init() { anspress()->add_action( 'ap_ajax_suggest_similar_questions', __CLASS__, 'suggest_similar_questions' ); anspress()->add_action( 'ap_ajax_load_tinymce', __CLASS__, 'load_tinymce' ); anspress()->add_action( 'ap_ajax_load_comments', 'AnsPress_Comment_Hooks', 'load_comments' ); anspress()->add_action( 'ap_ajax_edit_comment_form', 'AnsPress_Comment_Hooks', 'edit_comment_form' ); anspress()->add_action( 'ap_ajax_edit_comment', 'AnsPress_Comment_Hooks', 'edit_comment' ); anspress()->add_action( 'ap_ajax_approve_comment', 'AnsPress_Comment_Hooks', 'approve_comment' ); anspress()->add_action( 'ap_ajax_vote', 'AnsPress_Vote', 'vote' ); anspress()->add_action( 'ap_ajax_delete_comment', 'AnsPress\Ajax\Comment_Delete', 'init' ); anspress()->add_action( 'wp_ajax_comment_modal', 'AnsPress\Ajax\Comment_Modal', 'init' ); anspress()->add_action( 'wp_ajax_nopriv_comment_modal', 'AnsPress\Ajax\Comment_Modal', 'init' ); anspress()->add_action( 'wp_ajax_ap_toggle_best_answer', 'AnsPress\Ajax\Toggle_Best_Answer', 'init' ); // Post actions. anspress()->add_action( 'ap_ajax_post_actions', 'AnsPress_Theme', 'post_actions' ); anspress()->add_action( 'ap_ajax_action_toggle_featured', __CLASS__, 'toggle_featured' ); anspress()->add_action( 'ap_ajax_action_close', __CLASS__, 'close_question' ); anspress()->add_action( 'ap_ajax_action_toggle_delete_post', __CLASS__, 'toggle_delete_post' ); anspress()->add_action( 'ap_ajax_action_delete_permanently', __CLASS__, 'permanent_delete_post' ); anspress()->add_action( 'ap_ajax_action_status', 'AnsPress_Post_Status', 'change_post_status' ); anspress()->add_action( 'ap_ajax_action_convert_to_post', __CLASS__, 'convert_to_post' ); // Flag ajax callbacks. anspress()->add_action( 'ap_ajax_action_flag', 'AnsPress_Flag', 'action_flag' ); // Uploader hooks. anspress()->add_action( 'ap_ajax_delete_attachment', 'AnsPress_Uploader', 'delete_attachment' ); // List filtering. anspress()->add_action( 'ap_ajax_load_filter_order_by', __CLASS__, 'load_filter_order_by' ); // Subscribe. anspress()->add_action( 'ap_ajax_subscribe', __CLASS__, 'subscribe_to_question' ); anspress()->add_action( 'wp_ajax_ap_repeatable_field', 'AnsPress\Ajax\Repeatable_Field', 'init' ); anspress()->add_action( 'wp_ajax_nopriv_ap_repeatable_field', 'AnsPress\Ajax\Repeatable_Field', 'init' ); anspress()->add_action( 'wp_ajax_ap_form_question', 'AP_Form_Hooks', 'submit_question_form', 11, 0 ); anspress()->add_action( 'wp_ajax_nopriv_ap_form_question', 'AP_Form_Hooks', 'submit_question_form', 11, 0 ); anspress()->add_action( 'wp_ajax_ap_form_answer', 'AP_Form_Hooks', 'submit_answer_form', 11, 0 ); anspress()->add_action( 'wp_ajax_nopriv_ap_form_answer', 'AP_Form_Hooks', 'submit_answer_form', 11, 0 ); anspress()->add_action( 'wp_ajax_ap_form_comment', 'AP_Form_Hooks', 'submit_comment_form', 11, 0 ); anspress()->add_action( 'wp_ajax_nopriv_ap_form_comment', 'AP_Form_Hooks', 'submit_comment_form', 11, 0 ); anspress()->add_action( 'wp_ajax_ap_search_tags', __CLASS__, 'search_tags' ); anspress()->add_action( 'wp_ajax_nopriv_ap_search_tags', __CLASS__, 'search_tags' ); anspress()->add_action( 'wp_ajax_ap_image_upload', 'AnsPress_Uploader', 'image_upload' ); anspress()->add_action( 'wp_ajax_ap_upload_modal', 'AnsPress_Uploader', 'upload_modal' ); anspress()->add_action( 'wp_ajax_nopriv_ap_upload_modal', 'AnsPress_Uploader', 'upload_modal' ); } /** * Show similar questions while asking a question. * * @since 2.0.1 */ public static function suggest_similar_questions() { // Die if question suggestion is disabled. if ( ap_disable_question_suggestion() ) { wp_die( 'false' ); } $keyword = ap_sanitize_unslash( 'value', 'request' ); if ( empty( $keyword ) || ( ! ap_verify_default_nonce() && ! current_user_can( 'manage_options' ) ) ) { wp_die( 'false' ); } $keyword = ap_sanitize_unslash( 'value', 'request' ); $is_admin = (bool) ap_isset_post_value( 'is_admin', false ); $questions = get_posts( array( 'post_type' => 'question', 'showposts' => 10, 's' => $keyword, ) ); if ( $questions ) { $items = '<div class="ap-similar-questions-head">'; // translators: %d is count of questions. $items .= '<p><strong>' . sprintf( _n( '%d similar question found', '%d similar questions found', count( $questions ), 'anspress-question-answer' ), count( $questions ) ) . '</strong></p>'; $items .= '<p>' . __( 'We have found some similar questions that have been asked earlier.', 'anspress-question-answer' ) . '</p>'; $items .= '</div>'; $items .= '<div class="ap-similar-questions">'; foreach ( (array) $questions as $p ) { $count = ap_get_answers_count( $p->ID ); $p->post_title = ap_highlight_words( $p->post_title, $keyword ); if ( $is_admin ) { $items .= '<div class="ap-q-suggestion-item clearfix"><a class="select-question-button button button-primary button-small" href="' . add_query_arg( array( 'post_type' => 'answer', 'post_parent' => $p->ID, ), admin_url( 'post-new.php' ) ) . '">' . __( 'Select', 'anspress-question-answer' ) . '</a><span class="question-title">' . // translators: %d is total answer count. $p->post_title . '</span><span class="acount">' . sprintf( _n( '%d Answer', '%d Answers', $count, 'anspress-question-answer' ), $count ) . '</span></div>'; } else { // translators: %d is total answer count. $items .= '<a class="ap-sqitem clearfix" target="_blank" href="' . get_permalink( $p->ID ) . '"><span class="acount">' . sprintf( _n( '%d Answer', '%d Answers', $count, 'anspress-question-answer' ), $count ) . '</span><span class="ap-title">' . $p->post_title . '</span></a>'; } } $items .= '</div>'; $result = array( 'status' => true, 'html' => $items, ); } else { $result = array( 'status' => false, 'message' => __( 'No related questions found.', 'anspress-question-answer' ), ); } ap_ajax_json( $result ); } /** * Process ajax trash posts callback. */ public static function toggle_delete_post() { $post_id = (int) ap_sanitize_unslash( 'post_id', 'request' ); $failed_response = array( 'success' => false, 'snackbar' => array( 'message' => __( 'Unable to trash this post', 'anspress-question-answer' ) ), ); if ( ! anspress_verify_nonce( 'trash_post_' . $post_id ) ) { ap_ajax_json( $failed_response ); } $post = ap_get_post( $post_id ); $post_type = 'question' === $post->post_type ? __( 'Question', 'anspress-question-answer' ) : __( 'Answer', 'anspress-question-answer' ); if ( 'trash' === $post->post_status ) { if ( ! ap_user_can_restore( $post ) ) { ap_ajax_json( $failed_response ); } wp_untrash_post( $post->ID ); ap_ajax_json( array( 'success' => true, 'action' => array( 'active' => false, 'label' => __( 'Delete', 'anspress-question-answer' ), 'title' => sprintf( /* Translators: %s Question or Answer post type label for deleting a question or answer. */ __( 'Delete this %s (can be restored again)', 'anspress-question-answer' ), ( 'question' === $post->post_type ) ? esc_html__( 'question', 'anspress-question-answer' ) : esc_html__( 'answer', 'anspress-question-answer' ) ), ), // translators: %s post type. 'snackbar' => array( 'message' => sprintf( __( '%s is restored', 'anspress-question-answer' ), $post_type ) ), 'newStatus' => 'publish', 'postmessage' => ap_get_post_status_message( $post_id ), ) ); } if ( ! ap_user_can_delete_post( $post_id ) ) { ap_ajax_json( $failed_response ); } // Delete lock feature. // Do not allow post to be trashed if defined time elapsed. if ( ( time() > ( get_the_time( 'U', $post->ID ) + (int) ap_opt( 'disable_delete_after' ) ) ) && ! is_super_admin() ) { ap_ajax_json( array( 'success' => false, // translators: %s is human time difference. 'snackbar' => array( 'message' => sprintf( __( 'This post was created %s, hence you cannot trash it', 'anspress-question-answer' ), ap_human_time( get_the_time( 'U', $post->ID ) ) ) ), ) ); } wp_trash_post( $post_id ); ap_ajax_json( array( 'success' => true, 'action' => array( 'active' => true, 'label' => __( 'Undelete', 'anspress-question-answer' ), 'title' => sprintf( /* Translators: %s Question or Answer post type label for restoring a question or answer. */ __( 'Restore this %s', 'anspress-question-answer' ), ( 'question' === $post->post_type ) ? esc_html__( 'question', 'anspress-question-answer' ) : esc_html__( 'answer', 'anspress-question-answer' ) ), ), // translators: %s is post type. 'snackbar' => array( 'message' => sprintf( __( '%s is trashed', 'anspress-question-answer' ), $post_type ) ), 'newStatus' => 'trash', 'postmessage' => ap_get_post_status_message( $post_id ), ) ); } /** * Handle Ajax callback for permanent delete of post. */ public static function permanent_delete_post() { $post_id = (int) ap_sanitize_unslash( 'post_id', 'request' ); if ( ! anspress_verify_nonce( 'delete_post_' . $post_id ) || ! ap_user_can_permanent_delete( $post_id ) ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Sorry, unable to delete post', 'anspress-question-answer' ) ), ) ); } $post = ap_get_post( $post_id ); if ( 'question' === $post->post_type ) { /** * Triggered right before deleting question. * * @param integer $post_id question ID. */ do_action( 'ap_wp_trash_question', $post_id ); } else { /** * Triggered right before deleting answer. * * @param integer $post_id answer ID. */ do_action( 'ap_wp_trash_answer', $post_id ); } wp_delete_post( $post_id, true ); if ( 'question' === $post->post_type ) { ap_ajax_json( array( 'success' => true, 'redirect' => ap_base_page_link(), 'snackbar' => array( 'message' => __( 'Question is deleted permanently', 'anspress-question-answer' ) ), ) ); } $current_ans = ap_count_published_answers( $post->post_parent ); // translators: %d is answers count. $count_label = sprintf( _n( '%d Answer', '%d Answers', $current_ans, 'anspress-question-answer' ), $current_ans ); ap_ajax_json( array( 'success' => true, 'snackbar' => array( 'message' => __( 'Answer is deleted permanently', 'anspress-question-answer' ) ), 'deletePost' => $post_id, 'answersCount' => array( 'text' => $count_label, 'number' => $current_ans, ), ) ); } /** * Handle toggle featured question ajax callback * * @since unknown * @since 4.1.2 Insert to activity table when question is featured. */ public static function toggle_featured() { $post_id = (int) ap_sanitize_unslash( 'post_id', 'request' ); if ( ! ap_user_can_toggle_featured() || ! anspress_verify_nonce( 'set_featured_' . $post_id ) ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Sorry, you cannot toggle a featured question', 'anspress-question-answer' ) ), ) ); } $post = ap_get_post( $post_id ); // Do nothing if post type is not question. if ( 'question' !== $post->post_type ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Only question can be set as featured', 'anspress-question-answer' ) ), ) ); } // Check if current question ID is in featured question array. if ( ap_is_featured_question( $post ) ) { ap_unset_featured_question( $post->ID ); // Update activity. ap_activity_add( array( 'q_id' => $post->ID, 'action' => 'unfeatured', ) ); ap_ajax_json( array( 'success' => true, 'action' => array( 'active' => false, 'title' => __( 'Mark this question as featured', 'anspress-question-answer' ), 'label' => __( 'Feature', 'anspress-question-answer' ), ), 'snackbar' => array( 'message' => __( 'Question is unmarked as featured.', 'anspress-question-answer' ) ), ) ); } ap_set_featured_question( $post->ID ); // Update activity. ap_activity_add( array( 'q_id' => $post->ID, 'action' => 'featured', ) ); ap_ajax_json( array( 'success' => true, 'action' => array( 'active' => true, 'title' => __( 'Unmark this question as featured', 'anspress-question-answer' ), 'label' => __( 'Unfeature', 'anspress-question-answer' ), ), 'snackbar' => array( 'message' => __( 'Question is marked as featured.', 'anspress-question-answer' ) ), ) ); } /** * Close question callback. * * @since unknown * @since 4.1.2 Add activity when question is closed. */ public static function close_question() { $post_id = ap_sanitize_unslash( 'post_id', 'p' ); // Check permission and nonce. if ( ! is_user_logged_in() || ! check_ajax_referer( 'close_' . $post_id, 'nonce', false ) || ! ap_user_can_close_question() ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'You cannot close a question', 'anspress-question-answer' ) ), ) ); } $_post = ap_get_post( $post_id ); $toggle = ap_toggle_close_question( $post_id ); $close_label = $_post->closed ? __( 'Close', 'anspress-question-answer' ) : __( 'Open', 'anspress-question-answer' ); $close_title = $_post->closed ? __( 'Close this question for new answer.', 'anspress-question-answer' ) : __( 'Open this question for new answers', 'anspress-question-answer' ); $message = 1 === $toggle ? __( 'Question closed', 'anspress-question-answer' ) : __( 'Question is opened', 'anspress-question-answer' ); // Log in activity table. if ( 1 === $toggle ) { ap_activity_add( array( 'q_id' => $_post->ID, 'action' => 'closed_q', ) ); } else { ap_activity_add( array( 'q_id' => $_post->ID, 'action' => 'open_q', ) ); } $results = array( 'success' => true, 'action' => array( 'label' => $close_label, 'title' => $close_title, ), 'snackbar' => array( 'message' => $message ), 'postmessage' => ap_get_post_status_message( $post_id ), ); ap_ajax_json( $results ); } /** * Send JSON response and terminate. * * @param array|string $result Ajax response. */ public static function send( $result ) { ap_send_json( ap_ajax_responce( $result ) ); } /** * Load tinyMCE assets using ajax. * * @since 3.0.0 */ public static function load_tinymce() { ap_answer_form( ap_sanitize_unslash( 'question_id', 'r' ) ); ap_ajax_tinymce_assets(); wp_die(); } /** * Ajax callback for converting a question into a post. * * @since 3.0.0 */ public static function convert_to_post() { $post_id = ap_sanitize_unslash( 'post_id', 'r' ); if ( ! anspress_verify_nonce( 'convert-post-' . $post_id ) || ! ( is_super_admin() || current_user_can( 'manage_options' ) ) ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Sorry, you are not allowed to convert this question to post', 'anspress-question-answer' ) ), ) ); } $row = set_post_type( $post_id, 'post' ); // After success trash all answers. if ( $row ) { global $wpdb; // Get IDs of all answer. $answer_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d and post_type = 'answer' ", (int) $post_id ) ); // phpcs:ignore WordPress.DB foreach ( (array) $answer_ids as $id ) { wp_delete_post( $id ); } ap_ajax_json( array( 'success' => true, // translators: %s is post title. 'snackbar' => array( 'message' => sprintf( __( ' Question “%s” is converted to post and its answers are trashed', 'anspress-question-answer' ), esc_html( get_the_title( $post_id ) ) ) ), 'redirect' => get_the_permalink( $post_id ), ) ); } } /** * Ajax callback for loading order by filter. * * @since 4.0.0 */ public static function load_filter_order_by() { $filter = ap_sanitize_unslash( 'filter', 'r' ); check_ajax_referer( 'filter_' . $filter, '__nonce' ); ap_ajax_json( array( 'success' => true, 'multiple' => false, 'items' => ap_get_questions_orderby(), ) ); } /** * Subscribe user to a question. * * @return void * @since unknown */ public static function subscribe_to_question() { $post_id = (int) ap_sanitize_unslash( 'id', 'r' ); if ( ! is_user_logged_in() ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'You must be logged in to subscribe to a question', 'anspress-question-answer' ) ), ) ); } $_post = ap_get_post( $post_id ); if ( 'question' === $_post->post_type && ! anspress_verify_nonce( 'subscribe_' . $post_id ) ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Sorry, unable to subscribe', 'anspress-question-answer' ) ), ) ); } // Check if already subscribed, toggle if subscribed. $exists = ap_get_subscriber( false, 'question', $post_id ); if ( $exists ) { ap_delete_subscriber( $post_id, get_current_user_id(), 'question' ); ap_ajax_json( array( 'success' => true, 'snackbar' => array( 'message' => sprintf( /* Translators: %s Unsubscribed to the question title */ __( 'Successfully unsubscribed from question: %s', 'anspress-question-answer' ), $_post->post_title ), ), 'count' => ap_get_post_field( 'subscribers', $post_id ), 'label' => __( 'Subscribe', 'anspress-question-answer' ), ) ); } // Insert subscriber. $insert = ap_new_subscriber( false, 'question', $post_id ); if ( false === $insert ) { ap_ajax_json( array( 'success' => false, 'snackbar' => array( 'message' => __( 'Sorry, unable to subscribe', 'anspress-question-answer' ) ), ) ); } ap_ajax_json( array( 'success' => true, 'snackbar' => array( 'message' => sprintf( /* Translators: %s Subscribed to the question title */ __( 'Successfully subscribed to question: %s', 'anspress-question-answer' ), $_post->post_title ), ), 'count' => ap_get_post_field( 'subscribers', $post_id ), 'label' => __( 'Unsubscribe', 'anspress-question-answer' ), ) ); } /** * Ajax callback for `ap_search_tags`. This was called by tags field * for fetching tags suggestions. * * @return void * @since 4.1.5 */ public static function search_tags() { $q = ap_sanitize_unslash( 'q', 'r' ); $form = ap_sanitize_unslash( 'form', 'r' ); $field_name = ap_sanitize_unslash( 'field', 'r' ); if ( ! anspress_verify_nonce( 'tags_' . $form . $field_name ) ) { wp_send_json( '{}' ); } // Die if not valid form. if ( ! anspress()->form_exists( $form ) ) { ap_ajax_json( 'something_wrong' ); } $field = anspress()->get_form( $form )->find( $field_name ); // Check if field exists and type is tags. if ( ! is_a( $field, 'AnsPress\Form\Field\Tags' ) ) { ap_ajax_json( 'something_wrong' ); } $taxo = $field->get( 'terms_args.taxonomy' ); $taxo = ! empty( $taxo ) ? $taxo : 'tag'; $terms = get_terms( array( 'taxonomy' => $taxo, 'search' => $q, 'count' => true, 'number' => 20, 'hide_empty' => false, 'orderby' => 'count', ) ); $format = array(); if ( $terms ) { foreach ( $terms as $t ) { $format[] = array( 'term_id' => $t->term_id, 'name' => $t->name, 'description' => $t->description, // translators: %d is question count. 'count' => sprintf( _n( '%d Question', '%d Questions', $t->count, 'anspress-question-answer' ), $t->count ), ); } } wp_send_json( $format ); } }
Expand full source code Collapse full source code View on GitHub: includes/ajax-hooks.php:22
Add your comment