230 lines
7.9 KiB
PHP
230 lines
7.9 KiB
PHP
<?php
|
|
// Database configuration
|
|
define('DB_PATH', __DIR__ . '/../data/database/bookmarkly.db');
|
|
|
|
// Create a new database connection
|
|
try {
|
|
$pdo = new PDO('sqlite:' . DB_PATH);
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
die("Database connection failed: " . $e->getMessage());
|
|
}
|
|
|
|
// Load language files, which now uses the $pdo object from this script
|
|
require_once __DIR__ . '/language.php';
|
|
|
|
// Start session is now in language.php
|
|
// session_start();
|
|
|
|
// Error reporting for development is now handled in language.php based on settings
|
|
/*
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
*/
|
|
|
|
// Function to check if a table exists
|
|
function tableExists($pdo, $tableName) {
|
|
try {
|
|
$result = $pdo->query("SELECT 1 FROM {$tableName} LIMIT 1");
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
return $result !== false;
|
|
}
|
|
|
|
// Function to check if a column exists in a table
|
|
function columnExists($pdo, $tableName, $columnName) {
|
|
try {
|
|
$result = $pdo->query("SELECT {$columnName} FROM {$tableName} LIMIT 1");
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
return $result !== false;
|
|
}
|
|
|
|
// Initialize database schema if tables don't exist
|
|
$db_initialized = tableExists($pdo, 'users');
|
|
|
|
if ($db_initialized) {
|
|
// For existing installations, run migration checks
|
|
if (!columnExists($pdo, 'users', 'role')) {
|
|
$pdo->exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user'");
|
|
$pdo->exec("UPDATE users SET role = 'admin' WHERE id = 1");
|
|
}
|
|
}
|
|
|
|
if (!$db_initialized) {
|
|
// Create users table
|
|
$pdo->exec("
|
|
CREATE TABLE users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'user'
|
|
)
|
|
");
|
|
// Insert a default user (e.g., admin/password)
|
|
$default_password = password_hash('password', PASSWORD_DEFAULT);
|
|
$stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
|
|
$stmt->execute(['admin', $default_password, 'admin']);
|
|
|
|
// Create settings table
|
|
$pdo->exec("
|
|
CREATE TABLE settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT
|
|
)
|
|
");
|
|
// Insert default settings
|
|
$default_settings = [
|
|
'dashboard_protected' => '0',
|
|
'remember_me_duration' => '2 weeks',
|
|
'open_new_tab' => '1',
|
|
'language' => 'en',
|
|
'favicon_extractor_url' => 'https://favicon.hibbit.cloud',
|
|
'debug_mode' => '0',
|
|
'theme' => 'transparent',
|
|
'background_image_url' => '',
|
|
'background_brightness' => '50',
|
|
'background_saturation' => '100',
|
|
'pexels_api_key' => 'VaNzz6B9q31971WDf1h4TjwEvgib6XvXQp58AhJnX7dGqDawavi7SQAd',
|
|
'custom_css' => '',
|
|
'theme_transparency' => '40'
|
|
];
|
|
$stmt = $pdo->prepare("INSERT INTO settings (key, value) VALUES (?, ?)");
|
|
foreach ($default_settings as $key => $value) {
|
|
$stmt->execute([$key, $value]);
|
|
}
|
|
|
|
// Create categories table
|
|
$pdo->exec("
|
|
CREATE TABLE categories (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
sort_order INTEGER
|
|
)
|
|
");
|
|
|
|
// Create bookmarks table
|
|
$pdo->exec("
|
|
CREATE TABLE bookmarks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
category_id INTEGER,
|
|
title TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
icon TEXT,
|
|
is_favorite INTEGER DEFAULT 0,
|
|
sort_order INTEGER,
|
|
FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE
|
|
)
|
|
");
|
|
}
|
|
|
|
// Check if tabs table exists
|
|
if (!tableExists($pdo, 'tabs')) {
|
|
$pdo->exec("
|
|
CREATE TABLE tabs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
user_id INTEGER,
|
|
sort_order INTEGER,
|
|
background_image_url TEXT,
|
|
background_brightness INTEGER DEFAULT 100,
|
|
background_saturation INTEGER DEFAULT 100,
|
|
theme TEXT DEFAULT 'dark',
|
|
theme_transparency INTEGER DEFAULT 85,
|
|
login_token VARCHAR(255) UNIQUE,
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL
|
|
)
|
|
");
|
|
// Insert a default tab
|
|
$default_token = bin2hex(random_bytes(16));
|
|
$pdo->prepare("INSERT INTO tabs (name, sort_order, login_token) VALUES (?, ?, ?)")
|
|
->execute(['Default', 1, $default_token]);
|
|
}
|
|
|
|
// Migration: Add sort_order to tabs table if it doesn't exist
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'sort_order')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN sort_order INTEGER");
|
|
// Initialize sort order based on existing IDs
|
|
$pdo->exec("UPDATE tabs SET sort_order = id");
|
|
}
|
|
|
|
// Migration: Add new columns to tabs table if they don't exist
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'background_image_url')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN background_image_url TEXT");
|
|
}
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'background_brightness')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN background_brightness INTEGER DEFAULT 100");
|
|
}
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'background_saturation')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN background_saturation INTEGER DEFAULT 100");
|
|
}
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'theme')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN theme TEXT DEFAULT 'dark'");
|
|
}
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'theme_transparency')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN theme_transparency INTEGER DEFAULT 85");
|
|
}
|
|
|
|
// Migration: Add column_count to tabs table if it doesn't exist
|
|
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'column_count')) {
|
|
$pdo->exec("ALTER TABLE tabs ADD COLUMN column_count INTEGER DEFAULT 5");
|
|
}
|
|
|
|
// Check if tab_id column exists in bookmarks table
|
|
if (!columnExists($pdo, 'bookmarks', 'tab_id')) {
|
|
$pdo->exec("ALTER TABLE bookmarks ADD COLUMN tab_id INTEGER");
|
|
// Set default tab_id for existing bookmarks
|
|
$pdo->exec("UPDATE bookmarks SET tab_id = 1");
|
|
}
|
|
|
|
// Check if tab_id column exists in categories table
|
|
if (!columnExists($pdo, 'categories', 'tab_id')) {
|
|
$pdo->exec("ALTER TABLE categories ADD COLUMN tab_id INTEGER");
|
|
// Set default tab_id for existing categories
|
|
$pdo->exec("UPDATE categories SET tab_id = 1");
|
|
}
|
|
|
|
// Create tab_viewer_access table
|
|
if (!tableExists($pdo, 'tab_viewer_access')) {
|
|
$pdo->exec("
|
|
CREATE TABLE tab_viewer_access (
|
|
user_id INTEGER NOT NULL,
|
|
tab_id INTEGER NOT NULL,
|
|
PRIMARY KEY (user_id, tab_id),
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
|
FOREIGN KEY (tab_id) REFERENCES tabs (id) ON DELETE CASCADE
|
|
)
|
|
");
|
|
}
|
|
|
|
// Create user_tab_visibility table
|
|
if (!tableExists($pdo, 'user_tab_visibility')) {
|
|
$pdo->exec("
|
|
CREATE TABLE user_tab_visibility (
|
|
user_id INTEGER NOT NULL,
|
|
tab_id INTEGER NOT NULL,
|
|
PRIMARY KEY (user_id, tab_id),
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
|
FOREIGN KEY (tab_id) REFERENCES tabs (id) ON DELETE CASCADE
|
|
)
|
|
");
|
|
}
|
|
|
|
// Load all settings into a global variable for easy access
|
|
try {
|
|
$settings_stmt = $pdo->query("SELECT key, value FROM settings");
|
|
$settings = $settings_stmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
$GLOBALS['settings'] = $settings; // Make it globally available
|
|
} catch (PDOException $e) {
|
|
// If settings can't be loaded, initialize as empty array to prevent fatal errors
|
|
$settings = [];
|
|
$GLOBALS['settings'] = [];
|
|
}
|
|
|
|
// Set timezone, default to UTC
|
|
date_default_timezone_set($settings['timezone'] ?? 'UTC');
|