dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxInstallerWorkflow_test.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
5$root = dirname(__DIR__, 4);
6chdir($root);
7$_SERVER['REQUEST_URI'] = '/dbxapp/';
8$_SERVER['HTTP_HOST'] = 'localhost';
9$_SERVER['SERVER_NAME'] = 'localhost';
10$_SERVER['SERVER_SOFTWARE'] = 'dbxapp-test';
11$_SERVER['SERVER_PORT'] = 443;
12$_SERVER['HTTPS'] = 'on';
13$_SERVER['SCRIPT_NAME'] = '/dbxapp/index.php';
14$_SERVER['REQUEST_METHOD'] = 'GET';
15
16if (!defined('dbxSystem')) {
17 define('dbxSystem', 'dbxWebApp');
18}
19if (!defined('dbxRunAsAdmin')) {
20 define('dbxRunAsAdmin', 1);
21}
22
23require_once $root . '/dbx/vendor/autoload.php';
24require_once $root . '/dbx/include/dbxKernel.php';
25require_once dirname(__DIR__) . '/include/dbxInstallationService.class.php';
26require_once dirname(__DIR__) . '/include/dbxInstall.class.php';
27
29
30function installer_workflow_assert(bool $condition, string $message): void
31{
32 if (!$condition) {
33 throw new RuntimeException($message);
34 }
35}
36
37$installer = new dbxInstall();
38$checks = $installer->systemChecks();
39$byId = array_column($checks, null, 'id');
40foreach (array(
41 'php',
42 'ext-session',
43 'ext-pdo',
44 'ext-json',
45 'ext-openssl',
46 'write-config',
47 'write-files',
48 'write-tmp',
49 'vendor',
50) as $requiredId) {
52 isset($byId[$requiredId])
53 && $byId[$requiredId]['required'] === true
54 && $byId[$requiredId]['status'] === 'ok',
55 'Notwendige Systemprüfung fehlt oder schlägt fehl: ' . $requiredId
56 );
57}
58foreach (array(
59 'optional-pdo_sqlite',
60 'optional-pdo_mysql',
61 'optional-pdo_pgsql',
62 'optional-pdo_sqlsrv',
63 'https',
64 'memory',
65) as $optionalId) {
67 isset($byId[$optionalId]),
68 'Optionale Systemprüfung fehlt: ' . $optionalId
69 );
70}
71
72$template = (string)file_get_contents(
73 $root . '/dbx/design/dbxapp/htm/install.htm'
74);
75$style = (string)file_get_contents(
76 $root . '/dbx/design/dbxapp/css/install.css'
77);
78$javascript = (string)file_get_contents(
79 $root . '/dbx/design/dbxapp/js/install.js'
80);
81$utilities = (string)file_get_contents(
82 $root . '/dbx/js/lib/utilities.js'
83);
84$openWin = (string)file_get_contents(
85 $root . '/dbx/js/lib/openWin.js'
86);
87$workflow = (string)file_get_contents(
88 dirname(__DIR__) . '/include/dbxInstall.class.php'
89);
90$webApp = (string)file_get_contents(
91 $root . '/dbx/include/dbxWebApp.class.php'
92);
93$api = (string)file_get_contents(
94 $root . '/dbx/include/dbxApi.php'
95);
96$mail = (string)file_get_contents(
97 $root . '/dbx/include/dbxMail.class.php'
98);
99
101 str_contains($template, '[dbx:content]')
102 && str_contains($template, 'install.css')
103 && str_contains($template, 'dbx/design/dbxapp/css/colors.css')
104 && str_contains($template, 'install.js')
105 && str_contains($template, 'install.css?v=5')
106 && str_contains($template, 'install.js?v=3')
107 && str_contains($template, 'v=90'),
108 'Eigenständiges Installationsdesign ist unvollständig.'
109);
111 str_contains($style, '.dbx-install-layout')
112 && str_contains($style, '@media (max-width: 780px)')
113 && str_contains($style, 'dbx-content-blue-v1.svg?v=2')
114 && str_contains($style, 'background-attachment: fixed')
115 && str_contains($style, '.dbx-install-password-toggle')
116 && str_contains($javascript, 'data-dbx-password-toggle')
117 && str_contains($javascript, 'data-install-storage-note')
118 && str_contains($javascript, 'syncStorageMode')
119 && str_contains($javascript, 'Passwort verbergen'),
120 'Installationsdesign ist nicht responsiv oder nicht im dbxapp-Blue-Stil definiert.'
121);
123 str_contains($openWin, 'getViewportPageBounds()')
124 && str_contains($openWin, 'window.visualViewport')
125 && str_contains($openWin, 'bounds.top + (viewportHeight - height) / 2')
126 && str_contains($openWin, 'Math.max(bounds.top, bounds.bottom - height)')
127 && str_contains($openWin, 'this.clampWindowToViewport(windowData)'),
128 'openWin muss Installationshilfen vollständig innerhalb des sichtbaren Viewports öffnen.'
129);
131 str_contains($workflow, 'data-install-storage-note="sqlite"')
132 && str_contains($workflow, 'data-install-storage-note="mysql"')
133 && str_contains($workflow, 'data-install-storage-note="configured"')
134 && str_contains($workflow, "value=\"' . \$this->h(\$checkAction) . '\"")
135 && str_contains($workflow, "'check_database'")
136 && str_contains($workflow, "'check_mail'")
137 && str_contains($workflow, 'Datenbank erneut prüfen')
138 && str_contains($workflow, 'E-Mail erneut prüfen')
139 && str_contains($workflow, 'Zuletzt erfolgreich:')
140 && str_contains($javascript, 'markCheckedValuesChanged')
141 && str_contains($javascript, 'Werte seit der letzten Prüfung geändert'),
142 'Datenspeicher, E-Mail-Werte und ihr aktueller Prüfstatus müssen eindeutig dargestellt werden.'
143);
145 str_contains($workflow, 'storage_advanced_confirm')
146 && str_contains($workflow, 'Erweiterte Datenbankauswahl bestätigen')
147 && str_contains($workflow, 'auch später in der Administration auswählen')
148 && str_contains($workflow, 'Bereits eingerichtete Datenbanken')
149 && !str_contains($workflow, "'Vorhandene Bindungen'")
150 && str_contains($javascript, 'data-install-storage-confirm')
151 && str_contains($style, '.dbx-install-storage-confirm'),
152 'PDO und bestehende Datenbankziele benötigen eine verständliche Bestätigung mit DB3 als einfachem Standard.'
153);
155 str_contains($workflow, 'if (!$this->stayOnStep)')
156 && str_contains($workflow, '$step === 3 && $action === \'check_database\'')
157 && str_contains($workflow, '$step === 6 && $action === \'check_mail\'')
158 && str_contains($workflow, 'mail_test_recipient')
159 && str_contains($workflow, 'Empfänger der Test-E-Mail')
160 && str_contains($workflow, 'Ohne diese ausdrückliche Auswahl wird keine E-Mail versendet.')
161 && str_contains($style, '.dbx-install-action-group')
162 && str_contains($style, '.dbx-install-check-status'),
163 'Datenbank- und E-Mail-Prüfungen müssen wiederholbar sein, ohne den Installationsschritt zu wechseln.'
164);
165foreach (array(
166 'Systemprüfung',
167 'Website & Design',
168 'Datenspeicher',
169 'Strukturen & Daten',
170 'Administration',
171 'E-Mail',
172 'Prüfen & starten',
173) as $stepTitle) {
175 str_contains($workflow, $stepTitle),
176 'Installationsschritt fehlt: ' . $stepTitle
177 );
178}
180 str_contains($workflow, "patch_local_config('dbx', \$patch)")
181 && str_contains($workflow, "'install' => 0")
182 && !str_contains($workflow, "set_config('dbx', \$config)"),
183 'Installationsabschluss ist nicht ausschließlich lokal/updatefest.'
184);
186 str_contains($webApp, 'if ($install || !$ok)')
187 && str_contains($webApp, "\$design = 'dbxapp'")
188 && str_contains($webApp, "\$page = 'install'"),
189 'Installationsrouting reagiert nicht verbindlich auf install=1.'
190);
192 str_contains($api, 'if (!$installMode)')
193 && str_contains($api, 'check_perma()'),
194 'Bootstrap trennt Installation und Datenbank-/Permalinkauflösung nicht.'
195);
197 str_contains($mail, "array('internal', 'disabled', 'external')")
198 && str_contains($mail, 'handle_internal_delivery'),
199 'Globaler E-Mail-Schalter ist nicht vollständig umgesetzt.'
200);
202 substr_count($workflow, "\$current[self::SQL_SERVER]['pass'] ?? ''") >= 2,
203 'Leere Passwortfelder müssen vorhandene SQL- und Mail-Passwörter bewahren.'
204);
206 str_contains($workflow, '$installer->verifyBundledSchema()')
207 && str_contains($workflow, "'read_only' => 1")
208 && str_contains($workflow, 'es wurde nichts verändert')
209 && str_contains($workflow, "\$this->actions(4, 'Weiter zur Administration')")
210 && str_contains($workflow, 'Danach folgt Schritt 5'),
211 'Der ausgelieferte DB3-Standard muss ohne Schema- oder Datenmutation geprüft werden.'
212);
214 str_contains($workflow, '$this->installer()->ensureInitialAdmin(')
215 && str_contains($workflow, "\$this->postSecret('admin_password'")
216 && str_contains($workflow, "\$this->postSecret('admin_password_repeat'")
217 && str_contains($workflow, '$this->passwordCriteriaMissing(')
218 && str_contains($workflow, 'bisherige Passwort des vorhandenen Benutzers')
219 && str_contains($workflow, 'Persönlicher Administratorzugang')
220 && str_contains($workflow, 'Administratorzugang speichern')
221 && str_contains($workflow, 'Persönliches Passwort eingerichtet')
222 && !str_contains($workflow, 'admin / 123456 festlegen')
223 && !str_contains($workflow, 'Passwortwechsel beim ersten Login erforderlich'),
224 'Schritt 5 muss das persönliche Admin-Passwort zweimal abfragen, prüfen und unmittelbar setzen.'
225);
227 str_contains($workflow, "'password_min_length' => max(")
228 && str_contains($workflow, 'Standard: 6 Zeichen')
229 && str_contains($workflow, '12 oder mehr Zeichen empfohlen')
230 && str_contains($workflow, 'data-install-password-rules')
231 && str_contains($javascript, 'initInstallPasswordRules')
232 && str_contains($style, '.dbx-install-password-rules'),
233 'Die konfigurierbare Passwort-Mindestlänge und ihre Live-Kriterien fehlen im Installer.'
234);
236 str_contains($workflow, 'dbx-install-mail-sections')
237 && str_contains($workflow, 'data-install-mail-fields')
238 && str_contains($workflow, 'box.hidden=')
239 && str_contains($style, '.dbx-install-mail-sections'),
240 'Die E-Mail-Konfiguration muss kompakt gruppiert und nur bei externem Versand sichtbar sein.'
241);
243 str_contains($workflow, 'private function fieldTooltip(')
244 && str_contains($workflow, 'private function tooltipIcon(')
245 && str_contains($workflow, 'data-dbx-tooltip=')
246 && str_contains($style, '.dbx-install-tooltip'),
247 'Installer-Eingabefelder benötigen zentrale, verständliche Tooltips.'
248);
249foreach (array(
250 'site_title',
251 'brand_name',
252 'brand_tagline',
253 'default_lng',
254 'timezone',
255 'default_design_user',
256 'default_design_admin',
257 'storage_advanced_confirm',
258 'db_type',
259 'db_host',
260 'db_port',
261 'db_name',
262 'db_user',
263 'db_password',
264 'db_create',
265 'migrate_data',
266 'initial_admin_user',
267 'admin_password',
268 'admin_password_repeat',
269 'password_min_length',
270 'mail_transport',
271 'mail_host',
272 'mail_port',
273 'mail_secure',
274 'mail_auth',
275 'mail_user',
276 'mail_password',
277 'mail_from_email',
278 'mail_from_name',
279 'mail_sender',
280 'mail_from_domains',
281 'contact_mail_from',
282 'shop_mail_from',
283 'mail_force_from',
284 'mail_test_recipient',
285 'mail_send_test',
286 'confirm_install',
287) as $tooltipField) {
289 str_contains($workflow, "'" . $tooltipField . "' => '"),
290 'Verständlicher Installer-Tooltip fehlt für: ' . $tooltipField
291 );
292}
294 str_contains($utilities, 'isSameWebsiteNavigation')
295 && str_contains($utilities, 'allowIfInternalNavigation')
296 && str_contains($utilities, 'window.addEventListener("beforeunload"')
297 && str_contains($utilities, 'leaveGuard')
298 && str_contains($utilities, 'data-dbx-leave-allow')
299 && str_contains($api, 'leaveGuard.allowIfInternal')
300 && !str_contains($javascript, 'beforeunload'),
301 'Die globale Verlassenswarnung muss zentral liegen und interne dbxapp-Weiterleitungen freigeben.'
302);
304 str_contains($workflow, "'mysql' => 'pdo_mysql'")
305 && str_contains($workflow, "'pgsql' => 'pdo_pgsql'")
306 && str_contains($workflow, "'sqlsrv' => 'pdo_sqlsrv'")
307 && substr_count(
308 $workflow,
309 '$db->can_connect_database_config($dbConfig, true)'
310 ) >= 2
311 && str_contains(
312 $workflow,
313 '$db->ensure_database_exists(self::SQL_SERVER, $dbConfig)'
314 ),
315 'PDO-Migration darf erst nach erreichbarer oder erfolgreich angelegter Zieldatenbank starten.'
316);
318 str_contains($workflow, "\$profile['host']")
319 && str_contains($workflow, "\$profile['dbname']")
320 && str_contains($workflow, "\$profile['user']")
321 && substr_count(
322 $workflow,
323 'Leer lassen: vorhandenes Passwort beibehalten'
324 ) >= 2,
325 'Vorhandene DB- und Mailwerte müssen als sichere Vorgaben weiterverwendet werden.'
326);
328 str_contains($workflow, "contact_mail_from")
329 && str_contains($workflow, "shop_mail_from")
330 && str_contains($workflow, "patch_local_config('dbxContact'")
331 && str_contains($workflow, "patch_local_config('dbxShop'")
332 && str_contains($workflow, 'Kontakt-Absender')
333 && str_contains($workflow, 'Shop-Absender'),
334 'Kontakt und Shop benötigen eigene frei konfigurierbare und lokal gespeicherte Absender.'
335);
337 str_contains($workflow, 'lib=openWin|id=install-help-')
338 && str_contains($workflow, "array('design', 'db3', 'pdo', 'email')")
339 && str_contains($workflow, 'KI-gestützte Designanpassung erklärt')
340 && str_contains($workflow, 'Das Design später mit KI weiterentwickeln')
341 && str_contains($workflow, 'Mitgelieferte DB3 direkt verwenden')
342 && str_contains($workflow, 'DB3-Daten auf einen PDO-Server übertragen')
343 && str_contains($workflow, 'E-Mail-Versand sicher konfigurieren')
344 && str_contains($workflow, 'E-Mail-Konfiguration ausführlich erklärt')
345 && str_contains($workflow, 'Globalen Absender für alle Module erzwingen')
346 && str_contains($workflow, 'dbxContact.mail_from')
347 && str_contains($workflow, 'dbxShop.mail_from'),
348 'Design, DB3-Standard, PDO-Migration und E-Mail-Konfiguration benötigen ausführliche openWin-Hilfen.'
349);
350
351$config = array();
352require $root . '/dbx/modules/dbx/cfg/config.php';
354 ($config['mail_delivery_mode'] ?? '') === 'internal',
355 'Öffentlicher Mailstandard muss intern und damit netzwerkfrei sein.'
356);
358 (int)($config['password_min_length'] ?? 0) === 6,
359 'Die ausgelieferte Passwort-Mindestlänge muss standardmäßig 6 Zeichen betragen.'
360);
362 (int)($config['install'] ?? 0) === 1,
363 'Die ausgelieferte Standardkonfiguration muss den Installer aktivieren.'
364);
365
366echo "OK installer workflow, environment checks, secure local finish and mail modes\n";
Geführte, wiederanlaufbare Erstinstallation von dbxapp.
if($failed !==array()) $installer
$_SERVER['REQUEST_METHOD']
if($resolved !==$expectedBase . 'files/test/') $config
if(!is_string($cms)||!is_string($process)) $checks
if(!is_array($rows)) $byId
installer_workflow_assert(bool $condition, string $message)