| Current Path : /home/seto/testhive.pm/admin/ |
| Current File : /home/seto/testhive.pm/admin/donors.php |
<?php
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/redis.php';
require_once __DIR__ . '/_layout.php';
// Delete donor + cascade
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
$id = (int)$_POST['delete_id'];
$pageIds = db()->prepare("SELECT id FROM pages WHERE donor_id=?");
$pageIds->execute([$id]);
$ids = array_column($pageIds->fetchAll(), 'id');
if ($ids) {
$in = implode(',', $ids);
db()->exec("DELETE FROM impressions_daily WHERE page_id IN ($in)");
db()->exec("DELETE FROM page_assignments WHERE page_id IN ($in)");
}
db()->prepare("DELETE FROM pages WHERE donor_id=?")->execute([$id]);
db()->prepare("DELETE FROM donors WHERE id=?")->execute([$id]);
header('Location: /admin/donors.php'); exit;
}
// Toggle active
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['toggle_id'])) {
$id = (int)$_POST['toggle_id'];
db()->prepare(
"UPDATE donors SET is_active = CASE WHEN is_active=1 THEN 0 ELSE 1 END WHERE id=?"
)->execute([$id]);
header('Location: /admin/donors.php'); exit;
}
// Add new donor manually
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_domain'])) {
$domain = trim($_POST['add_domain']);
if ($domain !== '') {
$newKey = bin2hex(random_bytes(16));
$now = time();
$stmt = db()->prepare(
"INSERT OR IGNORE INTO donors (domain, api_key, created_at, last_seen_at, is_active)
VALUES (?, ?, ?, ?, 1)"
);
$stmt->execute([$domain, $newKey, $now, $now]);
}
header('Location: /admin/donors.php'); exit;
}
$page = max(1, (int)($_GET['page'] ?? 1));
$offset = ($page - 1) * ROWS_PER_PAGE;
$total = (int)db()->query("SELECT COUNT(*) FROM donors")->fetchColumn();
$today = date('Y-m-d');
$donors = db()->prepare(
"SELECT d.*,
(SELECT COUNT(*) FROM pages WHERE donor_id=d.id) AS page_count,
(SELECT COALESCE(SUM(p2.hits),0) FROM pages p2 WHERE p2.donor_id=d.id) AS total_hits,
(SELECT COUNT(*) FROM page_assignments pa JOIN pages p3 ON p3.id=pa.page_id WHERE p3.donor_id=d.id) AS assigned_count,
(SELECT COUNT(*) FROM impressions_daily id2 JOIN pages p4 ON p4.id=id2.page_id WHERE p4.donor_id=d.id AND id2.date=?) AS imp_today,
(SELECT COUNT(*) FROM impressions_daily id3 JOIN pages p5 ON p5.id=id3.page_id WHERE p5.donor_id=d.id) AS imp_total
FROM donors d
ORDER BY imp_total DESC LIMIT ? OFFSET ?"
);
$donors->execute([$today, ROWS_PER_PAGE, $offset]);
$donors = $donors->fetchAll();
layout_head('Доноры');
?>
<form method="post" class="d-flex gap-2 mb-3" style="max-width:400px">
<input type="text" name="add_domain" class="form-control" placeholder="example.com" required>
<button class="btn btn-primary text-nowrap">+ Добавить донора</button>
</form>
<div class="card shadow-sm">
<table class="table table-hover mb-0">
<thead class="table-light small">
<tr>
<th>Domain</th>
<th class="text-end">Страниц</th>
<th class="text-end">Assigned</th>
<th class="text-end">Покрытие</th>
<th class="text-end">Хитов</th>
<th class="text-end">Показов сег.</th>
<th class="text-end">Показов всего</th>
<th>Последний визит</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<?php
$sumPages = $sumAssigned = $sumHits = $sumImpToday = $sumImpTotal = 0;
foreach ($donors as $d):
$coverage = $d['page_count'] > 0 ? round($d['assigned_count'] / $d['page_count'] * 100) : 0;
$sumPages += (int)$d['page_count'];
$sumAssigned += (int)$d['assigned_count'];
$sumHits += (int)$d['total_hits'];
$sumImpToday += (int)$d['imp_today'];
$sumImpTotal += (int)$d['imp_total'];
?>
<tr>
<td>
<?= htmlspecialchars($d['domain']) ?>
<a href="<?= 'http://' . htmlspecialchars($d['domain']) ?>" target="_blank" rel="noopener" class="ms-1 text-muted" title="Открыть сайт донора" style="opacity:.5;vertical-align:middle"><svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg></a>
</td>
<td class="text-end"><?= (int)$d['page_count'] ?></td>
<td class="text-end"><?= (int)$d['assigned_count'] ?></td>
<td class="text-end">
<span class="<?= $coverage < 30 ? 'text-danger' : ($coverage < 70 ? 'text-warning' : 'text-success') ?>">
<?= $coverage ?>%
</span>
</td>
<td class="text-end"><?= number_format((int)$d['total_hits']) ?></td>
<td class="text-end fw-semibold"><?= (int)$d['imp_today'] ?></td>
<td class="text-end"><?= number_format((int)$d['imp_total']) ?></td>
<td><?= $d['last_seen_at'] ? date('d.m.Y H:i', $d['last_seen_at']) : '—' ?></td>
<td class="d-flex align-items-center gap-2">
<form method="post" class="d-inline">
<input type="hidden" name="toggle_id" value="<?= $d['id'] ?>">
<?php if ($d['is_active']): ?>
<button class="badge bg-success border-0" style="cursor:pointer">Active</button>
<?php else: ?>
<button class="badge bg-danger border-0" style="cursor:pointer">Disabled</button>
<?php endif ?>
</form>
<form method="post" class="d-inline" onsubmit="return confirm('Удалить донора «<?= htmlspecialchars($d['domain'], ENT_QUOTES) ?>» и все его страницы?')">
<input type="hidden" name="delete_id" value="<?= $d['id'] ?>">
<button class="badge bg-danger border-0" style="cursor:pointer">Удалить</button>
</form>
</td>
</tr>
<?php endforeach ?>
<?php if (empty($donors)): ?>
<tr><td colspan="10" class="text-center text-muted py-3">Доноров пока нет</td></tr>
<?php endif ?>
<?php if (!empty($donors)): ?>
<tr class="table-light fw-semibold small">
<td class="text-muted">Итого</td>
<td class="text-end"><?= number_format($sumPages) ?></td>
<td class="text-end"><?= number_format($sumAssigned) ?></td>
<td class="text-end"><?= $sumPages > 0 ? round($sumAssigned / $sumPages * 100) : 0 ?>%</td>
<td class="text-end"><?= number_format($sumHits) ?></td>
<td class="text-end"><?= number_format($sumImpToday) ?></td>
<td class="text-end"><?= number_format($sumImpTotal) ?></td>
<td colspan="3"></td>
</tr>
<?php endif ?>
</tbody>
</table>
</div>
<?php if ($total > ROWS_PER_PAGE): ?>
<div class="mt-3"><?= paginate($total, $page, ROWS_PER_PAGE, '/admin/donors.php') ?></div>
<?php endif ?>
<?php layout_foot() ?>