123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
<?php
class Initializer {
private $indexerFilesDir;
private $baseDir;
public function __construct($indexerFilesDir, $baseDir = null) {
$this->indexerFilesDir = $indexerFilesDir;
$this->baseDir = $baseDir;
}
public function initializeCache($verbose = false) {
if ($verbose) {
echo "[Initializer] Setting up Cache system...\n";
}
$cacheDir = $this->indexerFilesDir . '/cache';
$created = [];
if (!is_dir($cacheDir)) {
@mkdir($cacheDir, 0777, true);
if (is_dir($cacheDir)) {
@chmod($cacheDir, 0777);
$created[] = $cacheDir;
if ($verbose) echo " [OK] Created: $cacheDir\n";
}
}
$subdirs = ['files', 'img', 'zip'];
foreach ($subdirs as $subdir) {
$path = $cacheDir . '/' . $subdir;
if (!is_dir($path)) {
@mkdir($path, 0777, true);
if (is_dir($path)) {
@chmod($path, 0777);
$created[] = $path;
if ($verbose) echo " [OK] Created: $path\n";
}
}
}
$versionDb = $cacheDir . '/version.sqlite';
if (!file_exists($versionDb)) {
try {
$pdo = new PDO('sqlite:' . $versionDb);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("CREATE TABLE IF NOT EXISTS version_info (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
cached_at INTEGER NOT NULL
)");
if (file_exists($versionDb)) {
@chmod($versionDb, 0666);
}
$created[] = $versionDb;
if ($verbose) echo " [OK] Created: $versionDb\n";
} catch (Exception $e) {
if ($verbose) echo " [ERROR] Failed to create version.sqlite: " . $e->getMessage() . "\n";
}
}
if ($verbose && empty($created)) {
echo " [INFO] Cache system already initialized\n";
}
return true;
}
public function initializeDatabase($verbose = false) {
if ($verbose) {
echo "[Initializer] Setting up Database system...\n";
}
$dbDir = $this->indexerFilesDir . '/db';
$dbPath = $dbDir . '/indexer.sqlite';
if (!is_dir($dbDir)) {
@mkdir($dbDir, 0777, true);
if (is_dir($dbDir)) {
@chmod($dbDir, 0777);
if ($verbose) echo " [OK] Created: $dbDir\n";
} else {
if ($verbose) echo " [ERROR] Failed to create: $dbDir\n";
return false;
}
}
try {
$pdo = new PDO('sqlite:' . $dbPath);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (file_exists($dbPath)) {
@chmod($dbPath, 0666);
}
if ($verbose) echo " [OK] Database created: $dbPath\n";
if ($verbose) echo " [INFO] Creating database tables...\n";
$pdo->exec("CREATE TABLE IF NOT EXISTS system_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
last_updated INTEGER NOT NULL
)");
if ($verbose) echo " [OK] system_config table\n";
$pdo->exec("CREATE TABLE IF NOT EXISTS extension_mappings (
extension TEXT PRIMARY KEY,
indexing_setting TEXT,
viewing_setting TEXT,
last_updated INTEGER NOT NULL
)");
if ($verbose) echo " [OK] extension_mappings table\n";
$pdo->exec("CREATE TABLE IF NOT EXISTS icon_mappings (
identifier TEXT PRIMARY KEY,
icon_filename TEXT NOT NULL,
last_updated INTEGER NOT NULL
)");
if ($verbose) echo " [OK] icon_mappings table\n";
$pdo->exec("CREATE TABLE IF NOT EXISTS file_metadata (
path TEXT PRIMARY KEY,
filename TEXT NOT NULL,
extension TEXT,
size INTEGER NOT NULL,
modified INTEGER NOT NULL,
is_directory INTEGER NOT NULL,
parent_path TEXT,
indexed_at INTEGER NOT NULL,
last_verified INTEGER NOT NULL
)");
if ($verbose) echo " [OK] file_metadata table\n";
if ($verbose) echo " [INFO] Creating indexes...\n";
$pdo->exec("CREATE INDEX IF NOT EXISTS idx_file_parent ON file_metadata(parent_path)");
$pdo->exec("CREATE INDEX IF NOT EXISTS idx_file_extension ON file_metadata(extension)");
$pdo->exec("CREATE INDEX IF NOT EXISTS idx_file_modified ON file_metadata(modified)");
$pdo->exec("CREATE INDEX IF NOT EXISTS idx_file_directory ON file_metadata(is_directory)");
if ($verbose) echo " [OK] Indexes created\n";
if ($verbose) echo " [INFO] Syncing system files to database...\n";
$this->syncSystemFilesToDatabase($pdo, $verbose);
if ($this->baseDir && is_dir($this->baseDir)) {
if ($verbose) {
echo " [INFO] Indexing existing files (this may take a while)...\n";
}
$this->indexExistingFiles($pdo, $verbose);
}
if ($verbose) echo " [INFO] Optimizing database...\n";
$pdo->exec("VACUUM");
$pdo->exec("ANALYZE");
if ($verbose) echo " [OK] Database optimized\n";
} catch (Exception $e) {
if ($verbose) echo " [ERROR] Database initialization failed: " . $e->getMessage() . "\n";
return false;
}
if ($verbose) {
echo "[Initializer] Database initialization complete!\n";
$this->displayDatabaseStats($pdo);
}
return true;
}
private function syncSystemFilesToDatabase($pdo, $verbose = false) {
$configFile = $this->indexerFilesDir . '/config.json';
$extensionMapFile = $this->indexerFilesDir . '/local_api/extensionMap.json';
$iconsFile = $this->indexerFilesDir . '/local_api/icons.json';
$timestamp = time();
if (file_exists($configFile)) {
$configData = json_decode(file_get_contents($configFile), true);
if ($configData) {
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("INSERT OR REPLACE INTO system_config (key, value, last_updated) VALUES (?, ?, ?)");
$stmt->execute(['config_data', json_encode($configData), $timestamp]);
$stmt->execute(['config_timestamp', $timestamp, $timestamp]);
if (isset($configData['version'])) {
$stmt->execute(['version', $configData['version'], $timestamp]);
}
if (isset($configData['main'])) {
foreach ($configData['main'] as $key => $value) {
$stmt->execute(['main_' . $key, json_encode($value), $timestamp]);
}
}
$pdo->commit();
if ($verbose) echo " [OK] config.json synced\n";
} catch (Exception $e) {
$pdo->rollBack();
if ($verbose) echo " [ERROR] config.json sync failed: " . $e->getMessage() . "\n";
}
}
} else {
if ($verbose) echo " [WARNING] config.json not found\n";
}
if (file_exists($extensionMapFile)) {
$mapData = json_decode(file_get_contents($extensionMapFile), true);
if ($mapData) {
$pdo->beginTransaction();
try {
$pdo->exec("DELETE FROM extension_mappings");
$stmt = $pdo->prepare("INSERT INTO extension_mappings (extension, indexing_setting, viewing_setting, last_updated) VALUES (?, ?, ?, ?)");
if (isset($mapData['indexing'])) {
foreach ($mapData['indexing'] as $ext => $setting) {
$viewingSetting = isset($mapData['viewing'][$ext]) ? $mapData['viewing'][$ext] : null;
$stmt->execute([$ext, $setting, $viewingSetting, $timestamp]);
}
}
if (isset($mapData['viewing'])) {
foreach ($mapData['viewing'] as $ext => $setting) {
if (!isset($mapData['indexing'][$ext])) {
$stmt->execute([$ext, null, $setting, $timestamp]);
}
}
}
$stmt = $pdo->prepare("INSERT OR REPLACE INTO system_config (key, value, last_updated) VALUES (?, ?, ?)");
$stmt->execute(['extension_map_timestamp', $timestamp, $timestamp]);
$pdo->commit();
if ($verbose) echo " [OK] extensionMap.json synced\n";
} catch (Exception $e) {
$pdo->rollBack();
if ($verbose) echo " [ERROR] extensionMap.json sync failed: " . $e->getMessage() . "\n";
}
}
} else {
if ($verbose) echo " [WARNING] extensionMap.json not found\n";
}
if (file_exists($iconsFile)) {
$iconsData = json_decode(file_get_contents($iconsFile), true);
if ($iconsData) {
$pdo->beginTransaction();
try {
$pdo->exec("DELETE FROM icon_mappings");
$stmt = $pdo->prepare("INSERT INTO icon_mappings (identifier, icon_filename, last_updated) VALUES (?, ?, ?)");
foreach ($iconsData as $identifier => $iconFile) {
$stmt->execute([$identifier, $iconFile, $timestamp]);
}
$stmt = $pdo->prepare("INSERT OR REPLACE INTO system_config (key, value, last_updated) VALUES (?, ?, ?)");
$stmt->execute(['icons_timestamp', $timestamp, $timestamp]);
$pdo->commit();
if ($verbose) echo " [OK] icons.json synced\n";
} catch (Exception $e) {
$pdo->rollBack();
if ($verbose) echo " [ERROR] icons.json sync failed: " . $e->getMessage() . "\n";
}
}
} else {
if ($verbose) echo " [WARNING] icons.json not found\n";
}
}
private function indexExistingFiles($pdo, $verbose = false) {
if (!$this->baseDir || !is_dir($this->baseDir)) {
return;
}
$filesIndexed = 0;
$dirsIndexed = 0;
$this->indexDirectoryRecursive($pdo, $this->baseDir, '', $filesIndexed, $dirsIndexed, $verbose);
if ($verbose) {
echo " [OK] Indexed {$filesIndexed} files and {$dirsIndexed} directories\n";
}
}
private function indexDirectoryRecursive($pdo, $fullPath, $relativePath, &$filesCount, &$dirsCount, $verbose = false) {
$items = @scandir($fullPath);
if (!$items) return;
$stmt = $pdo->prepare("INSERT OR REPLACE INTO file_metadata
(path, filename, extension, size, modified, is_directory, parent_path, indexed_at, last_verified)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$timestamp = time();
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
if ($item == '.indexer_files') continue;
$itemPath = $fullPath . '/' . $item;
$itemRelativePath = $relativePath ? $relativePath . '/' . $item : $item;
if (is_dir($itemPath)) {
$size = 0;
$modified = filemtime($itemPath);
$stmt->execute([
$itemRelativePath,
$item,
null,
$size,
$modified,
1,
$relativePath ?: null,
$timestamp,
$timestamp
]);
$dirsCount++;
$this->indexDirectoryRecursive($pdo, $itemPath, $itemRelativePath, $filesCount, $dirsCount, $verbose);
} else {
$extension = pathinfo($item, PATHINFO_EXTENSION);
$size = filesize($itemPath);
$modified = filemtime($itemPath);
$stmt->execute([
$itemRelativePath,
$item,
$extension ? strtolower($extension) : null,
$size,
$modified,
0,
$relativePath ?: null,
$timestamp,
$timestamp
]);
$filesCount++;
}
if ($verbose && ($filesCount + $dirsCount) % 500 == 0) {
echo " Progress: {$filesCount} files, {$dirsCount} directories\r";
}
}
}
private function displayDatabaseStats($pdo) {
try {
$stmt = $pdo->query("SELECT COUNT(*) as count FROM file_metadata WHERE is_directory = 0");
$fileCount = $stmt->fetch(PDO::FETCH_ASSOC)['count'];
$stmt = $pdo->query("SELECT COUNT(*) as count FROM file_metadata WHERE is_directory = 1");
$dirCount = $stmt->fetch(PDO::FETCH_ASSOC)['count'];
$stmt = $pdo->query("SELECT SUM(size) as total FROM file_metadata WHERE is_directory = 0");
$totalSize = $stmt->fetch(PDO::FETCH_ASSOC)['total'] ?: 0;
echo "\n[Statistics]\n";
echo " Files: " . number_format($fileCount) . "\n";
echo " Directories: " . number_format($dirCount) . "\n";
echo " Total Size: " . $this->formatBytes($totalSize) . "\n";
} catch (Exception $e) {
}
}
private function formatBytes($bytes) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, 2) . ' ' . $units[$i];
}
}
if (php_sapi_name() === 'cli' && isset($argv)) {
$scriptDir = dirname(dirname(dirname(__FILE__)));
$indexerFilesDir = $scriptDir . '/.indexer_files';
$baseDir = $scriptDir . '/files';
$initializer = new Initializer($indexerFilesDir, $baseDir);
$command = isset($argv[1]) ? $argv[1] : 'help';
switch ($command) {
case 'cache':
case 'initializeCache':
echo "Initializing Cache files...\n\n";
$success = $initializer->initializeCache(true);
echo "\n" . ($success ? "[SUCCESS] Cache initialized!" : "[FAILED] Cache initialization failed!") . "\n";
break;
case 'database':
case 'initializeDatabase':
echo "Initializing Database files...\n\n";
$success = $initializer->initializeDatabase(true);
echo "\n" . ($success ? "[SUCCESS] Database initialized!" : "[FAILED] Database initialization failed!") . "\n";
break;
case 'all':
case 'both':
echo "Initializing both Cache and Database files...\n\n";
$cacheSuccess = $initializer->initializeCache(true);
echo "\n";
$dbSuccess = $initializer->initializeDatabase(true);
echo "\n" . (($cacheSuccess && $dbSuccess) ? "[SUCCESS] All files initialized!" : "[WARNING] Some files failed to initialize!") . "\n";
break;
case 'help':
default:
echo "Commands:\n";
echo " cache - Initialize Cache files only\n";
echo " database - Initialize Database files only\n";
echo " all - Initialize all files\n";
break;
}
exit;
}
?>