250 lines
7.8 KiB
PHP
250 lines
7.8 KiB
PHP
<?php
|
|
// Function to fetch company settings from DB
|
|
function get_company_settings() {
|
|
static $settings = null;
|
|
if ($settings === null) {
|
|
try {
|
|
if (function_exists('db')) {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("SELECT * FROM company_settings LIMIT 1");
|
|
$settings = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
} catch (Exception $e) {
|
|
// Log error or ignore if table doesn't exist yet
|
|
}
|
|
|
|
// Default values if no settings found
|
|
if (!$settings) {
|
|
$settings = [
|
|
'company_name' => 'My Restaurant',
|
|
'address' => '123 Food Street',
|
|
'phone' => '555-0199',
|
|
'email' => 'info@restaurant.com',
|
|
'vat_rate' => 0.00,
|
|
'currency_symbol' => '$',
|
|
'currency_decimals' => 2
|
|
];
|
|
}
|
|
}
|
|
return $settings;
|
|
}
|
|
|
|
// Function to format currency using settings
|
|
function format_currency($amount) {
|
|
$settings = get_company_settings();
|
|
return ($settings['currency_symbol'] ?? '$') . number_format((float)$amount, (int)($settings['currency_decimals'] ?? 2));
|
|
}
|
|
|
|
/**
|
|
* Calculate the current price of a product considering promotions.
|
|
*
|
|
* @param array|object $product The product data from DB.
|
|
* @return float The effective price.
|
|
*/
|
|
function get_product_price($product) {
|
|
$product = (array)$product;
|
|
$price = (float)$product['price'];
|
|
|
|
$today = date('Y-m-d');
|
|
$promo_active = !empty($product['promo_discount_percent']) &&
|
|
!empty($product['promo_date_from']) &&
|
|
!empty($product['promo_date_to']) &&
|
|
$today >= $product['promo_date_from'] &&
|
|
$today <= $product['promo_date_to'];
|
|
|
|
if ($promo_active) {
|
|
$discount = $price * ((float)$product['promo_discount_percent'] / 100);
|
|
$price -= $discount;
|
|
}
|
|
|
|
return $price;
|
|
}
|
|
|
|
function get_base_url() {
|
|
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://";
|
|
$domainName = $_SERVER['HTTP_HOST'];
|
|
|
|
// Check for Flatlogic VM base URL (if needed)
|
|
// For now, standard detection
|
|
$path = str_replace(basename($_SERVER['SCRIPT_NAME']), "", $_SERVER['SCRIPT_NAME']);
|
|
|
|
// Normalize path: ensure it ends with /
|
|
if (substr($path, -1) !== '/') {
|
|
$path .= '/';
|
|
}
|
|
|
|
// If we are in admin/ or api/ or other subdirs, we might need to go up
|
|
// But this function is usually called from root files or with knowledge of its location
|
|
return $protocol . $domainName . $path;
|
|
}
|
|
|
|
/**
|
|
* Initialize session with security and persistence improvements
|
|
*/
|
|
function init_session() {
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
// Set session lifetime to 1 week (604800 seconds)
|
|
$lifetime = 604800;
|
|
|
|
// Ensure gc_maxlifetime is at least as long as cookie lifetime
|
|
ini_set('session.gc_maxlifetime', (string)$lifetime);
|
|
|
|
// Set cookie parameters before session_start
|
|
$isSecure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
|
|
|
|
session_set_cookie_params([
|
|
'lifetime' => $lifetime,
|
|
'path' => '/',
|
|
'domain' => '',
|
|
'secure' => $isSecure,
|
|
'httponly' => true,
|
|
'samesite' => 'Lax'
|
|
]);
|
|
|
|
session_start();
|
|
}
|
|
|
|
// Refresh session expiration on each load if user is logged in
|
|
if (isset($_SESSION['user'])) {
|
|
// Optional: you could implement a last_activity check here
|
|
}
|
|
}
|
|
|
|
function login_user($username, $password) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT u.*, g.name as group_name, g.permissions
|
|
FROM users u
|
|
LEFT JOIN user_groups g ON u.group_id = g.id
|
|
WHERE u.username = ? AND u.is_active = 1
|
|
LIMIT 1");
|
|
$stmt->execute([$username]);
|
|
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($user && password_verify($password, $user['password'])) {
|
|
init_session();
|
|
unset($user['password']); // Don't store hash in session
|
|
$_SESSION['user'] = $user;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function logout_user() {
|
|
init_session();
|
|
unset($_SESSION['user']);
|
|
session_destroy();
|
|
}
|
|
|
|
function get_logged_user() {
|
|
init_session();
|
|
return $_SESSION['user'] ?? null;
|
|
}
|
|
|
|
function require_login() {
|
|
if (!get_logged_user()) {
|
|
header('Location: ' . get_base_url() . 'login.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
function has_permission($permission) {
|
|
$user = get_logged_user();
|
|
if (!$user) return false;
|
|
|
|
// Admin has all permissions
|
|
if ($user['permissions'] === 'all') return true;
|
|
|
|
$permissions = json_decode($user['permissions'] ?: '[]', true);
|
|
return in_array('all', $permissions) || in_array($permission, $permissions);
|
|
}
|
|
|
|
function require_permission($permission) {
|
|
if (!has_permission($permission)) {
|
|
die("Access Denied: You do not have permission to view this page ($permission).");
|
|
}
|
|
}
|
|
|
|
function get_user_outlets($userId) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT outlet_id FROM user_outlets WHERE user_id = ?");
|
|
$stmt->execute([$userId]);
|
|
return $stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
}
|
|
|
|
function can_access_outlet($userId, $outletId) {
|
|
if (has_permission('all')) return true;
|
|
$outlets = get_user_outlets($userId);
|
|
return in_array($outletId, $outlets);
|
|
}
|
|
|
|
function create_backup() {
|
|
$backupDir = __DIR__ . '/../storage/backups/';
|
|
if (!is_dir($backupDir)) {
|
|
mkdir($backupDir, 0777, true);
|
|
}
|
|
|
|
$filename = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
|
|
$path = $backupDir . $filename;
|
|
|
|
// We'll use the environment variables from db/config.php
|
|
$command = sprintf(
|
|
'mysqldump -h %s -u %s -p%s %s > %s',
|
|
escapeshellarg(DB_HOST),
|
|
escapeshellarg(DB_USER),
|
|
escapeshellarg(DB_PASS),
|
|
escapeshellarg(DB_NAME),
|
|
escapeshellarg($path)
|
|
);
|
|
|
|
exec($command, $output, $returnVar);
|
|
|
|
if ($returnVar === 0) {
|
|
// Enforce retention: keep 5 latest
|
|
$files = glob($backupDir . '/*.sql');
|
|
if (count($files) > 5) {
|
|
usort($files, function($a, $b) {
|
|
return filemtime($a) - filemtime($b);
|
|
});
|
|
while (count($files) > 5) {
|
|
$oldest = array_shift($files);
|
|
unlink($oldest);
|
|
}
|
|
}
|
|
return $filename;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Trigger auto backup if enabled and 24h passed since last backup.
|
|
* Optimized to prevent session locking and hang.
|
|
*/
|
|
function trigger_auto_backup() {
|
|
$settings = get_company_settings();
|
|
if (empty($settings['auto_backup_enabled'])) return;
|
|
|
|
// Only Admin (with 'all' permission) should trigger backups to avoid overhead
|
|
if (!has_permission('all')) return;
|
|
|
|
$lastBackup = !empty($settings['last_auto_backup']) ? strtotime($settings['last_auto_backup']) : 0;
|
|
$now = time();
|
|
|
|
// Run once every 24 hours
|
|
if ($now - $lastBackup > 86400) {
|
|
// Release session lock before starting a potentially long-running backup
|
|
if (session_status() === PHP_SESSION_ACTIVE) {
|
|
session_write_close();
|
|
}
|
|
|
|
if (create_backup()) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("UPDATE company_settings SET last_auto_backup = NOW(), updated_at = NOW() LIMIT 1");
|
|
$stmt->execute();
|
|
} else {
|
|
error_log("Auto backup failed at " . date('Y-m-d H:i:s'));
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("UPDATE company_settings SET last_auto_backup = NOW(), updated_at = NOW() LIMIT 1");
|
|
$stmt->execute();
|
|
}
|
|
}
|
|
} |