开发版本

This commit is contained in:
文派备案 2025-03-10 12:38:31 +08:00
parent b99c5a7343
commit fa7b00b4f5
5 changed files with 882 additions and 0 deletions

View file

@ -0,0 +1,123 @@
<?php
namespace WPBan_Anything;
if (!defined('ABSPATH')) {
exit;
}
class WPBan_AI_Crawlers {
private $ai_crawlers;
public function __construct() {
$this->ai_crawlers = $this->get_default_crawlers();
add_filter('robots_txt', [$this, 'add_ai_robots_txt'], 10, 2);
add_action('wp_head', [$this, 'add_meta_tag']);
add_action('init', [$this, 'monitor_crawlers']);
}
private function get_default_crawlers() {
return [
'AI2Bot' => ['description' => __('Explores sites for web content that is used to train open language models', 'wpban-anything'), 'link' => 'https://allenai.org/crawler'],
'Ai2Bot-Dolma' => ['description' => __('Generates data sets used to train open language models', 'wpban-anything'), 'link' => 'https://allenai.org/dolma'],
'AmazonBot' => ['description' => __('Used by Amazon\'s Alexa AI to provide AI answers.', 'wpban-anything'), 'link' => 'https://developer.amazon.com/amazonbot'],
'Applebot-Extended' => ['description' => __('Used by Apple for generative AI features across Apple products, including Apple Intelligence, Services, and Developer Tools.', 'wpban-anything'), 'link' => 'https://support.apple.com/en-us/119829'],
'anthropic-ai' => ['description' => __('Used by Anthropic\'s Claude.', 'wpban-anything'), 'link' => 'https://support.anthropic.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler'],
'Bytespider' => ['description' => __('Used by TikTok for AI training.', 'wpban-anything'), 'link' => 'https://darkvisitors.com/agents/bytespider'],
'CCBot' => ['description' => __('Compiles datasets used to train AI models.', 'wpban-anything'), 'link' => 'https://commoncrawl.org/big-picture/frequently-asked-questions/'],
'ChatGPT-User' => ['description' => __('Used by OpenAI to power ChatGPT.', 'wpban-anything'), 'link' => 'https://platform.openai.com/docs/plugins/bot'],
'ClaudeBot' => ['description' => __('Used by Anthropic\'s Claude.', 'wpban-anything'), 'link' => 'https://support.anthropic.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler'],
'Claude-Web' => ['description' => __('Used by Anthropic\'s Claude.', 'wpban-anything'), 'link' => 'https://support.anthropic.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler'],
'cohere-ai' => ['description' => __('Used by Cohere to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://cohere.com/about'],
'cohere-training-data-crawler' => ['description' => __('Used by Cohere to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://cohere.com/about'],
'Crawlspace' => ['description' => __('A web scraper that can be used to extract data for AI training.', 'wpban-anything'), 'link' => 'https://crawlspace.dev/'],
'Diffbot' => ['description' => __('Used by Diffbot to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://docs.diffbot.com/reference/crawl-introduction'],
'FacebookBot' => ['description' => __('Used by Meta (Facebook) for their AI.', 'wpban-anything'), 'link' => 'https://developers.facebook.com/docs/sharing/bot'],
'FriendlyCrawler' => ['description' => __('Crawls websites to build datasets for machine learning experiments.', 'wpban-anything'), 'link' => 'https://imho.alex-kunz.com/2024/01/25/an-update-on-friendly-crawler/'],
'GPTBot' => ['description' => __('Used by OpenAI to power ChatGPT.', 'wpban-anything'), 'link' => 'https://platform.openai.com/docs/bots'],
'Google-Extended' => ['description' => __('Used by Google to power Gemini (formerly known as Bard).', 'wpban-anything'), 'link' => 'https://developers.google.com/search/docs/crawling-indexing/overview-google-crawlers'],
'ImagesiftBot' => ['description' => __('Used by Hive\'s Imagesift tool that scrapes images. This may be used for the company\'s generative AI product.', 'wpban-anything'), 'link' => 'https://imagesift.com/about'],
'Kangaroo Bot' => ['description' => __('Used to power the Australia-focused Kangaroo LLM.', 'wpban-anything'), 'link' => 'https://kangaroollm.com.au/kangaroo-bot/'],
'Meta-ExternalAgent' => ['description' => __('Used by Meta (Facebook) to train AI products.', 'wpban-anything'), 'link' => 'https://developers.facebook.com/docs/sharing/webmasters/web-crawlers'],
'Meta-ExternalFetcher' => ['description' => __('Used by Meta (Facebook) to train AI products.', 'wpban-anything'), 'link' => 'https://developers.facebook.com/docs/sharing/webmasters/web-crawlers'],
'OAI-SearchBot' => ['description' => __('Used by OpenAI for their SearchGPT product.', 'wpban-anything'), 'link' => 'https://platform.openai.com/docs/bots'],
'Omgili' => ['description' => __('Used by Omgili to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://webz.io/blog/machine-learning/common-crawl-vs-webz-io-data'],
'Omgilibot' => ['description' => __('Used by Omgili to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://webz.io/blog/machine-learning/common-crawl-vs-webz-io-data'],
'PanguBot' => ['description' => __('Used by Huawei to download data for the Large Language Model (LLM) called PanGu.', 'wpban-anything'), 'link' => 'https://darkvisitors.com/agents/pangubot'],
'PetalBot' => ['description' => __('Used by Huawei to scrape data for AI training.', 'wpban-anything'), 'link' => 'https://darkvisitors.com/agents/petalbot'],
'PerplexityBot' => ['description' => __('Used by Perplexity for their AI products.', 'wpban-anything'), 'link' => 'https://docs.perplexity.ai/docs/perplexitybot'],
'Scrapy' => ['description' => __('Blocks the Scrapy bot (used for scraping websites).', 'wpban-anything'), 'link' => 'https://scrapy.org/'],
'SemrushBot' => ['description' => __('Blocks the Semrush bot used to pull data into the Semrush platform. Data is used for their ContentShake AI tool.', 'wpban-anything'), 'link' => 'https://www.semrush.com/bot/'],
'SemrushBot-OCOB' => ['description' => __('Blocks the Semrush bot used to pull data into the Semrush platform.', 'wpban-anything'), 'link' => 'https://www.semrush.com/bot/'],
'SemrushBot-FT' => ['description' => __('Blocks the Semrush bot used to pull data into the Semrush platform.', 'wpban-anything'), 'link' => 'https://www.semrush.com/bot/'],
'SentiBot' => ['description' => __('Used for sentiment analysis and AI training.', 'wpban-anything'), 'link' => 'https://darkvisitors.com/agents/sentibot'],
'sentibot' => ['description' => __('Used for sentiment analysis and AI training.', 'wpban-anything'), 'link' => 'https://darkvisitors.com/agents/sentibot'],
'Timpibot' => ['description' => __('Used by Timpi; likely for their Wilson AI Product.', 'wpban-anything'), 'link' => 'https://timpi.io/wilson-ai/'],
'TurnitinBot' => ['description' => __('Used by Turnitin to scrape data for plagiarism detection.', 'wpban-anything'), 'link' => 'https://www.turnitin.com/robot/crawlerinfo.html'],
'YouBot' => ['description' => __('Used by You.com to train AI products.', 'wpban-anything'), 'link' => 'https://about.you.com/es/youbot/'],
'webzio' => ['description' => __('Used by Webz.io for their social listening and intelligence platforms.', 'wpban-anything'), 'link' => 'https://webz.io/bot.html'],
'webzio-extended' => ['description' => __('Used by Webz.io for AI training.', 'wpban-anything'), 'link' => 'https://webz.io/bot.html']
];
}
public function get_settings() {
return get_option('ai_crawler_settings', [
'enabled_crawlers' => array_keys($this->ai_crawlers)
]);
}
public function save_settings($data) {
$settings = [
'enabled_crawlers' => isset($data['ai_crawlers']) ? array_map('sanitize_text_field', $data['ai_crawlers']) : []
];
update_option('ai_crawler_settings', $settings);
return $settings;
}
public function add_ai_robots_txt($robots, $public) {
$settings = $this->get_settings();
$robots .= "\n# WPBan-Anything AI Crawler Blocks\n";
foreach ($settings['enabled_crawlers'] as $crawler) {
if (array_key_exists($crawler, $this->ai_crawlers)) {
$robots .= "User-agent: $crawler\nDisallow: /\n";
}
}
$robots .= "# End WPBan-Anything AI Crawler Blocks\n";
return $robots;
}
public function add_meta_tag() {
echo '<meta name="robots" content="noai, noimageai" />';
}
public function get_crawler_list() {
return $this->ai_crawlers;
}
public function monitor_crawlers() {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$settings = $this->get_settings();
foreach ($settings['enabled_crawlers'] as $crawler) {
if (stripos($ua, $crawler) !== false) {
$stats = get_option('banned_stats', [
'users' => [],
'total_count' => 0,
'last_ban_time' => null,
'types' => ['ip_ban' => 0, 'login_restriction' => 0, 'wechat_qq_block' => 0, 'ai_crawler_block' => 0, 'seo_crawler_block' => 0]
]);
$ip = ban_anything_get_ip();
$stats['users'][$ip] = [
'count' => ($stats['users'][$ip]['count'] ?? 0) + 1,
'last_time' => current_time('mysql'),
'type' => 'ai_crawler_block'
];
$stats['total_count']++;
$stats['last_ban_time'] = current_time('mysql');
$stats['types']['ai_crawler_block']++;
update_option('banned_stats', $stats);
break;
}
}
}
}

View file

@ -0,0 +1,559 @@
<?php
namespace WPBan_Anything;
if (!defined('ABSPATH')) {
exit;
}
class WPBan_Anything {
private $ai_crawlers;
private $seo_crawlers;
public function __construct() {
add_action('init', [$this, 'check_ban']);
add_action('init', [$this, 'restrict_login_access']);
add_action('wp_footer', [$this, 'block_wechat_qq_browsers']);
add_action('admin_menu', [$this, 'add_admin_menu']);
add_action('wp_ajax_ban_anything_preview', [$this, 'preview_banned_message']);
add_action('wp_ajax_save_ban_anything_settings', [$this, 'ajax_save_settings']);
$this->ai_crawlers = new WPBan_AI_Crawlers();
$this->seo_crawlers = new WPBan_SEO_Crawlers();
}
public function check_ban() {
$ip = ban_anything_get_ip();
$options = $this->get_options();
$is_banned = false;
foreach ($options['banned_ips'] as $banned_ip) {
if (preg_match_wildcard($banned_ip, $ip)) {
$is_banned = true;
break;
}
}
if ($is_banned && !in_array($ip, $options['banned_exclude_ips'])) {
$this->update_stats($ip, 'ip_ban');
$this->print_banned_message();
}
}
public function print_banned_message() {
$options = $this->get_options();
$message = str_replace(
['%SITE_NAME%', '%SITE_URL%', '%USER_IP%', '%USER_HOSTNAME%'],
[get_option('blogname'), get_option('siteurl'), ban_anything_get_ip(), @gethostbyaddr(ban_anything_get_ip())],
stripslashes($options['banned_message'])
);
wp_die($message, 'Access Denied', ['response' => 403]);
}
public function restrict_login_access() {
$options = $this->get_options();
if (strpos($_SERVER['REQUEST_URI'], 'wp-login.php') !== false) {
$user_ip = ban_anything_get_ip();
$allowed_ips = $options['login_restrictions']['allowed_ips'] ?? [];
if (!empty($allowed_ips) && !ban_anything_ip_in_range($user_ip, $allowed_ips)) {
$this->update_stats($user_ip, 'login_restriction');
wp_redirect(home_url());
exit;
}
}
}
public function block_wechat_qq_browsers() {
$options = $this->get_options();
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (strpos($ua, 'MQQBrowser') !== false || strpos($ua, 'MicroMessenger') !== false) {
$settings = $options['wechat_qq_settings'];
if ($settings['enabled']) {
$this->update_stats(ban_anything_get_ip(), 'wechat_qq_block');
?>
<div id="wechat-qq-mask" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; backdrop-filter: blur(10px); z-index: 9999; display: flex; justify-content: center; align-items: center;">
<div style="background-color: rgba(255, 255, 255, 0.8); padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); max-width: 90%; text-align: center;">
<p style="font-size: 16px; line-height: 1.5em; margin-bottom: 20px;">
<span style="color: red; font-size: 24px; vertical-align: middle;"></span>
<?php echo esc_html($settings['message']); ?>
</p>
<button id="wechat-qq-copy" style="width: 140px; background-color: #007aff; color: #fff; border-radius: 5px; padding: 10px 0; border: none; font-size: 16px; cursor: pointer;">
<?php echo esc_html($settings['copy_text']); ?>
</button>
</div>
</div>
<script>
document.getElementById('wechat-qq-copy').addEventListener('click', function() {
navigator.clipboard.writeText(window.location.href).then(() => {
alert('<?php _e("Link copied to clipboard!", "wpban-anything"); ?>');
});
});
document.body.style.overflow = 'hidden';
</script>
<?php
}
}
}
public function add_admin_menu() {
$hook = add_options_page(
__('Ban Anything', 'wpban-anything'),
__('Ban Anything', 'wpban-anything'),
'manage_options',
'wpban-anything',
[$this, 'render_admin_page']
);
add_action("admin_print_scripts-{$hook}", function() {
wp_enqueue_script('jquery');
});
}
private function get_options() {
return [
'banned_ips' => get_option('banned_ips', []),
'banned_ips_range' => get_option('banned_ips_range', []),
'banned_hosts' => get_option('banned_hosts', []),
'banned_referers' => get_option('banned_referers', []),
'banned_user_agents' => get_option('banned_user_agents', []),
'banned_exclude_ips' => get_option('banned_exclude_ips', []),
'banned_message' => get_option('banned_message', "<div id='wp-ban-container'><p>You are banned.</p></div>"),
'banned_options' => get_option('banned_options', ['reverse_proxy' => 0]),
'login_restrictions' => get_option('login_restrictions', ['allowed_ips' => []]),
'wechat_qq_settings' => get_option('wechat_qq_settings', [
'enabled' => false,
'message' => __('Please use your system browser to open this site.', 'wpban-anything'),
'copy_text' => __('Copy Link', 'wpban-anything')
]),
'banned_stats' => get_option('banned_stats', [
'users' => [],
'total_count' => 0,
'last_ban_time' => null,
'types' => ['ip_ban' => 0, 'login_restriction' => 0, 'wechat_qq_block' => 0, 'ai_crawler_block' => 0, 'seo_crawler_block' => 0]
]),
'ai_crawler_settings' => $this->ai_crawlers->get_settings(),
'seo_crawler_settings' => $this->seo_crawlers->get_settings()
];
}
private function save_options($data) {
$allowed_tags = wp_kses_allowed_html('post');
$allowed_tags['html'] = $allowed_tags['head'] = $allowed_tags['body'] = true;
$allowed_tags['meta'] = ['charset' => true];
$options = [
'banned_options' => ['reverse_proxy' => isset($data['reverse_proxy']) ? 1 : 0],
'banned_ips' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_ips'] ?? '')))),
'banned_ips_range' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_ips_range'] ?? '')))),
'banned_hosts' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_hosts'] ?? '')))),
'banned_referers' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_referers'] ?? '')))),
'banned_user_agents' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_user_agents'] ?? '')))),
'banned_exclude_ips' => array_map('esc_html', array_filter(explode("\n", trim($data['banned_exclude_ips'] ?? '')))),
'banned_message' => wp_kses(trim($data['banned_message'] ?? ''), $allowed_tags),
'login_restrictions' => [
'allowed_ips' => array_map('esc_html', array_filter(explode("\n", trim($data['login_allowed_ips'] ?? ''))))
],
'wechat_qq_settings' => [
'enabled' => isset($data['wechat_qq_enabled']) ? 1 : 0,
'message' => esc_html($data['wechat_qq_message'] ?? ''),
'copy_text' => esc_html($data['wechat_qq_copy_text'] ?? '')
],
'ai_crawler_settings' => $this->ai_crawlers->save_settings($data),
'seo_crawler_settings' => $this->seo_crawlers->save_settings($data)
];
foreach ($options as $key => $value) {
if ($key !== 'ai_crawler_settings' && $key !== 'seo_crawler_settings') {
update_option($key, $value);
}
}
return $options;
}
private function update_stats($ip, $type) {
$stats = get_option('banned_stats', [
'users' => [],
'total_count' => 0,
'last_ban_time' => null,
'types' => ['ip_ban' => 0, 'login_restriction' => 0, 'wechat_qq_block' => 0, 'ai_crawler_block' => 0, 'seo_crawler_block' => 0]
]);
$stats['users'][$ip] = [
'count' => ($stats['users'][$ip]['count'] ?? 0) + 1,
'last_time' => current_time('mysql'),
'type' => $type
];
$stats['total_count']++;
$stats['last_ban_time'] = current_time('mysql');
$stats['types'][$type]++;
update_option('banned_stats', $stats);
}
public function render_admin_page() {
if (!current_user_can('manage_options')) {
wp_die(__('You do not have permission to access this page.', 'wpban-anything'));
}
$options = $this->get_options();
?>
<div class="wrap">
<h1><?php _e('WPBan Anything Settings', 'wpban-anything'); ?></h1>
<div class="card">
<h2><?php _e('Your Details', 'wpban-anything'); ?></h2>
<p><?php _e('Your current connection details.', 'wpban-anything'); ?></p>
<table class="wp-list-table widefat fixed">
<tr><th><?php _e('IP', 'wpban-anything'); ?></th><td><?php echo ban_anything_get_ip(); ?></td></tr>
<tr><th><?php _e('Host', 'wpban-anything'); ?></th><td><?php echo @gethostbyaddr(ban_anything_get_ip()); ?></td></tr>
<tr><th><?php _e('User Agent', 'wpban-anything'); ?></th><td><?php echo esc_html($_SERVER['HTTP_USER_AGENT'] ?? 'Unknown'); ?></td></tr>
</table>
</div>
<div class="card">
<h2><?php _e('Ban Settings', 'wpban-anything'); ?></h2>
<span id="ban-save-status" class="notice" style="display:none; margin-top: 10px;"></span>
<form id="ban-settings-form" method="post">
<?php wp_nonce_field('wpban_anything_nonce', 'wpban_anything_nonce'); ?>
<div class="styles-sync-tabs">
<?php
$sections = [
'general_bans' => ['title' => __('General Bans', 'wpban-anything'), 'desc' => __('Basic ban settings for IPs.')],
'advanced_bans' => ['title' => __('Advanced Bans', 'wpban-anything'), 'desc' => __('Ban settings for hosts and agents.')],
'login_restrictions' => ['title' => __('Login Restrictions', 'wpban-anything'), 'desc' => __('Restrict login page access.')],
'browser_bans' => ['title' => __('Browser Bans', 'wpban-anything'), 'desc' => __('Ban specific browsers.')],
'ai_bans' => ['title' => __('AI Bans', 'wpban-anything'), 'desc' => __('Block AI crawlers.')],
'seo_bans' => ['title' => __('SEO Bans', 'wpban-anything'), 'desc' => __('Block SEO crawlers.')],
'ban_message' => ['title' => __('Ban Message', 'wpban-anything'), 'desc' => __('Customize the ban message.')],
'options' => ['title' => __('Options', 'wpban-anything'), 'desc' => __('Additional ban options.')],
];
foreach ($sections as $key => $data): ?>
<button type="button" class="styles-tab <?php echo $key === 'general_bans' ? 'active' : ''; ?>" data-tab="<?php echo esc_attr($key); ?>">
<?php echo esc_html($data['title']); ?>
</button>
<?php endforeach; ?>
</div>
<div class="styles-sync-content">
<div class="postbox styles-section" data-section="general_bans" style="">
<div class="postbox-header"><h2 class="hndle"><?php _e('General Bans', 'wpban-anything'); ?></h2></div>
<div class="inside">
<p><?php _e('Banned IPs (Use * for wildcards, e.g., 192.168.1.*):', 'wpban-anything'); ?></p>
<textarea name="banned_ips" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_ips'])); ?></textarea>
<p><?php _e('Banned IP Ranges (e.g., 192.168.1.1-192.168.1.255):', 'wpban-anything'); ?></p>
<textarea name="banned_ips_range" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_ips_range'])); ?></textarea>
<p><?php _e('Excluded IPs (e.g., 192.168.1.100):', 'wpban-anything'); ?></p>
<textarea name="banned_exclude_ips" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_exclude_ips'])); ?></textarea>
</div>
</div>
<div class="postbox styles-section" data-section="advanced_bans" style="display:none;">
<div class="postbox-header"><h2 class="hndle"><?php _e('Advanced Bans', 'wpban-anything'); ?></h2></div>
<div class="inside">
<p><?php _e('Banned Hosts (Use * for wildcards, e.g., *.com):', 'wpban-anything'); ?></p>
<textarea name="banned_hosts" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_hosts'])); ?></textarea>
<p><?php _e('Banned Referers (e.g., http://*.example.com):', 'wpban-anything'); ?></p>
<textarea name="banned_referers" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_referers'])); ?></textarea>
<p><?php _e('Banned User Agents (e.g., Bot*):', 'wpban-anything'); ?></p>
<textarea name="banned_user_agents" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['banned_user_agents'])); ?></textarea>
</div>
</div>
<div class="postbox styles-section" data-section="login_restrictions" style="display:none;">
<div class="postbox-header"><h2 class="hndle"><?php _e('Login Restrictions', 'wpban-anything'); ?></h2></div>
<div class="inside">
<p><?php _e('Allowed IPs for wp-login.php (e.g., 192.168.1.0/24):', 'wpban-anything'); ?></p>
<textarea name="login_allowed_ips" rows="5" cols="50"><?php echo esc_textarea(implode("\n", $options['login_restrictions']['allowed_ips'])); ?></textarea>
</div>
</div>
<div class="postbox styles-section" data-section="browser_bans" style="display:none;">
<div class="postbox-header"><h2 class="hndle"><?php _e('Browser Bans', 'wpban-anything'); ?></h2></div>
<div class="inside">
<label><input type="checkbox" name="wechat_qq_enabled" value="1" <?php checked($options['wechat_qq_settings']['enabled'], 1); ?>> <?php _e('Enable WeChat/QQ Ban', 'wpban-anything'); ?></label><br>
<p><?php _e('Message:', 'wpban-anything'); ?></p>
<textarea name="wechat_qq_message" rows="3" cols="50"><?php echo esc_textarea($options['wechat_qq_settings']['message']); ?></textarea><br>
<p><?php _e('Copy Button Text:', 'wpban-anything'); ?></p>
<input type="text" name="wechat_qq_copy_text" value="<?php echo esc_attr($options['wechat_qq_settings']['copy_text']); ?>">
</div>
</div>
<div class="postbox styles-section" data-section="ai_bans" style="display:none;">
<div class="postbox-header">
<h2 class="hndle"><?php _e('AI Bans', 'wpban-anything'); ?></h2>
<div class="handle-actions hide-if-no-js">
<button type="button" class="select-all button button-small" data-section="ai_bans"><?php _e('Select All', 'wpban-anything'); ?></button>
<button type="button" class="select-none button button-small" data-section="ai_bans"><?php _e('Select None', 'wpban-anything'); ?></button>
</div>
</div>
<div class="inside">
<p><?php _e('Search AI crawlers:', 'wpban-anything'); ?></p>
<input type="text" id="ai-crawler-search" placeholder="<?php _e('Search...', 'wpban-anything'); ?>" style="width: 100%; margin-bottom: 10px;">
<?php
$ai_groups = [
'AI Training' => ['GPTBot', 'ChatGPT-User', 'ClaudeBot', 'anthropic-ai', 'cohere-ai', 'Bytespider'],
'Social Media' => ['FacebookBot', 'Meta-ExternalAgent'],
'Research & Analytics' => array_diff(array_keys($this->ai_crawlers->get_crawler_list()), ['GPTBot', 'ChatGPT-User', 'ClaudeBot', 'anthropic-ai', 'cohere-ai', 'Bytespider', 'FacebookBot', 'Meta-ExternalAgent'])
];
foreach ($ai_groups as $group => $crawlers): ?>
<details open>
<summary><?php echo esc_html($group); ?> (<?php echo count($crawlers); ?> crawlers)</summary>
<table class="wp-list-table widefat fixed crawler-table" data-type="ai">
<thead>
<tr>
<th><?php _e('Crawler', 'wpban-anything'); ?></th>
<th><?php _e('Description', 'wpban-anything'); ?></th>
<th><?php _e('Risk', 'wpban-anything'); ?></th>
<th><?php _e('Recommended', 'wpban-anything'); ?></th>
<th><?php _e('Block', 'wpban-anything'); ?></th>
<th><?php _e('More Info', 'wpban-anything'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($crawlers as $crawler):
$info = $this->ai_crawlers->get_crawler_list()[$crawler];
$risk = in_array($crawler, ['GPTBot', 'ClaudeBot']) ? 'High' : (in_array($crawler, ['FacebookBot']) ? 'Medium' : 'Low');
$recommended = in_array($crawler, ['GPTBot', 'ClaudeBot']) ? 'Yes' : 'No';
?>
<tr data-group="<?php echo esc_attr($group); ?>">
<td><?php echo esc_html($crawler); ?></td>
<td><?php echo esc_html($info['description']); ?> <span class="dashicons dashicons-info" title="<?php echo esc_attr(__('Blocking may affect AI training datasets.', 'wpban-anything')); ?>"></span></td>
<td><?php echo esc_html($risk); ?></td>
<td><?php echo esc_html($recommended); ?></td>
<td><input type="checkbox" name="ai_crawlers[]" value="<?php echo esc_attr($crawler); ?>" <?php checked(in_array($crawler, $options['ai_crawler_settings']['enabled_crawlers'])); ?> class="crawler-checkbox"></td>
<td><a href="<?php echo esc_url($info['link']); ?>" target="_blank"><?php _e('More Info', 'wpban-anything'); ?></a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</details>
<?php endforeach; ?>
</div>
</div>
<div class="postbox styles-section" data-section="seo_bans" style="display:none;">
<div class="postbox-header">
<h2 class="hndle"><?php _e('SEO Bans', 'wpban-anything'); ?></h2>
<div class="handle-actions hide-if-no-js">
<button type="button" class="select-all button button-small" data-section="seo_bans"><?php _e('Select All', 'wpban-anything'); ?></button>
<button type="button" class="select-none button button-small" data-section="seo_bans"><?php _e('Select None', 'wpban-anything'); ?></button>
</div>
</div>
<div class="notice notice-warning" style="margin-bottom: 15px;">
<p><?php _e('Warning: Blocking major SEO crawlers (e.g., Googlebot, Bingbot) may reduce your site\'s visibility and traffic. Review recommendations before saving.', 'wpban-anything'); ?></p>
</div>
<div class="inside">
<p><?php _e('Search SEO crawlers:', 'wpban-anything'); ?></p>
<input type="text" id="seo-crawler-search" placeholder="<?php _e('Search...', 'wpban-anything'); ?>" style="width: 100%; margin-bottom: 10px;">
<?php
$seo_groups = [
'Major Search Engines' => ['Googlebot', 'Bingbot', 'YandexBot', 'Baiduspider'],
'SEO Analytics' => ['AhrefsBot', 'SemrushBot', 'MJ12bot'],
'Other Crawlers' => array_diff(array_keys($this->seo_crawlers->get_crawler_list()), ['Googlebot', 'Bingbot', 'YandexBot', 'Baiduspider', 'AhrefsBot', 'SemrushBot', 'MJ12bot'])
];
foreach ($seo_groups as $group => $crawlers): ?>
<details open>
<summary><?php echo esc_html($group); ?> (<?php echo count($crawlers); ?> crawlers)</summary>
<table class="wp-list-table widefat fixed crawler-table" data-type="seo">
<thead>
<tr>
<th><?php _e('Crawler', 'wpban-anything'); ?></th>
<th><?php _e('Description', 'wpban-anything'); ?></th>
<th><?php _e('Risk', 'wpban-anything'); ?></th>
<th><?php _e('Recommended', 'wpban-anything'); ?></th>
<th><?php _e('Block', 'wpban-anything'); ?></th>
<th><?php _e('More Info', 'wpban-anything'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($crawlers as $crawler):
$info = $this->seo_crawlers->get_crawler_list()[$crawler];
$risk = in_array($crawler, ['Googlebot', 'Bingbot']) ? 'High' : (in_array($crawler, ['AhrefsBot']) ? 'Medium' : 'Low');
$recommended = in_array($crawler, ['Googlebot', 'Bingbot']) ? 'No' : 'Yes';
?>
<tr data-group="<?php echo esc_attr($group); ?>">
<td><?php echo esc_html($crawler); ?></td>
<td><?php echo esc_html($info['description']); ?> <span class="dashicons dashicons-info" title="<?php echo esc_attr(__('Blocking may affect SEO rankings.', 'wpban-anything')); ?>"></span></td>
<td><?php echo esc_html($risk); ?></td>
<td><?php echo esc_html($recommended); ?></td>
<td><input type="checkbox" name="seo_crawlers[]" value="<?php echo esc_attr($crawler); ?>" <?php checked(in_array($crawler, $options['seo_crawler_settings']['enabled_crawlers'])); ?> class="crawler-checkbox"></td>
<td><a href="<?php echo esc_url($info['link']); ?>" target="_blank"><?php _e('More Info', 'wpban-anything'); ?></a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</details>
<?php endforeach; ?>
</div>
</div>
<div class="postbox styles-section" data-section="ban_message" style="display:none;">
<div class="postbox-header"><h2 class="hndle"><?php _e('Ban Message', 'wpban-anything'); ?></h2></div>
<div class="inside">
<p><?php _e('Message shown to banned users:', 'wpban-anything'); ?></p>
<textarea name="banned_message" rows="10" style="width:100%;"><?php echo esc_textarea($options['banned_message']); ?></textarea>
</div>
</div>
<div class="postbox styles-section" data-section="options" style="display:none;">
<div class="postbox-header"><h2 class="hndle"><?php _e('Options', 'wpban-anything'); ?></h2></div>
<div class="inside">
<p><label><input type="checkbox" name="reverse_proxy" value="1" <?php checked($options['banned_options']['reverse_proxy'], 1); ?>> <?php _e('Use Reverse Proxy', 'wpban-anything'); ?></label></p>
</div>
</div>
</div>
<p class="submit"><button type="button" id="ban-save-settings" class="button button-primary"><?php _e('Save Changes', 'wpban-anything'); ?></button></p>
</form>
</div>
<div class="card">
<h2><?php _e('Ban Statistics', 'wpban-anything'); ?></h2>
<p><?php _e('View detailed ban attempt statistics.', 'wpban-anything'); ?></p>
<table class="wp-list-table widefat fixed">
<thead>
<tr>
<th><?php _e('Metric', 'wpban-anything'); ?></th>
<th><?php _e('Value', 'wpban-anything'); ?></th>
</tr>
</thead>
<tbody>
<tr><th><?php _e('Total Ban Attempts', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['total_count']); ?></td></tr>
<tr><th><?php _e('Unique IPs Banned', 'wpban-anything'); ?></th><td><?php echo esc_html(count($options['banned_stats']['users'])); ?></td></tr>
<tr><th><?php _e('Last Ban Time', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['last_ban_time'] ?? __('Never', 'wpban-anything')); ?></td></tr>
<tr><th><?php _e('IP Bans', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['types']['ip_ban']); ?></td></tr>
<tr><th><?php _e('Login Restrictions', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['types']['login_restriction']); ?></td></tr>
<tr><th><?php _e('WeChat/QQ Bans', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['types']['wechat_qq_block']); ?></td></tr>
<tr><th><?php _e('AI Crawler Bans', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['types']['ai_crawler_block']); ?></td></tr>
<tr><th><?php _e('SEO Crawler Bans', 'wpban-anything'); ?></th><td><?php echo esc_html($options['banned_stats']['types']['seo_crawler_block']); ?></td></tr>
<tr><th><?php _e('Recent Banned IPs', 'wpban-anything'); ?></th><td>
<?php
$recent = array_slice($options['banned_stats']['users'], -5, 5, true);
if (empty($recent)) {
echo __('None', 'wpban-anything');
} else {
foreach ($recent as $ip => $data) {
echo esc_html("$ip ({$data['count']} times, last: {$data['last_time']}, type: {$data['type']})<br>");
}
}
?>
</td></tr>
</tbody>
</table>
</div>
<script>
jQuery(document).ready(function($) {
// Tab functionality
$('.styles-tab').on('click', function() {
$('.styles-tab').removeClass('active');
$(this).addClass('active');
var tab = $(this).data('tab');
$('.styles-section').hide();
$(`[data-section="${tab}"]`).show();
});
// Search and filter crawlers
$('#ai-crawler-search, #seo-crawler-search').on('keyup', function() {
var $input = $(this);
var value = $input.val().toLowerCase();
var $tables = $input.siblings('details').find('.crawler-table');
$tables.find('tbody tr').each(function() {
var $row = $(this);
var text = $row.text().toLowerCase();
$row.toggle(text.indexOf(value) > -1);
});
});
// Select All/None
$('.select-all').on('click', function(e) {
e.preventDefault();
var section = $(this).data('section');
$(`.styles-section[data-section="${section}"] .crawler-checkbox`).prop('checked', true);
});
$('.select-none').on('click', function(e) {
e.preventDefault();
var section = $(this).data('section');
$(`.styles-section[data-section="${section}"] .crawler-checkbox`).prop('checked', false);
});
// Save settings with confirmation
$('#ban-save-settings').on('click', function() {
var $button = $(this);
var formData = $('#ban-settings-form').serializeArray();
var settings = {};
formData.forEach(item => {
if (item.name.endsWith('[]')) {
var key = item.name.replace('[]', '');
if (!settings[key]) settings[key] = [];
settings[key].push(item.value);
} else {
settings[item.name] = item.value;
}
});
// Check for critical SEO crawlers
var criticalCrawlers = ['Googlebot', 'Bingbot'];
var blockingCritical = criticalCrawlers.some(crawler => settings['seo_crawlers'] && settings['seo_crawlers'].includes(crawler));
if (blockingCritical && !confirm('<?php _e("You are about to block major SEO crawlers (e.g., Googlebot, Bingbot), which may reduce your site\'s traffic. Are you sure?", "wpban-anything"); ?>')) {
return;
}
$button.prop('disabled', true);
$('#ban-save-status').text('<?php _e("Saving...", "wpban-anything"); ?>').show();
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'save_ban_anything_settings',
settings: settings,
_ajax_nonce: $('#wpban_anything_nonce').val()
},
success: function(response) {
if (response.success) {
$('#ban-save-status').removeClass('notice-error').addClass('notice-success')
.text('<?php _e("Settings saved successfully!", "wpban-anything"); ?>')
.delay(3000).fadeOut();
} else {
$('#ban-save-status').removeClass('notice-success').addClass('notice-error')
.text(response.data || '<?php _e("Failed to save settings.", "wpban-anything"); ?>');
}
$button.prop('disabled', false);
},
error: function(xhr, status, error) {
$('#ban-save-status').removeClass('notice-success').addClass('notice-error')
.text('<?php _e("Server error occurred: ", "wpban-anything"); ?>' + error);
$button.prop('disabled', false);
}
});
});
});
</script>
<style>
.card { background: #fff; border: 1px solid #ccd0d4; max-width: unset; border-radius: 4px; margin-top: 20px; padding: 20px; }
.styles-sync-tabs { display: flex; gap: 5px; border-bottom: 1px solid #c3c4c7; margin-bottom: 20px; flex-wrap: wrap; }
.styles-tab { padding: 8px 16px; border: none; background: none; cursor: pointer; font-size: 14px; border-bottom: 2px solid transparent; }
.styles-tab.active { border-bottom: 2px solid #007cba; font-weight: 600; background: #f0f0f1; }
.styles-tab:hover:not(.active) { background: #f0f0f1; }
.postbox { border: 0; }
.postbox-header { padding: 10px; display: flex; justify-content: space-between; align-items: center; }
.postbox .handle-actions { display: flex; gap: 5px; }
.postbox .button-small { font-size: 11px; padding: 0 6px; line-height: 20px; height: 20px; }
.notice { padding: 8px 12px; border-radius: 3px; }
.notice-success { background-color: #dff0d8; border-left: 4px solid #46b450; }
.notice-error { background-color: #f2dede; border-left: 4px solid #dc3232; }
.notice-warning { background-color: #fff3cd; border-left: 4px solid #ffca2c; }
details { margin-bottom: 15px; }
summary { font-weight: bold; cursor: pointer; padding: 5px; }
.dashicons-info { font-size: 16px; vertical-align: middle; color: #007cba; cursor: help; }
</style>
</div>
<?php
}
public function ajax_save_settings() {
if (!check_ajax_referer('wpban_anything_nonce', '_ajax_nonce', false)) {
wp_send_json_error(__('Invalid nonce.', 'wpban-anything'));
}
if (!current_user_can('manage_options')) {
wp_send_json_error(__('Permission denied.', 'wpban-anything'));
}
$settings = isset($_POST['settings']) ? wp_unslash((array)$_POST['settings']) : [];
$this->save_options($settings);
wp_send_json_success(['message' => __('Settings saved.', 'wpban-anything')]);
}
public function preview_banned_message() {
check_ajax_referer('wpban_anything_nonce');
$this->print_banned_message();
}
}

View file

@ -0,0 +1,105 @@
<?php
namespace WPBan_Anything;
if (!defined('ABSPATH')) {
exit;
}
class WPBan_SEO_Crawlers {
private $seo_crawlers;
public function __construct() {
$this->seo_crawlers = $this->get_default_crawlers();
add_filter('robots_txt', [$this, 'add_seo_robots_txt'], 10, 2);
add_action('init', [$this, 'monitor_crawlers']);
}
private function get_default_crawlers() {
return [
'Googlebot' => ['description' => __('Google\'s primary crawler for indexing web pages.', 'wpban-anything'), 'link' => 'https://developers.google.com/search/docs/crawling-indexing/googlebot'],
'Bingbot' => ['description' => __('Microsoft Bing\'s crawler for indexing web content.', 'wpban-anything'), 'link' => 'https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0'],
'Baiduspider' => ['description' => __('Baidu\'s crawler for indexing content, primarily for the Chinese market.', 'wpban-anything'), 'link' => 'https://www.baidu.com/search/spider.html'],
'YandexBot' => ['description' => __('Yandex\'s crawler for indexing web pages, used in Russia and beyond.', 'wpban-anything'), 'link' => 'https://yandex.com/support/webmaster/robot-workings/yandex-robot.html'],
'DuckDuckBot' => ['description' => __('DuckDuckGo\'s crawler for indexing privacy-focused search results.', 'wpban-anything'), 'link' => 'https://duckduckgo.com/duckduckbot'],
'Yahoo! Slurp' => ['description' => __('Yahoo\'s legacy crawler for indexing web content.', 'wpban-anything'), 'link' => 'https://help.yahoo.com/kb/SLN22600.html'],
'Sogou Spider' => ['description' => __('Sogou\'s crawler for indexing content, popular in China.', 'wpban-anything'), 'link' => 'http://www.sogou.com/docs/service/spider.htm'],
'Exabot' => ['description' => __('Exalead\'s crawler for indexing web pages, used by Dassault Systèmes.', 'wpban-anything'), 'link' => 'https://www.exalead.com/software/exabot/'],
'AhrefsBot' => ['description' => __('Ahrefs\' crawler for SEO analysis and backlink indexing.', 'wpban-anything'), 'link' => 'https://ahrefs.com/robot'],
'MJ12bot' => ['description' => __('Majestic\'s crawler for SEO and backlink analysis.', 'wpban-anything'), 'link' => 'https://majestic.com/support/mj12bot'],
'MauiBot' => ['description' => __('MauiBot is a web crawler used for data collection.', 'wpban-anything'), 'link' => 'https://www.mauibot.com'],
'MegaIndex.ru' => ['description' => __('MegaIndex.ru is a Russian SEO tool crawler.', 'wpban-anything'), 'link' => 'https://www.megaindex.com'],
'bytedance' => ['description' => __('Bytedance\'s crawler for data collection.', 'wpban-anything'), 'link' => 'https://www.bytedance.com'],
'SemrushBot' => ['description' => __('SemrushBot is a crawler used by Semrush for SEO analysis.', 'wpban-anything'), 'link' => 'https://www.semrush.com/bot/'],
'Windows NT 5' => ['description' => __('User agent for older Windows operating systems (e.g., Windows XP).', 'wpban-anything'), 'link' => 'https://en.wikipedia.org/wiki/Windows_NT'],
'BLEXBot' => ['description' => __('BLEXBot is a web crawler used by WebMeUp for backlink analysis.', 'wpban-anything'), 'link' => 'https://webmeup.com/crawler.html'],
'DotBot' => ['description' => __('DotBot is a web crawler used by Moz for SEO data collection.', 'wpban-anything'), 'link' => 'https://moz.com/help/guides/moz-procedures/what-is-dotbot'],
'CocCocBot' => ['description' => __('CocCocBot is a Vietnamese search engine crawler.', 'wpban-anything'), 'link' => 'https://help.coccoc.com/searchengine'],
'ImagesiftBot' => ['description' => __('ImagesiftBot is a crawler used for image analysis.', 'wpban-anything'), 'link' => 'https://imagesift.com'],
'Apache-HttpClient/4.5.2 (Java/1.8.0_151)' => ['description' => __('A common user agent for Java-based HTTP clients.', 'wpban-anything'), 'link' => 'https://hc.apache.org/httpcomponents-client-ga/'],
'Windows NT 6' => ['description' => __('User agent for Windows Vista, 7, 8, and 10.', 'wpban-anything'), 'link' => 'https://en.wikipedia.org/wiki/Windows_NT'],
'Macintosh' => ['description' => __('User agent for macOS devices.', 'wpban-anything'), 'link' => 'https://en.wikipedia.org/wiki/Macintosh'],
'python' => ['description' => __('User agent for Python-based web requests.', 'wpban-anything'), 'link' => 'https://www.python.org'],
'Fedora' => ['description' => __('User agent for Fedora Linux systems.', 'wpban-anything'), 'link' => 'https://getfedora.org'],
'X11' => ['description' => __('User agent for X11-based systems (e.g., Linux).', 'wpban-anything'), 'link' => 'https://en.wikipedia.org/wiki/X_Window_System'],
'WOW64' => ['description' => __('User agent for 64-bit Windows on Windows (WOW64) systems.', 'wpban-anything'), 'link' => 'https://en.wikipedia.org/wiki/WoW64'],
];
}
public function get_settings() {
return get_option('seo_crawler_settings', [
'enabled_crawlers' => []
]);
}
public function save_settings($data) {
$settings = [
'enabled_crawlers' => isset($data['seo_crawlers']) ? array_map('sanitize_text_field', $data['seo_crawlers']) : []
];
update_option('seo_crawler_settings', $settings);
return $settings;
}
public function add_seo_robots_txt($robots, $public) {
$settings = $this->get_settings();
$robots .= "\n# WPBan-Anything SEO Crawler Blocks\n";
foreach ($settings['enabled_crawlers'] as $crawler) {
if (array_key_exists($crawler, $this->seo_crawlers)) {
$robots .= "User-agent: $crawler\nDisallow: /\n";
}
}
$robots .= "# End WPBan-Anything SEO Crawler Blocks\n";
return $robots;
}
public function get_crawler_list() {
return $this->seo_crawlers;
}
public function monitor_crawlers() {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$settings = $this->get_settings();
foreach ($settings['enabled_crawlers'] as $crawler) {
if (stripos($ua, $crawler) !== false) {
$stats = get_option('banned_stats', [
'users' => [],
'total_count' => 0,
'last_ban_time' => null,
'types' => ['ip_ban' => 0, 'login_restriction' => 0, 'wechat_qq_block' => 0, 'ai_crawler_block' => 0, 'seo_crawler_block' => 0]
]);
$ip = ban_anything_get_ip();
$stats['users'][$ip] = [
'count' => ($stats['users'][$ip]['count'] ?? 0) + 1,
'last_time' => current_time('mysql'),
'type' => 'seo_crawler_block'
];
$stats['total_count']++;
$stats['last_ban_time'] = current_time('mysql');
$stats['types']['seo_crawler_block']++;
update_option('banned_stats', $stats);
break;
}
}
}
}

44
includes/functions.php Normal file
View file

@ -0,0 +1,44 @@
<?php
namespace WPBan_Anything;
if (!defined('ABSPATH')) {
exit;
}
function ban_anything_get_ip() {
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
$options = get_option('banned_options', ['reverse_proxy' => 0]);
if ($options['reverse_proxy']) {
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
} elseif (!empty($_SERVER['HTTP_X_REAL_IP'])) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
}
return sanitize_text_field($ip);
}
function preg_match_wildcard($pattern, $subject) {
$pattern = preg_quote($pattern, '#');
$pattern = str_replace('\*', '.*', $pattern);
return preg_match("#^$pattern$#i", $subject);
}
function ban_anything_ip_in_range($ip, $ranges) {
foreach ($ranges as $range) {
if (strpos($range, '/') !== false) {
list($subnet, $bits) = explode('/', $range);
$ip_long = ip2long($ip);
$subnet_long = ip2long($subnet);
$mask = -1 << (32 - (int)$bits);
if (($ip_long & $mask) === ($subnet_long & $mask)) {
return true;
}
} elseif ($ip === $range) {
return true;
}
}
return false;
}

51
wpban-anything.php Normal file
View file

@ -0,0 +1,51 @@
<?php
/*
Plugin Name: WPBan-Anything
Plugin URI: https://wpban.com/
Description: Ban users by IP, IP Range, host name, user agent, referer URL, restrict login page, block WeChat/QQ browsers, AI crawlers, and SEO crawlers.
Version: 3.3
Author: WPBan
Author URI: https://wpban.com
Text Domain: wpban-anything
Requires at least: 6.7.2
*/
if (!defined('ABSPATH')) {
exit;
}
define('WPBAN_ANYTHING_VERSION', '3.3');
define('WPBAN_ANYTHING_DIR', plugin_dir_path(__FILE__));
define('WPBAN_ANYTHING_URL', plugin_dir_url(__FILE__));
require_once WPBAN_ANYTHING_DIR . 'includes/class-wpban-anything.php';
require_once WPBAN_ANYTHING_DIR . 'includes/class-wpban-ai-crawlers.php';
require_once WPBAN_ANYTHING_DIR . 'includes/class-wpban-seo-crawlers.php';
require_once WPBAN_ANYTHING_DIR . 'includes/functions.php';
function wpban_anything_init() {
load_plugin_textdomain('wpban-anything', false, dirname(plugin_basename(__FILE__)) . '/languages/');
$wpban_anything = new WPBan_Anything\WPBan_Anything();
$wpban_ai_crawlers = new WPBan_Anything\WPBan_AI_Crawlers();
$wpban_seo_crawlers = new WPBan_Anything\WPBan_SEO_Crawlers();
}
add_action('plugins_loaded', 'wpban_anything_init');
register_uninstall_hook(__FILE__, 'wpban_anything_uninstall');
function wpban_anything_uninstall() {
$options = [
'banned_ips', 'banned_hosts', 'banned_stats', 'banned_message',
'banned_referers', 'banned_exclude_ips', 'banned_ips_range',
'banned_user_agents', 'banned_options', 'login_restrictions',
'wechat_qq_settings', 'ai_crawler_settings', 'seo_crawler_settings'
];
if (is_multisite()) {
foreach (get_sites(['fields' => 'ids']) as $blog_id) {
switch_to_blog($blog_id);
array_walk($options, 'delete_option');
restore_current_blog();
}
} else {
array_walk($options, 'delete_option');
}
}