'POST', 'callback' => array($this, 'create_suggestion'), 'permission_callback' => array($this, 'check_user_permission'), 'args' => array( 'title' => array( 'required' => true, 'validate_callback' => array($this, 'validate_title'), 'sanitize_callback' => 'sanitize_text_field' ), 'content' => array( 'required' => true, 'validate_callback' => array($this, 'validate_content'), 'sanitize_callback' => 'wp_kses_post' ) ) )); register_rest_route('pc-community-suggestions/v1', '/suggestions/(?P\d+)/vote', array( 'methods' => 'POST', 'callback' => array($this, 'vote_suggestion'), 'permission_callback' => array($this, 'check_user_permission'), 'args' => array( 'id' => array( 'required' => true, 'validate_callback' => array($this, 'validate_suggestion_id') ) ) )); register_rest_route('pc-community-suggestions/v1', '/suggestions', array( 'methods' => 'GET', 'callback' => array($this, 'get_suggestions'), 'permission_callback' => '__return_true', 'args' => array( 'page' => array( 'default' => 1, 'validate_callback' => array($this, 'validate_page') ), 'per_page' => array( 'default' => 10, 'validate_callback' => array($this, 'validate_per_page') ), 'sort' => array( 'default' => 'popular', 'validate_callback' => array($this, 'validate_sort') ) ) )); } public function check_user_permission() { return is_user_logged_in(); } public function validate_title($title) { $title = sanitize_text_field($title); return !empty($title) && strlen($title) <= 255; } public function validate_content($content) { $content = wp_kses_post($content); return !empty($content) && strlen($content) >= 10; } public function validate_suggestion_id($id) { return is_numeric($id) && $id > 0; } public function validate_page($page) { return is_numeric($page) && $page > 0; } public function validate_per_page($per_page) { return is_numeric($per_page) && $per_page > 0 && $per_page <= 50; } public function validate_sort($sort) { return in_array($sort, array('popular', 'newest')); } public function create_suggestion(WP_REST_Request $request) { $title = $request->get_param('title'); $content = $request->get_param('content'); $user_id = get_current_user_id(); // Check for duplicate submissions $existing = $this->check_duplicate_suggestion($user_id, $title); if ($existing) { return new WP_Error('duplicate', __('You have already submitted a similar suggestion.', 'pc-community-suggestions-7d3f'), array('status' => 400)); } $suggestion_id = PC_Community_Suggestions_Database::add_suggestion($user_id, $title, $content); if (!$suggestion_id) { return new WP_Error('database_error', __('Failed to create suggestion.', 'pc-community-suggestions-7d3f'), array('status' => 500)); } return rest_ensure_response(array( 'success' => true, 'suggestion_id' => $suggestion_id, 'message' => __('Your suggestion has been published successfully.', 'pc-community-suggestions-7d3f') )); } private function check_duplicate_suggestion($user_id, $title) { global $wpdb; $table_name = $wpdb->prefix . 'pc_community_suggestions'; $similar_title = '%' . $wpdb->esc_like($title) . '%'; $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE user_id = %d AND title LIKE %s AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)", $user_id, $similar_title ) ); return $count > 0; } public function vote_suggestion(WP_REST_Request $request) { $suggestion_id = $request->get_param('id'); $user_id = get_current_user_id(); $result = PC_Community_Suggestions_Database::add_vote($suggestion_id, $user_id); if (!$result) { return new WP_Error('already_voted', __('You have already voted for this suggestion.', 'pc-community-suggestions-7d3f'), array('status' => 400)); } return rest_ensure_response(array( 'success' => true, 'message' => __('Vote recorded successfully.', 'pc-community-suggestions-7d3f') )); } public function get_suggestions(WP_REST_Request $request) { $page = $request->get_param('page'); $per_page = $request->get_param('per_page'); $sort = $request->get_param('sort'); $suggestions = PC_Community_Suggestions_Database::get_suggestions($page, $per_page, $sort); $total = PC_Community_Suggestions_Database::get_suggestion_count(); $formatted_suggestions = array(); foreach ($suggestions as $suggestion) { $formatted_suggestions[] = array( 'id' => $suggestion->id, 'title' => $suggestion->title, 'content' => $suggestion->content, 'upvotes' => $suggestion->upvotes, 'author' => $suggestion->display_name ?: $suggestion->user_login, 'created_at' => $suggestion->created_at, 'human_date' => human_time_diff(strtotime($suggestion->created_at), current_time('timestamp')) ); } return rest_ensure_response(array( 'suggestions' => $formatted_suggestions, 'pagination' => array( 'current_page' => $page, 'per_page' => $per_page, 'total' => $total, 'total_pages' => ceil($total / $per_page) ) )); } public function handle_suggestion_submission() { error_log('PC Community Suggestions: handle_suggestion_submission called'); $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : ''; error_log('PC Community Suggestions: Nonce value: ' . substr($nonce, 0, 20) . '...'); if (!check_ajax_referer('pc_community_suggestions_nonce', 'nonce', false)) { error_log('PC Community Suggestions: Nonce check failed'); wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } if (!is_user_logged_in()) { error_log('PC Community Suggestions: User not logged in'); wp_send_json_error(array('message' => __('You must be logged in to submit suggestions.', 'pc-community-suggestions-7d3f'))); } $title = isset($_POST['title']) ? sanitize_text_field($_POST['title']) : ''; $content = isset($_POST['content']) ? wp_kses_post($_POST['content']) : ''; error_log('PC Community Suggestions: Title length: ' . strlen($title) . ', Content length: ' . strlen($content)); if (empty($title) || empty($content)) { wp_send_json_error(array('message' => __('Please fill in all required fields.', 'pc-community-suggestions-7d3f'))); } if (strlen($title) > 255) { wp_send_json_error(array('message' => __('Title must be less than 255 characters.', 'pc-community-suggestions-7d3f'))); } if (strlen($content) < 10) { wp_send_json_error(array('message' => __('Content must be at least 10 characters long.', 'pc-community-suggestions-7d3f'))); } $user_id = get_current_user_id(); error_log('PC Community Suggestions: User ID: ' . $user_id); try { $existing = $this->check_duplicate_suggestion($user_id, $title); if ($existing) { error_log('PC Community Suggestions: Duplicate suggestion detected'); wp_send_json_error(array('message' => __('You have already submitted a similar suggestion recently.', 'pc-community-suggestions-7d3f'))); } if (!PC_Community_Suggestions_Database::verify_tables()) { error_log('PC Community Suggestions: Tables do not exist, creating...'); PC_Community_Suggestions_Database::create_tables(); } $suggestion_id = PC_Community_Suggestions_Database::add_suggestion($user_id, $title, $content); if (!$suggestion_id) { global $wpdb; $last_error = $wpdb->last_error; error_log('PC Community Suggestions DB Error: ' . $last_error); wp_send_json_error(array('message' => __('Failed to submit suggestion. Database error.', 'pc-community-suggestions-7d3f'))); } error_log('PC Community Suggestions: Suggestion created successfully with ID: ' . $suggestion_id); wp_send_json_success(array( 'message' => __('Your suggestion has been published successfully.', 'pc-community-suggestions-7d3f') )); } catch (Exception $e) { error_log('PC Community Suggestions Exception: ' . $e->getMessage()); wp_send_json_error(array('message' => __('An error occurred: ', 'pc-community-suggestions-7d3f') . $e->getMessage())); } } public function handle_vote() { if (!check_ajax_referer('pc_community_suggestions_nonce', 'nonce', false)) { wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } if (!is_user_logged_in()) { wp_send_json_error(array('message' => __('You must be logged in to vote.', 'pc-community-suggestions-7d3f'))); } $suggestion_id = isset($_POST['suggestion_id']) ? intval($_POST['suggestion_id']) : 0; $user_id = get_current_user_id(); if ($suggestion_id <= 0) { wp_send_json_error(array('message' => __('Invalid suggestion.', 'pc-community-suggestions-7d3f'))); } $result = PC_Community_Suggestions_Database::add_vote($suggestion_id, $user_id); if (!$result) { wp_send_json_error(array('message' => __('You have already voted for this suggestion.', 'pc-community-suggestions-7d3f'))); } wp_send_json_success(array('message' => __('Vote recorded successfully.', 'pc-community-suggestions-7d3f'))); } public function handle_not_logged_in() { wp_send_json_error(array('message' => __('You must be logged in to perform this action.', 'pc-community-suggestions-7d3f'))); } public function handle_get_suggestion() { if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('You do not have permission to view this suggestion.', 'pc-community-suggestions-7d3f'))); } if (!check_ajax_referer('pc_admin_nonce', 'nonce', false)) { wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } $suggestion_id = isset($_POST['suggestion_id']) ? intval($_POST['suggestion_id']) : 0; if ($suggestion_id <= 0) { wp_send_json_error(array('message' => __('Invalid suggestion ID.', 'pc-community-suggestions-7d3f'))); } global $wpdb; $table_name = $wpdb->prefix . 'pc_community_suggestions'; $suggestion = $wpdb->get_row( $wpdb->prepare( "SELECT s.*, u.user_login, u.display_name FROM $table_name s LEFT JOIN {$wpdb->users} u ON s.user_id = u.ID WHERE s.id = %d", $suggestion_id ) ); if (!$suggestion) { wp_send_json_error(array('message' => __('Suggestion not found.', 'pc-community-suggestions-7d3f'))); } wp_send_json_success(array( 'id' => $suggestion->id, 'title' => $suggestion->title, 'content' => wpautop($suggestion->content), 'author' => $suggestion->display_name ?: $suggestion->user_login, 'date' => date_i18n(get_option('date_format'), strtotime($suggestion->created_at)), 'upvotes' => $suggestion->upvotes, )); } public function handle_get_stats() { if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('You do not have permission to view statistics.', 'pc-community-suggestions-7d3f'))); } if (!check_ajax_referer('pc_admin_nonce', 'nonce', false)) { wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } wp_send_json_success(array( 'total' => PC_Community_Suggestions_Database::get_suggestion_count() )); } public function handle_add_comment() { if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('You do not have permission to add comments.', 'pc-community-suggestions-7d3f'))); } if (!check_ajax_referer('pc_admin_nonce', 'nonce', false)) { wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } $suggestion_id = isset($_POST['suggestion_id']) ? intval($_POST['suggestion_id']) : 0; $comment = isset($_POST['comment']) ? wp_kses_post($_POST['comment']) : ''; $admin_id = get_current_user_id(); if ($suggestion_id <= 0 || empty($comment)) { wp_send_json_error(array('message' => __('Invalid data provided.', 'pc-community-suggestions-7d3f'))); } $comment_id = PC_Community_Suggestions_Database::add_comment($suggestion_id, $admin_id, $comment); if (!$comment_id) { wp_send_json_error(array('message' => __('Failed to add comment.', 'pc-community-suggestions-7d3f'))); } $admin = get_userdata($admin_id); $admin_name = $admin->display_name ?: $admin->user_login; wp_send_json_success(array( 'message' => __('Comment added successfully.', 'pc-community-suggestions-7d3f'), 'comment' => array( 'id' => $comment_id, 'content' => wpautop($comment), 'author' => $admin_name, 'date' => date_i18n(get_option('date_format'), current_time('timestamp')) ) )); } public function handle_delete_comment() { if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('You do not have permission to delete comments.', 'pc-community-suggestions-7d3f'))); } if (!check_ajax_referer('pc_admin_nonce', 'nonce', false)) { wp_send_json_error(array('message' => __('Security check failed. Please try again.', 'pc-community-suggestions-7d3f'))); } $comment_id = isset($_POST['comment_id']) ? intval($_POST['comment_id']) : 0; if ($comment_id <= 0) { wp_send_json_error(array('message' => __('Invalid comment ID.', 'pc-community-suggestions-7d3f'))); } $result = PC_Community_Suggestions_Database::delete_comment($comment_id); if (!$result) { wp_send_json_error(array('message' => __('Failed to delete comment.', 'pc-community-suggestions-7d3f'))); } wp_send_json_success(array( 'message' => __('Comment deleted successfully.', 'pc-community-suggestions-7d3f') )); } }