Skip to content

Commit 0be6368

Browse files
feat: Generate a helpful web page if missing composer
If `composer install` has not been setup yet, causing `vendor/autoload.php` to not be created, generate a helpful error message on the web page. Before the server would just generate a 500 message with no details.
1 parent 88551cf commit 0be6368

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

Pages/Page.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<?php
22

3-
// debugging tools / libs
4-
if (file_exists(ROOT_DIR . 'vendor/autoload.php')) {
5-
require ROOT_DIR . 'vendor/autoload.php';
6-
}
3+
require_once(ROOT_DIR . 'lib/ComposerDependenciesGuard.php');
4+
EnsureComposerDependenciesInstalledForRequest();
75

86
require_once(ROOT_DIR . 'Pages/IPage.php');
97
require_once(ROOT_DIR . 'Pages/Pages.php');

Web/Services/index.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
define('ROOT_DIR', '../../');
44

5+
require_once(ROOT_DIR . 'lib/ComposerDependenciesGuard.php');
6+
EnsureComposerDependenciesInstalledForRequest();
7+
58
require_once(ROOT_DIR . 'lib/WebService/namespace.php');
69
require_once(ROOT_DIR . 'lib/WebService/Slim/namespace.php');
710

lib/ComposerDependenciesGuard.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
function EnsureComposerDependenciesInstalledForRequest(): void
4+
{
5+
$autoloadPath = ROOT_DIR . 'vendor/autoload.php';
6+
if (file_exists($autoloadPath)) {
7+
require_once $autoloadPath;
8+
return;
9+
}
10+
11+
$isApiRequest = str_starts_with($_SERVER['REQUEST_URI'] ?? '', '/Web/Services')
12+
|| str_contains($_SERVER['HTTP_ACCEPT'] ?? '', 'application/json');
13+
14+
if ($isApiRequest) {
15+
if (!headers_sent()) {
16+
header('Content-Type: application/json; charset=utf-8', true, 503);
17+
}
18+
echo json_encode(
19+
[
20+
'error' => 'dependencies_missing',
21+
'message' => 'Application dependencies are not installed. Run "composer install" in the project root.',
22+
],
23+
JSON_UNESCAPED_SLASHES
24+
);
25+
exit;
26+
}
27+
28+
if (!headers_sent()) {
29+
header('Content-Type: text/html; charset=utf-8', true, 503);
30+
}
31+
32+
echo <<<'HTML'
33+
<!DOCTYPE html>
34+
<html lang="en">
35+
<head>
36+
<meta charset="utf-8" />
37+
<meta name="viewport" content="width=device-width, initial-scale=1" />
38+
<title>LibreBooking Setup Required</title>
39+
<style>
40+
body {
41+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
42+
background: #f7f7f7;
43+
color: #1f2937;
44+
margin: 0;
45+
padding: 2rem;
46+
}
47+
48+
.container {
49+
max-width: 780px;
50+
margin: 3rem auto;
51+
background: #ffffff;
52+
border: 1px solid #e5e7eb;
53+
border-radius: 10px;
54+
padding: 2rem;
55+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
56+
}
57+
58+
h1 {
59+
margin-top: 0;
60+
color: #991b1b;
61+
font-size: 1.6rem;
62+
}
63+
64+
code {
65+
background: #f3f4f6;
66+
border: 1px solid #e5e7eb;
67+
border-radius: 6px;
68+
padding: 0.25rem 0.4rem;
69+
font-size: 0.95rem;
70+
}
71+
72+
p {
73+
line-height: 1.5;
74+
}
75+
</style>
76+
</head>
77+
<body>
78+
<div class="container">
79+
<h1>Application setup is incomplete</h1>
80+
<p>Composer dependencies are missing, so LibreBooking cannot start yet.</p>
81+
<p>From the project root, run <code>composer install</code>, then reload this page.</p>
82+
</div>
83+
</body>
84+
</html>
85+
HTML;
86+
87+
exit;
88+
}

0 commit comments

Comments
 (0)