3declare(strict_types=1);
12if (!defined(
'dbxSystem')) {
13 define(
'dbxSystem',
'dbxWebApp');
15if (!defined(
'dbxRunAsAdmin')) {
16 define(
'dbxRunAsAdmin', 1);
19require_once
$root .
'/dbx/vendor/autoload.php';
20require_once
$root .
'/dbx/include/dbxKernel.php';
21require_once dirname(__DIR__) .
'/include/dbxInstallationService.class.php';
30 private int $nextId = 1;
36 'resolved_server' => str_ends_with(
$dd,
'dbxUser')
50 foreach ($where as $name =>
$value) {
51 if (($row[$name] ??
null) !==
$value) {
71 $values[
'id'] = $this->nextId++;
73 $this->inserted[] = array(
'dd' =>
$dd,
'values' => $values);
74 return (
int)$values[
'id'];
87 if ((
int)($row[
'id'] ?? 0) !== $id) {
91 $this->updated[] = array(
111 if (
$mode ===
'reset') {
112 return array(
'status' =>
'reset');
114 return array(
'status' =>
'finished',
'message' =>
'ok');
123 string $sourceServer,
125 string $targetServer,
131 $this->transfers[] = array(
141 'status' =>
$mode ===
'reset' ?
'reset' :
'finished',
150 throw new RuntimeException($message);
161 in_array(
'dbx|dbxUser', array_column(
$catalog,
'dd'),
true),
162 'dbxUser fehlt im Installationskatalog.'
166 static fn(array $record):
bool => $record[
'dd'] ===
'dbx|dbxUser'
171 'Deklarierter DD-Quellspeicher wird nicht erkannt.'
178 'Nicht alle DDs wurden provisioniert.'
181$dd->allTablesExist =
true;
186 && count(
$dd->calls) ===
$schema[
'total'] * 2,
187 'Lesende DB3-Prüfung darf keine zusätzliche Schema-Synchronisierung auslösen.'
189$dd->allTablesExist =
false;
195 && count(
$dd->transfers) === 2
196 &&
$dd->transfers[0][4] ===
'reset'
197 &&
$dd->transfers[1][4] ===
'step',
198 'Optionale DD-Datenübertragung ist nicht deterministisch.'
203 $groups[
'created'] === array(
'guest',
'member',
'admin'),
204 'Core-Gruppen wurden nicht deterministisch angelegt.'
209 &&
$groupsAgain[
'existing'] === array(
'guest',
'member',
'admin'),
210 'Core-Seed ist nicht idempotent.'
214 'Test-Passwort-2026!',
215 'admin@example.test',
221 static fn(array $entry):
bool => $entry[
'dd'] ===
'dbx|dbxUser'
226 'Test-Passwort-2026!',
229 'Admin-Passwort wurde nicht mit password_hash gespeichert.'
233 'Anderes-Passwort-2026!',
234 'other@example.test',
239 && count(array_filter(
241 static fn(array $entry):
bool => $entry[
'dd'] ===
'dbx|dbxUser'
243 'Vorhandener Admin wurde bei erneutem Seed veraendert.'
259 'Ohne ausdrückliches Sicherstellen darf ein fehlender Admin nicht geschrieben werden.'
268 static fn(array $entry):
bool => $entry[
'dd'] ===
'dbx|dbxUser'
277 && password_verify(
'Admin-2026!', (
string)
$initialRows[0][
'values'][
'pass']),
278 'Ein leeres SQL-Ziel benötigt den in der Installation gewählten Administratorzugang.'
285 'pass' => password_hash(
'Individuell-2026!', PASSWORD_DEFAULT),
286 'email' =>
'existing@example.test',
291 'settings' => json_encode(array(
292 'dashboard_layout' =>
'compact',
293 'password_changed_at' =>
'2026-01-01T00:00:00+00:00',
312 &&
$resetAdmin[
'password_reset_required'] ===
false
313 && password_verify(
'Neues-Admin-2026!', (
string)
$resetRow[
'pass'])
314 &&
$resetRow[
'email'] ===
'existing@example.test'
322 'Ein vorhandener Admin muss das in der Installation gewählte persönliche Passwort erhalten.'
325echo
"OK DD installation catalog, schema provisioning and idempotent seeds\n";
insert(string $dd, array $values, int $verifyAccess, int $verifyFields, int $verifyValues, int $trace)
update(string $dd, array $values, int $id, int $verifyAccess, int $verifyFields, int $verifyValues, int $trace)
get_dd_server_binding_info(string $dd)
select1(string $dd, array $where, array $columns, int $verifyAccess)
sync_dd_to_db(string $module, string $dd, string $mode)
get_table_exist(string $server, string $table)
transfer_table(string $sourceServer, string $sourceTable, string $targetServer, string $targetTable, string $mode, int $createTarget, int $truncateTarget)
Reproduzierbare Erstinstallation aus DDs und idempotenten Seeds.
$_SERVER['REQUEST_METHOD']
if(preg_match('/core\.js\? foreach[^"\']*v=(\d+)/', $designTemplate, $assetMatch) !== 1 || !str_contains($shopReference, 'dbxapp-Asset-Version ' . $assetMatch[1])) foreach (array( 'reference\\archive', 'provision_docs_content.php', 'dbxSelfTest') as $needle)(array('Installation'=> $installation, 'Installations-Tutorial'=> $installationTutorial, 'SelfTest'=> $selfTest) as $label=> $html)
$existingDb rows['dbx|dbxUser'][]
installation_assert(bool $condition, string $message)