This commit is contained in:
kirill.khorkov
2025-12-17 01:24:01 +03:00
parent fe288b3caf
commit f4f57bd153
18 changed files with 4 additions and 115 deletions

View File

@@ -1,13 +1,10 @@
FROM php:8.2-apache FROM php:8.2-apache
# Установка PostgreSQL драйвера
RUN apt-get update && apt-get install -y libpq-dev \ RUN apt-get update && apt-get install -y libpq-dev \
&& docker-php-ext-install pdo pdo_pgsql \ && docker-php-ext-install pdo pdo_pgsql \
&& apt-get clean && rm -rf /var/lib/apt/lists/* && apt-get clean && rm -rf /var/lib/apt/lists/*
# Включить модули Apache
RUN a2enmod rewrite headers alias RUN a2enmod rewrite headers alias
# Установка рабочей директории
WORKDIR /var/www/html WORKDIR /var/www/html

View File

@@ -25,4 +25,3 @@ services:
networks: networks:
cite_practica_network: cite_practica_network:
driver: bridge driver: bridge

View File

@@ -1,16 +1,12 @@
#!/bin/bash #!/bin/bash
set -e set -e
# Включаем модули Apache
a2enmod rewrite a2enmod rewrite
a2enmod headers a2enmod headers
# Добавляем admin в hosts
echo "127.0.0.1 admin" >> /etc/hosts echo "127.0.0.1 admin" >> /etc/hosts
# Активируем виртуальный хост
a2ensite 000-default a2ensite 000-default
# Запускаем Apache
exec apache2-foreground exec apache2-foreground

View File

@@ -2,8 +2,6 @@
ServerName admin ServerName admin
ServerAlias localhost ServerAlias localhost
DocumentRoot /var/www/html DocumentRoot /var/www/html
# Alias для пути /cite_practica/
Alias /cite_practica /var/www/html/cite_practica Alias /cite_practica /var/www/html/cite_practica
<Directory /var/www/html> <Directory /var/www/html>
@@ -19,13 +17,10 @@
DirectoryIndex cite_mebel.php index.php index.html DirectoryIndex cite_mebel.php index.php index.html
</Directory> </Directory>
# Настройка PHP
<FilesMatch \.php$> <FilesMatch \.php$>
SetHandler application/x-httpd-php SetHandler application/x-httpd-php
</FilesMatch> </FilesMatch>
# Логи
ErrorLog ${APACHE_LOG_DIR}/cite_practica_error.log ErrorLog ${APACHE_LOG_DIR}/cite_practica_error.log
CustomLog ${APACHE_LOG_DIR}/cite_practica_access.log combined CustomLog ${APACHE_LOG_DIR}/cite_practica_access.log combined
</VirtualHost> </VirtualHost>

View File

@@ -1,7 +1,3 @@
-- 001_initial_schema.sql
-- Создание базовых таблиц для AETERNA
-- Таблица пользователей
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS users (
user_id SERIAL PRIMARY KEY, user_id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL, email VARCHAR(255) UNIQUE NOT NULL,
@@ -16,7 +12,6 @@ CREATE TABLE IF NOT EXISTS users (
is_admin BOOLEAN DEFAULT FALSE is_admin BOOLEAN DEFAULT FALSE
); );
-- Таблица категорий
CREATE TABLE IF NOT EXISTS categories ( CREATE TABLE IF NOT EXISTS categories (
category_id SERIAL PRIMARY KEY, category_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL, name VARCHAR(100) NOT NULL,
@@ -29,7 +24,6 @@ CREATE TABLE IF NOT EXISTS categories (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
-- Таблица подкатегорий
CREATE TABLE IF NOT EXISTS subcategories ( CREATE TABLE IF NOT EXISTS subcategories (
subcategory_id SERIAL PRIMARY KEY, subcategory_id SERIAL PRIMARY KEY,
category_id INTEGER REFERENCES categories(category_id) ON DELETE CASCADE, category_id INTEGER REFERENCES categories(category_id) ON DELETE CASCADE,
@@ -41,7 +35,6 @@ CREATE TABLE IF NOT EXISTS subcategories (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
-- Таблица товаров
CREATE TABLE IF NOT EXISTS products ( CREATE TABLE IF NOT EXISTS products (
product_id SERIAL PRIMARY KEY, product_id SERIAL PRIMARY KEY,
category_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL, category_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL,
@@ -64,10 +57,8 @@ CREATE TABLE IF NOT EXISTS products (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
-- Индексы для быстрого поиска
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id); CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id);
CREATE INDEX IF NOT EXISTS idx_products_available ON products(is_available); CREATE INDEX IF NOT EXISTS idx_products_available ON products(is_available);
CREATE INDEX IF NOT EXISTS idx_products_price ON products(price); CREATE INDEX IF NOT EXISTS idx_products_price ON products(price);
CREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id); CREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id);
CREATE INDEX IF NOT EXISTS idx_categories_active ON categories(is_active); CREATE INDEX IF NOT EXISTS idx_categories_active ON categories(is_active);

View File

@@ -1,7 +1,3 @@
-- 002_add_cart_orders.sql
-- Таблицы для корзины и заказов
-- Таблица корзины
CREATE TABLE IF NOT EXISTS cart ( CREATE TABLE IF NOT EXISTS cart (
cart_id SERIAL PRIMARY KEY, cart_id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE, user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE,
@@ -12,36 +8,23 @@ CREATE TABLE IF NOT EXISTS cart (
UNIQUE(user_id, product_id) UNIQUE(user_id, product_id)
); );
-- Таблица заказов
CREATE TABLE IF NOT EXISTS orders ( CREATE TABLE IF NOT EXISTS orders (
order_id SERIAL PRIMARY KEY, order_id SERIAL PRIMARY KEY,
order_number VARCHAR(50) UNIQUE NOT NULL, order_number VARCHAR(50) UNIQUE NOT NULL,
user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL, user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
-- Контактная информация
customer_name VARCHAR(100) NOT NULL, customer_name VARCHAR(100) NOT NULL,
customer_email VARCHAR(255) NOT NULL, customer_email VARCHAR(255) NOT NULL,
customer_phone VARCHAR(20) NOT NULL, customer_phone VARCHAR(20) NOT NULL,
-- Адрес доставки
delivery_address TEXT NOT NULL, delivery_address TEXT NOT NULL,
delivery_region VARCHAR(100), delivery_region VARCHAR(100),
postal_code VARCHAR(20), postal_code VARCHAR(20),
-- Способы
delivery_method VARCHAR(50) DEFAULT 'courier', delivery_method VARCHAR(50) DEFAULT 'courier',
payment_method VARCHAR(50) DEFAULT 'card', payment_method VARCHAR(50) DEFAULT 'card',
-- Суммы
subtotal DECIMAL(10, 2) NOT NULL, subtotal DECIMAL(10, 2) NOT NULL,
discount_amount DECIMAL(10, 2) DEFAULT 0, discount_amount DECIMAL(10, 2) DEFAULT 0,
delivery_price DECIMAL(10, 2) DEFAULT 0, delivery_price DECIMAL(10, 2) DEFAULT 0,
final_amount DECIMAL(10, 2) NOT NULL, final_amount DECIMAL(10, 2) NOT NULL,
-- Промокод
promo_code VARCHAR(50), promo_code VARCHAR(50),
-- Статус и даты
status VARCHAR(30) DEFAULT 'pending', status VARCHAR(30) DEFAULT 'pending',
notes TEXT, notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
@@ -49,7 +32,6 @@ CREATE TABLE IF NOT EXISTS orders (
completed_at TIMESTAMP completed_at TIMESTAMP
); );
-- Таблица позиций заказа
CREATE TABLE IF NOT EXISTS order_items ( CREATE TABLE IF NOT EXISTS order_items (
item_id SERIAL PRIMARY KEY, item_id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES orders(order_id) ON DELETE CASCADE, order_id INTEGER REFERENCES orders(order_id) ON DELETE CASCADE,
@@ -61,10 +43,8 @@ CREATE TABLE IF NOT EXISTS order_items (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
-- Индексы
CREATE INDEX IF NOT EXISTS idx_cart_user ON cart(user_id); CREATE INDEX IF NOT EXISTS idx_cart_user ON cart(user_id);
CREATE INDEX IF NOT EXISTS idx_orders_user ON orders(user_id); CREATE INDEX IF NOT EXISTS idx_orders_user ON orders(user_id);
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status); CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
CREATE INDEX IF NOT EXISTS idx_orders_created ON orders(created_at); CREATE INDEX IF NOT EXISTS idx_orders_created ON orders(created_at);
CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id); CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id);

View File

@@ -1,57 +1,43 @@
-- 003_add_product_fields.sql
-- Добавление дополнительных полей (если таблицы уже существуют)
-- Добавляем поля в products если их нет
DO $$ DO $$
BEGIN BEGIN
-- color
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'products' AND column_name = 'color') THEN WHERE table_name = 'products' AND column_name = 'color') THEN
ALTER TABLE products ADD COLUMN color VARCHAR(50); ALTER TABLE products ADD COLUMN color VARCHAR(50);
END IF; END IF;
-- material
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'products' AND column_name = 'material') THEN WHERE table_name = 'products' AND column_name = 'material') THEN
ALTER TABLE products ADD COLUMN material VARCHAR(100); ALTER TABLE products ADD COLUMN material VARCHAR(100);
END IF; END IF;
-- card_size
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'products' AND column_name = 'card_size') THEN WHERE table_name = 'products' AND column_name = 'card_size') THEN
ALTER TABLE products ADD COLUMN card_size VARCHAR(20) DEFAULT 'small'; ALTER TABLE products ADD COLUMN card_size VARCHAR(20) DEFAULT 'small';
END IF; END IF;
END $$; END $$;
-- Добавляем поля в users если их нет
DO $$ DO $$
BEGIN BEGIN
-- city
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'users' AND column_name = 'city') THEN WHERE table_name = 'users' AND column_name = 'city') THEN
ALTER TABLE users ADD COLUMN city VARCHAR(100); ALTER TABLE users ADD COLUMN city VARCHAR(100);
END IF; END IF;
-- last_login
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'users' AND column_name = 'last_login') THEN WHERE table_name = 'users' AND column_name = 'last_login') THEN
ALTER TABLE users ADD COLUMN last_login TIMESTAMP; ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
END IF; END IF;
END $$; END $$;
-- Добавляем поля в categories если их нет
DO $$ DO $$
BEGIN BEGIN
-- updated_at
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'categories' AND column_name = 'updated_at') THEN WHERE table_name = 'categories' AND column_name = 'updated_at') THEN
ALTER TABLE categories ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP; ALTER TABLE categories ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
END IF; END IF;
-- created_at
IF NOT EXISTS (SELECT 1 FROM information_schema.columns IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'categories' AND column_name = 'created_at') THEN WHERE table_name = 'categories' AND column_name = 'created_at') THEN
ALTER TABLE categories ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP; ALTER TABLE categories ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
END IF; END IF;
END $$; END $$;

View File

@@ -1,14 +1,9 @@
-- 004_grant_admin_to_admin_mail.sql
-- Миграция: Назначение прав администратора пользователю admin@mail.ru
-- Обновляем пользователя admin@mail.ru, давая ему права администратора
UPDATE users UPDATE users
SET is_admin = TRUE, SET is_admin = TRUE,
is_active = TRUE, is_active = TRUE,
updated_at = CURRENT_TIMESTAMP updated_at = CURRENT_TIMESTAMP
WHERE email = 'admin@mail.ru'; WHERE email = 'admin@mail.ru';
-- Проверяем результат
DO $$ DO $$
DECLARE DECLARE
updated_count INTEGER; updated_count INTEGER;
@@ -17,7 +12,6 @@ BEGIN
GET DIAGNOSTICS updated_count = ROW_COUNT; GET DIAGNOSTICS updated_count = ROW_COUNT;
IF updated_count > 0 THEN IF updated_count > 0 THEN
-- Получаем информацию об обновленном пользователе
SELECT user_id, email, full_name, is_admin, is_active SELECT user_id, email, full_name, is_admin, is_active
INTO user_info INTO user_info
FROM users FROM users
@@ -28,11 +22,10 @@ BEGIN
RAISE NOTICE 'ФИО: %, Админ: %, Активен: %', RAISE NOTICE 'ФИО: %, Админ: %, Активен: %',
user_info.full_name, user_info.is_admin, user_info.is_active; user_info.full_name, user_info.is_admin, user_info.is_active;
ELSE ELSE
-- Если пользователь не найден, создаем его с правами админа
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active) INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
VALUES ( VALUES (
'admin@mail.ru', 'admin@mail.ru',
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123 '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'Администратор', 'Администратор',
'+79129991223', '+79129991223',
'Москва', 'Москва',
@@ -47,4 +40,3 @@ BEGIN
RAISE NOTICE 'Пользователь admin@mail.ru создан/обновлен с правами администратора'; RAISE NOTICE 'Пользователь admin@mail.ru создан/обновлен с правами администратора';
END IF; END IF;
END $$; END $$;

View File

@@ -1,11 +1,7 @@
-- seed_data.sql
-- Начальные данные для AETERNA
-- Администратор (пароль: admin123)
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active) INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
VALUES ( VALUES (
'admin@aeterna.ru', 'admin@aeterna.ru',
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123 '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'Администратор AETERNA', 'Администратор AETERNA',
'+79129991223', '+79129991223',
'Москва', 'Москва',
@@ -13,11 +9,10 @@ VALUES (
TRUE TRUE
) ON CONFLICT (email) DO NOTHING; ) ON CONFLICT (email) DO NOTHING;
-- Тестовый пользователь (пароль: user123)
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active) INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
VALUES ( VALUES (
'user@test.com', 'user@test.com',
'$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', -- user123 '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm',
'Тестовый Пользователь', 'Тестовый Пользователь',
'+79111234567', '+79111234567',
'Санкт-Петербург', 'Санкт-Петербург',
@@ -25,7 +20,6 @@ VALUES (
TRUE TRUE
) ON CONFLICT (email) DO NOTHING; ) ON CONFLICT (email) DO NOTHING;
-- Категории
INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
('Диваны', 'divany', 'Прямые и угловые диваны для гостиной', 1, TRUE), ('Диваны', 'divany', 'Прямые и угловые диваны для гостиной', 1, TRUE),
('Кресла', 'kresla', 'Кресла для гостиной и офиса', 2, TRUE), ('Кресла', 'kresla', 'Кресла для гостиной и офиса', 2, TRUE),
@@ -35,7 +29,6 @@ INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
('Светильники', 'svetilniki', 'Торшеры, люстры и настольные лампы', 6, TRUE) ('Светильники', 'svetilniki', 'Торшеры, люстры и настольные лампы', 6, TRUE)
ON CONFLICT (slug) DO NOTHING; ON CONFLICT (slug) DO NOTHING;
-- Товары
INSERT INTO products (category_id, name, slug, description, price, old_price, sku, stock_quantity, is_available, image_url, color, material, card_size) VALUES INSERT INTO products (category_id, name, slug, description, price, old_price, sku, stock_quantity, is_available, image_url, color, material, card_size) VALUES
(1, 'Светильник MINNIGHT', 'svetilnik-minnight', 'Настольный светильник в современном стиле', 7999, 9999, 'LAMP-MIN-001', 15, TRUE, 'img2/1_2.png', 'Черный', 'Металл', 'small'), (1, 'Светильник MINNIGHT', 'svetilnik-minnight', 'Настольный светильник в современном стиле', 7999, 9999, 'LAMP-MIN-001', 15, TRUE, 'img2/1_2.png', 'Черный', 'Металл', 'small'),
(3, 'Кровать MODER', 'krovat-moder', 'Двуспальная кровать с мягким изголовьем', 45999, 55999, 'BED-MOD-001', 5, TRUE, 'img2/3_3.png', 'Серый', 'Дерево/Ткань', 'large'), (3, 'Кровать MODER', 'krovat-moder', 'Двуспальная кровать с мягким изголовьем', 45999, 55999, 'BED-MOD-001', 5, TRUE, 'img2/3_3.png', 'Серый', 'Дерево/Ткань', 'large'),
@@ -48,7 +41,6 @@ INSERT INTO products (category_id, name, slug, description, price, old_price, sk
(1, 'Диван HEMMINS', 'divan-hemmins', 'Большой модульный диван для всей семьи', 89999, 110000, 'SOFA-HEM-001', 2, TRUE, 'img2/9_9.png', 'Темно-серый', 'Ткань', 'full-width') (1, 'Диван HEMMINS', 'divan-hemmins', 'Большой модульный диван для всей семьи', 89999, 110000, 'SOFA-HEM-001', 2, TRUE, 'img2/9_9.png', 'Темно-серый', 'Ткань', 'full-width')
ON CONFLICT (slug) DO NOTHING; ON CONFLICT (slug) DO NOTHING;
-- Выводим статистику
DO $$ DO $$
DECLARE DECLARE
users_count INTEGER; users_count INTEGER;
@@ -62,4 +54,3 @@ BEGIN
RAISE NOTICE 'Загружено: % пользователей, % категорий, % товаров', RAISE NOTICE 'Загружено: % пользователей, % категорий, % товаров',
users_count, categories_count, products_count; users_count, categories_count, products_count;
END $$; END $$;

View File

@@ -4,7 +4,6 @@ header('Content-Type: application/json; charset=utf-8');
session_start(); session_start();
require_once __DIR__ . '/../config/database.php'; require_once __DIR__ . '/../config/database.php';
// Проверка прав администратора
if (!isset($_SESSION['isAdmin']) || !$_SESSION['isAdmin']) { if (!isset($_SESSION['isAdmin']) || !$_SESSION['isAdmin']) {
echo json_encode(['success' => false, 'message' => 'Доступ запрещен']); echo json_encode(['success' => false, 'message' => 'Доступ запрещен']);
exit(); exit();
@@ -21,7 +20,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try { try {
$db = Database::getInstance()->getConnection(); $db = Database::getInstance()->getConnection();
// Проверяем, есть ли товары в этой категории
$checkStmt = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ?"); $checkStmt = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ?");
$checkStmt->execute([$categoryId]); $checkStmt->execute([$categoryId]);
$productCount = $checkStmt->fetchColumn(); $productCount = $checkStmt->fetchColumn();
@@ -31,7 +29,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit(); exit();
} }
// Удаляем категорию
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?"); $stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$categoryId]); $stmt->execute([$categoryId]);

View File

@@ -150,7 +150,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$material = trim($_POST['material'] ?? ''); $material = trim($_POST['material'] ?? '');
if ($category_id <= 0) { if ($category_id <= 0) {
$firstCat = $db->query("SELECT category_id FROM categories LIMIT 1")->fetchColumn(); $firstCat = $db->query("SELECT category_id FROM categories LIMIT 1")->fetchColumn();
$category_id = $firstCat ?: 1; $category_id = $firstCat ?: 1;
} }
@@ -192,24 +191,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$childCount = $checkChildren->fetchColumn(); $childCount = $checkChildren->fetchColumn();
if ($productCount > 0) { if ($productCount > 0) {
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?"); $stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
$stmt->execute([$categoryId]); $stmt->execute([$categoryId]);
header('Location: index.php?action=categories&message=Категория+скрыта+(содержит+товары)'); header('Location: index.php?action=categories&message=Категория+скрыта+(содержит+товары)');
exit(); exit();
} elseif ($childCount > 0) { } elseif ($childCount > 0) {
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?"); $stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
$stmt->execute([$categoryId]); $stmt->execute([$categoryId]);
header('Location: index.php?action=categories&message=Категория+скрыта+(имеет+дочерние+категории)'); header('Location: index.php?action=categories&message=Категория+скрыта+(имеет+дочерние+категории)');
exit(); exit();
} else { } else {
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?"); $stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
$stmt->execute([$categoryId]); $stmt->execute([$categoryId]);
header('Location: index.php?action=categories&message=Категория+удалена'); header('Location: index.php?action=categories&message=Категория+удалена');
exit(); exit();
} }
@@ -224,7 +217,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} }
try { try {
$stats = [ $stats = [
'total_products' => $db->query("SELECT COUNT(*) FROM products")->fetchColumn(), 'total_products' => $db->query("SELECT COUNT(*) FROM products")->fetchColumn(),
'active_products' => $db->query("SELECT COUNT(*) FROM products WHERE is_available = TRUE")->fetchColumn(), 'active_products' => $db->query("SELECT COUNT(*) FROM products WHERE is_available = TRUE")->fetchColumn(),
@@ -502,13 +494,11 @@ try {
<td><?= htmlspecialchars($category['name']) ?></td> <td><?= htmlspecialchars($category['name']) ?></td>
<td><?= htmlspecialchars($category['slug']) ?></td> <td><?= htmlspecialchars($category['slug']) ?></td>
<td><?= htmlspecialchars($category['parent_name'] ?? '—') ?></td> <td><?= htmlspecialchars($category['parent_name'] ?? '—') ?></td>
<td><?= $category['product_count'] ?></td> <td><?= $category['product_count'] ?> </td>
<td class="action-buttons"> <td class="action-buttons">
<a href="index.php?action=edit_category&id=<?= $category['category_id'] ?>" class="btn btn-warning btn-sm"> <a href="index.php?action=edit_category&id=<?= $category['category_id'] ?>" class="btn btn-warning btn-sm">
<i class="fas fa-edit"></i> Редактировать <i class="fas fa-edit"></i> Редактировать
</a> </a>
<button type="button" class="btn btn-danger btn-sm delete-category-btn" <button type="button" class="btn btn-danger btn-sm delete-category-btn"
data-id="<?= $category['category_id'] ?>" data-id="<?= $category['category_id'] ?>"
<?= $category['product_count'] > 0 ? 'disabled' : '' ?>> <?= $category['product_count'] > 0 ? 'disabled' : '' ?>>
@@ -752,7 +742,6 @@ try {
<?php endif; ?> <?php endif; ?>
</div> </div>
<script> <script>
$('.delete-category-btn').click(function() { $('.delete-category-btn').click(function() {
const categoryId = $(this).data('id'); const categoryId = $(this).data('id');
const btn = $(this); const btn = $(this);

View File

@@ -1,6 +1,4 @@
$(document).ready(function() { $(document).ready(function() {
let cart = { let cart = {
items: [ items: [
{ id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 }, { id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 },
@@ -44,9 +42,7 @@ $(document).ready(function() {
} }
function validateFullName(name) { function validateFullName(name) {
const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/; const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/;
const words = name.trim().split(/\s+/); const words = name.trim().split(/\s+/);
return nameRegex.test(name) && words.length >= 2; return nameRegex.test(name) && words.length >= 2;

View File

@@ -1,6 +1,3 @@
// ===================================
// === ПЕРЕМЕННЫЕ И МИКСИНЫ AETERNA ===
// ===================================
@color-primary: #617365; @color-primary: #617365;
@color-secondary: #D1D1D1; @color-secondary: #D1D1D1;
@color-accent: #453227; @color-accent: #453227;

View File

@@ -1,7 +1,4 @@
@import "mixins.less"; @import "mixins.less";
// =======================
// === БАЗОВЫЕ СТИЛИ ===
// =======================
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;

View File

@@ -1,6 +1,3 @@
// ===================================
// === ПЕРЕМЕННЫЕ И МИКСИНЫ AETERNA ===
// ===================================
@color-primary: #617365; @color-primary: #617365;
@color-secondary: #D1D1D1; @color-secondary: #D1D1D1;
@color-accent: #453227; @color-accent: #453227;

View File

@@ -47,7 +47,6 @@ try {
$similarStmt->execute([$product['category_id'], $product_id]); $similarStmt->execute([$product['category_id'], $product_id]);
$similarProducts = $similarStmt->fetchAll(); $similarProducts = $similarStmt->fetchAll();
// Отзывы временно отключены (таблица reviews не существует)
$reviews = []; $reviews = [];
} catch (PDOException $e) { } catch (PDOException $e) {
@@ -459,7 +458,6 @@ $(document).ready(function() {
window.deleteProduct = function(productId) { window.deleteProduct = function(productId) {
if (confirm('Вы уверены, что хотите удалить этот товар?')) { if (confirm('Вы уверены, что хотите удалить этот товар?')) {
// Redirect to admin panel for deletion
window.location.href = 'admin/index.php?action=products'; window.location.href = 'admin/index.php?action=products';
} }
}; };

View File

@@ -11,7 +11,6 @@ if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
$user_id = $_SESSION['user_id'] ?? 0; $user_id = $_SESSION['user_id'] ?? 0;
$db = Database::getInstance()->getConnection(); $db = Database::getInstance()->getConnection();
// Загружаем данные пользователя
$user = null; $user = null;
try { try {
$stmt = $db->prepare("SELECT user_id, email, full_name, phone, city FROM users WHERE user_id = ?"); $stmt = $db->prepare("SELECT user_id, email, full_name, phone, city FROM users WHERE user_id = ?");
@@ -31,7 +30,6 @@ $update_success = $_SESSION['update_success'] ?? '';
unset($_SESSION['update_errors']); unset($_SESSION['update_errors']);
unset($_SESSION['update_success']); unset($_SESSION['update_success']);
// Обработка обновления профиля
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$full_name = trim($_POST['fio'] ?? ''); $full_name = trim($_POST['fio'] ?? '');
$city = trim($_POST['city'] ?? ''); $city = trim($_POST['city'] ?? '');

View File

@@ -1,8 +1,5 @@
@import "mixins.less"; @import "mixins.less";
@import "стили_оформления.less"; @import "стили_оформления.less";
// =======================
// === БАЗОВЫЕ СТИЛИ ===
// =======================
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@@ -52,10 +49,6 @@ p, li, span {
font-family: @font-main; font-family: @font-main;
} }
// =======================
// === КОМПОНЕНТЫ ===
// =======================
.logo, .footer-logo { .logo, .footer-logo {
font: bold 32px/1 @font-logo; font: bold 32px/1 @font-logo;
letter-spacing: 2px; letter-spacing: 2px;