get_pending_posts( $paged ); include PRAUTOBLOGGER_PLUGIN_DIR . 'templates/admin/review-queue.php'; } /** * Query generated draft posts awaiting review. * * @param int $paged Page number. * * @return \WP_Query */ public function get_pending_posts( int $paged = 1 ): \WP_Query { return new \WP_Query( [ 'post_type' => 'post', 'post_status' => 'draft', 'posts_per_page' => 20, 'paged' => $paged, 'meta_query' => [ [ 'key' => '_prautoblogger_generated', 'value' => '1', ], ], 'orderby' => 'date', 'order' => 'DESC', ] ); } /** * Handle bulk approve/reject actions submitted via form POST. * * Verifies nonce and capability before processing. Redirects back with * a status message query arg. * * Side effects: changes post status, may trash posts. * * @return void */ public function on_handle_bulk_actions(): void { if ( ! isset( $_POST['prautoblogger_bulk_action'] ) ) { return; } check_admin_referer( 'prautoblogger_review_queue_bulk', 'prautoblogger_review_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { return; } $action = sanitize_text_field( wp_unslash( $_POST['prautoblogger_bulk_action'] ) ); $post_ids = isset( $_POST['prautoblogger_post_ids'] ) && is_array( $_POST['prautoblogger_post_ids'] ) ? array_map( 'absint', $_POST['prautoblogger_post_ids'] ) : []; if ( empty( $post_ids ) ) { return; } $count = 0; foreach ( $post_ids as $post_id ) { if ( $post_id <= 0 ) { continue; } if ( 'approve' === $action ) { $result = wp_update_post( [ 'ID' => $post_id, 'post_status' => 'publish' ], true ); if ( ! is_wp_error( $result ) ) { update_post_meta( $post_id, '_prautoblogger_approved_at', gmdate( 'c' ) ); $count++; } } elseif ( 'reject' === $action ) { $result = wp_trash_post( $post_id ); if ( false !== $result ) { $count++; } } } $redirect = add_query_arg( [ 'page' => 'prautoblogger-review-queue', 'prautoblogger_bulk_done' => $count, 'prautoblogger_bulk_type' => $action, ], admin_url( 'admin.php' ) ); wp_safe_redirect( $redirect ); exit; } /** * AJAX handler: approve a single post (publish it). * * Side effects: changes post status to 'publish'. * * @return void */ public function on_ajax_approve_post(): void { check_ajax_referer( 'prautoblogger_review_queue', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'prautoblogger' ) ], 403 ); return; } $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; if ( $post_id <= 0 ) { wp_send_json_error( [ 'message' => __( 'Invalid post ID.', 'prautoblogger' ) ] ); return; } $result = wp_update_post( [ 'ID' => $post_id, 'post_status' => 'publish' ], true ); if ( is_wp_error( $result ) ) { wp_send_json_error( [ 'message' => $result->get_error_message() ] ); return; } update_post_meta( $post_id, '_prautoblogger_approved_at', gmdate( 'c' ) ); wp_send_json_success( [ 'message' => __( 'Post published.', 'prautoblogger' ), 'post_id' => $post_id ] ); } /** * AJAX handler: reject a single post (trash it). * * Side effects: trashes the post. * * @return void */ public function on_ajax_reject_post(): void { check_ajax_referer( 'prautoblogger_review_queue', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'prautoblogger' ) ], 403 ); return; } $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; if ( $post_id <= 0 ) { wp_send_json_error( [ 'message' => __( 'Invalid post ID.', 'prautoblogger' ) ] ); return; } $result = wp_trash_post( $post_id ); if ( false === $result || null === $result ) { wp_send_json_error( [ 'message' => __( 'Failed to reject post.', 'prautoblogger' ) ] ); return; } wp_send_json_success( [ 'message' => __( 'Post rejected.', 'prautoblogger' ), 'post_id' => $post_id ] ); } }