Commit a45e66f7 authored by Administrator's avatar Administrator

Update 5 files via Son of Anton

parent 6d82d38f
<?php
declare(strict_types=1);
// Make sure your Database constructor stores dbName.
// Find and verify/replace the constructor:
namespace App\Core;
private string $dbName;
private ?\PDO $pdo = null;
private array $config;
use PDO;
use PDOStatement;
use PDOException;
final class Database
{
private ?PDO $pdo = null;
private string $host;
private int $port;
private string $name;
private string $user;
private string $pass;
private string $charset;
private array $queryLog = [];
private bool $queryLogEnabled = false;
private array $beforeInsertCallbacks = [];
private array $afterInsertCallbacks = [];
private array $beforeUpdateCallbacks = [];
private array $afterUpdateCallbacks = [];
private array $afterDeleteCallbacks = [];
public function __construct(string $host, int $port, string $name, string $user, string $pass, string $charset = 'utf8mb4')
public function __construct(array $config)
{
$this->host = $host;
$this->port = $port;
$this->name = $name;
$this->user = $user;
$this->pass = $pass;
$this->charset = $charset;
$this->config = $config;
$this->dbName = $config['name'] ?? '';
}
private function connect(): PDO
private function connect(): \PDO
{
if ($this->pdo === null) {
$dsn = "mysql:host={$this->host};port={$this->port};dbname={$this->name};charset={$this->charset}";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES '{$this->charset}' COLLATE '{$this->charset}_unicode_ci', sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",
];
$this->pdo = new PDO($dsn, $this->user, $this->pass, $options);
$dsn = sprintf(
'mysql:host=%s;port=%s;dbname=%s;charset=%s',
$this->config['host'] ?? '127.0.0.1',
$this->config['port'] ?? '3306',
$this->config['name'] ?? '',
$this->config['charset'] ?? 'utf8mb4'
);
$this->pdo = new \PDO($dsn, $this->config['user'] ?? 'root', $this->config['pass'] ?? '', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'",
]);
}
return $this->pdo;
}
public function pdo(): PDO
{
return $this->connect();
}
public function query(string $sql, array $params = []): PDOStatement
{
$start = microtime(true);
$stmt = $this->connect()->prepare($sql);
$stmt->execute($params);
$elapsed = (microtime(true) - $start) * 1000;
if ($this->queryLogEnabled) {
$this->queryLog[] = [
'sql' => $sql,
'params' => $params,
'time' => round($elapsed, 2),
];
}
return $stmt;
}
public function select(string $sql, array $params = []): array
{
return $this->query($sql, $params)->fetchAll();
}
public function selectOne(string $sql, array $params = []): ?array
{
$result = $this->query($sql, $params)->fetch();
return $result !== false ? $result : null;
}
public function insert(string $table, array $data): int
{
foreach ($this->beforeInsertCallbacks as $cb) {
$cb($table, $data, null);
}
$columns = implode(', ', array_map(fn($c) => "`{$c}`", array_keys($data)));
$placeholders = implode(', ', array_fill(0, count($data), '?'));
$sql = "INSERT INTO `{$table}` ({$columns}) VALUES ({$placeholders})";
$this->query($sql, array_values($data));
$id = (int) $this->connect()->lastInsertId();
foreach ($this->afterInsertCallbacks as $cb) {
$cb($table, $data, $id);
}
return $id;
}
public function update(string $table, array $data, string $where, array $whereParams = []): int
{
foreach ($this->beforeUpdateCallbacks as $cb) {
$cb($table, $data, null);
}
$set = implode(', ', array_map(fn($c) => "`{$c}` = ?", array_keys($data)));
$sql = "UPDATE `{$table}` SET {$set} WHERE {$where}";
$params = array_merge(array_values($data), $whereParams);
$stmt = $this->query($sql, $params);
$count = $stmt->rowCount();
foreach ($this->afterUpdateCallbacks as $cb) {
$cb($table, $data, null);
}
return $count;
}
public function delete(string $table, string $where, array $whereParams = []): int
{
$sql = "DELETE FROM `{$table}` WHERE {$where}";
$stmt = $this->query($sql, $whereParams);
$count = $stmt->rowCount();
foreach ($this->afterDeleteCallbacks as $cb) {
$cb($table, [], null);
}
return $count;
}
public function beginTransaction(): bool
{
return $this->connect()->beginTransaction();
}
public function commit(): bool
{
return $this->connect()->commit();
}
public function rollBack(): bool
{
return $this->connect()->rollBack();
}
public function inTransaction(): bool
{
return $this->connect()->inTransaction();
}
public function lastInsertId(): int
{
return (int) $this->connect()->lastInsertId();
}
public function raw(string $sql): PDOStatement
{
return $this->connect()->query($sql);
}
public function enableQueryLog(): void
{
$this->queryLogEnabled = true;
}
public function disableQueryLog(): void
{
$this->queryLogEnabled = false;
}
public function getQueryLog(): array
{
return $this->queryLog;
}
public function onBeforeInsert(callable $fn): void
{
$this->beforeInsertCallbacks[] = $fn;
}
public function onAfterInsert(callable $fn): void
{
$this->afterInsertCallbacks[] = $fn;
}
public function onBeforeUpdate(callable $fn): void
{
$this->beforeUpdateCallbacks[] = $fn;
}
public function onAfterUpdate(callable $fn): void
{
$this->afterUpdateCallbacks[] = $fn;
}
public function onAfterDelete(callable $fn): void
{
$this->afterDeleteCallbacks[] = $fn;
}
public function tableExists(string $table): bool
{
$stmt = $this->query("SHOW TABLES LIKE ?", [$table]);
return $stmt->rowCount() > 0;
}
}
\ No newline at end of file
return $this->pdo;
}
\ No newline at end of file
......@@ -15,29 +15,27 @@ final class SeederRunner
$this->db = $db;
}
public function seedAll(): array
public function run(): array
{
$this->ensureSeedsTable();
$ran = $this->getRanSeeds();
$executed = $this->getExecutedSeeds();
$files = $this->getSeedFiles();
$results = [];
foreach ($files as $file) {
$name = basename($file, '.php');
if (in_array($name, $ran)) {
if (in_array($name, $executed)) {
continue;
}
require_once $file;
echo " Running: {$name}...\n";
$fnName = str_replace(['-', '.'], '_', $name);
if (function_exists($fnName)) {
($fnName)($this->db);
} else {
$seed = require $file;
if (is_callable($seed)) {
$seed($this->db);
}
$seed = require $file;
if (is_callable($seed)) {
$seed($this->db);
} elseif (is_object($seed) && method_exists($seed, 'run')) {
$seed->run($this->db);
}
$this->db->insert('seeds', [
......@@ -51,36 +49,50 @@ final class SeederRunner
return $results;
}
public function runOne(string $name): bool
public function runSingle(string $seedName): void
{
$this->ensureSeedsTable();
$file = $this->getSeedDir() . '/' . $name . '.php';
$files = $this->getSeedFiles();
$targetFile = null;
foreach ($files as $file) {
if (str_contains(basename($file, '.php'), $seedName)) {
$targetFile = $file;
break;
}
}
if (!file_exists($file)) {
return false;
if (!$targetFile) {
throw new \RuntimeException("Seed not found: {$seedName}");
}
$seed = require $file;
$seed = require $targetFile;
if (is_callable($seed)) {
$seed($this->db);
} elseif (is_object($seed) && method_exists($seed, 'run')) {
$seed->run($this->db);
}
$ran = $this->getRanSeeds();
if (!in_array($name, $ran)) {
// Record it (ignore duplicate)
$name = basename($targetFile, '.php');
$existing = $this->db->selectOne("SELECT id FROM seeds WHERE seed = ?", [$name]);
if (!$existing) {
$this->db->insert('seeds', [
'seed' => $name,
'executed_at' => date('Y-m-d H:i:s'),
]);
}
return true;
}
private function ensureSeedsTable(): void
{
if (!$this->db->tableExists('seeds')) {
// Seeds table might not exist if migrations haven't created it
// The schema.sql has it, but individual migrations might not
// Create it directly
$this->db->raw("
CREATE TABLE `seeds` (
CREATE TABLE IF NOT EXISTS `seeds` (
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`seed` VARCHAR(255) NOT NULL,
`executed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
......@@ -90,7 +102,7 @@ final class SeederRunner
}
}
private function getRanSeeds(): array
private function getExecutedSeeds(): array
{
$rows = $this->db->select("SELECT seed FROM seeds ORDER BY id");
return array_column($rows, 'seed');
......
<?php
declare(strict_types=1);
// Load environment
/**
* CLI Entry Point — Migrations, Seeds, and System Commands.
*
* Usage:
* php cli.php migrate Run all pending migrations
* php cli.php migrate:rollback Rollback last batch
* php cli.php migrate:status Show migration status
* php cli.php seed Run all pending seeds
* php cli.php seed:run <Name> Run a specific seed
* php cli.php cron Run background jobs
*/
// Prevent web access
if (PHP_SAPI !== 'cli') {
die('CLI only.');
}
require_once __DIR__ . '/app/Core/Autoloader.php';
\App\Core\Autoloader::register();
// Load .env
$envFile = __DIR__ . '/.env';
if (file_exists($envFile)) {
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#')) continue;
if ($line === '' || $line[0] === '#') continue;
if (str_contains($line, '=')) {
[$key, $val] = explode('=', $line, 2);
$_ENV[trim($key)] = trim($val);
$_SERVER[trim($key)] = trim($val);
[$key, $value] = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
if (!isset($_ENV[$key])) {
$_ENV[$key] = $value;
putenv("{$key}={$value}");
}
}
}
}
require_once __DIR__ . '/app/Core/Autoloader.php';
\App\Core\Autoloader::register();
// Minimal bootstrap — just database, no session/routing
$config = [];
$configDir = __DIR__ . '/config';
if (is_dir($configDir)) {
foreach (glob($configDir . '/*.php') as $configFile) {
$key = basename($configFile, '.php');
$config[$key] = require $configFile;
}
}
$config = new \App\Core\Config();
$config->loadAll();
// Build database config
$dbConfig = [
'host' => $_ENV['DB_HOST'] ?? $config['database']['host'] ?? '127.0.0.1',
'port' => $_ENV['DB_PORT'] ?? $config['database']['port'] ?? '3306',
'name' => $_ENV['DB_NAME'] ?? $config['database']['name'] ?? 'the_club_erp',
'user' => $_ENV['DB_USER'] ?? $config['database']['user'] ?? 'root',
'pass' => $_ENV['DB_PASS'] ?? $config['database']['pass'] ?? '',
'charset' => $config['database']['charset'] ?? 'utf8mb4',
'collation' => $config['database']['collation'] ?? 'utf8mb4_unicode_ci',
];
$db = new \App\Core\Database(
$config->get('database.host', '127.0.0.1'),
(int) $config->get('database.port', '3306'),
$config->get('database.name', 'the_club_erp'),
$config->get('database.user', 'root'),
$config->get('database.pass', ''),
$config->get('database.charset', 'utf8mb4')
);
$db = new \App\Core\Database($dbConfig);
$command = $argv[1] ?? 'help';
$arg2 = $argv[2] ?? null;
echo "╔══════════════════════════════════════╗\n";
echo "║ THE CLUB ERP — CLI Tool ║\n";
echo "╚══════════════════════════════════════╝\n\n";
echo "\n";
switch ($command) {
case 'migrate':
$runner = new \App\Core\Migration\MigrationRunner($db);
$results = $runner->migrate();
if (empty($results)) {
echo " ✓ Nothing to migrate. All up to date.\n";
echo "✅ Nothing to migrate. All migrations are up to date.\n";
} else {
foreach ($results as $m) {
echo " ✓ Migrated: {$m}\n";
echo "✅ Ran " . count($results) . " migration(s):\n";
foreach ($results as $name) {
echo " ✔ {$name}\n";
}
}
break;
......@@ -54,10 +86,11 @@ switch ($command) {
$runner = new \App\Core\Migration\MigrationRunner($db);
$results = $runner->rollback();
if (empty($results)) {
echo " Nothing to rollback.\n";
echo "⚠️ Nothing to rollback.\n";
} else {
foreach ($results as $m) {
echo " ↩ Rolled back: {$m}\n";
echo "✅ Rolled back " . count($results) . " migration(s):\n";
foreach ($results as $name) {
echo " ↩ {$name}\n";
}
}
break;
......@@ -68,56 +101,57 @@ switch ($command) {
echo str_pad('Migration', 60) . "Status\n";
echo str_repeat('─', 70) . "\n";
foreach ($status as $s) {
$icon = $s['status'] === 'Ran' ? '' : '○';
echo " {$icon} " . str_pad($s['migration'], 58) . $s['status'] . "\n";
$icon = $s['status'] === 'Ran' ? '' : '○';
echo "{$icon} " . str_pad($s['migration'], 58) . $s['status'] . "\n";
}
break;
case 'seed':
echo "🌱 Running seeds...\n";
$runner = new \App\Core\Seeder\SeederRunner($db);
$results = $runner->seedAll();
$results = $runner->run();
if (empty($results)) {
echo " ✓ Nothing to seed. All seeds already ran.\n";
echo "✅ Nothing to seed. All seeds already executed.\n";
} else {
foreach ($results as $s) {
echo " ✓ Seeded: {$s}\n";
echo "✅ Ran " . count($results) . " seed(s):\n";
foreach ($results as $name) {
echo " 🌱 {$name}\n";
}
}
break;
case 'seed:run':
$name = $argv[2] ?? null;
if (!$name) {
echo " ✗ Please provide seed name.\n";
if (!$arg2) {
echo "❌ Please specify seed name: php cli.php seed:run SeedName\n";
exit(1);
}
$runner = new \App\Core\Seeder\SeederRunner($db);
if ($runner->runOne($name)) {
echo " ✓ Seeded: {$name}\n";
} else {
echo " ✗ Seed not found: {$name}\n";
}
$runner->runSingle($arg2);
echo "✅ Seed executed: {$arg2}\n";
break;
case 'cron':
echo " Running background jobs...\n";
echo "⏰ Running cron jobs...\n";
$cronRunner = __DIR__ . '/cron/runner.php';
if (file_exists($cronRunner)) {
require $cronRunner;
} else {
echo " ✗ Cron runner not found (Phase 15).\n";
echo "⚠️ No cron runner found.\n";
}
break;
case 'help':
default:
echo "Available commands:\n";
echo " migrate Run all pending migrations\n";
echo " migrate:rollback Rollback last migration batch\n";
echo " migrate:status Show migration status\n";
echo " seed Run all pending seeds\n";
echo " seed:run <name> Run a specific seed\n";
echo " cron Run background jobs\n";
echo "THE CLUB ERP — CLI Commands\n";
echo "───────────────────────────────────\n";
echo " php cli.php migrate Run pending migrations\n";
echo " php cli.php migrate:rollback Rollback last batch\n";
echo " php cli.php migrate:status Show migration status\n";
echo " php cli.php seed Run all pending seeds\n";
echo " php cli.php seed:run <Name> Run specific seed\n";
echo " php cli.php cron Run background jobs\n";
echo " php cli.php help Show this help\n";
break;
}
echo "\nDone.\n";
\ No newline at end of file
echo "\n";
\ No newline at end of file
#!/bin/bash
set -e
echo "=========================================="
echo " THE CLUB ERP — Starting Deployment"
echo "=========================================="
# ── DB credentials from environment ──
DB_HOST="${DB_HOST:-srv-captain--mysql-db}"
DB_PORT="${DB_PORT:-3306}"
DB_NAME="${DB_NAME:-the_club_erp}"
DB_USER="${DB_USER:-root}"
DB_PASS="${DB_PASS:-Alarcade123#}"
echo "DB: ${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
# ── Write .env file from Docker env vars ──
cat > /var/www/html/.env <<EOF
echo "========================================="
echo " THE CLUB ERP — Container Starting"
echo "========================================="
# ── Wait for MySQL to be ready ──
echo "⏳ Waiting for MySQL at ${DB_HOST}:${DB_PORT}..."
MAX_TRIES=30
COUNT=0
until mysql -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" -e "SELECT 1" &>/dev/null; do
COUNT=$((COUNT + 1))
if [ $COUNT -ge $MAX_TRIES ]; then
echo "❌ MySQL not ready after ${MAX_TRIES} attempts. Aborting."
exit 1
fi
echo " Attempt ${COUNT}/${MAX_TRIES}..."
sleep 2
done
echo "✅ MySQL is ready!"
# ── Create database if it doesn't exist ──
echo "📦 Ensuring database '${DB_NAME}' exists..."
mysql -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" -e \
"CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
echo "✅ Database ready!"
# ── Generate .env from environment variables if not exists ──
ENV_FILE="/var/www/html/.env"
if [ ! -f "$ENV_FILE" ]; then
echo "📝 Generating .env from environment variables..."
cat > "$ENV_FILE" <<EOF
APP_URL=${APP_URL:-http://localhost}
APP_DEBUG=${APP_DEBUG:-true}
APP_ENV=${APP_ENV:-local}
APP_DEBUG=${APP_DEBUG:-false}
APP_ENV=${APP_ENV:-production}
DB_HOST=${DB_HOST}
DB_PORT=${DB_PORT}
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASS=${DB_PASS}
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-3306}
DB_NAME=${DB_NAME:-the_club_erp}
DB_USER=${DB_USER:-root}
DB_PASS=${DB_PASS:-}
SMS_PROVIDER=${SMS_PROVIDER:-}
SMS_API_KEY=${SMS_API_KEY:-}
SMS_SENDER_ID=${SMS_SENDER_ID:-}
EOF
chown www-data:www-data /var/www/html/.env
chmod 640 /var/www/html/.env
echo "✅ .env written"
# ── Fix permissions ──
chown -R www-data:www-data /var/www/html/storage 2>/dev/null || true
chmod -R 775 /var/www/html/storage 2>/dev/null || true
# ══════════════════════════════════════
# START APACHE IMMEDIATELY IN BACKGROUND
# so CapRover health check passes while
# we run migrations/seeds
# ══════════════════════════════════════
echo "Starting Apache in background (health check will pass)..."
apache2-foreground &
APACHE_PID=$!
# Give Apache a moment to bind port 80
sleep 2
# Verify Apache is running
if ! kill -0 $APACHE_PID 2>/dev/null; then
echo "❌ Apache failed to start!"
exit 1
fi
echo "✅ Apache is running (PID: $APACHE_PID)"
# ══════════════════════════════════════
# WAIT FOR MYSQL (non-blocking — Apache is already up)
# ══════════════════════════════════════
echo "Waiting for MySQL..."
TRIES=0
MAX_TRIES=60
MYSQL_READY=false
until mysqladmin ping -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" --silent 2>/dev/null; do
TRIES=$((TRIES + 1))
if [ $TRIES -ge $MAX_TRIES ]; then
echo "⚠️ MySQL not reachable after 2 minutes — skipping migrations"
break
fi
sleep 2
done
if [ $TRIES -lt $MAX_TRIES ]; then
MYSQL_READY=true
echo "✅ MySQL is alive"
fi
# ══════════════════════════════════════
# DATABASE SETUP (only if MySQL is reachable)
# ══════════════════════════════════════
if [ "$MYSQL_READY" = true ]; then
# ── Create database ──
echo "Creating database if needed..."
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" -e "
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\`
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
" 2>&1 || echo "⚠️ Could not create database (may already exist)"
# ── Create infrastructure tables ──
echo "Creating infrastructure tables..."
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -e "
CREATE TABLE IF NOT EXISTS seeds (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
seed VARCHAR(255) NOT NULL,
executed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uq_seeds_name (seed)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS async_event_queue (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_name VARCHAR(200) NOT NULL,
event_data_json JSON NULL,
status VARCHAR(30) NOT NULL DEFAULT 'pending',
attempts INT UNSIGNED NOT NULL DEFAULT 0,
max_attempts INT UNSIGNED NOT NULL DEFAULT 3,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
processed_at TIMESTAMP NULL DEFAULT NULL,
failed_at TIMESTAMP NULL DEFAULT NULL,
error_message TEXT NULL,
INDEX idx_async_events_status (status),
INDEX idx_async_events_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS cron_job_log (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
job_name VARCHAR(200) NOT NULL,
started_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
finished_at TIMESTAMP NULL DEFAULT NULL,
status VARCHAR(30) NOT NULL DEFAULT 'running',
records_processed INT UNSIGNED NOT NULL DEFAULT 0,
error_message TEXT NULL,
execution_time_ms INT UNSIGNED NULL,
INDEX idx_cron_job_name (job_name),
INDEX idx_cron_job_started (started_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
" 2>&1 || echo "⚠️ Infrastructure tables may already exist"
echo "✅ Infrastructure tables ready"
# ══════════════════════════════════════
# RUN MIGRATIONS
# ══════════════════════════════════════
echo ""
echo "=========================================="
echo " RUNNING MIGRATIONS"
echo "=========================================="
cd /var/www/html
MIGRATION_COUNT=$(ls -1 database/migrations/Phase_*.php 2>/dev/null | wc -l)
echo "Found ${MIGRATION_COUNT} migration files"
php cli.php migrate 2>&1 || {
echo "⚠️ Migration command returned error"
TC=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null || echo "0")
echo "Tables in DB: ${TC}"
}
# ══════════════════════════════════════
# RUN SEEDS
# ══════════════════════════════════════
echo ""
echo "=========================================="
echo " RUNNING SEEDS"
echo "=========================================="
SEED_COUNT=$(ls -1 database/seeds/Phase_*.php 2>/dev/null | wc -l)
echo "Found ${SEED_COUNT} seed files"
php cli.php seed 2>&1 || {
echo "⚠️ Seed command returned error (some may have already run)"
}
# ══════════════════════════════════════
# VERIFY
# ══════════════════════════════════════
echo ""
echo "=========================================="
echo " DEPLOYMENT VERIFICATION"
echo "=========================================="
TC=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null || echo "?")
echo "Tables: ${TC}"
EC=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM employees;" 2>/dev/null || echo "0")
echo "Employees: ${EC}"
RC=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM roles;" 2>/dev/null || echo "0")
echo "Roles: ${RC}"
BC=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM branches;" 2>/dev/null || echo "0")
echo "Branches: ${BC}"
chown www-data:www-data "$ENV_FILE"
echo "✅ .env generated!"
else
echo "⚠️ Skipped migrations/seeds — MySQL unavailable"
echo "✅ .env already exists, skipping generation."
fi
echo ""
echo "=========================================="
echo " ✅ Login: admin / ChangeMe123!"
echo " ⚠️ Password change forced on first login"
echo "=========================================="
echo ""
# ── Run Migrations ──
echo "========================================="
echo "🔄 Running Migrations..."
echo "========================================="
cd /var/www/html
php cli.php migrate 2>&1 || {
echo "⚠️ Migration had issues, but continuing..."
}
echo "✅ Migrations complete!"
# ── Run Seeds ──
echo "========================================="
echo "🌱 Running Seeds..."
echo "========================================="
php cli.php seed 2>&1 || {
echo "⚠️ Seeding had issues, but continuing..."
}
echo "✅ Seeds complete!"
# ── Fix permissions after migrations/seeds ──
chown -R www-data:www-data /var/www/html/storage 2>/dev/null || true
chmod -R 775 /var/www/html/storage 2>/dev/null || true
# ══════════════════════════════════════
# WAIT FOR APACHE (foreground — keeps container alive)
# ══════════════════════════════════════
echo "Apache is serving on port 80. Waiting for process..."
wait $APACHE_PID
\ No newline at end of file
echo "========================================="
echo "🚀 Starting Apache..."
echo "========================================="
exec apache2-foreground
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment