From a8e369cf77cd3225d5403c0eb73bdee706e3c05f Mon Sep 17 00:00:00 2001 From: Norcross Date: Fri, 15 Nov 2024 09:52:41 -0500 Subject: [PATCH 1/4] adding settings field adding the bulk update button into the existing settings setup --- includes/settings-api.php | 75 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/includes/settings-api.php b/includes/settings-api.php index 7c0cc37..a2989cc 100644 --- a/includes/settings-api.php +++ b/includes/settings-api.php @@ -16,8 +16,43 @@ /** * Start our engines. */ +add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\load_settings_field_css' ); add_action( 'admin_init', __NAMESPACE__ . '\load_comment_settings' ); +/** + * Include a small bit of CSS for our admin. + * + * @param string $hook_suffix The hook suffix on admin. + * + * @return void + */ +function load_settings_field_css( $hook_suffix ) { + + // Only load this on the comment settings page. + if ( empty( $hook_suffix ) || 'options-discussion.php' !== $hook_suffix ) { + return; + } + + // Set my CSS up. + $setup_css = ' + tr.ip-scrub-bulk-action-wrapper th, + tr.ip-scrub-bulk-action-wrapper td { + padding-top: 0; + } + + tr.ip-scrub-bulk-action-wrapper a.ip-scrub-bulk-admin-button { + margin-bottom: 5px; + } + + tr.ip-scrub-bulk-action-wrapper p.ip-scrub-bulk-button-explain { + margin-top: 0; + } + '; + + // And add the CSS. + wp_add_inline_style( 'common', $setup_css ); +} + /** * Add a checkbox to the comment settings for removing IP addresses. * @@ -25,11 +60,22 @@ */ function load_comment_settings() { + // Define the args for the setting registration. + $setup_args = [ + 'type' => 'string', + 'show_in_rest' => false, + 'default' => 'yes', + 'sanitize_callback' => __NAMESPACE__ . '\sanitize_scrub_setting', + ]; + // Add out checkbox with a sanitiation callback. - register_setting( 'discussion', Core\OPTION_KEY, __NAMESPACE__ . '\sanitize_scrub_setting' ); + register_setting( 'discussion', Core\OPTION_KEY, $setup_args ); + + // Load the actual checkbox field itself. + add_settings_field( 'ip-scrub-enable', __( 'Scrub Comment IPs', 'scrub-comment-author-ip' ), __NAMESPACE__ . '\display_field', 'discussion', 'default', [ 'class' => 'ip-scrub-enable-wrapper' ] ); - // Load the actual field itself. - add_settings_field( 'ip-scrub-enable', __( 'Scrub Comment IPs', 'scrub-comment-author-ip' ), __NAMESPACE__ . '\display_field', 'discussion', 'default' ); + // Load the button for the bulk action. + add_settings_field( 'ip-scrub-bulk-action', '', __NAMESPACE__ . '\bulk_action_field', 'discussion', 'default', [ 'class' => 'ip-scrub-bulk-action-wrapper' ] ); } /** @@ -58,6 +104,29 @@ function display_field() { echo ''; } +/** + * Display a button for the bulk action. + * + * @return HTML + */ +function bulk_action_field() { + + // Set the bulk args up. + $set_bulk_args = [ + 'ip-scrub-run-bulk' => 'yes', + 'ip-scrub-nonce' => wp_create_nonce( 'scrub_bulk' ), + ]; + + // Set up the link for runniing the bulk update. + $set_bulk_link = add_query_arg( $set_bulk_args, admin_url( 'options-discussion.php' ) ); + + // And show the button link. + echo '' . __( 'Bulk Cleanup', 'scrub-comment-author-ip' ) . ''; + + // And add some text explaining what this is. + echo '

' . esc_html__( 'For sites with a large amount of comments, it is suggested to use the WP-CLI command included with this plugin.', 'scrub-comment-author-ip' ) . '

