'; } function verify_csrf($token) { return isset($_SESSION[CSRF_TOKEN_NAME]) && hash_equals($_SESSION[CSRF_TOKEN_NAME], $token); } // Currency Format function format_currency($amount) { return 'LKR ' . number_format($amount, 2); } // Slug Generator function create_slug($string) { $string = strtolower($string); $string = preg_replace('/[^a-z0-9-]/', '-', $string); $string = preg_replace('/-+/', '-', $string); return trim($string, '-'); } // Time Ago function time_ago($timestamp) { $time_ago = strtotime($timestamp); $current_time = time(); $time_difference = $current_time - $time_ago; $seconds = $time_difference; $minutes = round($seconds / 60); $hours = round($seconds / 3600); $days = round($seconds / 86400); $weeks = round($seconds / 604800); $months = round($seconds / 2629440); $years = round($seconds / 31553280); if ($seconds <= 60) return 'Just now'; else if ($minutes <= 60) return $minutes == 1 ? '1 minute ago' : $minutes . ' minutes ago'; else if ($hours <= 24) return $hours == 1 ? '1 hour ago' : $hours . ' hours ago'; else if ($days <= 7) return $days == 1 ? '1 day ago' : $days . ' days ago'; else if ($weeks <= 4.3) return $weeks == 1 ? '1 week ago' : $weeks . ' weeks ago'; else if ($months <= 12) return $months == 1 ? '1 month ago' : $months . ' months ago'; else return $years == 1 ? '1 year ago' : $years . ' years ago'; } // Generate Order Number function generate_order_number() { return 'VEL-' . date('Ymd') . '-' . strtoupper(bin2hex(random_bytes(4))); } // Flash Messages function set_flash($type, $message) { $_SESSION['flash'] = ['type' => $type, 'message' => $message]; } function get_flash() { if (isset($_SESSION['flash'])) { $flash = $_SESSION['flash']; unset($_SESSION['flash']); return $flash; } return null; } function display_flash() { $flash = get_flash(); if ($flash) { $type = $flash['type']; $message = $flash['message']; $icons = [ 'success' => 'fas fa-check-circle', 'error' => 'fas fa-exclamation-circle', 'warning' => 'fas fa-exclamation-triangle', 'info' => 'fas fa-info-circle' ]; $icon = $icons[$type] ?? 'fas fa-info-circle'; echo ''; } } // Image Upload // Cache-busted image URL function img_url($url) { static $cache = []; if (empty($url)) return SITE_URL . 'assets/images/no-image.jpg'; if (isset($cache[$url])) return $cache[$url]; // Add timestamp for cache busting (only for uploaded images, not for static assets) if (strpos($url, 'assets/uploads/') !== false) { $sep = (strpos($url, '?') !== false) ? '&' : '?'; $path_part = explode('?', $url, 2)[0]; // Try to find the local path $local = ''; if (strpos($path_part, SITE_URL) === 0) { $local = str_replace(SITE_URL, ROOT_PATH, $path_part); } else { // Fallback: extract path after assets/uploads/ $pos = strpos($path_part, 'assets/uploads/'); if ($pos !== false) { $relative = substr($path_part, $pos); $local = ROOT_PATH . $relative; } } if (!empty($local) && file_exists($local)) { $url .= $sep . 'v=' . filemtime($local); } } $cache[$url] = $url; return $url; } function upload_image($file, $folder, $name = null) { $target_dir = UPLOADS_PATH . $folder . '/'; if (!file_exists($target_dir)) { if (!@mkdir($target_dir, 0755, true) && !is_dir($target_dir)) { error_log("Upload failed: could not create directory $target_dir"); return false; } } if (!is_writable($target_dir)) { @chmod($target_dir, 0755); if (!is_writable($target_dir)) { error_log("Upload failed: directory $target_dir is not writable"); return false; } } $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (!in_array($extension, $allowed)) { error_log("Upload rejected: extension '$extension' not allowed"); return false; } $filename = ($name ? create_slug($name) : uniqid()) . '.' . $extension; $target_file = $target_dir . $filename; if (move_uploaded_file($file['tmp_name'], $target_file)) { // Set proper file permissions (rw-r--r--) @chmod($target_file, 0644); return $filename; } error_log("Upload failed: move_uploaded_file failed for $target_file (upload error: " . $file['error'] . ")"); return false; } // Cart Functions function get_cart_count() { $count = 0; if (isset($_SESSION['cart'])) { foreach ($_SESSION['cart'] as $item) { $count += $item['quantity']; } } return $count; } function get_cart_total() { $total = 0; if (isset($_SESSION['cart'])) { foreach ($_SESSION['cart'] as $item) { $price = $item['sale_price'] > 0 ? $item['sale_price'] : $item['regular_price']; $total += $price * $item['quantity']; } } return $total; } function get_wishlist_count() { return isset($_SESSION['wishlist']) ? count($_SESSION['wishlist']) : 0; } // Check if user is logged in function is_logged_in() { return isset($_SESSION['user_id']); } // Get current user data function get_user_data() { global $db; static $cache = null; if (!is_logged_in()) return null; if ($cache !== null) return $cache; try { if (!isset($_SESSION['user_id']) || !$db) return null; $stmt = $db->prepare("SELECT * FROM users WHERE id = ? AND status = 1"); $stmt->execute([$_SESSION['user_id']]); $cache = $stmt->fetch(PDO::FETCH_ASSOC) ?: null; return $cache; } catch (Exception $e) { return null; } } // Get settings function get_settings() { global $db; static $settings = null; if ($settings === null) { $stmt = $db->query("SELECT * FROM settings WHERE id = 1"); $settings = $stmt->fetch(PDO::FETCH_ASSOC); } return $settings; } // Pagination function paginate($total_items, $per_page = 12, $current_page = 1) { $total_pages = ceil($total_items / $per_page); return [ 'total_items' => $total_items, 'per_page' => $per_page, 'current_page' => $current_page, 'total_pages' => $total_pages, 'offset' => ($current_page - 1) * $per_page ]; } function pagination_links($pagination, $base_url) { if ($pagination['total_pages'] <= 1) return ''; $html = ''; return $html; }