Toolvana: production-ready media tools platform (CodeIgniter 4)

- 134-tool registry with programmatic SEO (unique titles/H1/descriptions,
  JSON-LD graphs, sitemap index, canonical 301 enforcement via required filter)
- DB-backed job queue (SKIP LOCKED) with drivers: Ffmpeg, Images (GD),
  Pdf (qpdf/gs/poppler), Youtube (thumbnails), Qr (server-side PNG)
- Security: SSRF guard, MIME validation, rate limits, API-key auth,
  bcrypt admin login, security headers
- Admin panel: dashboard, tools/categories/guides CRUD, SEO audit,
  analytics, job inspector with retry, system health, feature flags
- Docker deployment (nginx + web/api FPM pools + scalable workers),
  PHPUnit suite (19 tests / 1139 assertions), PWA manifest + service worker
This commit is contained in:
deepseek
2026-08-23 07:10:30 +00:00
commit beaf0e1f37
217 changed files with 19619 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
<?= view('partials/admin_nav') ?>
<h1 style="font-size:1.7rem;margin-bottom:1rem">Analytics (anonymous events only)</h1>
<div class="grid cols-4" style="margin-bottom:1.4rem">
<?php foreach (['tool_view' => 'Tool views', 'tool_start' => 'Jobs started', 'tool_success' => 'Successes', 'download' => 'Downloads'] as $key => $label): ?>
<div class="card"><p style="font-size:.78rem;text-transform:uppercase;color:var(--ink-500)"><?= esc($label) ?></p>
<h2 style="font-size:1.7rem;font-weight:800;margin:.15rem 0"><?= number_format($counts[$key] ?? 0) ?> <span class="hint">/24h</span></h2></div>
<?php endforeach ?>
</div>
<h2 class="section-title">Top tools (7 days)</h2>
<table style="width:100%;font-size:.87rem;border-collapse:collapse;background:#fff;border-radius:var(--radius-sm);box-shadow:var(--shadow-sm)">
<tr style="text-align:left;color:var(--ink-500)"><th style="padding:.65rem">Tool</th><th>Views</th><th>Starts</th><th>Success rate</th></tr>
<?php foreach ($topTools as $row): ?>
<tr style="border-top:1px solid #f2f2f5">
<td style="padding:.5rem .65rem"><a href="/<?= esc($row['tool_slug']) ?>"><?= esc(str_replace('-', ' ', $row['tool_slug'])) ?></a></td>
<td><?= number_format((float)$row['views']) ?></td>
<td><?= number_format((float)$row['starts']) ?></td>
<td><?= $row['success_rate'] === null ? '' : $row['success_rate'] . '%' ?></td>
</tr>
<?php endforeach ?>
</table>
<div class="grid cols-2" style="margin-top:1.4rem">
<div class="card">
<h3>Output formats (7d)</h3>
<?php if ($formats === []): ?><p class="hint">No downloads yet.</p><?php else: ?>
<ul style="padding-left:1.1rem"><?php foreach ($formats as $f): ?><li><strong><?= esc(strtoupper($f['format'])) ?></strong> — <?= number_format((float)$f['total']) ?></li><?php endforeach ?></ul>
<?php endif ?>
</div>
<div class="card">
<h3>Recent searches</h3>
<?php if ($searches === []): ?><p class="hint">None yet.</p><?php else: ?>
<ul style="padding-left:1.1rem"><?php foreach ($searches as $s): $m = json_decode((string)($s['meta'] ?? '{}'), true); ?><li><?= esc($m['term'] ?? '?') ?></li><?php endforeach ?></ul>
<?php endif ?>
</div>
</div>