<?php
/**
 * Name: Username Blacklist
 * Description: Block specific usernames from being registered including common names like admin, test, or custom blocked list to prevent spam registrations and improve security
 * Category: Security
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Block Common Targets",
 *     "description": "Prevent registration of usernames like 'admin', 'administrator', 'root' that are primary targets for brute force attacks."
 *   },
 *   {
 *     "title": "Prevent Spam Accounts",
 *     "description": "Block spam bots from registering with common test usernames like 'test', 'demo', 'guest' on membership sites."
 *   },
 *   {
 *     "title": "Enforce Naming Policy",
 *     "description": "Blacklist inappropriate or reserved usernames to maintain professional user base and prevent impersonation."
 *   }
 * ]
 * Added: 2025-09-01
 * Tags: username, registration, security, spam, blacklist
 * WhereToFind: {
 *   "location": "User Registration",
 *   "url": "wp-login.php?action=register",
 *   "instructions": "Try registering blacklisted username - should be rejected",
 *   "newTab": true
 * }
 */

// Prevent direct access
if (!defined('ABSPATH')) exit;

class SwitchboardUsernameBlacklist {

    public function __construct() {
        add_filter('registration_errors', [$this, 'check_username'], 10, 3);
        add_filter('illegal_user_logins', [$this, 'add_to_illegal_logins']);
    }

    /**
     * Register data locations for cleanup system
     *
     * @return array Data storage locations
     */
    public function register_data_locations() {
        return [
            'options' => [
                'switchboard_username-blacklist_settings',
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }

    private function get_settings() {
        return get_option('switchboard_username-blacklist_settings', []);
    }
    
    private function get_blocked_usernames() {
        $settings = $this->get_settings();
        $blocked = isset($settings['blocked_usernames']) ? $settings['blocked_usernames'] : "admin\nadministrator\nroot\ntest\ndemo";

        // Validate it's a string
        if (!is_string($blocked)) {
            $blocked = "admin\nadministrator\nroot\ntest\ndemo";
        }

        $usernames = array_filter(array_map('trim', explode("\n", $blocked)));
        return array_map('strtolower', $usernames);
    }
    
    public function check_username($errors, $sanitized_user_login, $user_email) {
        $blocked = $this->get_blocked_usernames();

        if (in_array(strtolower($sanitized_user_login), $blocked, true)) {
            $errors->add('username_blacklisted', '<strong>' . esc_html__('Error:', 'wpswitchboard') . '</strong> ' . esc_html__('This username is not allowed.', 'wpswitchboard'));
        }

        return $errors;
    }
    
    public function add_to_illegal_logins($usernames) {
        return array_merge($usernames, $this->get_blocked_usernames());
    }

    /**
     * Render settings panel for Username Blacklist
     *
     * @param array $settings Current module settings
     * @return void Outputs HTML directly
     */
    public function render_settings($settings = []) {
        $blocked_usernames = isset($settings['blocked_usernames']) ? $settings['blocked_usernames'] : "admin\nadministrator\nroot\ntest\ndemo";
        ?>
        <input type="hidden" name="module" value="username-blacklist">
        <label for="setting_blocked_usernames"><?php esc_html_e('Blocked Usernames', 'wpswitchboard'); ?></label>
        <textarea name="setting_blocked_usernames" id="setting_blocked_usernames" rows="8" class="sb-sp-textarea"><?php echo esc_textarea($blocked_usernames); ?></textarea>
        <p class="sb-sp-description"><?php esc_html_e('One username per line. Case-insensitive.', 'wpswitchboard'); ?></p>
        <?php
    }
}

// Initialize and register with data system
$switchboard_instance = new SwitchboardUsernameBlacklist();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);
