43 if (!is_dir(
$dir))
return;
44 foreach (
new FilesystemIterator(
$dir, FilesystemIterator::SKIP_DOTS) as
$file) {
46 else unlink(
$file->getPathname());
51$tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR .
'dbx-design-service-test-' . bin2hex(random_bytes(5));
53dbx()->files =
$tmp . DIRECTORY_SEPARATOR .
'files';
54$source =
$tmp . DIRECTORY_SEPARATOR .
'dbx' . DIRECTORY_SEPARATOR .
'design' . DIRECTORY_SEPARATOR .
'source';
55foreach (array(
'htm',
'css',
'js',
'img') as $sub) {
56 mkdir(
$source . DIRECTORY_SEPARATOR . $sub, 0777,
true);
58file_put_contents(
$source .
'/htm/default.htm',
'<html><head><title>{dbx:title}</title><link href="{dbx:skin_css}"></head><body class="{dbx:skin_class}" data-dbx-design="{dbx:design}">[dbx:content]<script src="dbx/js/lib/core.js?design={dbx:design}"></script></body></html>');
59file_put_contents(
$source .
'/css/colors.css',
':root{--dbx-primary:#123456}');
60file_put_contents(
$source .
'/css/base.css',
'.source{background:url("../img/a.png")}');
61file_put_contents(
$source .
'/css/theme.css',
'.card{}');
63require_once dirname(__DIR__) .
'/include/dbxDesignService.class.php';
64$service = new \dbx\dbxDesign_admin\dbxDesignService();
67 'source_design' =>
'source',
68 'target_design' =>
'customer-design',
69 'title' =>
'Customer Design',
70 'brand_name' =>
'Customer',
71 'tagline' =>
'Einfach gut',
72 'layout' =>
'sidebar',
81 fwrite(STDERR,
"FAIL: $message\n");
86if ((
$result[
'name'] ??
'') !==
'customer-design' || !is_dir(
$target)) {
87 $fail(
'Wizard hat das Zielpaket nicht angelegt.', 1);
90 $fail(
'Content-Slot ist nicht exakt einmal vorhanden.', 2);
92foreach (array(
'[dbx:logo]',
'[dbx:branding]',
'[dbx:footer]') as $slot) {
94 $fail(
'Design-Slot fehlt: ' . $slot, 3);
97if ((
$metadata[
'contract'] ??
'') !== \
dbx\dbxDesign_admin\dbxDesignService::CONTRACT) {
98 $fail(
'design.json hat nicht den verbindlichen Vertrag.', 4);
100if ((
dbx()->config[
'dbx'][
'default_design_user'] ??
'') !==
'customer-design') {
101 $fail(
'Explizites Setzen als Frontend-Standard wurde nicht gespeichert.', 5);
105 $fail(
'Erzeugtes Design ist ungueltig: ' . implode(
' ',
$validation[
'errors']), 6);
107if (
$service->isAllowedDesignFile(
'../escape.php') ||
$service->isAllowedDesignFile(
'htm/evil.php')) {
108 $fail(
'Dateigrenze akzeptiert einen unzulaessigen Pfad.', 7);
112mkdir(
$delta .
'/htm', 0777,
true);
113file_put_contents(
$delta .
'/htm/branding.htm',
'<strong>Customer Update</strong>');
115file_put_contents(
$evil,
'<button onclick="fetch(\'https://evil.invalid\')">x</button>');
116if (
$service->validateResultFile(
'htm/evil.htm',
$evil) ===
'') {
117 $fail(
'Aktiver Inline-/Fremdcode wurde im KI-Ergebnis akzeptiert.', 8);
122 $fail(
'Update hat kein wiederherstellbares ZIP-Backup erstellt.', 9);
124if ((
string)file_get_contents(
$target .
'/htm/branding.htm') !==
'<strong>Customer Update</strong>') {
125 $fail(
'Validiertes Update wurde nicht atomar uebernommen.', 10);
if(($result['name'] ?? '') !=='customer-design'||!is_dir($target)) if(substr_count( $defaultHtml, '[dbx:content]') !==1) foreach(array('[dbx:logo]', '[dbx:branding]', '[dbx:footer]') as $slot) if(( $metadata[ 'contract'] ?? '') !==\dbx\dbxDesign_admin\dbxDesignService::CONTRACT) if((dbx() ->config['dbx']['default_design_user'] ?? '') !=='customer-design') $validation