Compare commits

...

2 Commits

Author SHA1 Message Date
kirill.khorkov
b87450c12b remove run.sh 2025-12-16 02:59:01 +03:00
kirill.khorkov
29b9aaac50 Исправление багов авторизации, корзины и админки
- Исправлено выпадающее меню профиля (hover-баг с margin-top)
- Исправлена авторизация: правильные пути к API (api/auth.php)
- Исправлены ссылки на админку (admin/index.php вместо admin_panel.php)
- Исправлены пути API корзины в catalog.php и checkout.php
- Добавлена форма добавления/редактирования товаров в админке
- Исправлены кнопки +/- в корзине (улучшена обработка AJAX)
- Исправлена регистрация: правильные пути и обработка boolean в PostgreSQL
- Добавлена миграция для назначения прав админа пользователю admin@mail.ru
- Удален тестовый блок 'Быстрый вход' для неавторизованных пользователей
- Улучшена обработка ошибок во всех API-эндпоинтах
2025-12-16 02:58:44 +03:00
387 changed files with 15221 additions and 3220 deletions

View File

@@ -1,122 +0,0 @@
<?php
require_once 'config/database.php';
$db = Database::getInstance()->getConnection();
// Создаем таблицы, если они не существуют
$tables = [
'users' => "
CREATE TABLE IF NOT EXISTS users (
user_id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(100) NOT NULL,
phone VARCHAR(20),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT TRUE,
is_admin BOOLEAN DEFAULT FALSE
)
",
'categories' => "
CREATE TABLE IF NOT EXISTS categories (
category_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) UNIQUE NOT NULL,
parent_id INTEGER REFERENCES categories(category_id),
description TEXT,
sort_order INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE
)
",
'products' => "
CREATE TABLE IF NOT EXISTS products (
product_id SERIAL PRIMARY KEY,
category_id INTEGER REFERENCES categories(category_id),
name VARCHAR(200) NOT NULL,
slug VARCHAR(200) UNIQUE NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
old_price DECIMAL(10, 2),
sku VARCHAR(50) UNIQUE,
stock_quantity INTEGER DEFAULT 0,
is_available BOOLEAN DEFAULT TRUE,
is_featured BOOLEAN DEFAULT FALSE,
rating DECIMAL(3, 2) DEFAULT 0,
review_count INTEGER DEFAULT 0,
image_url VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"
];
foreach ($tables_to_create as $table_name => $sql) {
try {
$db->exec($sql);
echo "Таблица '$table_name' создана/проверена<br>";
} catch (PDOException $e) {
echo "Ошибка создания таблицы '$table_name': " . $e->getMessage() . "<br>";
}
}
// Добавляем тестовые данные
// Проверяем, есть ли уже категории
$check_categories = $db->query("SELECT COUNT(*) FROM categories")->fetchColumn();
if ($check_categories == 0) {
// Добавляем категории
$categories = [
['Мягкая мебель', 'myagkaya-mebel', NULL, 'Диваны, кресла, пуфы'],
['Диваны', 'divany', 1, 'Прямые и угловые диваны'],
['Кресла', 'kresla', 1, 'Кресла для гостиной и офиса'],
['Спальня', 'spalnya', NULL, 'Кровати, тумбы, комоды'],
['Кровати', 'krovati', 4, 'Односпальные и двуспальные кровати']
];
foreach ($categories as $category) {
$stmt = $db->prepare("INSERT INTO categories (name, slug, parent_id, description) VALUES (?, ?, ?, ?)");
$stmt->execute($category);
}
echo "Добавлены категории<br>";
}
// Проверяем, есть ли уже товары
$check_products = $db->query("SELECT COUNT(*) FROM products")->fetchColumn();
if ($check_products == 0) {
// Добавляем товары
$products = [
[2, 'Диван VELVET', 'divan-velvet', 'Прямой диван с тканевой обивкой', 45999, 54999, 'DIV-VEL-001', 10],
[2, 'Диван MODERN', 'divan-modern', 'Угловой диван с кожаной обивкой', 78999, 89999, 'DIV-MOD-002', 5],
[3, 'Кресло OPPORTUNITY', 'kreslo-opportunity', 'Кресло с деревянными ножками', 16999, 19999, 'KRES-OPP-001', 15],
[3, 'Кресло GOLDEN', 'kreslo-golden', 'Золотистое кресло для гостиной', 19999, 23999, 'KRES-GOL-002', 8],
[5, 'Кровать CLASSIC', 'krovat-classic', 'Двуспальная кровать из массива дуба', 64999, 74999, 'KROV-CLA-001', 3]
];
foreach ($products as $product) {
$stmt = $db->prepare("INSERT INTO products (category_id, name, slug, description, price, old_price, sku, stock_quantity)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute($product);
}
echo "Добавлены товары<br>";
}
// Проверяем, есть ли администратор
$check_admin = $db->prepare("SELECT COUNT(*) FROM users WHERE email = ?");
$check_admin->execute(['admin@aeterna.ru']);
if ($check_admin->fetchColumn() == 0) {
// Добавляем администратора (пароль: admin123)
$admin_password = password_hash('admin123', PASSWORD_DEFAULT);
$stmt = $db->prepare("INSERT INTO users (email, password_hash, full_name, phone, is_admin)
VALUES (?, ?, ?, ?, ?)");
$stmt->execute(['admin@aeterna.ru', $admin_password, 'Администратор AETERNA', '+79129991223', true]);
echo "Добавлен администратор (email: admin@aeterna.ru, пароль: admin123)<br>";
}
echo "<h3>База данных успешно инициализирована!</h3>";
echo "<a href='catalog.php'>Перейти в каталог</a>";
?>

View File

@@ -1,19 +1,15 @@
<?php
// admin_panel.php - ПОЛНОСТЬЮ ИСПРАВЛЕННАЯ ВЕРСИЯ
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
// Включаем отладку ошибок
error_reporting(E_ALL);
ini_set('display_errors', 1);
if (empty($allCategories)) {
echo '<div class="alert alert-warning">Сначала добавьте категории!</div>';
}
// Проверка прав администратора
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {
echo "<script>alert('Требуется авторизация администратора'); window.location.href = 'вход.php';</script>";
echo "<script>alert('Требуется авторизация администратора'); window.location.href = 'login.php';</script>";
exit();
}
@@ -546,7 +542,7 @@ try {
<div class="form-container">
<h2><?= $action == 'add_category' ? 'Добавление категории' : 'Редактирование категории' ?></h2>
<form method="POST" action="fix_edit_category.php" id="categoryForm">
<form method="POST" action="admin_panel.php" id="categoryForm">
<input type="hidden" name="action" value="<?= $action == 'edit_category' ? 'edit_category' : 'add_category' ?>">
<?php if (isset($edit_data)): ?>
@@ -600,64 +596,6 @@ try {
</form>
</div>
<?php elseif (in_array($action, ['add_category', 'edit_category'])): ?>
<!-- Форма добавления/редактирования категории -->
<div class="form-container">
<h2><?= $action == 'add_category' ? 'Добавление категории' : 'Редактирование категории' ?></h2>
<form method="POST">
<input type="hidden" name="action" value="<?= $action == 'edit_category' ? 'edit_category' : 'add_category' ?>">
<?php if (isset($edit_data)): ?>
<input type="hidden" name="category_id" value="<?= $edit_data['category_id'] ?>">
<?php endif; ?>
<div class="form-group">
<label>Название категории *</label>
<input type="text" name="name" class="form-control"
value="<?= htmlspecialchars($edit_data['name'] ?? '') ?>" required>
</div>
<div class="form-group">
<label>Родительская категория</label>
<select name="parent_id" class="form-control">
<option value="">Без родительской категории</option>
<?php foreach ($parentCategories as $cat): ?>
<?php if (!isset($edit_data['category_id']) || $cat['category_id'] != $edit_data['category_id']): ?>
<option value="<?= $cat['category_id'] ?>"
<?= (isset($edit_data['parent_id']) && $edit_data['parent_id'] == $cat['category_id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($cat['name']) ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label>Описание</label>
<textarea name="description" class="form-control" rows="3"><?= htmlspecialchars($edit_data['description'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label>Порядок сортировки</label>
<input type="number" name="sort_order" class="form-control" min="0" max="100"
value="<?= $edit_data['sort_order'] ?? 0 ?>">
</div>
<div class="form-group">
<label>
<input type="checkbox" name="is_active" value="1"
<?= (!isset($edit_data['is_active']) || $edit_data['is_active']) ? 'checked' : '' ?>>
Активна
</label>
</div>
<button type="submit" class="btn btn-primary">
<?= $action == 'add_category' ? 'Добавить категорию' : 'Сохранить изменения' ?>
</button>
<a href="?action=categories" class="btn">Отмена</a>
</form>
</div>
<?php elseif ($action == 'orders'): ?>
<!-- Заказы -->
<h2>Заказы</h2>

View File

@@ -1,170 +0,0 @@
<?php
// admin_actions.php
session_start();
require_once 'config/database.php';
// Проверка прав администратора
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {
header('Location: вход.php?error=admin_only');
exit();
}
$db = Database::getInstance()->getConnection();
$action = $_GET['action'] ?? '';
try {
switch ($action) {
case 'delete_product':
if (isset($_GET['id'])) {
$productId = intval($_GET['id']);
// Делаем товар недоступным
$stmt = $db->prepare("
UPDATE products
SET is_available = FALSE, stock_quantity = 0, updated_at = CURRENT_TIMESTAMP
WHERE product_id = ?
");
$stmt->execute([$productId]);
header('Location: admin_panel.php?action=products&message=Товар помечен как недоступный');
exit();
}
break;
case 'restore_product':
if (isset($_GET['id'])) {
$productId = intval($_GET['id']);
// Восстанавливаем товар
$stmt = $db->prepare("
UPDATE products
SET is_available = TRUE, stock_quantity = 10, updated_at = CURRENT_TIMESTAMP
WHERE product_id = ?
");
$stmt->execute([$productId]);
header('Location: admin_panel.php?action=products&message=Товар восстановлен');
exit();
}
break;
case 'delete_category':
if (isset($_GET['id'])) {
$categoryId = intval($_GET['id']);
try {
// 1. Проверяем, есть ли товары в этой категории
$checkProducts = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ?");
$checkProducts->execute([$categoryId]);
$productCount = $checkProducts->fetchColumn();
if ($productCount > 0) {
// Если есть товары, делаем категорию неактивной
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
$stmt->execute([$categoryId]);
header('Location: admin_panel.php?action=categories&message=Категория скрыта (содержит товары)');
exit();
}
// 2. Проверяем, есть ли дочерние категории
$checkChildren = $db->prepare("SELECT COUNT(*) FROM categories WHERE parent_id = ?");
$checkChildren->execute([$categoryId]);
$childCount = $checkChildren->fetchColumn();
if ($childCount > 0) {
// Вариант A: Делаем категорию неактивной
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
$stmt->execute([$categoryId]);
header('Location: admin_panel.php?action=categories&message=Категория скрыта (имеет дочерние категории)');
exit();
// Вариант B: Удаляем вместе с дочерними (раскомментируйте если нужно)
/*
// Сначала удаляем дочерние категории
$stmt = $db->prepare("DELETE FROM categories WHERE parent_id = ?");
$stmt->execute([$categoryId]);
// Затем удаляем саму категорию
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$categoryId]);
header('Location: admin_panel.php?action=categories&message=Категория и её дочерние категории удалены');
exit();
*/
}
// 3. Если нет товаров и дочерних категорий, удаляем
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$categoryId]);
header('Location: admin_panel.php?action=categories&message=Категория удалена');
exit();
} catch (PDOException $e) {
header('Location: admin_panel.php?action=categories&error=' . urlencode($e->getMessage()));
exit();
}
}
break;
case 'delete_category_force':
// Принудительное удаление с дочерними категориями
if (isset($_GET['id'])) {
$categoryId = intval($_GET['id']);
try {
// Сначала перемещаем товары в другую категорию (например, в первую)
$firstCategory = $db->query("SELECT category_id FROM categories WHERE category_id != ? LIMIT 1")->fetchColumn();
if ($firstCategory) {
$moveProducts = $db->prepare("UPDATE products SET category_id = ? WHERE category_id = ?");
$moveProducts->execute([$firstCategory, $categoryId]);
}
// Обнуляем parent_id у дочерних категорий
$stmt = $db->prepare("UPDATE categories SET parent_id = NULL WHERE parent_id = ?");
$stmt->execute([$categoryId]);
// Удаляем категорию
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$categoryId]);
header('Location: admin_panel.php?action=categories&message=Категория удалена. Товары перемещены.');
exit();
} catch (PDOException $e) {
header('Location: admin_panel.php?action=categories&error=' . urlencode($e->getMessage()));
exit();
}
}
break;
case 'toggle_user':
if (isset($_GET['id'])) {
$userId = intval($_GET['id']);
$stmt = $db->prepare("
UPDATE users
SET is_active = NOT is_active, updated_at = CURRENT_TIMESTAMP
WHERE user_id = ?
");
$stmt->execute([$userId]);
header('Location: admin_panel.php?action=users&message=Статус пользователя изменен');
exit();
}
break;
case 'make_admin':
if (isset($_GET['id'])) {
$userId = intval($_GET['id']);
$stmt = $db->prepare("UPDATE users SET is_admin = TRUE WHERE user_id = ?");
$stmt->execute([$userId]);
header('Location: admin_panel.php?action=users&message=Пользователь назначен администратором');
exit();
}
break;
}
} catch (PDOException $e) {
header('Location: admin_panel.php?error=' . urlencode($e->getMessage()));
exit();
}
// Если действие не распознано
header('Location: admin_panel.php');
exit();
?>

View File

@@ -1,6 +1,6 @@
<?php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
echo json_encode(['success' => false, 'message' => 'Требуется авторизация']);

View File

@@ -1,7 +1,7 @@
<?php
// login_handler.php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';

134
api/cart.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
/**
* API для работы с корзиной
* Эндпоинты: add, update, remove, get, count
*/
session_start();
require_once __DIR__ . '/../config/database.php';
header('Content-Type: application/json; charset=utf-8');
// Проверка авторизации
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
echo json_encode(['success' => false, 'message' => 'Требуется авторизация']);
exit();
}
$userId = $_SESSION['user_id'] ?? 0;
$action = $_GET['action'] ?? $_POST['action'] ?? '';
$db = Database::getInstance()->getConnection();
try {
switch ($action) {
case 'add':
$productId = (int)($_POST['product_id'] ?? 0);
$quantity = (int)($_POST['quantity'] ?? 1);
if ($productId <= 0) {
echo json_encode(['success' => false, 'message' => 'Неверный ID товара']);
exit();
}
// Проверяем существование товара
$checkProduct = $db->prepare("SELECT product_id, stock_quantity FROM products WHERE product_id = ? AND is_available = TRUE");
$checkProduct->execute([$productId]);
$product = $checkProduct->fetch();
if (!$product) {
echo json_encode(['success' => false, 'message' => 'Товар не найден']);
exit();
}
// Проверяем, есть ли товар уже в корзине
$checkCart = $db->prepare("SELECT cart_id, quantity FROM cart WHERE user_id = ? AND product_id = ?");
$checkCart->execute([$userId, $productId]);
$cartItem = $checkCart->fetch();
if ($cartItem) {
// Обновляем количество
$newQuantity = $cartItem['quantity'] + $quantity;
$stmt = $db->prepare("UPDATE cart SET quantity = ?, updated_at = CURRENT_TIMESTAMP WHERE cart_id = ?");
$stmt->execute([$newQuantity, $cartItem['cart_id']]);
} else {
// Добавляем новый товар
$stmt = $db->prepare("INSERT INTO cart (user_id, product_id, quantity) VALUES (?, ?, ?)");
$stmt->execute([$userId, $productId, $quantity]);
}
echo json_encode(['success' => true, 'message' => 'Товар добавлен в корзину']);
break;
case 'update':
$productId = (int)($_POST['product_id'] ?? 0);
$quantity = (int)($_POST['quantity'] ?? 1);
if ($quantity <= 0) {
// Удаляем товар если количество 0
$stmt = $db->prepare("DELETE FROM cart WHERE user_id = ? AND product_id = ?");
$stmt->execute([$userId, $productId]);
} else {
$stmt = $db->prepare("UPDATE cart SET quantity = ?, updated_at = CURRENT_TIMESTAMP WHERE user_id = ? AND product_id = ?");
$stmt->execute([$quantity, $userId, $productId]);
}
echo json_encode(['success' => true, 'message' => 'Корзина обновлена']);
break;
case 'remove':
$productId = (int)($_POST['product_id'] ?? 0);
$stmt = $db->prepare("DELETE FROM cart WHERE user_id = ? AND product_id = ?");
$stmt->execute([$userId, $productId]);
echo json_encode(['success' => true, 'message' => 'Товар удален из корзины']);
break;
case 'get':
$stmt = $db->prepare("
SELECT c.cart_id, c.product_id, c.quantity, p.name, p.price, p.image_url, p.stock_quantity
FROM cart c
JOIN products p ON c.product_id = p.product_id
WHERE c.user_id = ? AND p.is_available = TRUE
ORDER BY c.created_at DESC
");
$stmt->execute([$userId]);
$items = $stmt->fetchAll();
$total = 0;
foreach ($items as &$item) {
$item['subtotal'] = $item['price'] * $item['quantity'];
$total += $item['subtotal'];
}
echo json_encode([
'success' => true,
'items' => $items,
'total' => $total,
'count' => array_sum(array_column($items, 'quantity'))
]);
break;
case 'count':
$stmt = $db->prepare("SELECT COALESCE(SUM(quantity), 0) FROM cart WHERE user_id = ?");
$stmt->execute([$userId]);
$count = $stmt->fetchColumn();
echo json_encode(['success' => true, 'count' => (int)$count]);
break;
case 'clear':
$stmt = $db->prepare("DELETE FROM cart WHERE user_id = ?");
$stmt->execute([$userId]);
echo json_encode(['success' => true, 'message' => 'Корзина очищена']);
break;
default:
echo json_encode(['success' => false, 'message' => 'Неизвестное действие']);
}
} catch (PDOException $e) {
echo json_encode(['success' => false, 'message' => 'Ошибка базы данных: ' . $e->getMessage()]);
}

View File

@@ -1,7 +1,7 @@
<?php
// get_cart.php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
echo json_encode(['success' => false, 'message' => 'Требуется авторизация']);

View File

@@ -1,7 +1,7 @@
<?php
// get_cart_count.php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
echo json_encode(['success' => false, 'cart_count' => 0]);

View File

@@ -1,6 +1,6 @@
<?php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
// Проверяем авторизацию администратора
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {

View File

@@ -1,17 +1,17 @@
<?php
// process_order.php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
header('Location: вход.php?error=auth_required');
header('Location: login.php?error=auth_required');
exit();
}
$user_id = $_SESSION['user_id'] ?? 0;
if ($user_id == 0) {
header('Location: вход.php?error=user_not_found');
header('Location: login.php?error=user_not_found');
exit();
}
@@ -124,11 +124,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} catch (Exception $e) {
$db->rollBack();
header('Location: оформлениеаказа.php?error=' . urlencode($e->getMessage()));
header('Location: checkout.php?error=' . urlencode($e->getMessage()));
exit();
}
} else {
header('Location: оформлениеаказа.php');
header('Location: checkout.php');
exit();
}
?>

View File

@@ -1,7 +1,7 @@
<?php
// register_handler.php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors = [];
@@ -53,7 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'email' => $email,
'phone' => $phone
];
header('Location: профиль.php');
header('Location: register.php');
exit();
}
@@ -73,7 +73,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'email' => $email,
'phone' => $phone
];
header('Location: профиль.php');
header('Location: register.php');
exit();
}
@@ -164,19 +164,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'email' => $email,
'phone' => $phone
];
header('Location: профиль.php');
header('Location: register.php');
exit();
} catch (Exception $e) {
error_log("Registration Error: " . $e->getMessage());
$_SESSION['registration_errors'] = [$e->getMessage()];
header('Location: профиль.php');
header('Location: register.php');
exit();
}
} else {
// Если запрос не POST, перенаправляем на форму регистрации
header('Location: профиль.php');
header('Location: register.php');
exit();
}
?>

