GG.deals clone: CodeIgniter 4 + MongoDB game price tracker

- Full gg.deals-style UI: deal feed with filters, game pages with price
  history charts, rankings, vouchers, news, prepaids, subscriptions,
  bundles, franchises, wishlist, API docs
- Real data crawlers:
  * gg:crawl (Steam Store API + GOG Catalog + Epic free games)
  * gg:catalog (252K game slugs from gg.deals sitemaps)
  * gg:ggdeals (per-game prices via FlareSolverr session, JSON-LD parsing)
  * gg:seed / gg:crawl-covers (demo seed + Steam CDN cover art)
- 24/7 self-updating scheduler (scripts/scheduler_loop.php, lockfile-protected)
- Tailwind v4 dark/light theme, Alpine.js, Chart.js
This commit is contained in:
deepseek
2026-08-23 07:06:02 +00:00
commit fff7a4b9b9
146 changed files with 15691 additions and 0 deletions
View File
+61
View File
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Libraries;
use MongoDB\Client;
use MongoDB\Database;
/**
* Shared MongoDB connection wrapper.
*/
final class Mongo
{
private static ?Database $db = null;
public static function db(): Database
{
if (self::$db === null) {
$db = env('MONGO_DB', 'ggdeals');
$client = new Client(
self::uri(),
[],
[
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
]
);
self::$db = $client->selectDatabase($db);
}
return self::$db;
}
private static function uri(): string
{
$uri = env('MONGO_URI');
if (is_string($uri) && $uri !== '') {
return $uri;
}
$host = env('MONGO_HOST', 'harness-mongo');
$port = env('MONGO_PORT', '27017');
$user = (string) env('MONGO_USER', '');
$pass = (string) env('MONGO_PASS', '');
$auth = $user !== '' ? urlencode($user) . ':' . urlencode($pass) . '@' : '';
return "mongodb://{$auth}{$host}:{$port}/?authSource=admin";
}
public static function collection(string $name): \MongoDB\Collection
{
return self::db()->selectCollection($name);
}
}