Files
website/scripts/whmcs-migrate/src/Logger.php
Claude Dev b4ef90465c feat: complete pre-launch audit — frontend polish, churn prevention, login history, financial reports, configurable checkout
Includes all work from phases 6-9+ and frontend polish rounds 1 & 2:

- Login history with device trust, new device notifications, session management
- Churn prevention: cancellation surveys, winback campaigns with email sequences
- Financial reports: revenue, P&L, tax, aging, refund, subscription reports with PDF/CSV/JSON export
- Configurable checkout: plan config groups/options, build-your-own VPS
- Frontend polish: fix broken legal links, add SEO meta tags, favicon, font display=swap,
  Head titles on all 14 marketing pages, mobile responsive fixes, AuthLayout legal footer,
  remove false 24/7 claims, hide empty stats, correct uptime SLA to 99.9%,
  GameServers notify buttons linked to /contact, 301 redirects for /terms and /privacy
- WHMCS migration scripts
- Update legal page effective dates to March 16, 2026

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:39:25 -04:00

80 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace WhmcsMigrate;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Monolog\Logger as MonologLogger;
final class Logger
{
private MonologLogger $logger;
public function __construct(string $logDir, string $level = 'info')
{
if (! is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
$this->logger = new MonologLogger('whmcs-migrate');
$monologLevel = Level::fromName($level);
// File handler — detailed format
$fileFormatter = new LineFormatter(
format: "[%datetime%] %level_name%: %message% %context%\n",
dateFormat: 'Y-m-d H:i:s',
allowInlineLineBreaks: true,
ignoreEmptyContextAndExtra: true,
);
$fileHandler = new StreamHandler($logDir . '/migration.log', $monologLevel);
$fileHandler->setFormatter($fileFormatter);
$this->logger->pushHandler($fileHandler);
// Console handler — colorized
$consoleFormatter = new LineFormatter(
format: "%level_name%: %message% %context%\n",
dateFormat: null,
allowInlineLineBreaks: true,
ignoreEmptyContextAndExtra: true,
);
$consoleHandler = new StreamHandler('php://stdout', $monologLevel);
$consoleHandler->setFormatter($consoleFormatter);
$this->logger->pushHandler($consoleHandler);
}
public function info(string $message, array $context = []): void
{
$this->logger->info($message, $context);
}
public function warning(string $message, array $context = []): void
{
$this->logger->warning($message, $context);
}
public function error(string $message, array $context = []): void
{
$this->logger->error($message, $context);
}
public function debug(string $message, array $context = []): void
{
$this->logger->debug($message, $context);
}
/**
* Log a visual section separator.
*/
public function section(string $title): void
{
$separator = str_repeat('=', 60);
$this->info("\n{$separator}\n{$title}\n{$separator}");
}
}