130 lines
3.4 KiB
PHP
130 lines
3.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../db/config.php';
|
|
|
|
@date_default_timezone_set('UTC');
|
|
if (session_status() !== PHP_SESSION_ACTIVE) {
|
|
session_start();
|
|
}
|
|
|
|
function h(string $value): string
|
|
{
|
|
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
|
}
|
|
|
|
function ensure_tables(): void
|
|
{
|
|
$pdo = db();
|
|
$pdo->exec(
|
|
"CREATE TABLE IF NOT EXISTS stores (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(150) NOT NULL,
|
|
slug VARCHAR(150) NOT NULL,
|
|
contact_email VARCHAR(190) DEFAULT NULL,
|
|
currency CHAR(3) NOT NULL DEFAULT 'USD',
|
|
created_at DATETIME NOT NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
|
|
);
|
|
|
|
$pdo->exec(
|
|
"CREATE TABLE IF NOT EXISTS products (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
store_id INT NOT NULL,
|
|
sku VARCHAR(64) NOT NULL,
|
|
name VARCHAR(180) NOT NULL,
|
|
price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
stock INT NOT NULL DEFAULT 0,
|
|
status VARCHAR(24) NOT NULL DEFAULT 'active',
|
|
created_at DATETIME NOT NULL,
|
|
INDEX (store_id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
|
|
);
|
|
}
|
|
|
|
function slugify(string $value): string
|
|
{
|
|
$slug = strtolower(trim($value));
|
|
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug) ?? '';
|
|
$slug = trim($slug, '-');
|
|
return $slug !== '' ? $slug : 'store';
|
|
}
|
|
|
|
function flash_set(string $type, string $message): void
|
|
{
|
|
$_SESSION['flash'] = ['type' => $type, 'message' => $message];
|
|
}
|
|
|
|
function flash_get(): ?array
|
|
{
|
|
if (empty($_SESSION['flash'])) {
|
|
return null;
|
|
}
|
|
$flash = $_SESSION['flash'];
|
|
unset($_SESSION['flash']);
|
|
return $flash;
|
|
}
|
|
|
|
function get_stores(): array
|
|
{
|
|
$stmt = db()->query(
|
|
"SELECT s.*, COUNT(p.id) AS product_count
|
|
FROM stores s
|
|
LEFT JOIN products p ON p.store_id = s.id
|
|
GROUP BY s.id
|
|
ORDER BY s.created_at DESC"
|
|
);
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
function get_store(int $id): ?array
|
|
{
|
|
$stmt = db()->prepare("SELECT * FROM stores WHERE id = :id LIMIT 1");
|
|
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
$store = $stmt->fetch();
|
|
return $store ?: null;
|
|
}
|
|
|
|
function get_products(?int $storeId = null, int $limit = 50): array
|
|
{
|
|
if ($storeId) {
|
|
$stmt = db()->prepare(
|
|
"SELECT p.*, s.name AS store_name
|
|
FROM products p
|
|
JOIN stores s ON s.id = p.store_id
|
|
WHERE p.store_id = :store_id
|
|
ORDER BY p.created_at DESC
|
|
LIMIT :limit"
|
|
);
|
|
$stmt->bindValue(':store_id', $storeId, PDO::PARAM_INT);
|
|
} else {
|
|
$stmt = db()->prepare(
|
|
"SELECT p.*, s.name AS store_name
|
|
FROM products p
|
|
JOIN stores s ON s.id = p.store_id
|
|
ORDER BY p.created_at DESC
|
|
LIMIT :limit"
|
|
);
|
|
}
|
|
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
function get_product(int $id): ?array
|
|
{
|
|
$stmt = db()->prepare(
|
|
"SELECT p.*, s.name AS store_name, s.currency
|
|
FROM products p
|
|
JOIN stores s ON s.id = p.store_id
|
|
WHERE p.id = :id
|
|
LIMIT 1"
|
|
);
|
|
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
$product = $stmt->fetch();
|
|
return $product ?: null;
|
|
}
|
|
|