[ 'label' => 'Cognition V3 (cognition.professionalwinner.us)', 'root_path' => '/home/jaysong/web/cognition.professionalwinner.us/public_html/cognition', 'snapshot_dir' => 'engine/logs/snapshots', // relative to root_path ], // Add more systems as you bring them online, e.g.: // 'reach_perks_prod' => [ // 'label' => 'REACH Perks – Production (reachperks.org)', // 'root_path' => '/home/jaysong/web/reachperks.org/public_html', // 'snapshot_dir' => 'engine/logs/snapshots', // ], ]; // ----------------------------------------------------------------------------- // GLOBAL DB CONFIG (optional, hybrid model) // ----------------------------------------------------------------------------- $pdo = null; $db_error = null; // This is where you will put your global DB config later. $global_db_config = '/home/jaysong/pw-core/system_tools_db.php'; if (file_exists($global_db_config)) { require_once $global_db_config; if (isset($SYSTEM_DB_DSN, $SYSTEM_DB_USER, $SYSTEM_DB_PASS)) { try { $pdo = new PDO($SYSTEM_DB_DSN, $SYSTEM_DB_USER, $SYSTEM_DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); } catch (Exception $e) { $db_error = 'DB connection failed: ' . $e->getMessage(); } } else { $db_error = 'DB config loaded but DSN/USER/PASS not set.'; } } else { $db_error = 'DB config file not found (optional): ' . $global_db_config; } // ----------------------------------------------------------------------------- // HELPERS // ----------------------------------------------------------------------------- function render_header() { ?>
This console takes a filesystem snapshot of a selected system. It records: file paths, sizes, last modified timestamps, and SHA1 hashes, then saves the snapshot as a JSON file in that system's logs directory. When configured, it also logs summary metadata into a global tools database.
'; } function format_bytes($bytes) { $units = ['B','KB','MB','GB','TB']; $i = 0; while ($bytes >= 1024 && $i < count($units) - 1) { $bytes /= 1024; $i++; } return round($bytes, 2) . ' ' . $units[$i]; } function build_snapshot($root_path) { $files = []; $total_size = 0; $file_count = 0; $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($root_path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($it as $file) { if ($file->isDir()) { continue; } $fullPath = $file->getPathname(); $relative = ltrim(str_replace($root_path, '', $fullPath), DIRECTORY_SEPARATOR); $size = $file->getSize(); $mtime = $file->getMTime(); $hash = @sha1_file($fullPath); $files[$relative] = [ 'size' => $size, 'mtime' => $mtime, 'hash' => $hash ?: null, ]; $total_size += $size; $file_count++; } return [ 'files' => $files, 'file_count' => $file_count, 'total_size' => $total_size, ]; } function save_snapshot_file($system_key, $root_path, $snapshot_dir, $snapshot_data) { $dir = rtrim($root_path, '/') . '/' . trim($snapshot_dir, '/'); if (!is_dir($dir)) { if (!mkdir($dir, 0755, true)) { throw new RuntimeException("Failed to create snapshot directory: $dir"); } } $timestamp = date('Y-m-d_H-i-s'); $filename = $dir . '/' . $system_key . '_snapshot_' . $timestamp . '.json'; $payload = [ 'system' => $system_key, 'root_path' => $root_path, 'created_at' => date('c'), 'file_count' => $snapshot_data['file_count'], 'total_size' => $snapshot_data['total_size'], 'files' => $snapshot_data['files'], ]; if (file_put_contents($filename, json_encode($payload, JSON_PRETTY_PRINT)) === false) { throw new RuntimeException("Failed to write snapshot file: $filename"); } return [$filename, $payload]; } function log_snapshot_metadata($pdo, $system_key, $snapshot_file, $payload) { if (!$pdo) { return false; } $pdo->exec(" CREATE TABLE IF NOT EXISTS system_snapshots ( id INT AUTO_INCREMENT PRIMARY KEY, system_key VARCHAR(100) NOT NULL, snapshot_file VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL, file_count INT NOT NULL, total_size BIGINT NOT NULL, INDEX (system_key), INDEX (created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; "); $stmt = $pdo->prepare(" INSERT INTO system_snapshots (system_key, snapshot_file, created_at, file_count, total_size) VALUES (:system_key, :snapshot_file, :created_at, :file_count, :total_size) "); $stmt->execute([ ':system_key' => $system_key, ':snapshot_file' => basename($snapshot_file), ':created_at' => date('Y-m-d H:i:s'), ':file_count' => $payload['file_count'], ':total_size' => $payload['total_size'], ]); return true; } // ----------------------------------------------------------------------------- // MAIN // ----------------------------------------------------------------------------- render_header(); global $db_error, $pdo, $systems; $action = $_POST['action'] ?? null; $system_key = $_POST['system_key'] ?? null; if ($db_error) { echo 'This will show you the root path and snapshot directory for the selected system before taking any action.
System:
Root Path:
Snapshot Directory (relative):
Snapshot Directory (full):
When you click "Run Snapshot Now", the tool will walk the filesystem for this system, compute hashes for each file, and save a JSON snapshot in the snapshot directory.
Step 3 – Snapshot Results'; if (!is_dir($root_path)) { echo 'system_snapshots.