Files
phpsite/config.php
alex d629689473 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
2026-05-09 23:49:02 +02:00

90 lines
2.0 KiB
PHP
Executable File

<?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);
}