View File

@@ -1,6 +1,6 @@
<?php
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/../config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
echo json_encode(['success' => false, 'message' => 'Требуется авторизация']);

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

View File

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 414 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 291 KiB

View File

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 372 KiB

View File

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 265 KiB

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 555 KiB

After

Width:  |  Height:  |  Size: 555 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 479 KiB

After

Width:  |  Height:  |  Size: 479 KiB

View File

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 430 KiB

After

Width:  |  Height:  |  Size: 430 KiB

View File

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 167 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

Before

Width:  |  Height:  |  Size: 497 KiB

After

Width:  |  Height:  |  Size: 497 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 759 KiB

After

Width:  |  Height:  |  Size: 759 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 654 KiB

After

Width:  |  Height:  |  Size: 654 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

Before

Width:  |  Height:  |  Size: 739 KiB

After

Width:  |  Height:  |  Size: 739 KiB

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 655 KiB

After

Width:  |  Height:  |  Size: 655 KiB

View File

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

View File

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 228 KiB

View File

Before

Width:  |  Height:  |  Size: 294 KiB

After

Width:  |  Height:  |  Size: 294 KiB

View File

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

View File

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 306 KiB

After

Width:  |  Height:  |  Size: 306 KiB

View File

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

142
assets/less/checkout.less Normal file
View File

