feat(admin): silent-drop block in settings page (dry-run, hard-rule, threshold, stats, reset)

This commit is contained in:
Vladimir Bryzgalov
2026-04-21 17:14:56 +05:00
parent 2fcebcc756
commit ea5666318b
2 changed files with 81 additions and 0 deletions
+19
View File
@@ -16,6 +16,8 @@ final class Settings_Page
add_action('admin_post_cf7stg_retro', [$this, 'handle_retro']);
add_action('admin_post_cf7stg_retry_failed', [$this, 'handle_retry_failed']);
add_action('admin_post_cf7stg_purge_sent', [$this, 'handle_purge_sent']);
add_action('admin_post_cf7stg_save_drop', [$this, 'handle_save_drop']);
add_action('admin_post_cf7stg_reset_drop_counters', [$this, 'handle_reset_drop_counters']);
}
public function add_menu(): void
@@ -92,6 +94,23 @@ final class Settings_Page
$this->redirect_back(['purged' => $n]);
}
public function handle_save_drop(): void
{
$this->guard('cf7stg_save_drop');
Settings::set_dry_run_drop(!empty($_POST['dry_run_drop']));
Settings::set_hard_drop_enabled(!empty($_POST['hard_drop_enabled']));
$threshold = (int)($_POST['drop_score_threshold'] ?? -5);
Settings::set_drop_score_threshold($threshold);
$this->redirect_back(['drop_saved' => 1]);
}
public function handle_reset_drop_counters(): void
{
$this->guard('cf7stg_reset_drop_counters');
Settings::reset_drop_counters();
$this->redirect_back(['drop_reset' => 1]);
}
private function guard(string $action): void
{
if (!current_user_can('manage_options')) wp_die('forbidden');
+62
View File
@@ -13,6 +13,8 @@ if (($_GET['test'] ?? '') === 'err') $notice = '<div class="notice notice-error"
if (isset($_GET['retro_added'])) $notice = '<div class="notice notice-success"><p>Добавлено в очередь: ' . (int)$_GET['retro_added'] . ', пропущено: ' . (int)$_GET['retro_skipped'] . '.</p></div>';
if (isset($_GET['retried'])) $notice = '<div class="notice notice-success"><p>Перезапущено с ошибкой: ' . (int)$_GET['retried'] . '.</p></div>';
if (isset($_GET['purged'])) $notice = '<div class="notice notice-success"><p>Удалено отправленных: ' . (int)$_GET['purged'] . '.</p></div>';
if (isset($_GET['drop_saved'])) $notice = '<div class="notice notice-success"><p>Настройки silent drop сохранены.</p></div>';
if (isset($_GET['drop_reset'])) $notice = '<div class="notice notice-success"><p>Счётчики silent drop сброшены.</p></div>';
?>
<div class="wrap">
<h1>CF7 Spam → Telegram</h1>
@@ -108,4 +110,64 @@ if (isset($_GET['purged'])) $notice = '<div class="notice notice-success"
<?php wp_nonce_field('cf7stg_purge_sent', $nonce); ?>
<button type="submit" class="button">Очистить отправленные</button>
</form>
<hr>
<h2>Silent drop</h2>
<p class="description">
Заявки, удовлетворяющие правилам, не отправляются в Telegram.
Подробности правил — в <code>docs/superpowers/specs/2026-04-21-cf7stg-silent-drop-design.md</code>.
</p>
<?php
$drop_counters = \Cf7stg\Settings::get_drop_counters();
$is_dry = \Cf7stg\Settings::is_dry_run_drop();
?>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<input type="hidden" name="action" value="cf7stg_save_drop">
<?php wp_nonce_field('cf7stg_save_drop', $nonce); ?>
<table class="form-table">
<tr>
<th>Dry-run mode</th>
<td>
<label>
<input type="checkbox" name="dry_run_drop" value="1" <?php checked($is_dry); ?>>
Не дропать реально, отправлять в TG с пометкой «[БЫЛО БЫ DROPPED]»
</label>
<p class="description">Включён по умолчанию. Снимите галочку только убедившись по TG-сообщениям, что среди дропов нет реальных клиентов.</p>
</td>
</tr>
<tr>
<th>Hard-rule override</th>
<td>
<label>
<input type="checkbox" name="hard_drop_enabled" value="1" <?php checked(\Cf7stg\Settings::is_hard_drop_enabled()); ?>>
Включить правило: нет позитивных сигналов + короткое латинское имя или ≥ 3 поля-плейсхолдера
</label>
</td>
</tr>
<tr>
<th><label for="drop_score_threshold">Score-порог drop</label></th>
<td>
<input type="number" id="drop_score_threshold" name="drop_score_threshold" value="<?php echo (int)\Cf7stg\Settings::get_drop_score_threshold(); ?>" step="1">
<p class="description">Дефолт 5. Заявка с score ≤ этого значения дропается даже без hard-rule.</p>
</td>
</tr>
</table>
<?php submit_button('Сохранить silent-drop настройки'); ?>
</form>
<h3>Статистика</h3>
<p>
Всего дропнуто: <b><?php echo (int)$drop_counters['total']; ?></b><br>
Сегодня (real): <b><?php echo (int)$drop_counters['real_today']; ?></b> · сегодня (dry-run): <b><?php echo (int)$drop_counters['dry_today']; ?></b><br>
Вчера (real): <b><?php echo (int)$drop_counters['real_yesterday']; ?></b> · вчера (dry-run): <b><?php echo (int)$drop_counters['dry_yesterday']; ?></b><br>
Счётчик с: <b><?php echo esc_html((string)$drop_counters['reset_at']); ?></b>
</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<input type="hidden" name="action" value="cf7stg_reset_drop_counters">
<?php wp_nonce_field('cf7stg_reset_drop_counters', $nonce); ?>
<button type="submit" class="button">Сбросить счётчики</button>
</form>
</div>