-
+
+
-
\ No newline at end of file
+
diff --git a/admin/backup.php b/admin/backup.php
new file mode 100644
index 0000000..8d127e7
--- /dev/null
+++ b/admin/backup.php
@@ -0,0 +1,215 @@
+ 5) {
+ usort($files, function($a, $b) {
+ return filemtime($a) - filemtime($b);
+ });
+ while (count($files) > 5) {
+ $oldest = array_shift($files);
+ unlink($oldest);
+ }
+ }
+}
+
+// Handle actions
+$action = $_GET['action'] ?? '';
+
+if ($action === 'backup') {
+ $filename = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
+ $path = $backupDir . $filename;
+
+ $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) {
+ enforceRetention($backupDir);
+ $message = '
Backup created successfully: ' . $filename . '
';
+ } else {
+ $message = '
Error creating backup.
';
+ }
+} elseif ($action === 'download' && isset($_GET['file'])) {
+ $file = basename($_GET['file']);
+ $path = $backupDir . $file;
+ if (file_exists($path)) {
+ header('Content-Description: File Transfer');
+ header('Content-Type: application/octet-stream');
+ header('Content-Disposition: attachment; filename="' . $file . '"');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate');
+ header('Pragma: public');
+ header('Content-Length: ' . filesize($path));
+ readfile($path);
+ exit;
+ }
+} elseif ($action === 'delete' && isset($_GET['file'])) {
+ $file = basename($_GET['file']);
+ $path = $backupDir . $file;
+ if (file_exists($path)) {
+ unlink($path);
+ $message = '
Backup deleted.
';
+ }
+} elseif ($action === 'restore' && isset($_GET['file'])) {
+ $file = basename($_GET['file']);
+ $path = $backupDir . $file;
+ if (file_exists($path)) {
+ $command = sprintf(
+ 'mysql -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) {
+ $message = '
Database restored successfully from ' . $file . '
';
+ } else {
+ $message = '
Error restoring database.
';
+ }
+ }
+} elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['toggle_auto'])) {
+ $status = $_POST['auto_backup_enabled'] ? 1 : 0;
+ $stmt = $pdo->prepare("UPDATE company_settings SET auto_backup_enabled = ?, updated_at = NOW() LIMIT 1");
+ $stmt->execute([$status]);
+ $message = '
Auto backup settings updated.
';
+}
+
+$settings = get_company_settings();
+$backups = glob($backupDir . '*.sql');
+usort($backups, function($a, $b) {
+ return filemtime($b) - filemtime($a);
+});
+
+include 'includes/header.php';
+?>
+
+
+
+= $message ?>
+
+
+
+
+
+
+
+
Available Backups (Max 5)
+
+
+
+
+ Filename
+ Date
+ Size
+ Actions
+
+
+
+
+
+ No backups found.
+
+
+
+
+
+ = $file ?>
+ = $date ?>
+ = $size ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/categories.php b/admin/categories.php
index 7758e83..e58a544 100644
--- a/admin/categories.php
+++ b/admin/categories.php
@@ -1,15 +1,68 @@
prepare("SELECT image_url FROM categories WHERE id = ?");
+ $stmt->execute([$id]);
+ $image_url = $stmt->fetchColumn();
+ } else {
+ $image_url = 'https://placehold.co/400x300?text=' . urlencode($name);
+ }
+
+ if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
+ $uploadDir = __DIR__ . '/../assets/images/categories/';
+ if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
+
+ $file_ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
+ if (in_array($file_ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
+ $fileName = uniqid('cat_') . '.' . $file_ext;
+ if (move_uploaded_file($_FILES['image']['tmp_name'], $uploadDir . $fileName)) {
+ $image_url = 'assets/images/categories/' . $fileName;
+ }
+ }
+ }
+
+ try {
+ if ($action === 'edit_category' && $id) {
+ if (!has_permission('categories_edit') && !has_permission('categories_add')) {
+ $message = '
Access Denied: You do not have permission to edit categories.
';
+ } else {
+ $stmt = $pdo->prepare("UPDATE categories SET name = ?, description = ?, image_url = ? WHERE id = ?");
+ $stmt->execute([$name, $description, $image_url, $id]);
+ $message = '
Category updated successfully!
';
+ }
+ } elseif ($action === 'add_category') {
+ if (!has_permission('categories_add')) {
+ $message = '
Access Denied: You do not have permission to add categories.
';
+ } else {
+ $stmt = $pdo->prepare("INSERT INTO categories (name, description, image_url) VALUES (?, ?, ?)");
+ $stmt->execute([$name, $description, $image_url]);
+ $message = '
Category created successfully!
';
+ }
+ }
+ } catch (PDOException $e) {
+ $message = '
Database error: ' . $e->getMessage() . '
';
+ }
+}
+
// Handle Delete
if (isset($_GET['delete'])) {
if (!has_permission('categories_del')) {
- $message = '
Access Denied: You do not have permission to delete categories.
';
+ $message = '
Access Denied: You do not have permission to delete categories.
';
} else {
$id = $_GET['delete'];
$pdo->prepare("DELETE FROM categories WHERE id = ?")->execute([$id]);
@@ -18,7 +71,7 @@ if (isset($_GET['delete'])) {
}
}
-$query = "SELECT * FROM categories ORDER BY sort_order ASC, name ASC";
+$query = "SELECT * FROM categories ORDER BY name ASC";
$categories_pagination = paginate_query($pdo, $query);
$categories = $categories_pagination['data'];
@@ -26,75 +79,141 @@ include 'includes/header.php';
?>
-
Categories
+
+
Product Categories
+
Organize your menu and inventory
+
-
- Add Category
-
+
+ Add Category
+
= $message ?>
-
-
-
-
-
-
+
+
+
+
No categories found
+
Start by adding your first category.
+
+
+
- ID
- Image
- Name
- Sort Order
+ Category
+ Description
Actions
- #= $cat['id'] ?>
-
-
-
-
-
-
-
-
+
+
+
+
= htmlspecialchars($cat['name']) ?>
+
+
+
+ = htmlspecialchars($cat['description'] ?? 'No description') ?>
- = htmlspecialchars($cat['name']) ?>
- = $cat['sort_order'] ?>
-
-
-
-
-
-
-
+
-
-
- No categories found.
-
-
-
-
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
+
+
+
diff --git a/admin/category_edit.php b/admin/category_edit.php
deleted file mode 100644
index c335d25..0000000
--- a/admin/category_edit.php
+++ /dev/null
@@ -1,150 +0,0 @@
-prepare("SELECT * FROM categories WHERE id = ?");
- $stmt->execute([$id]);
- $category = $stmt->fetch();
- if ($category) {
- $isEdit = true;
- } else {
- // ID not found, redirect to list
- header("Location: categories.php");
- exit;
- }
-}
-
-// Handle Form Submission
-if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- $name = trim($_POST['name']);
- $sort_order = (int)$_POST['sort_order'];
- $image_url = $isEdit ? $category['image_url'] : null;
-
- // Basic Validation
- if (empty($name)) {
- $message = '
Category name is required.
';
- } else {
- // Image Upload Handling
- if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
- $uploadDir = __DIR__ . '/../assets/images/categories/';
- if (!is_dir($uploadDir)) {
- mkdir($uploadDir, 0755, true);
- }
-
- $fileInfo = pathinfo($_FILES['image']['name']);
- $fileExt = strtolower($fileInfo['extension']);
- $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
-
- if (in_array($fileExt, $allowedExts)) {
- $fileName = uniqid('cat_') . '.' . $fileExt;
- $targetFile = $uploadDir . $fileName;
-
- if (move_uploaded_file($_FILES['image']['tmp_name'], $targetFile)) {
- // Remove old image if exists and not default placeholder (optional, strict cleanup)
- if ($isEdit && !empty($category['image_url']) && file_exists(__DIR__ . '/../' . $category['image_url'])) {
- // unlink(__DIR__ . '/../' . $category['image_url']); // Uncomment to auto-delete old images
- }
- $image_url = 'assets/images/categories/' . $fileName;
- } else {
- $message = '
Failed to upload image. Check permissions.
';
- }
- } else {
- $message = '
Invalid file type. Allowed: jpg, png, gif, webp.
';
- }
- }
-
- if (empty($message)) {
- try {
- if ($isEdit) {
- $stmt = $pdo->prepare("UPDATE categories SET name = ?, sort_order = ?, image_url = ? WHERE id = ?");
- $stmt->execute([$name, $sort_order, $image_url, $id]);
- $message = '
Category updated successfully!
';
- // Refresh data
- $stmt = $pdo->prepare("SELECT * FROM categories WHERE id = ?");
- $stmt->execute([$id]);
- $category = $stmt->fetch();
- } else {
- $stmt = $pdo->prepare("INSERT INTO categories (name, sort_order, image_url) VALUES (?, ?, ?)");
- $stmt->execute([$name, $sort_order, $image_url]);
- header("Location: categories.php?success=created");
- exit;
- }
- } catch (PDOException $e) {
- $message = '
Database error: ' . $e->getMessage() . '
';
- }
- }
- }
-}
-
-// Defaults for Add Mode or Error State
-if (!$isEdit) {
- $category = [
- 'name' => $_POST['name'] ?? '',
- 'sort_order' => $_POST['sort_order'] ?? 0,
- 'image_url' => ''
- ];
-}
-
-include 'includes/header.php';
-?>
-
-
-
-= $message ?>
-
-
-
-
-
-
-
- Category Name *
-
-
-
-
Sort Order
-
-
Lower numbers appear first. Default is 0.
-
-
-
-
-
Category Image
-
-
-
-
-
-
- No Image
-
-
-
-
-
Allowed: JPG, PNG, GIF, WEBP. Leave empty to keep current.
-
-
-
-
-
-
Cancel
-
= $isEdit ? 'Save Changes' : 'Create Category' ?>
-
-
-
-
-
-
\ No newline at end of file
diff --git a/admin/customers.php b/admin/customers.php
index b9baad8..ef3160d 100644
--- a/admin/customers.php
+++ b/admin/customers.php
@@ -1,45 +1,44 @@
Access Denied: You do not have permission to add customers.
';
- } else {
- $name = $_POST['name'];
- $email = $_POST['email'];
- $phone = $_POST['phone'];
- $address = $_POST['address'];
+ $action = $_POST['action'];
+ $id = isset($_POST['id']) ? (int)$_POST['id'] : null;
+ $name = trim($_POST['name']);
+ $email = trim($_POST['email']);
+ $phone = trim($_POST['phone']);
+ $address = trim($_POST['address'] ?? '');
- $stmt = $pdo->prepare("INSERT INTO customers (name, email, phone, address) VALUES (?, ?, ?, ?)");
- if ($stmt->execute([$name, $email, $phone, $address])) {
- $message = '
Customer added successfully!
';
- } else {
- $message = '
Error adding customer.
';
- }
- }
- } elseif ($_POST['action'] === 'edit_customer') {
- if (!has_permission('customers_add')) { // Use customers_add for editing as well
- $message = '
Access Denied: You do not have permission to edit customers.
';
- } else {
- $id = $_POST['id'];
- $name = $_POST['name'];
- $email = $_POST['email'];
- $phone = $_POST['phone'];
- $address = $_POST['address'];
-
- $stmt = $pdo->prepare("UPDATE customers SET name = ?, email = ?, phone = ?, address = ? WHERE id = ?");
- if ($stmt->execute([$name, $email, $phone, $address, $id])) {
- $message = '
Customer updated successfully!
';
- } else {
- $message = '
Error updating customer.
';
+ if (empty($name)) {
+ $message = '
Customer name is required.
';
+ } else {
+ try {
+ if ($action === 'edit_customer' && $id) {
+ if (!has_permission('customers_edit') && !has_permission('customers_add')) {
+ $message = '
Access Denied: You do not have permission to edit customers.
';
+ } else {
+ $stmt = $pdo->prepare("UPDATE customers SET name = ?, email = ?, phone = ?, address = ? WHERE id = ?");
+ $stmt->execute([$name, $email, $phone, $address, $id]);
+ $message = '
Customer updated successfully!
';
+ }
+ } elseif ($action === 'add_customer') {
+ if (!has_permission('customers_add')) {
+ $message = '
Access Denied: You do not have permission to add customers.
';
+ } else {
+ $stmt = $pdo->prepare("INSERT INTO customers (name, email, phone, address) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$name, $email, $phone, $address]);
+ $message = '
Customer created successfully!
';
+ }
}
+ } catch (PDOException $e) {
+ $message = '
Database error: ' . $e->getMessage() . '
';
}
}
}
@@ -56,118 +55,155 @@ if (isset($_GET['delete'])) {
}
}
-// Fetch Customers
-$query = "SELECT * FROM customers ORDER BY id DESC";
-$customers_pagination = paginate_query($pdo, $query);
+$search = $_GET['search'] ?? '';
+$params = [];
+$query = "SELECT * FROM customers";
+
+if ($search) {
+ $query .= " WHERE name LIKE ? OR phone LIKE ? OR email LIKE ?";
+ $params = ["%$search%", "%$search%", "%$search%"];
+}
+
+$query .= " ORDER BY id DESC";
+
+$customers_pagination = paginate_query($pdo, $query, $params);
$customers = $customers_pagination['data'];
include 'includes/header.php';
?>
-
Customers
+
+
Customer Relationship
+
Manage your customer database and contact info
+
-
- Add Customer
+
+ Add Customer
= $message ?>
-
-
-
-
-
-
+
+
+
+
+
+ Search Records
+
+
+
+
+
+
+
+
+
No customers found
+
No results matching your search criteria.
+
+
+
- Name
- Email
- Phone
+ Customer
+ Contact Info
Address
- Redemptions
- Actions
+ Points
+ Actions
- = htmlspecialchars($customer['name']) ?>
- = htmlspecialchars($customer['email']) ?>
- = htmlspecialchars($customer['phone']) ?>
- = htmlspecialchars(substr($customer['address'] ?? '', 0, 30)) ?>...
-
- = intval($customer['loyalty_redemptions_count'] ?? 0) ?>
+
+
+
+ = strtoupper(substr($customer['name'], 0, 1)) ?>
+
+
= htmlspecialchars($customer['name']) ?>
+
-
-
-
+
= htmlspecialchars($customer['phone'] ?: '-') ?>
+
= htmlspecialchars($customer['email'] ?: '-') ?>
+
+
+ = htmlspecialchars($customer['address'] ?: '-') ?>
+
+
+ = number_format($customer['loyalty_points'] ?? 0) ?> pts
+
+
+
-
-
- No customers found.
-
-
-
-
+
-
+
-
-