174 lines
10 KiB
PHP
174 lines
10 KiB
PHP
<?php
|
||
/** @var string $page_slug */
|
||
/** @var string $nonce */
|
||
$last_test = \Cf7stg\Settings::get_last_test();
|
||
$pending = \Cf7stg\Queue::count_by_status(\Cf7stg\Queue::STATUS_PENDING);
|
||
$sent24 = \Cf7stg\Queue::count_sent_last_24h();
|
||
$failed = \Cf7stg\Queue::count_failed();
|
||
|
||
$notice = '';
|
||
if (!empty($_GET['saved'])) $notice = '<div class="notice notice-success"><p>Настройки сохранены.</p></div>';
|
||
if (($_GET['test'] ?? '') === 'ok') $notice = '<div class="notice notice-success"><p>Тестовое сообщение отправлено.</p></div>';
|
||
if (($_GET['test'] ?? '') === 'err') $notice = '<div class="notice notice-error"><p>Ошибка отправки: ' . esc_html($last_test['err'] ?? '') . '</p></div>';
|
||
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>
|
||
<?php echo $notice; ?>
|
||
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
|
||
<input type="hidden" name="action" value="cf7stg_save">
|
||
<?php wp_nonce_field('cf7stg_save', $nonce); ?>
|
||
<h2>Настройки Telegram</h2>
|
||
<table class="form-table">
|
||
<tr>
|
||
<th><label for="bot_token">Bot Token</label></th>
|
||
<td>
|
||
<?php if (\Cf7stg\Settings::is_bot_token_constant()): ?>
|
||
<em>Задано константой <code>SPAM2TG_BOT_TOKEN</code> в wp-config.php (readonly).</em>
|
||
<?php else: ?>
|
||
<input type="password" id="bot_token" name="bot_token" class="regular-text" autocomplete="off" placeholder="<?php echo \Cf7stg\Settings::get_bot_token() ? '(сохранён)' : ''; ?>">
|
||
<p class="description">Можно задать константой <code>SPAM2TG_BOT_TOKEN</code> в wp-config.php вместо БД.</p>
|
||
<?php endif; ?>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th><label for="chat_id">Chat ID</label></th>
|
||
<td>
|
||
<?php if (\Cf7stg\Settings::is_chat_id_constant()): ?>
|
||
<em>Задано константой <code>SPAM2TG_CHAT_ID</code> (readonly).</em>
|
||
<?php else: ?>
|
||
<input type="text" id="chat_id" name="chat_id" class="regular-text" value="<?php echo esc_attr(\Cf7stg\Settings::get_chat_id()); ?>">
|
||
<?php endif; ?>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th><label for="site_title">Заголовок сайта</label></th>
|
||
<td>
|
||
<input type="text" id="site_title" name="site_title" class="regular-text" value="<?php echo esc_attr((string)get_option(\Cf7stg\Settings::OPT_SITE_TITLE, '')); ?>" placeholder="<?php echo esc_attr(\Cf7stg\Settings::get_site_title()); ?>">
|
||
<p class="description">Если пусто — используется домен (декодированный из Punycode).</p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<?php submit_button('Сохранить настройки'); ?>
|
||
</form>
|
||
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="margin-top:16px">
|
||
<input type="hidden" name="action" value="cf7stg_test">
|
||
<?php wp_nonce_field('cf7stg_test', $nonce); ?>
|
||
<button type="submit" class="button">Отправить тестовое сообщение</button>
|
||
<?php if (!empty($last_test)): ?>
|
||
<span style="margin-left:12px">
|
||
<?php if (!empty($last_test['ok'])): ?>
|
||
✅ Последняя проверка: <?php echo esc_html((string)$last_test['at']); ?> — OK
|
||
<?php else: ?>
|
||
⚠️ Последняя проверка: <?php echo esc_html((string)$last_test['at']); ?> — <?php echo esc_html((string)$last_test['err']); ?>
|
||
<?php endif; ?>
|
||
</span>
|
||
<?php endif; ?>
|
||
</form>
|
||
|
||
<hr>
|
||
|
||
<h2>Ретроспективная выгрузка из Flamingo</h2>
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
|
||
<input type="hidden" name="action" value="cf7stg_retro">
|
||
<?php wp_nonce_field('cf7stg_retro', $nonce); ?>
|
||
<table class="form-table">
|
||
<tr>
|
||
<th>Количество записей</th>
|
||
<td><input type="number" name="retro_count" value="10" min="1" max="50"> <span class="description">макс. 50</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th>Только за последние</th>
|
||
<td><input type="number" name="retro_days" value="0" min="0"> дней <span class="description">(0 = без ограничения)</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th> </th>
|
||
<td><label><input type="checkbox" name="retro_repeat" value="1"> Разрешить повтор уже отправленных</label></td>
|
||
</tr>
|
||
</table>
|
||
<?php submit_button('Добавить в очередь', 'secondary'); ?>
|
||
</form>
|
||
|
||
<hr>
|
||
|
||
<h2>Состояние очереди</h2>
|
||
<p>В очереди (ожидают): <b><?php echo (int)$pending; ?></b> · Отправлено за сутки: <b><?php echo (int)$sent24; ?></b> · С ошибками: <b><?php echo (int)$failed; ?></b></p>
|
||
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline-block;margin-right:8px">
|
||
<input type="hidden" name="action" value="cf7stg_retry_failed">
|
||
<?php wp_nonce_field('cf7stg_retry_failed', $nonce); ?>
|
||
<button type="submit" class="button">Повторить все ошибочные</button>
|
||
</form>
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline-block">
|
||
<input type="hidden" name="action" value="cf7stg_purge_sent">
|
||
<?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>
|