| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- <?php
- // Αρχείο: /var/www/html/hockey-cms/seller_dashboard.php
- session_start();
- if (!isset($_SESSION['user_id']) or empty($_SESSION['is_seller'])) {
- header("Location: index.php");
- exit;
- }
- require_once __DIR__ . '/vendor/autoload.php';
- require_once __DIR__ . '/config/database.php';
- // --- Μηχανισμός Αλλαγής Γλώσσας ---
- if (isset($_GET['lang']) and in_array($_GET['lang'], ['el', 'en'])) {
- $_SESSION['lang'] =$_GET['lang'];
- }
- $current_lang =$_SESSION['lang'] ?? 'el';
- // --- Λεξικό Μεταφράσεων ---
- $translations = [
- 'el' => [
- 'seller_panel' => 'Πίνακας Πωλητή',
- 'my_listings' => 'Οι Αγγελίες Μου',
- 'customer_orders' => 'Παραγγελίες Πελατών',
- 'edit_listing' => 'Επεξεργασία Αγγελίας',
- 'add_listing' => 'Ανέβασμα Αγγελίας',
- 'title' => 'Τίτλος Προϊόντος *',
- 'category' => 'Κατηγορία *',
- 'select_cat' => '-- Επίλεξε Κατηγορία --',
- 'sku' => 'Κωδικός (SKU)',
- 'price' => 'Τιμή (€) *',
- 'stock' => 'Απόθεμα',
- 'tags' => 'Ετικέτες Αναζήτησης (Tags)',
- 'tags_placeholder' => 'Γράψτε λέξη και πατήστε Enter...',
- 'description' => 'Περιγραφή',
- 'listing_status' => 'Κατάσταση Αγγελίας',
- 'status_opt_available' => 'Ενεργή (Εμφανίζεται)',
- 'status_opt_hidden' => 'Προσωρινή Απόκρυψη',
- 'status_opt_sold' => 'Πουλήθηκε',
- 'status_active' => 'Ενεργή',
- 'status_hidden' => 'Κρυφή',
- 'status_sold' => 'Πουλήθηκε',
- 'photo' => 'Φωτογραφία',
- 'photo_req' => '(Απαραίτητη)',
- 'photo_opt' => '(Αφήστε κενό αν δεν αλλάξει)',
- 'btn_save' => 'Αποθήκευση',
- 'btn_upload' => 'Ανέβασμα Προϊόντος',
- 'btn_cancel' => 'Ακύρωση',
- 'stock_short' => 'Αποθ:',
- 'no_img' => 'No IMG',
- 'confirm_delete' => 'Σίγουρα θέλετε να διαγράψετε την αγγελία;',
- 'no_listings' => 'Δεν έχεις ανεβάσει ακόμα καμία αγγελία.',
- 'use_form' => 'Χρησιμοποίησε τη φόρμα για να ξεκινήσεις!',
- 'features' => 'Χαρακτηριστικά',
- 'features_placeholder' => 'π.χ. τιμή...'
- ],
- 'en' => [
- 'seller_panel' => 'Seller Dashboard',
- 'my_listings' => 'My Listings',
- 'customer_orders' => 'Customer Orders',
- 'edit_listing' => 'Edit Listing',
- 'add_listing' => 'Upload Listing',
- 'title' => 'Product Title *',
- 'category' => 'Category *',
- 'select_cat' => '-- Select Category --',
- 'sku' => 'SKU',
- 'price' => 'Price (€) *',
- 'stock' => 'Stock',
- 'tags' => 'Search Tags',
- 'tags_placeholder' => 'Type a word and press Enter...',
- 'description' => 'Description',
- 'listing_status' => 'Listing Status',
- 'status_opt_available' => 'Active (Visible)',
- 'status_opt_hidden' => 'Temporarily Hidden',
- 'status_opt_sold' => 'Sold',
- 'status_active' => 'Active',
- 'status_hidden' => 'Hidden',
- 'status_sold' => 'Sold',
- 'photo' => 'Photo',
- 'photo_req' => '(Required)',
- 'photo_opt' => '(Leave blank if unchanged)',
- 'btn_save' => 'Save Changes',
- 'btn_upload' => 'Upload Product',
- 'btn_cancel' => 'Cancel',
- 'stock_short' => 'Qty:',
- 'no_img' => 'No IMG',
- 'confirm_delete' => 'Are you sure you want to delete this listing?',
- 'no_listings' => 'You haven\'t uploaded any listings yet.',
- 'use_form' => 'Use the form to get started!',
- 'features' => 'Features',
- 'features_placeholder' => 'e.g. value...'
- ]
- ];
- $t =$translations[$current_lang];$seller_id = $_SESSION['user_id'];$message = '';
- // AJAX GET ATTRIBUTES
- if (isset($_GET['ajax_get_attributes']) and isset($_GET['category_id'])) {$cat_id = (int)$_GET['category_id'];$product_id = isset($_GET['product_id']) ? (int)$_GET['product_id'] : 0;
-
- $stmt =$pdo->prepare("SELECT attribute_group_id FROM categories WHERE id = ?");
- $stmt->execute([$cat_id]);
- $cat =$stmt->fetch();
-
- if ($cat &&$cat['attribute_group_id']) {
- $attrStmt =$pdo->prepare("SELECT id, name, unit FROM attributes WHERE group_id = ? ORDER BY name");
- $attrStmt->execute([$cat['attribute_group_id']]);$attributes = $attrStmt->fetchAll();$existing_values = [];
- if ($product_id > 0) {
- $valStmt =$pdo->prepare("SELECT attribute_id, value FROM product_attribute_values WHERE product_id = ?");
- $valStmt->execute([$product_id]);
- while ($vRow = $valStmt->fetch(PDO::FETCH_ASSOC)) {$existing_values[$vRow['attribute_id']] =$vRow['value'];
- }
- }
-
- if ($attributes) {
- echo "<h4 style='margin-bottom: 12px; margin-top: 20px; color: var(--primary); text-transform: uppercase; letter-spacing: 1px; font-size: 14px;'>".$t['features']."</h4>";
- echo "<div class='form-cols' style='display: grid; grid-template-columns: 1fr 1fr; gap: 15px;'>";
- foreach ($attributes as $attr) {$val = isset($existing_values[$attr['id']]) ? htmlspecialchars($existing_values[$attr['id']]) : '';
- echo "<div class='form-group'>";
- echo "<label>" . htmlspecialchars($attr['name']) . ($attr['unit'] ? " ({$attr['unit']})" : "") . "</label>";
- echo "<input type='text' name='attributes[" . $attr['id'] . "]' value='" . $val . "' placeholder='".$t['features_placeholder']."'>";
- echo "</div>";
- }
- echo "</div>";
- }
- }
- exit;
- }
- // --- 2. AJAX API: Δημιουργία προτεινόμενου SKU (Πρόθεμα 3 Γράμματα + Αύξων) ---
- if (isset($_GET['ajax_generate_sku']) && isset($_GET['category_id'])) {
- $cat_id = (int)$_GET['category_id'];
- $stmt =$pdo->prepare("SELECT name_en FROM categories WHERE id = ?");
- $stmt->execute([$cat_id]);
- $name_en =$stmt->fetchColumn();
- if ($name_en) {
- // Κρατάμε μόνο τα γράμματα από τα Αγγλικά
- $clean_name = preg_replace('/[^a-zA-Z]/', '',$name_en);
- $prefix = strtoupper(substr($clean_name, 0, 3));
- if (empty($prefix)) {$prefix = 'CAT'; }
- // Βρίσκουμε το μεγαλύτερο νούμερο με αυτό το πρόθεμα που ανήκει στον seller (ή γενικά)
- // Θα το κάνουμε γενικά (όπως στο Admin) για να είναι το SKU απολύτως μοναδικό σε όλο το σύστημα
- $stmtSku =$pdo->prepare("SELECT sku FROM products WHERE sku LIKE ?");
- $stmtSku->execute([$prefix . '-%']);
- $skus =$stmtSku->fetchAll(PDO::FETCH_COLUMN);
- $max = 0;
- foreach ($skus as$s) {
- $parts = explode('-',$s);
- if (count($parts) > 1) {
- $num = (int)end($parts);
- if ($num >$max) { $max =$num; }
- }
- }
- $next_num = str_pad($max + 1, 3, '0', STR_PAD_LEFT);
- echo $prefix . '-' .$next_num;
- }
- exit;
- }
- // Βοηθητική Resize
- function resizeAndSaveImage($source_file, $target_file,$max_resolution = 800) {
- $info = getimagesize($source_file);
- if (!$info) return false;
- $mime =$info['mime'];
- switch ($mime) {
- case 'image/jpeg': $image = imagecreatefromjpeg($source_file); break;
- case 'image/png': $image = imagecreatefrompng($source_file); break;
- case 'image/gif': $image = imagecreatefromgif($source_file); break;
- default: return false;
- }
- $original_width = imagesx($image);
- $original_height = imagesy($image);
- $ratio =$max_resolution / max($original_width,$original_height);
- $new_width =$original_width > $max_resolution ? round($original_width * $ratio) :$original_width;
- $new_height =$original_height > $max_resolution ? round($original_height * $ratio) :$original_height;
- $new_image = imagecreatetruecolor($new_width,$new_height);
- if ($mime == 'image/png') {
- imagealphablending($new_image, false);
- imagesavealpha($new_image, true);
- }
- imagecopyresampled($new_image,$image, 0, 0, 0, 0, $new_width,$new_height, $original_width,$original_height);
- imagejpeg($new_image,$target_file, 85);
- imagedestroy($image);
- imagedestroy($new_image);
- return true;
- }
- // POST Actions
- if ($_SERVER['REQUEST_METHOD'] === 'POST' and isset($_POST['action'])) {
- $action =$_POST['action'];
-
- if ($action == 'delete_product') {
- $product_id = (int)$_POST['product_id'];
- try {
- $delStmt =$pdo->prepare("DELETE FROM products WHERE id = ? AND seller_id = ?");
- $delStmt->execute([$product_id,$seller_id]);
- if ($delStmt->rowCount() > 0) {$message = "<div class='alert success'>Η αγγελία διαγράφηκε επιτυχώς!</div>";
- } else {
- $message = "<div class='alert error'>Αδυναμία διαγραφής.</div>";
- }
- } catch (Exception $e) {$message = "<div class='alert error'>Σφάλμα: " . $e->getMessage() . "</div>";
- }
- }
- else {
- $title = trim($_POST['title']);
- $sku = trim($_POST['sku']);
- $category_id = (int)$_POST['category_id'];
- $price = (float)$_POST['price'];
- $quantity = (int)$_POST['quantity'];
- $status =$_POST['status'] ?? 'available';
- $description = trim($_POST['description']);
- $search_tags = trim($_POST['search_tags']);
- if (!empty($title) and !empty($category_id) and !empty($price)) {
- try {
- $pdo->beginTransaction();
- $stmtGrp =$pdo->prepare("SELECT attribute_group_id FROM categories WHERE id = ?");
- $stmtGrp->execute([$category_id]);
- $group_id =$stmtGrp->fetchColumn();
- if ($action == 'add_product') {
- $stmt =$pdo->prepare("INSERT INTO products (seller_id, category_id, attribute_group_id, title, sku, description, search_tags, price, quantity, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
- $stmt->execute([$seller_id, $category_id,$group_id, $title,$sku, $description,$search_tags, $price,$quantity, $status]);$product_id = $pdo->lastInsertId();$message = "<div class='alert success'>Η αγγελία ανέβηκε επιτυχώς!</div>";
- } elseif ($action == 'edit_product') {
- $product_id = (int)$_POST['product_id'];
- $stmt =$pdo->prepare("UPDATE products SET category_id = ?, attribute_group_id = ?, title = ?, sku = ?, description = ?, search_tags = ?, price = ?, quantity = ?, status = ? WHERE id = ? AND seller_id = ?");
- $stmt->execute([$category_id, $group_id,$title, $sku,$description, $search_tags,$price, $quantity,$status, $product_id,$seller_id]);
-
- $delAttr =$pdo->prepare("DELETE FROM product_attribute_values WHERE product_id = ?");
- $delAttr->execute([$product_id]);$message = "<div class='alert success'>Η αγγελία ενημερώθηκε επιτυχώς!</div>";
- }
- if (isset($_POST['attributes']) and is_array($_POST['attributes'])) {
- $insAttr =$pdo->prepare("INSERT INTO product_attribute_values (product_id, attribute_id, value) VALUES (?, ?, ?)");
- foreach ($_POST['attributes'] as $attr_id =>$val) {
- $val = trim($val);
- if ($val !== '') {
- $insAttr->execute([$product_id, $attr_id,$val]);
- }
- }
- }
- if (isset($_FILES['image']) and $_FILES['image']['error'] == 0) {$upload_dir = __DIR__ . '/uploads/equipment/';
- if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); }
-
- $filename = 'prod_' .$product_id . '_' . time() . '.jpg';
- $target_path = $upload_dir .$filename;
-
- if (resizeAndSaveImage($_FILES['image']['tmp_name'],$target_path)) {
- $checkImg =$pdo->prepare("SELECT id FROM product_images WHERE product_id = ? AND is_primary = 1");
- $checkImg->execute([$product_id]);
- if ($checkImg->fetch()) {
- $updImg =$pdo->prepare("UPDATE product_images SET image_path = ? WHERE product_id = ? AND is_primary = 1");
- $updImg->execute(['uploads/equipment/' . $filename,$product_id]);
- } else {
- $insImg =$pdo->prepare("INSERT INTO product_images (product_id, image_path, is_primary) VALUES (?, ?, 1)");
- $insImg->execute([$product_id, 'uploads/equipment/' .$filename]);
- }
- }
- }
- $pdo->commit();
- } catch (Exception $e) {
- $pdo->rollBack();$message = "<div class='alert error'>Σφάλμα: " . $e->getMessage() . "</div>";
- }
- } else {
- $message = "<div class='alert error'>Συμπληρώστε τα υποχρεωτικά πεδία!</div>";
- }
- }
- }
- // Ανάκτηση δεδομένων για το View
- $edit_product = null;
- if (isset($_GET['edit'])) {
- $edit_id = (int)$_GET['edit'];
- $editStmt =$pdo->prepare("SELECT * FROM products WHERE id = ? AND seller_id = ?");
- $editStmt->execute([$edit_id,$seller_id]);
- $edit_product =$editStmt->fetch(PDO::FETCH_ASSOC);
- }
- $categories =$pdo->query("SELECT id, parent_id, IFNULL(NULLIF(name_en, ''), name_el) as display_name FROM categories ORDER BY sort_order ASC, name_el ASC")->fetchAll();
- if ($current_lang === 'el') {
- $categories =$pdo->query("SELECT id, parent_id, name_el as display_name FROM categories ORDER BY sort_order ASC, name_el ASC")->fetchAll();
- }
- $stmtProds =$pdo->prepare("
- SELECT p.id, p.sku, p.title, p.search_tags, p.price, p.quantity, p.status,
- IFNULL(NULLIF(c.name_en, ''), c.name_el) as cat_name_en, c.name_el as cat_name_el,
- pi.image_path
- FROM products p
- LEFT JOIN categories c ON p.category_id = c.id
- LEFT JOIN product_images pi ON (p.id = pi.product_id AND pi.is_primary = 1)
- WHERE p.seller_id = ?
- ORDER BY p.id DESC
- ");
- $stmtProds->execute([$seller_id]);
- $my_products =$stmtProds->fetchAll(PDO::FETCH_ASSOC);
- // --- ΦΟΡΤΩΣΗ TWIG ---
- $active_theme = 'default';
- $site_logo = '';$site_title = 'Hockey CMS';
- try {
- $stmtSettings =$pdo->query("SELECT `key`, value FROM settings WHERE `key` IN ('active_theme', 'site_logo', 'site_title')");
- while ($row =$stmtSettings->fetch(PDO::FETCH_ASSOC)) {
- if ($row['key'] === 'active_theme' && !empty($row['value'])) {
- $active_theme =$row['value'];
- } elseif ($row['key'] === 'site_logo') {
- $site_logo =$row['value'];
- } elseif ($row['key'] === 'site_title' && !empty($row['value'])) {
- $site_title =$row['value'];
- }
- }
- } catch (Exception $e) {}
- $theme_dir = __DIR__ . '/themes/' .$active_theme;
- if (!is_dir($theme_dir)) {
- $active_theme = 'default';$theme_dir = __DIR__ . '/themes/default';
- }
- $loader = new \Twig\Loader\FilesystemLoader($theme_dir);
- $twig = new \Twig\Environment($loader, ['cache' => false]);
- $twig->addGlobal('session',$_SESSION);
- $twig->addGlobal('current_lang',$current_lang);
- $twig->addGlobal('site_logo',$site_logo);
- echo $twig->render('seller_dashboard.html.twig', [
- 'site_title' => $site_title,
- 't' => $t,
- 'message' => $message,
- 'edit_product' => $edit_product,
- 'categories' => $categories,
- 'my_products' => $my_products
- ]);
|