Redesign as VM webshop with NetBox virtualization integration
- Split single-page into 3 pages: - index.php: product catalog with VM size cards - create.php: order form (name, domain, description) - requests.php: request history with pagination - Rewrite NetBox integration to create Virtual Machines (/virtualization/virtual-machines/) instead of DCIM devices - Add netbox_integration/netbox_api.php: NetBoxClient with createVirtualMachine(), findCluster(), findTag(), getList() - Generate new sleek product-card images (420x280) with aligned spec boxes (vcpus/ram/disk) - Add webshop CSS: product cards, nav links, hero section, order layout, responsive grid - Update redirects: send.php -> requests.php, cancel.php -> requests.php - Update E2E test for new page structure - Add .gitignore, deploy-local.sh, setup_database.sql to repo
This commit is contained in:
89
config.php
Executable file
89
config.php
Executable file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
$localConfig = __DIR__ . '/config.local.php';
|
||||
$config = is_readable($localConfig) ? require $localConfig : [];
|
||||
|
||||
$dbConfig = [
|
||||
'host' => $config['db_host'] ?? getenv('PHPSITE_DB_HOST') ?: '127.0.0.1',
|
||||
'name' => $config['db_name'] ?? getenv('PHPSITE_DB_NAME') ?: 'phpsite',
|
||||
'user' => $config['db_user'] ?? getenv('PHPSITE_DB_USER') ?: 'phpsite_app',
|
||||
'pass' => $config['db_pass'] ?? getenv('PHPSITE_DB_PASS') ?: '',
|
||||
];
|
||||
|
||||
// Include NetBox integration
|
||||
require_once __DIR__ . '/netbox_integration/config.php';
|
||||
|
||||
function db(): PDO
|
||||
{
|
||||
static $pdo = null;
|
||||
global $dbConfig;
|
||||
|
||||
if ($pdo instanceof PDO) {
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$dsn = sprintf(
|
||||
'mysql:host=%s;dbname=%s;charset=utf8mb4',
|
||||
$dbConfig['host'],
|
||||
$dbConfig['name']
|
||||
);
|
||||
|
||||
$pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass'], [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function start_app_session(): void
|
||||
{
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
session_start();
|
||||
}
|
||||
|
||||
function h(?string $value): string
|
||||
{
|
||||
return htmlspecialchars($value ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
function require_login(): void
|
||||
{
|
||||
start_app_session();
|
||||
|
||||
if (empty($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
header('Location: /login.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function csrf_token(): string
|
||||
{
|
||||
start_app_session();
|
||||
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
return $_SESSION['csrf_token'];
|
||||
}
|
||||
|
||||
function verify_csrf(?string $token): bool
|
||||
{
|
||||
start_app_session();
|
||||
|
||||
return is_string($token)
|
||||
&& isset($_SESSION['csrf_token'])
|
||||
&& hash_equals($_SESSION['csrf_token'], $token);
|
||||
}
|
||||
Reference in New Issue
Block a user