@@ -0,0 +1,142 @@
.error-message {
color: #ff0000;
font-size: 12px;
margin-top: 5px;
display: none;
}
.form__input.error {
border-color: #ff0000;
}
.form__group {
position: relative;
margin-bottom: 15px;
}
/* Стили для сообщений внизу страницы */
.page-messages {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
width: 90%;
max-width: 500px;
}
.message {
padding: 15px;
margin: 10px 0;
border-radius: 5px;
text-align: center;
font-weight: bold;
display: none;
}
.message.error {
background-color: #ffebee;
color: #c62828;
border: 1px solid #ffcdd2;
}
.message.success {
background-color: #e8f5e9;
color: #453227;
border: 1px solid #c8e6c9;
}
.message.warning {
background-color: #fff3e0;
color: #ef6c00;
border: 1px solid #ffe0b2;
}
.privacy-error {
color: #ff0000;
font-size: 12px;
margin-top: 5px;
display: none;
text-align: center;
}
/* Дополнительные стили для формы регистрации */
.input-group {
position: relative;
margin-bottom: 20px;
}
.profile-form input.error {
border-color: #ff0000;
background-color: #fff5f5;
}
.privacy-checkbox {
margin: 20px 0;
text-align: center;
}
.privacy-checkbox label {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
cursor: pointer;
font-size: 14px;
}
.privacy-checkbox input[type="checkbox"] {
margin: 0;
}
/* Исправление отступов для страницы регистрации */
.profile-page-main {
padding: 40px 0;
min-height: calc(100vh - 200px);
}
/* Убедимся, что контейнер не перекрывает шапку и футер */
.profile-container {
margin: 0 auto;
position: relative;
z-index: 1;
}
.input-hint {
font-size: 12px;
color: #666;
margin-top: 5px;
}
/* Стили для страницы входа */
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin: 20px 0;
}
.remember-me {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #453227;
}
.remember-me input[type="checkbox"] {
width: 16px;
height: 16px;
cursor: pointer;
}
.forgot-password {
font-size: 14px;
color: #453227;
text-decoration: underline;
}
.forgot-password:hover {
color: #617365;
text-decoration: none;
}

86
assets/less/mixins.less Normal file
View File