'; +} + /** * Make sure the setting is valid. * From 78f192180683bf0a7709bd21508523644bd4733c Mon Sep 17 00:00:00 2001 From: Norcross Date: Fri, 15 Nov 2024 10:55:15 -0500 Subject: [PATCH 2/4] adding UI element adding UI element and related processing --- includes/bulk-process.php | 200 ++++++++++++++++++++++++++++++++++++ includes/database.php | 35 +++++++ includes/helpers.php | 18 ++++ includes/settings-api.php | 20 ++-- scrub-comment-author-ip.php | 1 + 5 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 includes/bulk-process.php diff --git a/includes/bulk-process.php b/includes/bulk-process.php new file mode 100644 index 0000000..ee65184 --- /dev/null +++ b/includes/bulk-process.php @@ -0,0 +1,200 @@ + true ] ); + } + + // Now get the IDs of the comments we have. + $fetch_comments = Database\get_ids_for_update(); + + // If none exist, say so. + if ( empty( $fetch_comments ) ) { + + // Now set my redirect link. + $redirect_link = Helpers\fetch_settings_url( ['ip-scrub-bulk-error' => 'no-comments', 'ip-scrub-bulk-success' => 'no'] ); + + // Do the redirect. + wp_safe_redirect( $redirect_link ); + exit; + } + + // Handle the WP_Error return on it's own. + if ( is_wp_error( $fetch_comments ) ) { + + // Now set my redirect link. + $redirect_link = Helpers\fetch_settings_url( ['ip-scrub-bulk-error' => 'query-error', 'ip-scrub-bulk-success' => 'no'] ); + + // Do the redirect. + wp_safe_redirect( $redirect_link ); + exit; + } + + // Attempt the update. + $attempt_update = Database\replace_batch_comment_ips( $fetch_comments ); + + // Bail if the update did. + if ( empty( $attempt_update ) || is_wp_error( $attempt_update ) ) { + + // Now set my redirect link. + $redirect_link = Helpers\fetch_settings_url( ['ip-scrub-bulk-error' => 'update-error', 'ip-scrub-bulk-success' => 'no'] ); + + // Do the redirect. + wp_safe_redirect( $redirect_link ); + exit; + } + + // Now set my redirect link. + $redirect_link = Helpers\fetch_settings_url( ['ip-scrub-bulk-count' => count( $fetch_comments ), 'ip-scrub-bulk-success' => 'yes'] ); + + // Do the redirect. + wp_safe_redirect( $redirect_link ); + exit; +} + +/** + * Check for the result of bulk action. + * + * @return void + */ +function admin_bulk_action_notice() { + + // Confirm we requested this action. + $confirm_result = filter_input( INPUT_GET, 'ip-scrub-bulk-success', FILTER_SANITIZE_SPECIAL_CHARS ); // phpcs:ignore -- no need for a nonce check. + + // Make sure it is what we want. + if ( empty( $confirm_result ) ) { + return; + } + + // Handle the success first. + if ( 'yes' === $confirm_result ) { + + // Set the counts. + $set_counts = filter_input( INPUT_GET, 'ip-scrub-bulk-count', FILTER_SANITIZE_NUMBER_INT ); + + // Set our notice text. + $set_notice = sprintf( _n( 'Success! %d comment was updated.', 'Success! %d comments were updated.', absint( $set_counts ), 'scrub-comment-author-ip' ), absint( $set_counts ) ); + + // Set the wrapper around it. + echo '
'; + + // Display the actual message. + echo '

' . wp_kses_post( $set_notice ) . '

'; + + // Close the wrapper. + echo '
'; + + // And be done. + return; + } + + // Handle the errors now. + $set_error = filter_input( INPUT_GET, 'ip-scrub-bulk-error', FILTER_SANITIZE_SPECIAL_CHARS ); + + // If we have no comments, show a warning. + if ( 'no-comments' === $set_error ) { + + // Set the notice text. + $set_notice = __( 'There are no comments requiring update at this time.', 'scrub-comment-author-ip' ); + + // Set the wrapper around it. + echo '
'; + + // Display the actual message. + echo '

' . wp_kses_post( $set_notice ) . '

'; + + // Close the wrapper. + echo '
'; + + // And finish. + return; + } + + // Handle the rest of the possible error messages. + switch ( $set_error ) { + + case 'query-error' : + $set_notice = __( 'There was an error attempting to retrieve the comments. Please check your error logs.', 'scrub-comment-author-ip' ); + break; + + case 'update-error' : + $set_notice = __( 'There was an error attempting to update the comments. Please check your error logs.', 'scrub-comment-author-ip' ); + break; + + default : + $set_notice = __( 'There was an unknown error. Please check your error logs.', 'scrub-comment-author-ip' ); + break; + } + + // Set the wrapper around it. + echo '
'; + + // Display the actual message. + echo '

' . wp_kses_post( $set_notice ) . '

'; + + // Close the wrapper. + echo '
'; + + // Nothing left to display. +} + +/** + * Add our custom strings to the vars. + * + * @param array $args The existing array of args. + * + * @return array $args The modified array of args. + */ +function admin_removable_args( $args ) { + + // Set an array of the args we wanna exclude. + $remove = [ + 'ip-scrub-bulk-error', + 'ip-scrub-bulk-count', + 'ip-scrub-bulk-success', + ]; + + // Include my new args and return. + return wp_parse_args( $remove, $args ); +} diff --git a/includes/database.php b/includes/database.php index cdcc515..b7d1331 100644 --- a/includes/database.php +++ b/includes/database.php @@ -15,6 +15,41 @@ // And pull in any other namespaces. use WP_Error; +/** + * Just get a simple count. + * + * @return array + */ +function get_count_for_update() { + + // Fetch the masked IP. + $masked_ip = Helpers\fetch_masked_ip(); + + // Call the global class. + global $wpdb; + + // Set my table name. + $table_name = $wpdb->prefix . 'comments'; + + // Set up our query. + $query_args = $wpdb->prepare(" + SELECT COUNT(*) + FROM $table_name + WHERE comment_author_IP NOT LIKE '%s' + ", esc_attr( $masked_ip ) ); + + // Process the query. + $query_run = $wpdb->get_var( $query_args ); + + // Throw the error if we have one. + if ( is_wp_error( $query_run ) ) { + return new WP_Error( $query_run->get_error_code(), $query_run->get_error_message() ); + } + + // Return the count, whatever it may be. + return absint( $query_run ); +} + /** * Get all my comment IDs. * diff --git a/includes/helpers.php b/includes/helpers.php index 54a9f84..17d0a40 100644 --- a/includes/helpers.php +++ b/includes/helpers.php @@ -66,3 +66,21 @@ function fetch_masked_ip() { // Confirm it's a valid IP before returning it. return ! empty( $masked_ip ) && filter_var( $masked_ip, FILTER_VALIDATE_IP ) ? $masked_ip : '127.0.0.1'; } + +/** + * Get the URL for our settings page with any custom args. + * + * @param array $args The possible array of args. + * + * @return string + */ +function fetch_settings_url( $args = [] ) { + + // If we have no args, just do the basic link. + if ( empty( $args ) ) { + return admin_url( 'options-discussion.php' ); + } + + // Now return it in args. + return add_query_arg( $args, admin_url( 'options-discussion.php' ) ); +} diff --git a/includes/settings-api.php b/includes/settings-api.php index a2989cc..0794a29 100644 --- a/includes/settings-api.php +++ b/includes/settings-api.php @@ -74,8 +74,13 @@ function load_comment_settings() { // Load the actual checkbox field itself. add_settings_field( 'ip-scrub-enable', __( 'Scrub Comment IPs', 'scrub-comment-author-ip' ), __NAMESPACE__ . '\display_field', 'discussion', 'default', [ 'class' => 'ip-scrub-enable-wrapper' ] ); + // Get the amount we could fix. + $get_bulk_nums = Database\get_count_for_update(); + // Load the button for the bulk action. - add_settings_field( 'ip-scrub-bulk-action', '', __NAMESPACE__ . '\bulk_action_field', 'discussion', 'default', [ 'class' => 'ip-scrub-bulk-action-wrapper' ] ); + if ( ! empty( $get_bulk_nums ) ) { + add_settings_field( 'ip-scrub-bulk-action', '', __NAMESPACE__ . '\bulk_action_field', 'discussion', 'default', [ 'class' => 'ip-scrub-bulk-action-wrapper', 'counts' => $get_bulk_nums ] ); + } } /** @@ -109,22 +114,25 @@ function display_field() { * * @return HTML */ -function bulk_action_field() { +function bulk_action_field( $args ) { // Set the bulk args up. $set_bulk_args = [ 'ip-scrub-run-bulk' => 'yes', - 'ip-scrub-nonce' => wp_create_nonce( 'scrub_bulk' ), + 'ip-scrub-nonce' => wp_create_nonce( 'ip_scrub_bulk' ), ]; // Set up the link for runniing the bulk update. - $set_bulk_link = add_query_arg( $set_bulk_args, admin_url( 'options-discussion.php' ) ); + $set_bulk_link = Helpers\fetch_settings_url( $set_bulk_args ); // And show the button link. echo '' . __( 'Bulk Cleanup', 'scrub-comment-author-ip' ) . ''; - // And add some text explaining what this is. - echo '

' . esc_html__( 'For sites with a large amount of comments, it is suggested to use the WP-CLI command included with this plugin.', 'scrub-comment-author-ip' ) . '

'; + // If we have a lot of comments, show the CLI message. + // @todo decide on a large number. + if ( ! empty( $args['counts'] ) && 200 < absint( $args['counts'] ) ) { + echo '

' . esc_html__( 'For sites with a large amount of comments, it is suggested to use the WP-CLI command included with this plugin.', 'scrub-comment-author-ip' ) . '

'; + } } /** diff --git a/scrub-comment-author-ip.php b/scrub-comment-author-ip.php index 021a2ca..0999b2a 100644 --- a/scrub-comment-author-ip.php +++ b/scrub-comment-author-ip.php @@ -43,6 +43,7 @@ require_once __DIR__ . '/includes/helpers.php'; require_once __DIR__ . '/includes/settings-api.php'; require_once __DIR__ . '/includes/database.php'; +require_once __DIR__ . '/includes/bulk-process.php'; require_once __DIR__ . '/includes/comment-process.php'; // Check that we have the CLI constant available. From 38ef2af75062b5ccd96b7e11dffbc12d60254b94 Mon Sep 17 00:00:00 2001 From: Norcross Date: Mon, 18 Nov 2024 10:06:25 -0500 Subject: [PATCH 3/4] updating PHPCS linting updating all the linting messages from PHPCS --- includes/activate.php | 3 --- includes/database.php | 30 +++++++++--------------------- includes/deactivate.php | 3 --- includes/helpers.php | 4 ++-- includes/settings-api.php | 8 ++++---- includes/uninstall.php | 3 --- 6 files changed, 15 insertions(+), 36 deletions(-) diff --git a/includes/activate.php b/includes/activate.php index d221e53..40bad63 100644 --- a/includes/activate.php +++ b/includes/activate.php @@ -23,8 +23,5 @@ function activate() { // Include our action so that we may add to this later. do_action( Core\HOOK_PREFIX . 'activate_process' ); - - // And flush our rewrite rules. - flush_rewrite_rules(); } register_activation_hook( Core\FILE, __NAMESPACE__ . '\activate' ); diff --git a/includes/database.php b/includes/database.php index b7d1331..bb5e210 100644 --- a/includes/database.php +++ b/includes/database.php @@ -28,18 +28,15 @@ function get_count_for_update() { // Call the global class. global $wpdb; - // Set my table name. - $table_name = $wpdb->prefix . 'comments'; - // Set up our query. $query_args = $wpdb->prepare(" SELECT COUNT(*) - FROM $table_name + FROM $wpdb->comments WHERE comment_author_IP NOT LIKE '%s' ", esc_attr( $masked_ip ) ); // Process the query. - $query_run = $wpdb->get_var( $query_args ); + $query_run = $wpdb->get_var( $query_args ); // phpcs:ignore -- we are skipping the overhead of get_comments. // Throw the error if we have one. if ( is_wp_error( $query_run ) ) { @@ -63,18 +60,15 @@ function get_ids_for_update() { // Call the global class. global $wpdb; - // Set my table name. - $table_name = $wpdb->prefix . 'comments'; - // Set up our query. $query_args = $wpdb->prepare(" SELECT comment_ID - FROM $table_name + FROM $wpdb->comments WHERE comment_author_IP NOT LIKE '%s' ", esc_attr( $masked_ip ) ); // Process the query. - $query_run = $wpdb->get_col( $query_args ); + $query_run = $wpdb->get_col( $query_args ); // phpcs:ignore -- we are skipping the overhead of get_comments. // Throw the error if we have one. if ( is_wp_error( $query_run ) ) { @@ -119,12 +113,9 @@ function replace_single_comment_ip( $comment_id = 0, $masked_ip = '' ) { // Call the global class. global $wpdb; - // Set my table name. - $table_name = $wpdb->prefix . 'comments'; - // Run the actual DB update. - $update_row = $wpdb->update( - $table_name, + $update_row = $wpdb->update( // phpcs:ignore -- we dont want to trigger anything else here. + $wpdb->comments, [ 'comment_author_IP' => $set_new_ip ], [ 'comment_ID' => absint( $comment_id ) ], [ '%s' ], @@ -147,7 +138,7 @@ function replace_single_comment_ip( $comment_id = 0, $masked_ip = '' ) { * * @return mixed */ -function replace_batch_comment_ips( $comment_ids = array() ) { +function replace_batch_comment_ips( $comment_ids = [] ) { // Bail if no comment IDs were provided. if ( empty( $comment_ids ) ) { @@ -168,15 +159,12 @@ function replace_batch_comment_ips( $comment_ids = array() ) { // Call the global class. global $wpdb; - // Set my table name. - $table_name = $wpdb->prefix . 'comments'; - // Now loop the IDs and run the update. foreach ( $comment_ids as $comment_id ) { // Run the actual DB update. - $update_row = $wpdb->update( - $table_name, + $update_row = $wpdb->update( // phpcs:ignore -- we dont want to trigger anything else here. + $wpdb->comments, [ 'comment_author_IP' => $masked_ip ], [ 'comment_ID' => absint( $comment_id ) ], [ '%s' ], diff --git a/includes/deactivate.php b/includes/deactivate.php index 48f61d0..4a72d2b 100644 --- a/includes/deactivate.php +++ b/includes/deactivate.php @@ -20,8 +20,5 @@ function deactivate() { // Include our action so that we may add to this later. do_action( Core\HOOK_PREFIX . 'deactivate_process' ); - - // And flush our rewrite rules. - flush_rewrite_rules(); } register_deactivation_hook( Core\FILE, __NAMESPACE__ . '\deactivate' ); diff --git a/includes/helpers.php b/includes/helpers.php index 17d0a40..d6e60c6 100644 --- a/includes/helpers.php +++ b/includes/helpers.php @@ -36,7 +36,7 @@ function maybe_scrub_enabled( $return_type = 'string' ) { // Check for the stored "yes" to return. return ! empty( $set_option ) && 'yes' === sanitize_text_field( $set_option ) ? true : false; - // And break. + // Done. break; // Handle my yes / no string return. @@ -45,7 +45,7 @@ function maybe_scrub_enabled( $return_type = 'string' ) { // Check for the stored "yes" to return. return ! empty( $set_option ) && 'yes' === sanitize_text_field( $set_option ) ? 'yes' : 'no'; - // And break. + // Done. break; } diff --git a/includes/settings-api.php b/includes/settings-api.php index 0794a29..e372556 100644 --- a/includes/settings-api.php +++ b/includes/settings-api.php @@ -91,16 +91,16 @@ function load_comment_settings() { function display_field() { // Set a label with our default IP. - $set_label = sprintf( __( 'Replace the comment author IP address with %s', 'scrub-comment-author-ip' ), '' . esc_attr( Helpers\fetch_masked_ip() ) . '' ); + $set_label = sprintf( __( 'Replace the comment author IP address with %s', 'scrub-comment-author-ip' ), '' . esc_html( Helpers\fetch_masked_ip() ) . '' ); // Add a legend output for screen readers. - echo '' . __( 'Scrub Comment IPs', 'scrub-comment-author-ip' ) . ''; + echo '' . esc_html__( 'Scrub Comment IPs', 'scrub-comment-author-ip' ) . ''; // We are wrapping the entire thing in a label. echo '