Plugin Directory

Changeset 3315869


Ignore:
Timestamp:
06/22/2025 10:42:47 AM (10 months ago)
Author:
sheikhmizanbd
Message:

uploading a new version of the plugin
changes made to assets

Location:
bulk-delete-users-by-keyword
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • bulk-delete-users-by-keyword/trunk/bulk-delete-users-by-keyword.php

    r3153753 r3315869  
    22/*
    33Plugin Name: Bulk Delete Users by Keyword
    4 Description: This plugin allows you to bulk delete WordPress users based on a specified keyword.
    5 Version: 1.0
    6 Author: Sheikh MiZan (Shiek Md Anwar Hussain Mizan)
     4Description: Advanced bulk user deletion with AJAX processing and progress tracking.
     5Version: 2.0
     6Author: Sheikh MiZan
    77Author URI: https://sheikhmizan.com
    8 Requires at least: 4.7
    9 Tested up to: 6.6.1
    10 Requires PHP: 7.0
    11 License: GPL v2 or later
     8Requires at least: 5.5
     9Tested up to: 6.8
     10Requires PHP: 7.4
     11License: GPL v2
    1212License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1313*/
    1414
    15 // Ensure the code is not executed outside of WordPress.
    1615defined('ABSPATH') || exit;
    1716
     
    2221        add_action('admin_init', [$this, 'bdubk_process_bulk_delete']);
    2322        add_action('admin_enqueue_scripts', [$this, 'bdubk_enqueue_admin_styles']);
    24     }
    25 
    26     // Enqueue admin styles
     23        add_action('admin_init', [$this, 'bdubk_register_settings']);
     24        add_action('wp_ajax_bdubk_get_user_count', [$this, 'ajax_get_user_count']);
     25        add_action('wp_ajax_bdubk_process_batch', [$this, 'ajax_process_batch']);
     26    }
     27
     28    public function bdubk_register_settings() {
     29        register_setting('bdubk_settings', 'bdubk_batch_size', [
     30            'type' => 'integer',
     31            'default' => 100,
     32            'description' => 'Number of users to process in each batch',
     33            'sanitize_callback' => 'absint'
     34        ]);
     35    }
     36
    2737    public function bdubk_enqueue_admin_styles($hook_suffix) {
    2838        if ($hook_suffix === 'toplevel_page_bdubk_bulk_delete_users') {
    29             wp_enqueue_style('bdubk-admin-styles', plugin_dir_url(__FILE__) . 'css/bdubk-admin-styles.css', [], '1.0');
    30         }
    31     }
    32 
    33     // Add admin menu
     39            wp_enqueue_style('bdubk-admin-styles', plugin_dir_url(__FILE__) . 'css/bdubk-admin-styles.css', [], '2.0');
     40            wp_enqueue_script('bdubk-admin-script', plugin_dir_url(__FILE__) . 'js/bdubk-admin-script.js', ['jquery'], '2.0', true);
     41           
     42            wp_localize_script('bdubk-admin-script', 'bdubk_ajax', [
     43                'ajax_url' => admin_url('admin-ajax.php'),
     44                'nonce' => wp_create_nonce('bdubk_ajax_nonce'),
     45                'processing_text' => __('Processing...', 'bdubk'),
     46                'complete_text' => __('Process completed!', 'bdubk'),
     47                'error_text' => __('An error occurred:', 'bdubk')
     48            ]);
     49        }
     50    }
     51
    3452    public function bdubk_custom_admin_page() {
    3553        add_menu_page(
     
    4361    }
    4462
    45     // Render settings page
    4663    public function bdubk_render_keyword_settings_page() {
     64        $batch_size = get_option('bdubk_batch_size', 100);
    4765        ?>
    4866        <div class="wrap">
    4967            <h2><?php esc_html_e('Bulk Delete Users by Keyword', 'bdubk'); ?></h2>
    5068
    51             <?php
    52             // Display notices if any
    53             settings_errors('bdubk_bulk_delete_users');
    54             ?>
    55 
    56             <form method="post" action="">
    57                 <?php
    58                 wp_nonce_field('bdubk_bulk_delete_users_action', 'bdubk_bulk_delete_users_nonce');
    59                 ?>
     69            <?php settings_errors('bdubk_bulk_delete_users'); ?>
     70
     71            <form method="post" action="" id="bdubk-bulk-delete-form">
     72                <?php wp_nonce_field('bdubk_bulk_delete_users_action', 'bdubk_bulk_delete_users_nonce'); ?>
     73               
    6074                <table class="form-table">
    6175                    <tr valign="top">
    6276                        <th scope="row"><?php esc_html_e('Keyword', 'bdubk'); ?></th>
    63                         <td><input type="text" name="bdubk_keyword" value="" class="regular-text" /></td>
     77                        <td><input type="text" name="bdubk_keyword" value="" class="regular-text" required /></td>
     78                    </tr>
     79                    <tr valign="top">
     80                        <th scope="row"><?php esc_html_e('Batch Size', 'bdubk'); ?></th>
     81                        <td>
     82                            <input type="number" name="bdubk_batch_size" value="<?php echo esc_attr($batch_size); ?>" min="1" max="1000" />
     83                            <p class="description"><?php esc_html_e('Number of users to process at a time (recommended: 100-500 for large sites)', 'bdubk'); ?></p>
     84                        </td>
     85                    </tr>
     86                    <tr valign="top">
     87                        <th scope="row"><?php esc_html_e('Search In', 'bdubk'); ?></th>
     88                        <td>
     89                            <label><input type="checkbox" name="bdubk_search_fields[]" value="user_login" checked> <?php esc_html_e('Username', 'bdubk'); ?></label><br>
     90                            <label><input type="checkbox" name="bdubk_search_fields[]" value="user_nicename" checked> <?php esc_html_e('Nickname', 'bdubk'); ?></label><br>
     91                            <label><input type="checkbox" name="bdubk_search_fields[]" value="display_name" checked> <?php esc_html_e('Display Name', 'bdubk'); ?></label><br>
     92                            <label><input type="checkbox" name="bdubk_search_fields[]" value="user_email" checked> <?php esc_html_e('Email', 'bdubk'); ?></label>
     93                        </td>
    6494                    </tr>
    6595                </table>
    66                 <?php submit_button(__('Bulk Delete Users', 'bdubk')); ?>
     96               
     97                <?php submit_button(__('Bulk Delete Users', 'bdubk'), 'primary', 'bdubk_submit'); ?>
     98               
     99                <div id="bdubk-progress-container" style="display: none;">
     100                    <div id="bdubk-progress-bar">
     101                        <div id="bdubk-progress-bar-fill"></div>
     102                    </div>
     103                    <p id="bdubk-progress-text"><?php esc_html_e('Preparing to process...', 'bdubk'); ?></p>
     104                    <p id="bdubk-processed-count"><?php esc_html_e('Users processed:', 'bdubk'); ?> <span>0</span></p>
     105                    <p id="bdubk-deleted-count"><?php esc_html_e('Users deleted:', 'bdubk'); ?> <span>0</span></p>
     106                </div>
    67107            </form>
    68108
    69109            <div class="warning">
    70110                <h2><?php esc_html_e('Warning!', 'bdubk'); ?></h2>
    71                 <p><?php esc_html_e('Deleting users will permanently remove them from the database. Proceed with caution. It\'s recommended to backup your database before performing bulk deletion.', 'bdubk'); ?></p>
     111                <p><?php esc_html_e('Deleting users will permanently remove them from the database. This action cannot be undone. It\'s strongly recommended to backup your database before performing bulk deletion.', 'bdubk'); ?></p>
     112                <p><?php esc_html_e('For large sites, the process may take several minutes. Do not close the browser window until the process completes.', 'bdubk'); ?></p>
    72113            </div>
    73114        </div>
     
    75116    }
    76117
    77     // Process bulk delete
    78118    public function bdubk_process_bulk_delete() {
    79119        if (isset($_POST['bdubk_bulk_delete_users_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['bdubk_bulk_delete_users_nonce'])), 'bdubk_bulk_delete_users_action')) {
    80             $keyword = isset($_POST['bdubk_keyword']) ? sanitize_text_field(wp_unslash($_POST['bdubk_keyword'])) : '';
    81             if (!empty($keyword)) {
    82                 $this->bdubk_delete_users_by_keyword($keyword);
    83             }
    84         }
    85     }
    86 
    87     // Delete users by keyword
    88     private function bdubk_delete_users_by_keyword($keyword) {
    89         global $wpdb;
    90         $users = get_users(['search' => '*' . esc_attr($keyword) . '*', 'search_columns' => ['user_login', 'user_nicename', 'display_name', 'user_email']]);
    91 
    92         if (!empty($users)) {
    93             foreach ($users as $user) {
    94                 wp_delete_user($user->ID);
    95             }
    96             $deleted_count = count($users);
    97             // Translators: %d is the number of users deleted.
    98             add_settings_error('bdubk_bulk_delete_users', 'bdubk_bulk_delete_users_notice', sprintf(__('%d users deleted successfully.', 'bdubk'), $deleted_count), 'updated');
    99         } else {
    100             add_settings_error('bdubk_bulk_delete_users', 'bdubk_bulk_delete_users_notice', __('No users found with the specified keyword.', 'bdubk'), 'error');
     120            if (isset($_POST['bdubk_batch_size'])) {
     121                $new_batch_size = absint($_POST['bdubk_batch_size']);
     122                if ($new_batch_size > 0) {
     123                    update_option('bdubk_batch_size', $new_batch_size);
     124                }
     125            }
     126        }
     127    }
     128
     129    public function ajax_get_user_count() {
     130        try {
     131            check_ajax_referer('bdubk_ajax_nonce', 'nonce');
     132
     133            if (!current_user_can('manage_options')) {
     134                throw new Exception(__('Permission denied', 'bdubk'), 403);
     135            }
     136
     137            $keyword = isset($_POST['keyword']) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
     138            $search_fields = isset($_POST['search_fields']) ? array_map('sanitize_text_field', wp_unslash($_POST['search_fields'])) :
     139                              ['user_login', 'user_nicename', 'display_name', 'user_email'];
     140
     141            if (empty($keyword)) {
     142                throw new Exception(__('Keyword is required', 'bdubk'), 400);
     143            }
     144
     145            $args = [
     146                'search'         => '*' . $keyword . '*',
     147                'search_columns' => $search_fields,
     148                'fields'         => 'ID',
     149                'count_total'    => true
     150            ];
     151
     152            $user_query = new WP_User_Query($args);
     153            $total_users = $user_query->get_total();
     154
     155            /* translators: %d: number of users found */
     156            $message = sprintf(_n('%d user found', '%d users found', $total_users, 'bdubk'), $total_users);
     157
     158            wp_send_json_success([
     159                'total_users' => $total_users,
     160                'message' => $message
     161            ]);
     162        } catch (Exception $e) {
     163            wp_send_json_error($e->getMessage(), $e->getCode());
     164        }
     165    }
     166
     167    public function ajax_process_batch() {
     168        try {
     169            check_ajax_referer('bdubk_ajax_nonce', 'nonce');
     170
     171            if (!current_user_can('manage_options')) {
     172                throw new Exception(__('Permission denied', 'bdubk'), 403);
     173            }
     174
     175            $keyword = isset($_POST['keyword']) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
     176            $search_fields = isset($_POST['search_fields']) ? array_map('sanitize_text_field', wp_unslash($_POST['search_fields'])) :
     177                             ['user_login', 'user_nicename', 'display_name', 'user_email'];
     178            $offset = isset($_POST['offset']) ? absint($_POST['offset']) : 0;
     179            $batch_size = isset($_POST['batch_size']) ? absint($_POST['batch_size']) : 100;
     180
     181            if (empty($keyword)) {
     182                throw new Exception(__('Keyword is required', 'bdubk'), 400);
     183            }
     184
     185            $args = [
     186                'search'         => '*' . $keyword . '*',
     187                'search_columns' => $search_fields,
     188                'number'         => $batch_size,
     189                'offset'         => $offset,
     190                'fields'         => 'ID',
     191                'orderby'        => 'ID',
     192                'order'          => 'ASC'
     193            ];
     194
     195            $users = get_users($args);
     196            $deleted = 0;
     197            $errors = [];
     198
     199            foreach ($users as $user_id) {
     200                if (!wp_delete_user($user_id)) {
     201                    /* translators: %d: user ID that failed to delete */
     202                    $errors[] = sprintf(__('Failed to delete user ID %d', 'bdubk'), $user_id);
     203                } else {
     204                    $deleted++;
     205                }
     206            }
     207
     208            $result = [
     209                'processed' => count($users),
     210                'deleted' => $deleted,
     211                'offset' => $offset,
     212                'batch_size' => $batch_size
     213            ];
     214
     215            if (!empty($errors)) {
     216                $result['errors'] = $errors;
     217            }
     218
     219            wp_send_json_success($result);
     220        } catch (Exception $e) {
     221            wp_send_json_error($e->getMessage(), $e->getCode());
    101222        }
    102223    }
  • bulk-delete-users-by-keyword/trunk/css/bdubk-admin-styles.css

    r3153753 r3315869  
    1 /* Admin styles for Bulk Delete Users by Keyword plugin */
     1.wrap {
     2    max-width: 1200px;
     3    margin: 0 auto;
     4    padding: 20px;
     5    background: #fff;
     6    border-radius: 8px;
     7    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
     8    border: 1px solid rgba(255, 255, 255, 0.2);
     9    background: rgba(255, 255, 255, 0.9);
     10    backdrop-filter: blur(10px);
     11}
    212
    313.wrap h2 {
    4     font-size: 24px;
    5     color: #0073aa;
    6     margin-bottom: 20px;
    7 }
    8 
    9 .wrap table.form-table th {
    10     font-weight: 600;
    11     padding: 10px;
    12 }
    13 
    14 .wrap table.form-table td {
    15     padding: 10px;
    16 }
    17 
    18 .wrap input.regular-text {
     14    font-size: 28px;
     15    color: #2a2a72;
     16    margin-bottom: 25px;
     17    padding-bottom: 15px;
     18    border-bottom: 1px solid rgba(42, 42, 114, 0.1);
     19    position: relative;
     20}
     21
     22.wrap h2::after {
     23    content: '';
     24    position: absolute;
     25    bottom: -1px;
     26    left: 0;
     27    width: 100px;
     28    height: 3px;
     29    background: linear-gradient(90deg, #2a2a72, #009ffd);
     30}
     31
     32.form-table th {
     33    font-weight: 600;
     34    color: #2a2a72;
     35    padding: 15px 10px;
     36}
     37
     38.form-table td {
     39    padding: 15px 10px;
     40}
     41
     42.regular-text {
    1943    width: 100%;
    2044    max-width: 400px;
    21     padding: 8px;
     45    padding: 12px 15px;
     46    border: 1px solid rgba(42, 42, 114, 0.2);
     47    border-radius: 6px;
     48    background: rgba(255, 255, 255, 0.8);
     49    transition: all 0.3s ease;
     50}
     51
     52.regular-text:focus {
     53    border-color: #009ffd;
     54    box-shadow: 0 0 0 3px rgba(0, 159, 253, 0.2);
     55    outline: none;
     56}
     57
     58input[type="number"] {
     59    padding: 12px 15px;
     60    border: 1px solid rgba(42, 42, 114, 0.2);
     61    border-radius: 6px;
     62    background: rgba(255, 255, 255, 0.8);
     63}
     64
     65.description {
     66    font-size: 13px;
     67    color: #666;
     68    margin-top: 8px;
     69    font-style: italic;
     70}
     71
     72.warning {
     73    margin-top: 40px;
     74    padding: 20px;
     75    background: linear-gradient(135deg, rgba(255, 87, 34, 0.1), rgba(255, 87, 34, 0.05));
     76    border-left: 4px solid #ff5722;
     77    border-radius: 6px;
     78}
     79
     80.warning h2 {
     81    color: #ff5722;
     82    margin-top: 0;
     83    border-bottom: none;
     84}
     85
     86.warning h2::after {
     87    display: none;
     88}
     89
     90.warning p {
     91    margin: 10px 0 0;
     92    line-height: 1.6;
     93}
     94
     95#bdubk-progress-container {
     96    margin: 30px 0;
     97    padding: 20px;
     98    background: rgba(42, 42, 114, 0.03);
     99    border-radius: 8px;
     100    border: 1px dashed rgba(42, 42, 114, 0.1);
     101}
     102
     103#bdubk-progress-bar {
     104    height: 10px;
     105    background: rgba(42, 42, 114, 0.1);
     106    border-radius: 5px;
     107    overflow: hidden;
     108    margin-bottom: 15px;
     109}
     110
     111#bdubk-progress-bar-fill {
     112    height: 100%;
     113    width: 0;
     114    background: linear-gradient(90deg, #2a2a72, #009ffd);
     115    border-radius: 5px;
     116    transition: width 0.5s ease;
     117}
     118
     119#bdubk-progress-text {
     120    font-weight: 600;
     121    color: #2a2a72;
     122    margin: 0 0 10px;
     123}
     124
     125#bdubk-processed-count,
     126#bdubk-deleted-count {
     127    margin: 8px 0;
    22128    font-size: 14px;
    23     border: 1px solid #ccc;
     129}
     130
     131#bdubk-processed-count span,
     132#bdubk-deleted-count span {
     133    font-weight: 600;
     134    color: #2a2a72;
     135}
     136
     137/* Modern Checkboxes */
     138input[type="checkbox"] {
     139    -webkit-appearance: none;
     140    -moz-appearance: none;
     141    appearance: none;
     142    width: 18px;
     143    height: 18px;
     144    border: 2px solid rgba(42, 42, 114, 0.3);
    24145    border-radius: 4px;
    25 }
    26 
    27 .wrap input[type="submit"] {
    28     background-color: #0073aa;
     146    outline: none;
     147    cursor: pointer;
     148    vertical-align: middle;
     149    position: relative;
     150    transition: all 0.2s ease;
     151}
     152
     153input[type="checkbox"]:checked {
     154    background-color: #2a2a72;
     155    border-color: #2a2a72;
     156}
     157
     158input[type="checkbox"]:checked::after {
     159    content: '';
     160    position: absolute;
     161    left: 5px;
     162    top: 1px;
     163    width: 5px;
     164    height: 10px;
     165    border: solid white;
     166    border-width: 0 2px 2px 0;
     167    transform: rotate(45deg);
     168}
     169
     170/* Modern Submit Button */
     171#submit {
     172    background: linear-gradient(135deg, #2a2a72, #009ffd);
    29173    border: none;
    30     color: #fff;
    31     padding: 10px 20px;
     174    color: white;
     175    padding: 12px 25px;
    32176    font-size: 16px;
    33     border-radius: 4px;
     177    font-weight: 600;
     178    border-radius: 6px;
    34179    cursor: pointer;
    35 }
    36 
    37 .wrap input[type="submit"]:hover {
    38     background-color: #006799;
    39 }
     180    transition: all 0.3s ease;
     181    box-shadow: 0 4px 15px rgba(42, 42, 114, 0.2);
     182}
     183
     184#submit:hover {
     185    transform: translateY(-2px);
     186    box-shadow: 0 6px 20px rgba(42, 42, 114, 0.3);
     187}
     188
     189#submit:active {
     190    transform: translateY(0);
     191}
     192
     193/* Responsive Design */
     194@media (max-width: 782px) {
     195    .form-table th,
     196    .form-table td {
     197        display: block;
     198        width: 100%;
     199        padding: 10px 0;
     200    }
     201   
     202    .regular-text {
     203        max-width: 100%;
     204    }
     205}
     206
     207/* Animation Effects */
     208@keyframes fadeIn {
     209    from { opacity: 0; transform: translateY(10px); }
     210    to { opacity: 1; transform: translateY(0); }
     211}
     212
     213.wrap {
     214    animation: fadeIn 0.5s ease-out;
     215}
     216
     217/* Glow Effect for Active Processing */
     218.processing-glow {
     219    animation: glow 1.5s ease-in-out infinite alternate;
     220}
     221
     222@keyframes glow {
     223    from {
     224        box-shadow: 0 0 5px rgba(0, 159, 253, 0.5);
     225    }
     226    to {
     227        box-shadow: 0 0 20px rgba(0, 159, 253, 0.8);
     228    }
     229}
     230.processing-glow {
     231    position: relative;
     232    animation: processingGlow 1.5s infinite alternate;
     233}
     234
     235@keyframes processingGlow {
     236    from {
     237        box-shadow: 0 0 5px rgba(42, 42, 114, 0.5);
     238    }
     239    to {
     240        box-shadow: 0 0 15px rgba(42, 42, 114, 0.8);
     241    }
     242}
     243
     244#bdubk-progress-container {
     245    display: block !important;
     246    opacity: 0;
     247    height: 0;
     248    overflow: hidden;
     249    transition: opacity 0.3s ease, height 0.3s ease;
     250}
     251
     252#bdubk-progress-container.show {
     253    opacity: 1;
     254    height: auto;
     255}
  • bulk-delete-users-by-keyword/trunk/readme.txt

    r3153753 r3315869  
    11=== Bulk Delete Users by Keyword ===
    22Contributors: sheikhmizanbd
    3 Tags: bulk delete, delete users, keyword-based deletion, user management
    4 Requires at least: 4.0
    5 Tested up to: 6.6.1
    6 Stable tag: 1.0
     3Tags: bulk delete, delete users, keyword-based deletion, user management, admin tools
     4Requires at least: 5.5
     5Tested up to: 6.8
     6Stable tag: 2.0
    77License: GPLv2 or later
    88License URI: https://www.gnu.org/licenses/gpl-2.0.html
    99
    10 Easily bulk delete WordPress users by filtering them based on a specified keyword.
     10Efficiently manage your WordPress users with keyword-based bulk deletion capabilities.
    1111
    1212== Description ==
    1313
    14 The **Bulk Delete Users by Keyword** plugin provides an easy way to manage user cleanup in WordPress by allowing you to bulk delete users based on a specific keyword. Whether you need to manage users for better performance, remove spam accounts, or clean up your database, this plugin makes it simple.
     14The **Bulk Delete Users by Keyword** plugin provides administrators with a powerful tool for cleaning up user databases by allowing bulk deletion based on specific keywords. Perfect for removing spam accounts, inactive users, or performing database maintenance.
    1515
    16 **Main Features:**
    17 - Bulk delete users by filtering their usernames or display names using a specific keyword.
    18 - Intuitive custom admin interface for keyword input and management.
    19 - Displays a warning message to ensure users are aware that this action cannot be undone.
     16**Key Features:**
     17- Advanced keyword filtering across multiple user fields (username, email, display name)
     18- Batch processing for handling large user databases efficiently
     19- Real-time progress tracking during deletion operations
     20- Comprehensive safety warnings and confirmations
     21- Customizable batch sizes for optimal performance
    2022
    21 **How It Works:**
    22 1. Set the keyword on the custom admin page to filter users for deletion.
    23 2. Click the "Bulk Delete" button to initiate the process.
    24 3. All users whose usernames or display names contain the specified keyword will be permanently deleted from your WordPress database.
    25 
    26 This plugin is ideal for administrators who need to remove inactive or spam users quickly and efficiently.
     23**Enhanced Functionality in Version 2.0:**
     24- AJAX-powered processing for smooth operation
     25- Detailed progress reporting
     26- Support for multiple search fields
     27- Improved user interface
     28- Better error handling and notifications
    2729
    2830== Features ==
    29 - **Keyword-based User Deletion:** Quickly delete multiple users whose usernames or display names match the specified keyword.
    30 - **Custom Admin Page:** A simple settings page for managing the keyword used in bulk deletion.
    31 - **Safe Execution:** Includes a confirmation prompt before deletion to avoid accidental removals.
     31
     32= Core Functionality =
     33- Keyword-based user filtering and deletion
     34- Batch processing for large datasets
     35- Multi-field search (username, email, display name, nickname)
     36- Progress tracking during operations
     37
     38= Safety Features =
     39- Explicit warning messages
     40- Confirmation dialogs
     41- Nonce verification for all operations
     42- Capability checks
     43
     44= Performance =
     45- Optimized database queries
     46- Configurable batch sizes
     47- Memory-efficient processing
    3248
    3349== Installation ==
    3450
    35 **From your WordPress Dashboard:**
    36 1. Navigate to "Plugins > Add New".
    37 2. Search for "Bulk Delete Users by Keyword".
    38 3. Install and activate the plugin.
     51= Automatic Installation =
     521. Navigate to "Plugins > Add New" in your WordPress admin
     532. Search for "Bulk Delete Users by Keyword"
     543. Click "Install Now" and then "Activate"
    3955
    40 **From WordPress.org:**
    41 1. Download the plugin ZIP file from the [plugin page](https://wordpress.org/plugins/bulk-delete-users-by-keyword).
    42 2. In your WordPress admin, go to "Plugins > Add New > Upload Plugin".
    43 3. Upload the ZIP file and click "Install Now".
    44 4. After installation, click "Activate".
     56= Manual Installation =
     571. Download the plugin ZIP file
     582. Go to "Plugins > Add New > Upload Plugin" in WordPress
     593. Upload the ZIP file
     604. Click "Install Now" and then "Activate"
     61
     62= After Installation =
     631. Navigate to "Bulk Delete Users" in the admin menu
     642. Configure your search criteria
     653. Execute the deletion process
    4566
    4667== Frequently Asked Questions ==
    4768
    48 = Will this plugin delete users permanently? =
    49 Yes. When users are deleted using this plugin, they are permanently removed from the database. Please be cautious when using the bulk delete functionality.
     69= How does the keyword matching work? =
     70The plugin searches for your keyword in multiple user fields: username, email, display name, and nickname. Partial matches are included.
    5071
    51 = Can I undo a bulk delete? =
    52 No, this action is irreversible. Ensure you have backups of your database before performing a bulk deletion.
     72= Can I recover deleted users? =
     73No, this is a permanent deletion. Always maintain regular backups of your database.
    5374
    54 = How is the keyword matched? =
    55 The keyword is matched against both the username and display name fields of users. If either field contains the keyword, the user will be selected for deletion.
     75= What's the recommended batch size? =
     76For most sites, 100-500 users per batch works well. Larger sites may benefit from smaller batches (50-100).
     77
     78= Does this work with multisite installations? =
     79Yes, but users will only be deleted from the current site in the network.
    5680
    5781== Screenshots ==
    58 
    59 1. **Admin Settings Page:** The custom admin interface where you enter the keyword and manage user deletions.
     821. Main plugin interface showing keyword input and options
     832. Progress tracking during deletion
     843. Confirmation dialog
     854. Success/error notifications
    6086
    6187== Changelog ==
    6288
     89= 2.0 =
     90- Complete rewrite with AJAX processing
     91- Added progress tracking
     92- Enhanced search capabilities
     93- Improved user interface
     94- Better error handling
     95
    6396= 1.0 =
    64 - Initial release with keyword-based bulk user deletion.
     97- Initial release with basic functionality
    6598
    6699== Upgrade Notice ==
    67100
     101= 2.0 =
     102Major update with significant improvements. Recommended for all users.
     103
    68104= 1.0 =
    69 Initial release. Install this version for easy bulk deletion of users based on a keyword.
     105Initial release with basic keyword-based deletion.
    70106
    71107== License ==
     108GNU General Public License v2.0 or later
    72109
    73 This plugin is licensed under the [GNU General Public License v2.0 or later](https://www.gnu.org/licenses/gpl-2.0.html).
     110== Privacy Notice ==
     111This plugin does not collect any user data or transmit information to external servers. All operations occur entirely within your WordPress installation.
Note: See TracChangeset for help on using the changeset viewer.