@@ -0,0 +1,86 @@
// ===================================
// === ПЕРЕМЕННЫЕ И МИКСИНЫ AETERNA ===
// ===================================
@color-primary: #617365;
@color-secondary: #D1D1D1;
@color-accent: #453227;
@color-text-dark: #333;
@color-text-light: #fff;
@color-button: @color-accent;
@color-beige: #A2A09A;
@font-logo: 'Anek Kannada', sans-serif;
@font-main: 'Anonymous Pro', monospace;
@font-heading: 'Playfair Display', serif;
@shadow-light: 0 5px 15px rgba(0, 0, 0, 0.2);
@shadow-dark: 2px 2px 4px rgba(0, 0, 0, 0.3);
.flex-center(@gap: 0) {
display: flex;
align-items: center;
justify-content: center;
gap: @gap;
}
.flex-between() {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-column() {
display: flex;
flex-direction: column;
}
.icon-base(@size: 18px, @hover-scale: 1.1) {
cursor: pointer;
transition: all 0.3s ease;
font-size: @size;
&:hover {
transform: scale(@hover-scale);
}
}
.image-overlay() {
position: absolute;
inset: 0;
.flex-center(15px);
flex-direction: column;
text-align: center;
background-color: rgba(0, 0, 0, 0.4);
padding: 20px;
color: @color-text-light;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
transition: all 0.3s ease;
}
.menu-base() {
position: absolute;
top: 100%;
left: 0;
width: 250px;
background: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 15px;
z-index: 1000;
margin-top: 5px;
display: none;
}
.input-base() {
width: 100%;
padding: 12px 15px;
border: 1px solid #ccc;
background-color: #fff;
font-family: @font-main;
font-size: 14px;
outline: none;
transition: border-color 0.3s ease;
&:focus {
border-color: @color-primary;
}
}

3177
assets/less/style.less Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,924 +0,0 @@
<?php
// catalog_admin.php - единый файл каталога с админ-панелью
session_start();
// Подключение к базе данных
require_once 'config/database.php';
// Проверка прав администратора
$is_admin = isset($_SESSION['isAdmin']) && $_SESSION['isAdmin'] === true;
$action = $_GET['action'] ?? '';
$product_id = $_GET['id'] ?? 0;
$category_id = $_GET['category'] ?? '';
// Если не админ, перенаправляем
if (!$is_admin) {
header('Location: вход.php');
exit();
}
try {
$db = Database::getInstance()->getConnection();
// ОБРАБОТКА POST ЗАПРОСОВ ДЛЯ КАТЕГОРИЙ
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $is_admin) {
$form_action = $_POST['action'] ?? '';
if ($form_action === 'add_category' || $form_action === 'edit_category') {
$name = trim($_POST['name'] ?? '');
$parent_id = !empty($_POST['parent_id']) ? (int)$_POST['parent_id'] : null;
$description = trim($_POST['description'] ?? '');
$sort_order = (int)($_POST['sort_order'] ?? 0);
$is_active = isset($_POST['is_active']) ? 1 : 0;
$category_id_post = (int)($_POST['category_id'] ?? 0);
// Валидация
if (empty($name)) {
$_SESSION['error'] = 'Название категории обязательно';
header('Location: catalog_admin.php?action=' . $form_action . ($category_id_post ? '&id=' . $category_id_post : ''));
exit();
}
// Создаем slug
$slug = strtolower(preg_replace('/[^a-z0-9]+/i', '-', $name));
$slug = preg_replace('/^-+|-+$/', '', $slug); // Убираем дефисы по краям
if ($form_action === 'add_category') {
// Проверяем существование slug
$check = $db->prepare("SELECT COUNT(*) FROM categories WHERE slug = ?");
$check->execute([$slug]);
if ($check->fetchColumn() > 0) {
$slug = $slug . '-' . time(); // Добавляем timestamp для уникальности
}
$sql = "INSERT INTO categories (name, slug, parent_id, description, sort_order, is_active)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $db->prepare($sql);
$stmt->execute([$name, $slug, $parent_id, $description, $sort_order, $is_active]);
$_SESSION['message'] = 'Категория успешно добавлена';
header('Location: catalog_admin.php?action=categories');
exit();
} elseif ($form_action === 'edit_category' && $category_id_post > 0) {
// Проверяем существование slug для других категорий
$check = $db->prepare("SELECT COUNT(*) FROM categories WHERE slug = ? AND category_id != ?");
$check->execute([$slug, $category_id_post]);
if ($check->fetchColumn() > 0) {
$slug = $slug . '-' . $category_id_post;
}
$sql = "UPDATE categories SET
name = ?, slug = ?, parent_id = ?, description = ?,
sort_order = ?, is_active = ?, updated_at = CURRENT_TIMESTAMP
WHERE category_id = ?";
$stmt = $db->prepare($sql);
$stmt->execute([$name, $slug, $parent_id, $description, $sort_order, $is_active, $category_id_post]);
$_SESSION['message'] = 'Категория успешно обновлена';
header('Location: catalog_admin.php?action=categories');
exit();
}
}
// Удаление категории
if ($form_action === 'delete_category') {
$category_id_del = (int)($_POST['category_id'] ?? 0);
if ($category_id_del > 0) {
// Проверяем наличие активных товаров
$check_products = $db->prepare("
SELECT COUNT(*) as product_count
FROM products
WHERE category_id = ? AND is_available = TRUE
");
$check_products->execute([$category_id_del]);
$active_products = $check_products->fetchColumn();
if ($active_products > 0) {
$_SESSION['error'] = 'Невозможно удалить категорию с активными товарами';
header('Location: catalog_admin.php?action=categories');
exit();
}
// Проверяем дочерние категории
$check_children = $db->prepare("
SELECT COUNT(*) as child_count
FROM categories
WHERE parent_id = ? AND is_active = TRUE
");
$check_children->execute([$category_id_del]);
$active_children = $check_children->fetchColumn();
if ($active_children > 0) {
$_SESSION['error'] = 'Невозможно удалить категорию с активными дочерними категориями';
header('Location: catalog_admin.php?action=categories');
exit();
}
// Удаляем категорию
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$category_id_del]);
$_SESSION['message'] = 'Категория успешно удалена';
header('Location: catalog_admin.php?action=categories');
exit();
}
}
}
// Получаем категории для отображения
$categories_stmt = $db->query("
SELECT c1.*, c2.name as parent_name,
(SELECT COUNT(*) FROM products WHERE category_id = c1.category_id) as product_count
FROM categories c1
LEFT JOIN categories c2 ON c1.parent_id = c2.category_id
ORDER BY c1.sort_order, c1.name
");
$categories = $categories_stmt->fetchAll();
// Для редактирования категории
if ($action === 'edit_category' && $product_id > 0) {
$cat_stmt = $db->prepare("SELECT * FROM categories WHERE category_id = ?");
$cat_stmt->execute([$product_id]);
$current_category = $cat_stmt->fetch();
if (!$current_category) {
$_SESSION['error'] = 'Категория не найдена';
header('Location: catalog_admin.php?action=categories');
exit();
}
}
// Получаем товары
$sql = "SELECT p.*, c.name as category_name FROM products p
LEFT JOIN categories c ON p.category_id = c.category_id
WHERE p.is_available = TRUE";
$params = [];
if ($category_id && is_numeric($category_id)) {
$sql .= " AND p.category_id = ?";
$params[] = $category_id;
}
$sql .= " ORDER BY p.product_id DESC";
if ($params) {
$stmt = $db->prepare($sql);
$stmt->execute($params);
} else {
$stmt = $db->query($sql);
}
$products = $stmt->fetchAll();
// Сообщения из сессии
$message = $_SESSION['message'] ?? '';
$error = $_SESSION['error'] ?? '';
// Очищаем сообщения после использования
unset($_SESSION['message']);
unset($_SESSION['error']);
} catch (PDOException $e) {
$error = "Ошибка подключения к базе данных: " . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AETERNA - Каталог</title>
<link rel="stylesheet/less" type="text/css" href="style_for_cite.less">
<script src="https://cdn.jsdelivr.net/npm/less"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<style>
.admin-panel {
background: #f8f9fa;
padding: 20px;
margin: 20px 0;
border-radius: 8px;
border-left: 4px solid #617365;
}
.admin-btn {
background: #617365;
color: white;
padding: 8px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin: 5px;
text-decoration: none;
display: inline-block;
}
.admin-btn:hover {
background: #453227;
}
.admin-form {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
margin: 20px 0;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input, .form-group textarea, .form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: "Anonymous Pro", monospace;
font-size: 14px;
}
.form-group textarea {
min-height: 100px;
resize: vertical;
}
.form-group input[type="checkbox"] {
width: auto;
display: inline-block;
margin-right: 8px;
}
.alert {
padding: 15px;
margin-bottom: 20px;
border-radius: 4px;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-danger {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.badge {
padding: 3px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: bold;
margin-left: 5px;
}
.badge-warning {
background: #ffc107;
color: #212529;
}
.badge-info {
background: #17a2b8;
color: white;
}
.badge-success {
background: #28a745;
color: white;
}
.badge-danger {
background: #dc3545;
color: white;
}
.btn {
padding: 8px 15px;
border-radius: 4px;
border: none;
cursor: pointer;
font-size: 14px;
text-decoration: none;
display: inline-block;
}
.btn-sm {
padding: 5px 10px;
font-size: 12px;
}
.btn-warning {
background: #ffc107;
color: #212529;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
opacity: 0.6;
cursor: not-allowed;
}
.btn-success {
background: #28a745;
color: white;
}
.admin-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.admin-table th,
.admin-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.admin-table th {
background: #f8f9fa;
font-weight: bold;
color: #453227;
}
.admin-table tr:hover {
background: #f8f9fa;
}
.catalog-dropdown {
position: relative;
}
.catalog-dropdown__menu {
display: none;
position: absolute;
top: 100%;
left: 0;
width: 250px;
background: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
padding: 15px;
z-index: 1000;
margin-top: 5px;
max-height: 400px;
overflow-y: auto;
}
.catalog-dropdown:hover .catalog-dropdown__menu {
display: block;
}
.catalog-dropdown__menu ul {
list-style: none;
padding: 0;
margin: 0;
}
.catalog-dropdown__menu li {
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.catalog-dropdown__menu li:last-child {
border-bottom: none;
}
.catalog-dropdown__menu a {
color: #333;
text-decoration: none;
display: block;
}
.catalog-dropdown__menu a:hover {
color: #453227;
padding-left: 5px;
}
</style>
</head>
<body>
<header class="header">
<div class="header__top">
<div class="container header__top-content">
<div class="logo">AETERNA</div>
<div class="search-catalog">
<div class="catalog-dropdown">
Все категории <span>&#9660;</span>
<div class="catalog-dropdown__menu">
<ul>
<li><a href="catalog_admin.php">Все товары</a></li>
<?php foreach ($categories as $cat): ?>
<li><a href="catalog_admin.php?category=<?= $cat['category_id'] ?>">
<?= htmlspecialchars($cat['name']) ?>
</a></li>
<?php endforeach; ?>
</ul>
</div>
</div>
<div class="search-box">
<input type="text" placeholder="Поиск товаров">
<span class="search-icon"><i class="fas fa-search"></i></span>
</div>
</div>
<div class="header__icons--top">
<a href="оформлениеаказа.php" class="icon cart-icon">
<i class="fas fa-shopping-cart"></i>
<span class="cart-count">0</span>
</a>
<?php if ($is_admin): ?>
<div class="user-profile-dropdown">
<div class="user-profile-toggle">
<div class="user-avatar">
<?= strtoupper(substr($_SESSION['user_email'] ?? 'A', 0, 1)) ?>
</div>
<div class="user-info">
<div class="user-email"><?= htmlspecialchars($_SESSION['user_email'] ?? '') ?></div>
<div class="user-status admin">Админ</div>
</div>
<i class="fas fa-chevron-down dropdown-arrow"></i>
</div>
<div class="user-profile-menu">
<div class="user-profile-header">
<div class="user-profile-name">
<i class="fas fa-user-shield"></i>
<?= htmlspecialchars($_SESSION['full_name'] ?? $_SESSION['user_email']) ?>
</div>
</div>
<ul class="user-profile-links">
<li><a href="logout.php" class="logout-link">
<i class="fas fa-sign-out-alt"></i>
<span>Выйти</span>
</a></li>
</ul>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="header__bottom">
<div class="container header__bottom-content">
<div class="catalog-menu">
<a href="catalog_admin.php" class="catalog-link active-catalog">
<div class="catalog-icon">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
</div>
<span class="catalog-lines">☰</span>
Каталог
</a>
</div>
<nav class="nav">
<ul class="nav-list">
<li><a href="cite_mebel.php">Главная</a></li>
<li><a href="услуги.php">Услуги</a></li>
<li><a href="Доставка.php">Доставка и оплата</a></li>
<li><a href="Гарантия.php">Гарантия</a></li>
<li><a href="#footer">Контакты</a></li>
</ul>
</nav>
<div class="header-phone">+7(912)999-12-23</div>
</div>
</div>
</header>
<main class="catalog-main">
<div class="container">
<div class="breadcrumbs">
<a href="cite_mebel.php">Главная</a> • <span class="current-page">Каталог</span>
</div>
<?php if ($is_admin): ?>
<!-- Панель администратора -->
<div class="admin-panel">
<h3>Панель управления каталогом</h3>
<a href="?action=add_product" class="admin-btn">
<i class="fas fa-plus"></i> Добавить товар
</a>
<a href="?action=add_category" class="admin-btn">
<i class="fas fa-folder-plus"></i> Добавить категорию
</a>
<a href="?action=categories" class="admin-btn" style="background: #ffc107; color: #212529;">
<i class="fas fa-tags"></i> Управление категориями
</a>
</div>
<?php if ($message): ?>
<div class="alert alert-success">
<i class="fas fa-check-circle"></i> <?= htmlspecialchars($message) ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger">
<i class="fas fa-exclamation-circle"></i> <?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>
<?php if ($action === 'add_category' || $action === 'edit_category'): ?>
<!-- Форма добавления/редактирования категории -->
<div class="admin-form" id="categoryForm">
<h3><?= ($action === 'add_category') ? 'Добавление категории' : 'Редактирование категории' ?></h3>
<?php if (isset($error) && !empty($error)): ?>
<div class="alert alert-danger">
<i class="fas fa-exclamation-circle"></i> <?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>
<form method="POST" action="catalog_admin.php" id="categoryFormElement">
<input type="hidden" name="action" value="<?= $action ?>">
<?php if ($action === 'edit_category' && isset($current_category)): ?>
<input type="hidden" name="category_id" value="<?= $current_category['category_id'] ?>">
<?php endif; ?>
<div class="form-group">
<label for="category_name">Название категории: *</label>
<input type="text" name="name" id="category_name" required
value="<?= htmlspecialchars($current_category['name'] ?? '') ?>"
placeholder="Введите название категории">
</div>
<div class="form-group">
<label for="parent_category">Родительская категория:</label>
<select name="parent_id" id="parent_category">
<option value="">Без родительской категории</option>
<?php foreach ($categories as $cat): ?>
<?php if (!isset($current_category['category_id']) || $cat['category_id'] != $current_category['category_id']): ?>
<option value="<?= $cat['category_id'] ?>"
<?= (isset($current_category['parent_id']) && $current_category['parent_id'] == $cat['category_id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($cat['name']) ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="category_description">Описание:</label>
<textarea name="description" id="category_description" rows="3"
placeholder="Описание категории (необязательно)"><?= htmlspecialchars($current_category['description'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label for="sort_order">Порядок сортировки:</label>
<input type="number" name="sort_order" id="sort_order"
value="<?= $current_category['sort_order'] ?? 0 ?>"
min="0" max="100">
</div>
<div class="form-group">
<label>
<input type="checkbox" name="is_active" value="1"
<?= (!isset($current_category['is_active']) || $current_category['is_active']) ? 'checked' : '' ?>>
Активна
</label>
</div>
<button type="submit" class="admin-btn">
<i class="fas fa-save"></i> Сохранить
</button>
<a href="catalog_admin.php?action=categories" class="admin-btn" style="background: #6c757d;">
<i class="fas fa-times"></i> Отмена
</a>
</form>
</div>
<?php endif; ?>
<?php endif; ?>
<div class="catalog-wrapper">
<aside class="catalog-sidebar">
<div class="filter-group">
<h4 class="filter-title">КАТЕГОРИИ</h4>
<ul class="filter-list">
<li><a href="catalog_admin.php" class="<?= (!$category_id) ? 'active-category' : '' ?>">Все товары</a></li>
<?php foreach ($categories as $cat): ?>
<li>
<a href="catalog_admin.php?category=<?= $cat['category_id'] ?>"
class="<?= ($category_id == $cat['category_id']) ? 'active-category' : '' ?>">
<?= htmlspecialchars($cat['name']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<div class="filter-group">
<h4 class="filter-title">ЦЕНА</h4>
<div class="price-range">
<div class="range-slider">
<input type="range" min="1000" max="100000" value="50000" step="1000">
</div>
<div class="price-display">До 50 000 ₽</div>
</div>
</div>
<button class="btn primary-btn filter-apply-btn">ПРИМЕНИТЬ</button>
</aside>
<section class="catalog-products">
<?php if ($action === 'categories'): ?>
<!-- Раздел управления категориями -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<h2>Управление категориями</h2>
<a href="?action=add_category" class="btn btn-success">
<i class="fas fa-plus"></i> Добавить категорию
</a>
</div>
<table class="admin-table">
<thead>
<tr>
<th>ID</th>
<th>Название</th>
<th>Родительская</th>
<th>Товаров</th>
<th>Порядок</th>
<th>Статус</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
<?php foreach ($categories as $cat): ?>
<tr>
<td><?= $cat['category_id'] ?></td>
<td>
<strong><?= htmlspecialchars($cat['name']) ?></strong>
<br><small style="color: #666;"><?= htmlspecialchars($cat['slug']) ?></small>
</td>
<td><?= htmlspecialchars($cat['parent_name'] ?? '—') ?></td>
<td>
<span class="badge badge-info"><?= $cat['product_count'] ?> товаров</span>
</td>
<td><?= $cat['sort_order'] ?></td>
<td>
<?php if ($cat['is_active']): ?>
<span class="badge badge-success">Активна</span>
<?php else: ?>
<span class="badge badge-warning">Неактивна</span>
<?php endif; ?>
</td>
<td>
<a href="?action=edit_category&id=<?= $cat['category_id'] ?>"
class="btn btn-sm btn-warning" title="Редактировать">
<i class="fas fa-edit"></i>
</a>
<form method="POST" action="catalog_admin.php" style="display: inline-block;"
onsubmit="return confirm('Вы уверены, что хотите удалить категорию?');">
<input type="hidden" name="action" value="delete_category">
<input type="hidden" name="category_id" value="<?= $cat['category_id'] ?>">
<?php if ($cat['product_count'] == 0): ?>
<button type="submit" class="btn btn-sm btn-danger" title="Удалить">
<i class="fas fa-trash"></i>
</button>
<?php else: ?>
<button type="button" class="btn btn-sm btn-secondary"
title="Нельзя удалить категорию с товарами" disabled>
<i class="fas fa-trash"></i>
</button>
<?php endif; ?>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<!-- Основной каталог товаров -->
<div class="products-container">
<?php foreach ($products as $product): ?>
<div class="product-card <?= getCardSizeClass($product) ?>">
<?php if ($is_admin): ?>
<div class="admin-actions">
<a href="?action=edit&id=<?= $product['product_id'] ?>"
class="admin-btn" style="background: #28a745;">
<i class="fas fa-edit"></i>
</a>
<a href="?action=delete&id=<?= $product['product_id'] ?>"
class="admin-btn" style="background: #dc3545;"
onclick="return confirm('Сделать товар недоступным?')">
<i class="fas fa-trash"></i>
</a>
</div>
<?php endif; ?>
<div class="product-image-container">
<img src="<?= htmlspecialchars($product['image_url'] ?: 'img1/default.jpg') ?>"
alt="<?= htmlspecialchars($product['name']) ?>"
class="product-img">
<?php if ($product['old_price'] && $product['old_price'] > $product['price']): ?>
<span class="product-discount">
-<?= round(($product['old_price'] - $product['price']) / $product['old_price'] * 100) ?>%
</span>
<?php endif; ?>
<i class="fas fa-shopping-cart product-wishlist-icon"
onclick="addToCart(<?= $product['product_id'] ?>)"></i>
</div>
<div class="product-info" style="padding: 15px;">
<div class="product-name"><?= htmlspecialchars($product['name']) ?></div>
<div class="product-details">
<?= htmlspecialchars(mb_substr($product['description'], 0, 100)) ?>...
</div>
<div class="product-price" style="margin-top: 10px;">
<?php if ($product['old_price'] && $product['old_price'] > $product['price']): ?>
<span style="text-decoration: line-through; color: #999; font-size: 14px;">
<?= number_format($product['old_price'], 0, '', ' ') ?> ₽
</span><br>
<?php endif; ?>
<?= number_format($product['price'], 0, '', ' ') ?> ₽
</div>
<div class="product-stock" style="font-size: 12px; color: #28a745; margin-top: 5px;">
В наличии: <?= $product['stock_quantity'] ?> шт.
</div>
<button onclick="addToCart(<?= $product['product_id'] ?>)"
class="btn btn-primary" style="width: 100%; margin-top: 10px;">
<i class="fas fa-shopping-cart"></i> В корзину
</button>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
</div>
</div>
</main>
<footer class="footer" id="footer">
<div class="container footer__content">
<div class="footer__col footer--logo">
<div class="logo">AETERNA</div>
</div>
<div class="footer__col">
<h5>ПОКУПАТЕЛЮ</h5>
<ul>
<li><a href="catalog_admin.php">Каталог</a></li>
<li><a href="услуги.php">Услуги</a></li>
</ul>
</div>
<div class="footer__col">
<h5>ПОМОЩЬ</h5>
<ul>
<li><a href="Доставка.php">Доставка и оплата</a></li>
<li><a href="Гарантия.php">Гарантия и возврат</a></li>
<li><a href="cite_mebel.php#faq">Ответы на вопросы</a></li>
<li><a href="#footer">Контакты</a></li>
</ul>
</div>
<div class="footer__col">
<h5>КОНТАКТЫ</h5>
<p>aeterna@mail.ru</p>
<p>+7(912)999-12-23</p>
<div class="social-icons">
<span class="icon"><i class="fab fa-telegram"></i></span>
<span class="icon"><i class="fab fa-instagram"></i></span>
<span class="icon"><i class="fab fa-vk"></i></span>
</div>
</div>
<div class="footer__col">
<h5>ПРИНИМАЕМ К ОПЛАТЕ</h5>
<div class="payment-icons">
<span class="pay-icon"><i class="fab fa-cc-visa"></i></span>
<span class="pay-icon"><i class="fab fa-cc-mastercard"></i></span>
</div>
</div>
</div>
<div class="copyright">
<p>© 2025 AETERNA. Все права защищены.</p>
</div>
</footer>
<script>
// Функция для показа формы добавления товара
function showAddForm() {
window.location.href = 'catalog_admin.php?action=add';
}
// Функция для показа формы добавления категории
function showAddCategoryForm() {
window.location.href = 'catalog_admin.php?action=add_category';
}
// Функция для редактирования категории
function editCategory(categoryId) {
window.location.href = 'catalog_admin.php?action=edit_category&id=' + categoryId;
}
// Функция для скрытия формы
function hideForm() {
window.location.href = 'catalog_admin.php?action=categories';
}
// Функция добавления в корзину
function addToCart(productId) {
$.ajax({
url: "cart_handler.php",
method: "POST",
data: { action: "add", product_id: productId, quantity: 1 },
success: function(response) {
try {
var result = JSON.parse(response);
if (result.success) {
alert("Товар добавлен в корзину!");
// Обновляем счетчик корзины
if ($(".cart-count").length) {
var current = parseInt($(".cart-count").text()) || 0;
$(".cart-count").text(current + 1);
}
} else {
alert("Ошибка: " + result.message);
}
} catch(e) {
alert("Товар добавлен в корзину!");
}
},
error: function() {
alert("Товар добавлен в корзину!");
}
});
}
// Обработка формы категории с подтверждением
$(document).ready(function() {
$('#categoryFormElement').on('submit', function(e) {
const action = $(this).find('input[name="action"]').val();
const categoryName = $(this).find('input[name="name"]').val();
if (!categoryName.trim()) {
e.preventDefault();
alert('Пожалуйста, введите название категории');
return false;
}
const message = action === 'add_category'
? 'Добавить новую категорию "' + categoryName + '"?'
: 'Сохранить изменения в категории?';
if (!confirm(message)) {
e.preventDefault();
return false;
}
});
// Подтверждение удаления категории
$('form[action="catalog_admin.php"]').on('submit', function(e) {
const action = $(this).find('input[name="action"]').val();
if (action === 'delete_category') {
const categoryId = $(this).find('input[name="category_id"]').val();
if (!confirm('Вы уверены, что хотите удалить эту категорию?')) {
e.preventDefault();
return false;
}
}
});
<?php if ($is_admin): ?>
$('.product-card').hover(
function() {
$(this).find('.admin-actions').show();
},
function() {
$(this).find('.admin-actions').hide();
}
);
<?php endif; ?>
});
</script>
</body>
</html>
<?php
// Вспомогательная функция для определения размера карточки
function getCardSizeClass($product) {
$sizes = ['small', 'large', 'wide', 'tall', 'small1', 'wide2', 'wide3', 'wide2_1', 'full-width'];
$index = $product['product_id'] % count($sizes);
return $sizes[$index];
}

View File

@@ -1,111 +0,0 @@
<?php
// catalog_admin_action.php
session_start();
require_once 'config/database.php';
if (!isset($_SESSION['is_admin']) || $_SESSION['is_admin'] !== true) {
header('Location: вход.php');
exit();
}
$db = Database::getInstance()->getConnection();
$action = $_POST['action'] ?? '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
switch ($action) {
case 'add_category':
$name = $_POST['name'] ?? '';
$parent_id = $_POST['parent_id'] ?: null;
$description = $_POST['description'] ?? null;
$sort_order = $_POST['sort_order'] ?? 0;
$is_active = isset($_POST['is_active']) ? 1 : 0;
// Создаем slug из названия
$slug = strtolower(preg_replace('/[^a-z0-9]+/i', '-', $name));
$stmt = $db->prepare("
INSERT INTO categories (name, slug, parent_id, description, sort_order, is_active)
VALUES (?, ?, ?, ?, ?, ?)
");
$stmt->execute([$name, $slug, $parent_id, $description, $sort_order, $is_active]);
header('Location: catalog_admin.php?action=categories&message=Категория успешно добавлена');
exit();
case 'edit_category':
$category_id = $_POST['category_id'] ?? 0;
$name = $_POST['name'] ?? '';
$parent_id = $_POST['parent_id'] ?: null;
$description = $_POST['description'] ?? null;
$sort_order = $_POST['sort_order'] ?? 0;
$is_active = isset($_POST['is_active']) ? 1 : 0;
// Создаем slug из названия
$slug = strtolower(preg_replace('/[^a-z0-9]+/i', '-', $name));
$stmt = $db->prepare("
UPDATE categories SET
name = ?,
slug = ?,
parent_id = ?,
description = ?,
sort_order = ?,
is_active = ?
WHERE category_id = ?
");
$stmt->execute([$name, $slug, $parent_id, $description, $sort_order, $is_active, $category_id]);
header('Location: catalog_admin.php?action=categories&message=Категория успешно обновлена');
exit();
case 'delete_category':
$category_id = $_POST['category_id'] ?? 0;
// Проверяем, есть ли активные товары в этой категории
$checkStmt = $db->prepare("
SELECT COUNT(*)
FROM products
WHERE category_id = ? AND is_available = TRUE
");
$checkStmt->execute([$category_id]);
$active_products = $checkStmt->fetchColumn();
if ($active_products > 0) {
header('Location: catalog_admin.php?action=categories&error=Невозможно удалить категорию с активными товарами');
exit();
}
// Проверяем дочерние категории
$checkChildStmt = $db->prepare("
SELECT COUNT(*)
FROM categories
WHERE parent_id = ? AND is_active = TRUE
");
$checkChildStmt->execute([$category_id]);
$active_children = $checkChildStmt->fetchColumn();
if ($active_children > 0) {
header('Location: catalog_admin.php?action=categories&error=Невозможно удалить категорию с активными дочерними категориями');
exit();
}
// Удаляем категорию
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$category_id]);
header('Location: catalog_admin.php?action=categories&message=Категория успешно удалена');
exit();
}
} catch (PDOException $e) {
header('Location: catalog_admin.php?action=categories&error=' . urlencode('Ошибка базы данных: ' . $e->getMessage()));
exit();
}
}
header('Location: catalog_admin.php');
exit();
?>

View File

@@ -1,17 +0,0 @@
<?php
// check_admin.php
session_start();
function checkAdmin() {
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {
header('Location: вход.php?error=admin_required');
exit();
}
return true;
}
// Возвращает true если пользователь администратор
function isAdmin() {
return isset($_SESSION['isAdmin']) && $_SESSION['isAdmin'] === true;
}
?>

View File

@@ -1,21 +0,0 @@
<?php
// check_auth_status.php
session_start();
$response = [
'loggedIn' => isset($_SESSION['isLoggedIn']) && $_SESSION['isLoggedIn'] === true
];
if ($response['loggedIn']) {
$response['user'] = [
'user_id' => $_SESSION['user_id'] ?? 0,
'email' => $_SESSION['user_email'] ?? '',
'full_name' => $_SESSION['full_name'] ?? '',
'is_admin' => $_SESSION['isAdmin'] ?? false,
'login_time' => $_SESSION['login_time'] ?? time()
];
}
header('Content-Type: application/json');
echo json_encode($response);
?>

View File

@@ -1,51 +0,0 @@
<?php
require_once 'config/database.php';
$db = Database::getInstance()->getConnection();
echo "<h2>Проверка категорий в базе данных</h2>";
try {
$stmt = $db->query("SELECT category_id, name, slug, parent_id FROM categories ORDER BY category_id");
$categories = $stmt->fetchAll();
if (empty($categories)) {
echo "<p style='color: red;'>Категорий нет! Нужно сначала добавить категории.</p>";
// Добавим тестовые категории
$insert_sql = "
INSERT INTO categories (name, slug, parent_id, description) VALUES
('Мягкая мебель', 'myagkaya-mebel', NULL, 'Диваны, кресла, пуфы'),
('Диваны', 'divany', 1, 'Прямые и угловые диваны'),
('Кресла', 'kresla', 1, 'Кресла для гостиной и офиса'),
('Спальня', 'spalnya', NULL, 'Кровати, тумбы, комоды'),
('Кровати', 'krovati', 4, 'Односпальные и двуспальные кровати')
RETURNING category_id
";
$db->exec($insert_sql);
echo "<p style='color: green;'>Добавлены тестовые категории</p>";
// Снова проверим
$stmt = $db->query("SELECT category_id, name, slug, parent_id FROM categories ORDER BY category_id");
$categories = $stmt->fetchAll();
}
echo "<table border='1' cellpadding='5'>";
echo "<tr><th>ID</th><th>Название</th><th>Slug</th><th>Родитель</th></tr>";
foreach ($categories as $category) {
echo "<tr>";
echo "<td>" . $category['category_id'] . "</td>";
echo "<td>" . htmlspecialchars($category['name']) . "</td>";
echo "<td>" . htmlspecialchars($category['slug']) . "</td>";
echo "<td>" . ($category['parent_id'] ?: '-') . "</td>";
echo "</tr>";
}
echo "</table>";
} catch (PDOException $e) {
echo "Ошибка: " . $e->getMessage();
}
?>

View File

@@ -7,9 +7,9 @@ class Database {
private function __construct() {
try {
$this->connection = new PDO(
"pgsql:host=localhost;dbname=aeterna_db;",
"postgres",
"1234"
"pgsql:host=185.130.224.177;port=5481;dbname=postgres",
"admin",
"38feaad2840ccfda0e71243a6faaecfd"
);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->exec("SET NAMES 'utf8'");

View File

@@ -1,55 +0,0 @@
<?php
// debug_db.php
require_once 'config/database.php';
$db = Database::getInstance()->getConnection();
echo "<h2>Проверка базы данных:</h2>";
// Проверка таблиц
$tables = ['users', 'categories', 'products', 'orders', 'order_items', 'cart'];
foreach ($tables as $table) {
try {
$result = $db->query("SELECT COUNT(*) FROM $table")->fetchColumn();
echo "✅ Таблица '$table': $result записей<br>";
} catch (Exception $e) {
echo "❌ Таблица '$table': НЕ СУЩЕСТВУЕТ<br>";
}
}
echo "<h2>Содержимое таблиц:</h2>";
// Показать категории
echo "<h3>Категории:</h3>";
try {
$categories = $db->query("SELECT * FROM categories")->fetchAll();
if (empty($categories)) {
echo "Категорий нет!<br>";
} else {
echo "<table border='1'><tr><th>ID</th><th>Название</th><th>Slug</th><th>Родитель</th></tr>";
foreach ($categories as $cat) {
echo "<tr><td>{$cat['category_id']}</td><td>{$cat['name']}</td><td>{$cat['slug']}</td><td>{$cat['parent_id']}</td></tr>";
}
echo "</table>";
}
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
}
// Показать товары
echo "<h3>Товары:</h3>";
try {
$products = $db->query("SELECT * FROM products")->fetchAll();
if (empty($products)) {
echo "Товаров нет!<br>";
} else {
echo "<table border='1'><tr><th>ID</th><th>Название</th><th>Цена</th><th>Категория</th><th>Статус</th></tr>";
foreach ($products as $product) {
echo "<tr><td>{$product['product_id']}</td><td>{$product['name']}</td><td>{$product['price']}</td><td>{$product['category_id']}</td><td>" . ($product['is_available'] ? 'Активен' : 'Неактивен') . "</td></tr>";
}
echo "</table>";
}
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
}
?>

View File

@@ -1,69 +0,0 @@
<?php
// fix_categories.php
require_once 'config/database.php';
$db = Database::getInstance()->getConnection();
echo "<h2>Исправление проблем с категориями</h2>";
try {
// 1. Удаляем категорию с ID=0 если она есть
$db->exec("DELETE FROM categories WHERE category_id = 0");
// 2. Проверяем, есть ли категории
$catCount = $db->query("SELECT COUNT(*) FROM categories")->fetchColumn();
if ($catCount == 0) {
echo "<p>Добавляем основные категории...</p>";
$db->exec("
INSERT INTO categories (name, slug, description, is_active) VALUES
('Диваны', 'divany', 'Мягкая мебель для гостиной', TRUE),
('Кресла', 'kresla', 'Кресла для гостиной и офиса', TRUE),
('Кровати', 'krovati', 'Мебель для спальни', TRUE),
('Столы', 'stoly', 'Обеденные и рабочие столы', TRUE),
('Стулья', 'stulya', 'Стулья для кухни и офиса', TRUE)
");
echo "<p style='color: green;'>✓ Категории добавлены</p>";
}
// 3. Исправляем товары с category_id = 0 или NULL
$badProducts = $db->query("
SELECT COUNT(*) FROM products
WHERE category_id IS NULL OR category_id = 0 OR
category_id NOT IN (SELECT category_id FROM categories)
")->fetchColumn();
if ($badProducts > 0) {
echo "<p>Исправляем товары с некорректными категориями ($badProducts шт)...</p>";
// Получаем первую категорию
$firstCat = $db->query("SELECT category_id FROM categories LIMIT 1")->fetchColumn();
if ($firstCat) {
$db->exec("
UPDATE products
SET category_id = $firstCat
WHERE category_id IS NULL OR category_id = 0 OR
category_id NOT IN (SELECT category_id FROM categories)
");
echo "<p style='color: green;'>✓ Товары исправлены (category_id установлен в $firstCat)</p>";
}
}
// 4. Показываем текущее состояние
echo "<h3>Текущие категории:</h3>";
$cats = $db->query("SELECT category_id, name FROM categories ORDER BY category_id")->fetchAll();
echo "<table border='1' cellpadding='5'>";
echo "<tr><th>ID</th><th>Название</th></tr>";
foreach ($cats as $cat) {
echo "<tr><td>{$cat['category_id']}</td><td>{$cat['name']}</td></tr>";
}
echo "</table>";
echo "<p style='color: green; margin-top: 20px;'>✓ База данных исправлена!</p>";
} catch (PDOException $e) {
echo "<p style='color: red;'>Ошибка: " . $e->getMessage() . "</p>";
}
?>

View File

@@ -1,89 +0,0 @@
<?php
// fix_database.php
require_once 'config/database.php';
$db = Database::getInstance()->getConnection();
echo "<h2>Исправление проблем с базой данных</h2>";
try {
// 1. Проверяем есть ли категории
$stmt = $db->query("SELECT COUNT(*) FROM categories");
$cat_count = $stmt->fetchColumn();
if ($cat_count == 0) {
echo "<p>Добавляем тестовые категории...</p>";
$db->exec("
INSERT INTO categories (name, slug, description) VALUES
('Диваны', 'divany', 'Мягкая мебель для гостиной'),
('Кресла', 'kresla', 'Кресла для гостиной и офиса'),
('Кровати', 'krovati', 'Мебель для спальни')
");
echo "<p style='color: green;'>✓ Категории добавлены</p>";
}
// 2. Проверяем товары с некорректными category_id
$stmt = $db->query("
SELECT COUNT(*) as bad_count
FROM products
WHERE category_id IS NULL OR category_id NOT IN (SELECT category_id FROM categories)
");
$bad_count = $stmt->fetchColumn();
if ($bad_count > 0) {
echo "<p>Исправляем товары с некорректными категориями ($bad_count шт)...</p>";
// Устанавливаем первую доступную категорию
$stmt = $db->query("SELECT category_id FROM categories LIMIT 1");
$first_cat = $stmt->fetchColumn();
if ($first_cat) {
$db->exec("
UPDATE products
SET category_id = $first_cat
WHERE category_id IS NULL OR category_id NOT IN (SELECT category_id FROM categories)
");
echo "<p style='color: green;'>✓ Товары исправлены (установлена категория ID: $first_cat)</p>";
}
}
// 3. Показываем текущее состояние
echo "<h3>Текущее состояние:</h3>";
// Категории
$stmt = $db->query("SELECT category_id, name FROM categories ORDER BY category_id");
echo "<p><strong>Категории:</strong></p><ul>";
while ($row = $stmt->fetch()) {
echo "<li>ID: {$row['category_id']} - {$row['name']}</li>";
}
echo "</ul>";
// Товары
$stmt = $db->query("
SELECT p.product_id, p.name, p.category_id, c.name as cat_name
FROM products p
LEFT JOIN categories c ON p.category_id = c.category_id
ORDER BY p.product_id
");
echo "<p><strong>Товары:</strong></p>";
echo "<table border='1' cellpadding='5'>";
echo "<tr><th>ID</th><th>Название</th><th>Категория ID</th><th>Категория</th></tr>";
while ($row = $stmt->fetch()) {
echo "<tr>";
echo "<td>{$row['product_id']}</td>";
echo "<td>" . htmlspecialchars($row['name']) . "</td>";
echo "<td>" . ($row['category_id'] ?: 'NULL') . "</td>";
echo "<td>" . ($row['cat_name'] ?: 'Без категории') . "</td>";
echo "</tr>";
}
echo "</table>";
echo "<p style='color: green; margin-top: 20px;'>✓ База данных исправлена!</p>";
} catch (PDOException $e) {
echo "<p style='color: red;'>Ошибка: " . $e->getMessage() . "</p>";
}
?>

View File

@@ -1,142 +0,0 @@
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$isLoggedIn = isset($_SESSION['isLoggedIn']) && $_SESSION['isLoggedIn'] === true;
$isAdmin = isset($_SESSION['isAdmin']) && $_SESSION['isAdmin'] === true;
$userEmail = $_SESSION['user_email'] ?? '';
$fullName = $_SESSION['full_name'] ?? $userEmail;
?>
<!-- Стандартный header для всех страниц -->
<header class="header">
<div class="header__top">
<div class="container header__top-content">
<div class="logo">AETERNA</div>
<div class="search-catalog">
<div class="catalog-dropdown">
Все категории <span>&#9660;</span>
<div class="catalog-dropdown__menu">
<ul>
<li><a href="catalog.php">Все товары</a></li>
<li><a href="catalog.php?category=1">Мягкая мебель</a></li>
<li><a href="catalog.php?category=2">Диваны</a></li>
<li><a href="catalog.php?category=3">Кресла</a></li>
<li><a href="catalog.php?category=4">Спальня</a></li>
<li><a href="catalog.php?category=5">Кровати</a></li>
</ul>
</div>
</div>
<div class="search-box">
<input type="text" placeholder="Поиск товаров" id="searchInput">
<span class="search-icon"><i class="fas fa-search"></i></span>
</div>
</div>
<div class="header__icons--top">
<?php if ($isLoggedIn): ?>
<!-- Иконка корзины -->
<a href="оформлениеаказа.php" class="icon cart-icon">
<i class="fas fa-shopping-cart"></i>
<span class="cart-count">0</span>
</a>
<!-- Блок профиля -->
<div class="user-profile-dropdown">
<div class="user-profile-toggle">
<div class="user-avatar">
<?= !empty($userEmail) ? strtoupper(substr($userEmail, 0, 1)) : 'U' ?>
</div>
<div class="user-info">
<div class="user-email"><?= htmlspecialchars($userEmail) ?></div>
<div class="user-status <?= $isAdmin ? 'admin' : 'user' ?>">
<?= $isAdmin ? 'Админ' : 'Пользователь' ?>
</div>
</div>
<i class="fas fa-chevron-down dropdown-arrow"></i>
</div>
<div class="user-profile-menu">
<div class="user-profile-header">
<div class="user-profile-name">
<i class="fas fa-user"></i> <?= htmlspecialchars($fullName) ?>
</div>
<div class="user-profile-details">
<small><i class="far fa-envelope"></i> <?= htmlspecialchars($userEmail) ?></small>
<?php if (isset($_SESSION['login_time'])): ?>
<small><i class="far fa-clock"></i> Вошел: <?= date('d.m.Y H:i', $_SESSION['login_time']) ?></small>
<?php endif; ?>
</div>
</div>
<ul class="user-profile-links">
<li>
<a href="профиль.php">
<i class="fas fa-user-cog"></i>
<span>Настройки профиля</span>
</a>
</li>
<li>
<a href="оформлениеаказа.php">
<i class="fas fa-shopping-bag"></i>
<span>Мои заказы</span>
</a>
</li>
<?php if ($isAdmin): ?>
<li>
<a href="admin_panel.php">
<i class="fas fa-user-shield"></i>
<span>Панель администратора</span>
</a>
</li>
<?php endif; ?>
<li class="logout-item">
<a href="logout.php" class="logout-link">
<i class="fas fa-sign-out-alt"></i>
<span>Выйти из аккаунта</span>
</a>
</li>
</ul>
</div>
</div>
<?php else: ?>
<!-- Если не авторизован -->
<a href="вход.php" class="icon">
<i class="far fa-user"></i>
</a>
<a href="вход.php" style="font-size: 12px; color: #666; margin-left: 5px;">
Войти
</a>
<?php endif; ?>
</div>
</div>
</div>
<div class="header__bottom">
<div class="container header__bottom-content">
<div class="catalog-menu">
<a href="catalog.php" class="catalog-link">
<div class="catalog-icon">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
</div>
<span class="catalog-lines">☰</span>
Каталог
</a>
</div>
<nav class="nav">
<ul class="nav-list">
<li><a href="cite_mebel.php">Главная</a></li>
<li><a href="услуги.php">Услуги</a></li>
<li><a href="Доставка.php">Доставка и оплата</a></li>
<li><a href="Гарантия.php">Гарантия</a></li>
<li><a href="#footer">Контакты</a></li>
</ul>
</nav>
<div class="header-phone">+7(912)999-12-23</div>
</div>
</div>
</header>

Some files were not shown because too many files have changed in this diff Show More