Files
toolvana/app/Models/AnalyticsEventModel.php
deepseek beaf0e1f37 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
2026-08-23 07:10:30 +00:00

68 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Models;
use CodeIgniter\Model;
final class AnalyticsEventModel extends Model
{
protected $table = 'analytics_events';
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useTimestamps = false;
protected $allowedFields = ['name', 'tool_slug', 'format', 'value', 'session_id', 'country', 'meta', 'created_at'];
public function record(array $event): void
{
$event['created_at'] ??= date('Y-m-d H:i:s');
$this->insert($event, false);
}
/** Aggregated rows for the admin dashboard. */
public function topTools(int $days = 7, int $limit = 20): array
{
return $this->select("tool_slug, COUNT(*) AS views, SUM(name = 'tool_start') AS starts, SUM(name = 'tool_success') AS successes, SUM(name = 'tool_failure') AS failures")
->where('name', 'tool_view')
->where('created_at >=', gmdate('Y-m-d H:i:s', time() - $days * 86400))
->groupBy('tool_slug')
->orderBy('views', 'DESC')
->limit($limit)
->findAll();
}
public function countsSince(int $days = 1): array
{
$rows = $this->select('name, COUNT(*) AS total')
->where('created_at >=', gmdate('Y-m-d H:i:s', time() - $days * 86400))
->groupBy('name')
->findAll();
return array_column($rows, 'total', 'name');
}
/** @return list<array{format:string,total:int}> */
public function topFormats(int $days = 7, int $limit = 12): array
{
return $this->select("format, COUNT(*) AS total")
->where('name', 'download')
->where('format !=', '')
->where('created_at >=', gmdate('Y-m-d H:i:s', time() - $days * 86400))
->groupBy('format')
->orderBy('total', 'DESC')
->limit($limit)
->findAll();
}
/** Recent search queries (term stored in meta.term). */
public function recentSearches(int $limit = 30): array
{
return $this->like('meta', '"search_term"')
->where('name', 'search')
->orderBy('id', 'DESC')
->limit($limit)
->findAll();
}
}