Add templates, tests, and miscellaneous project files

Includes new page templates (fitness-gym, nonprofit, online-course,
photography-studio, real-estate, startup-company, travel-blog,
wedding-invitation) with thumbnail SVGs, test specs, documentation
files, and minor updates to index.html, router.php, and playwright config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 14:15:58 -08:00
parent 03f573b451
commit b511a6684d
61 changed files with 6919 additions and 6 deletions

View File

@@ -16,10 +16,16 @@ if (strpos($uri, '/api/') === 0) {
return true;
}
// Serve static files as-is
// Serve static files
$filePath = __DIR__ . $uri;
if ($uri !== '/' && is_file($filePath)) {
return false; // Let PHP's built-in server handle the file
// Video files need range request support for seeking
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
if (in_array($ext, ['mp4', 'webm', 'ogg', 'mov'])) {
serveVideoWithRangeSupport($filePath, $ext);
return true;
}
return false; // Let PHP's built-in server handle other files
}
// Default: serve index.html for directory requests
@@ -31,3 +37,54 @@ if (is_dir($filePath)) {
}
return false;
/**
* Serve video files with HTTP Range request support (required for seeking).
* PHP's built-in server does not support Range requests for static files.
*/
function serveVideoWithRangeSupport($filePath, $ext) {
$mimeTypes = [
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'ogg' => 'video/ogg',
'mov' => 'video/quicktime',
];
$mime = $mimeTypes[$ext] ?? 'application/octet-stream';
$fileSize = filesize($filePath);
header('Accept-Ranges: bytes');
header('Content-Type: ' . $mime);
if (isset($_SERVER['HTTP_RANGE'])) {
// Parse range header: "bytes=start-end"
if (preg_match('/bytes=(\d+)-(\d*)/', $_SERVER['HTTP_RANGE'], $matches)) {
$start = intval($matches[1]);
$end = $matches[2] !== '' ? intval($matches[2]) : $fileSize - 1;
if ($start > $end || $start >= $fileSize) {
http_response_code(416);
header("Content-Range: bytes */$fileSize");
return;
}
$end = min($end, $fileSize - 1);
$length = $end - $start + 1;
http_response_code(206);
header("Content-Range: bytes $start-$end/$fileSize");
header("Content-Length: $length");
$fp = fopen($filePath, 'rb');
fseek($fp, $start);
$remaining = $length;
while ($remaining > 0 && !feof($fp)) {
$chunk = min(8192, $remaining);
echo fread($fp, $chunk);
$remaining -= $chunk;
}
fclose($fp);
}
} else {
header("Content-Length: $fileSize");
readfile($filePath);
}
}