dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxDocsPortal_contract_test.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
5$root = dirname(__DIR__, 3);
6
7function docs_portal_assert(bool $condition, string $message): void
8{
9 if (!$condition) {
10 throw new RuntimeException($message);
11 }
12}
13
14function docs_portal_read(string $path): string
15{
16 $content = file_get_contents($path);
17 if ($content === false) {
18 throw new RuntimeException('Datei kann nicht gelesen werden: ' . $path);
19 }
20 return $content;
21}
22
23$designRoot = $root . '/dbx/design/dbxdocs';
24$template = docs_portal_read($designRoot . '/htm/default.htm');
25$layout = docs_portal_read($designRoot . '/css/docs-layout.css');
26$docsContent = docs_portal_read($designRoot . '/css/docs-content.css');
27$contentCss = docs_portal_read($designRoot . '/css/c-content.css');
28$darkSkin = docs_portal_read($designRoot . '/css/skin-dunkel.css');
30$cinematicJavascript = docs_portal_read($designRoot . '/js/dbxdocs-cinematic.js');
31$cinematicCss = docs_portal_read($designRoot . '/css/docs-cinematic.css');
32$cinematicContent = docs_portal_read($root . '/dbx/modules/dbxDocs/content/dbxapp_home_cinematic.html');
33$installationContent = docs_portal_read($root . '/dbx/modules/dbxDocs/content/dbxapp_user_installation.html');
34$installationTutorial = docs_portal_read($root . '/dbx/modules/dbxDocs/content/tutorial_installation.html');
35$selfTestContent = docs_portal_read($root . '/dbx/modules/dbxDocs/content/dbxapp_user_selftest.html');
36$menuJavascript = docs_portal_read($root . '/dbx/js/lib/menu.js');
37$menuModule = docs_portal_read($root . '/dbx/modules/dbxMenu/dbxMenu.class.php');
38$menuDe = docs_portal_read($root . '/dbx/modules/dbxMenu/tpl/htm/dbx-docs-main.htm');
39$menuEn = docs_portal_read($root . '/dbx/modules/dbxMenu/tpl/htm/dbx-docs-main_en.htm');
40$menuEs = docs_portal_read($root . '/dbx/modules/dbxMenu/tpl/htm/dbx-docs-main_es.htm');
42$index = docs_portal_read($root . '/index.php');
43$contentDd = docs_portal_read($root . '/dbx/modules/dbx/dd/dbxContent.dd.inc.php');
44$docsModule = docs_portal_read($root . '/dbx/modules/dbxDocs/dbxDocs.class.php');
45$docsTemplate = docs_portal_read($root . '/dbx/modules/dbxDocs/tpl/htm/reference.htm');
46$docsProvision = docs_portal_read($root . '/dbx/modules/dbxDocs/include/dbxDocsContentProvision.class.php');
47$docsMediaProvision = docs_portal_read($root . '/dbx/modules/dbxDocs/tools/update_docs_portal_media_20260728.php');
48$docsHomeCinematic = docs_portal_read($root . '/dbx/modules/dbxDocs/tools/update_docs_home_cinematic_20260728.php');
49$docsAccess = docs_portal_read($root . '/dbx/modules/dbxDocs/tools/configure_docs_access_20260728.php');
50$contentMenu = docs_portal_read($root . '/dbx/modules/dbxMenu/include/dbxContent_menu.class.php');
52 is_file($root . '/dbx/modules/dbxContent/tpl/htm/c-content.htm'),
53 'Das sprachunabhängige Standard-Content-Template c-content.htm fehlt.'
54);
55
56foreach (array(
57 'base.css',
58 'c-form.css',
59 'c-report.css',
60 'c-menu.css',
61 'skin-blau.css',
62 'theme.css',
63 'docs-layout.css',
64 'docs-content.css',
65 'docs-cinematic.css',
66) as $css) {
68 is_file($designRoot . '/css/' . $css),
69 'Erforderliche Design-CSS fehlt: ' . $css
70 );
71}
72
73$asidePosition = strpos($template, '<aside id="dbxHeader"');
74$mainPosition = strpos($template, '<main id="dbxMain"');
76 $asidePosition !== false && $mainPosition !== false && $asidePosition < $mainPosition,
77 'Die Dokumentationsnavigation muss links vor dem Hauptinhalt stehen.'
78);
80 str_contains($template, 'tpl=modul|dbx-docs-main'),
81 'Das sprachabhängige Dokumentationsmenü ist nicht eingebunden.'
82);
84 !str_contains($template, 'fleurop-') && !str_contains($layout, 'fleurop-'),
85 'Das dbxdocs-Design darf keine flowers-spezifischen Klassen übernehmen.'
86);
88 str_contains($layout, '--dbxdocs-blue-900')
89 && str_contains($layout, 'grid-template-columns')
90 && str_contains($layout, '.dbx-cms-menu-page'),
91 'Blauer Layout-, Seitenleisten- oder Einklappvertrag fehlt.'
92);
94 str_contains($template, 'data-dbx-menu-active-open="1"')
95 && str_contains($template, 'docs-layout.css?v=9')
96 && str_contains($template, 'dbxdocs.js?v=3')
97 && preg_match('/core\.js\?design=\{dbx:design\}&log=off&v=\d+/', $template) === 1
98 && str_contains($menuJavascript, "data-dbx-menu-active-open")
99 && str_contains($menuJavascript, 'restoreActivePath($el)')
100 && str_contains($menuJavascript, 'function closeBranch($item)')
101 && str_contains($menuJavascript, 'closeAllMenus(true)')
102 && str_contains($menuJavascript, "\$parent.addClass('is-active-path')")
103 && !str_contains($menuJavascript, "\$parent.addClass('is-active is-active-path')")
104 && str_contains($layout, '.is-active-path:not(.is-active)')
105 && str_contains($menuJavascript, '.dbxLngOpt, .dbx-design-opt, .dbx-design-skin-opt, .dbx-skin-opt')
106 && !str_contains(
107 $layout,
108 '.dbx-menu-item.is-active-path > .dbx-menu-list'
109 ),
110 'Aktive Dokumentationsordner lassen sich nicht zuverlässig schließen.'
111);
113 str_contains($layout, '.dbxdocs-admin-strip .dbx-menu > .dbx-menu-list')
114 && str_contains($layout, 'flex-wrap: wrap;')
115 && str_contains($layout, '.dbxdocs-stage #dbxMain')
116 && substr_count($layout, 'min-width: 0;') >= 8,
117 'Das Dokumentationsportal darf mit eingeblendeter Admin-Navigation nicht horizontal überlaufen.'
118);
120 str_contains($menuModule, "\$docsDisplay = stripos((string)\$menu, 'dbx-docs-main') !== false")
121 && str_contains($menuModule, "array('dbxdocs' => 'dbxapp (Blau)')")
122 && str_contains($menuModule, "array('blau' => true, 'dunkel' => true)")
123 && str_contains($menuModule, "\$options['blau']['label'] = 'Light'")
124 && str_contains($menuModule, "\$options['dunkel']['label'] = 'Dark'"),
125 'Die Dokumentationsnavigation muss genau dbxapp (Blau) mit Light und Dark anbieten.'
126);
128 str_contains($darkSkin, 'text-shadow: 0 0 1px rgba(95, 255, 95, 0.18)')
129 && !str_contains($darkSkin, '0 0 9px rgba(63, 255, 63, 0.30)')
130 && substr_count($darkSkin, 'text-shadow: none;') >= 2,
131 'Die grüne Dark-Skin-Schrift muss ohne unscharfen Leuchteffekt bleiben.'
132);
134 str_contains($template, 'docs-content.css?v=7')
135 && str_contains($docsContent, '.dbx-user-nav-icon svg')
136 && str_contains($docsContent, '.dbx-ki-area-grid')
137 && str_contains($docsContent, '.dbx-update-state-grid')
138 && str_contains($docsContent, 'body.dbx-docs .dbx-content-body')
139 && str_contains($docsContent, 'body.dbx-docs .dbxContent_wrapper.dbx-content-page')
140 && str_contains($docsContent, 'padding: clamp(.85rem, 1.4vw, 1.2rem)')
141 && str_contains($docsContent, '.dbx-doc-figure')
142 && str_contains($docsContent, '.dbxdocs-home-search')
143 && str_contains($docsContent, 'grid-template-columns: auto minmax(0, 1fr) auto')
144 && str_contains($docsContent, '.dbxdocs-path-grid')
145 && str_contains($docsContent, '--dbx-doc-table-hover: #fff0a8')
146 && str_contains($docsContent, 'table tbody tr:hover')
147 && str_contains($docsContent, 'body.dbx-app.skin-dunkel .dbxdocs-cms-article')
148 && str_contains($docsContent, '--dbx-doc-text: #7cff7c')
149 && str_contains($docsContent, 'text-shadow: 0 0 1px rgba(95, 255, 95, .18)'),
150 'Versionierte CMS-Sonderformatierung für Navigation, KI und Updates fehlt.'
151);
153 substr_count($contentCss, 'aspect-ratio: 16 / 9;') >= 2,
154 'Die Portal-Galerie muss Bilder im Querformat darstellen.'
155);
157 str_contains($docsMediaProvision, "\$mediaDd = 'dbx|dbxMedia';")
158 && str_contains($docsMediaProvision, "\$usageDd = 'dbx|dbxMediaUsage';")
159 && str_contains($docsMediaProvision, 'thumb_file_path')
160 && str_contains($docsMediaProvision, 'dbxContentPageCache::invalidateAll()'),
161 'Reproduzierbare Medienaktualisierung über dbxDB und Cache-Invalidierung fehlt.'
162);
164 str_contains($javascript, 'sidebarCollapsed')
165 && str_contains($javascript, 'is-mobile-nav-open')
166 && str_contains($javascript, 'resetInitialContentScroll')
167 && str_contains($javascript, 'scrollRestoration'),
168 'Persistente Desktop- und mobile Navigation fehlen.'
169);
171 str_contains($template, 'docs-cinematic.css?v=9')
172 && str_contains($template, 'dbxdocs-cinematic.js?v=4')
173 && str_contains($cinematicContent, 'data-duration="84"')
174 && str_contains($cinematicContent, 'Aus Anforderungen werden Anwendungen.')
175 && str_contains($cinematicContent, 'dbx-cinema-infrastructure')
176 && str_contains($cinematicContent, 'dbx-cinema-glints')
177 && str_contains($cinematicContent, 'dbx-cinema-shooting-star')
178 && !str_contains($cinematicContent, 'dbx-cinema-crawl')
179 && !str_contains($cinematicContent, 'dbx-cinema-intro')
180 && !str_contains($cinematicContent, 'Wenn starre Einzellösungen')
181 && str_contains($cinematicContent, 'Vom Gerät bis ins Rechenzentrum')
182 && str_contains($cinematicContent, 'Ton starten')
183 && str_contains($cinematicCss, '@keyframes dbxCinemaGlint')
184 && str_contains($cinematicCss, '@keyframes dbxCinemaShootingStar')
185 && str_contains($cinematicCss, '@keyframes dbxCinemaContentRise')
186 && str_contains($cinematicCss, '@keyframes dbxCinemaDeviceIn')
187 && str_contains($cinematicCss, '@keyframes dbxCinemaLogoImpact')
188 && str_contains($cinematicCss, 'aspect-ratio: 16 / 7.3')
189 && str_contains($cinematicCss, 'prefers-reduced-motion')
190 && str_contains($cinematicJavascript, 'IntersectionObserver')
191 && str_contains($cinematicJavascript, 'createSoundscape')
192 && str_contains($cinematicJavascript, 'createDynamicsCompressor')
193 && str_contains($cinematicJavascript, 'root.dataset.soundState')
194 && str_contains($cinematicJavascript, 'data-cinema-toggle'),
195 'Die kompakte, zugängliche 84-Sekunden-Startseitenanimation mit Infrastruktur-Szene, Schlusslogo und Ton ist nicht vollständig eingebunden.'
196);
198 str_contains($docsHomeCinematic, "\$contentDd = 'dbx|content_de';")
199 && str_contains($docsHomeCinematic, "\$usageDd = 'dbx|dbxMediaUsage';")
200 && str_contains($docsHomeCinematic, "array('active' => 0)")
201 && str_contains($docsHomeCinematic, 'dbxContentPageCache::invalidateAll()'),
202 'Die Animation muss reproduzierbar über dbxDB installiert und die alte Galerie reversibel deaktiviert werden.'
203);
205 str_contains($docsAccess, "array('dbxUser', 'dbxUser_groups')")
206 && str_contains($docsAccess, 'new dbxInstallationService')
207 && str_contains($docsAccess, "patch_local_config('dbxLogin', array('register' => '0'))")
208 && str_contains($docsAccess, 'DBX_DOCS_ADMIN_PASSWORD')
209 && !str_contains($docsAccess, 'bentox64'),
210 'Benutzer-DD, Admin-Seed und ausgeschaltete Registrierung sind nicht reproduzierbar konfiguriert.'
211);
212
213docs_portal_assert(str_contains($menuDe, '[cms:root=Dokumentation&flat=1]'), 'Deutscher Dokumentationsbaum fehlt.');
214docs_portal_assert(str_contains($menuEn, '[cms:root=Documentation&flat=1]'), 'Englischer Dokumentationsbaum fehlt.');
215docs_portal_assert(str_contains($menuEs, '[cms:root=Documentación&flat=1]'), 'Spanischer Dokumentationsbaum fehlt.');
216foreach (array($menuDe, $menuEn, $menuEs) as $menu) {
218 str_contains($menu, 'dbx_modul=dbxDocs')
219 && str_contains($menu, 'dbx_run2=classes')
220 && str_contains($menu, 'dbx_run2=namespaces')
221 && str_contains($menu, 'dbx_run2=files')
222 && str_contains($menu, 'dbx_run2=examples'),
223 'Generierte Doxygen-Bereiche fehlen in einem Sprachmenü.'
224 );
225}
227 str_contains($contentMenu, 'resolve_folder_reference')
228 && str_contains($contentMenu, 'menu_title')
229 && str_contains($contentMenu, 'dbx-cms-menu-folder'),
230 'Benannte CMS-Wurzeln, kurze Menütitel oder Untermenüs fehlen.'
231);
233 str_contains($docsModule, 'REFERENCE_PAGES')
234 && str_contains($docsModule, 'realpath')
235 && str_contains($docsTemplate, '<iframe')
236 && str_contains($docsTemplate, 'sandbox='),
237 'Die sichere, eingebettete Doxygen-Referenz ist unvollständig.'
238);
239foreach (array(
240 "'name' => 'Einstieg'",
241 "'name' => 'Content & KI'",
242 "'name' => 'Entwicklung'",
243 "'name' => 'Betrieb & Sicherheit'",
244 "'name' => 'Service'",
245 'dbxContact]dbx_run1=form',
246 'repairDocumentationLinks()',
247 'referenceDocumentPermalink',
248 'dbxcontent_tutorial_(.+)',
249 '2026-08-01-installation-2',
250 '2026-08-01-tutorial-installation-2',
251 '2026-08-01-selftest-2',
252 "'permalink' => 'dokumentation-installation'",
253 "'permalink' => 'tutorial-installation'",
254 "'permalink' => 'dokumentation-selbsttest'",
255 '2026-07-28-ki-design-2',
256) as $needle) {
258 str_contains($docsProvision, $needle),
259 'CMS-Dokumentationsstruktur ist unvollständig: ' . $needle
260 );
261}
263 is_file($root . '/dbx/modules/dbxDocs/content/dbxapp_user_ki_design.html')
264 && is_file($root . '/dbx/modules/dbxDocs/content/dbxapp_user_installation.html')
265 && is_file($root . '/dbx/modules/dbxDocs/content/tutorial_installation.html')
266 && is_file($root . '/dbx/modules/dbxDocs/content/dbxapp_user_selftest.html')
267 && is_file($root . '/dbx/modules/dbxDocs/assets/cms-content-tree-open.png'),
268 'Eine kuratierte Dokumentationsseite oder ihr CMS-Screenshot fehlt.'
269);
271 str_contains($installationContent, 'Die sieben Installationsschritte')
272 && str_contains($installationContent, 'PHP 8.2 oder neuer')
273 && str_contains($installationContent, 'persönliches Passwort')
274 && str_contains($installationContent, 'dokumentation-selbsttest'),
275 'Die kuratierte Installationsanleitung ist unvollständig.'
276);
278 str_contains($installationTutorial, '<h1>dbxapp Schritt für Schritt installieren</h1>')
279 && substr_count($installationTutorial, '<h2>') >= 5
280 && substr_count($installationTutorial, '<h3>') >= 5
281 && str_contains($installationTutorial, 'class="markdownTable"'),
282 'Das Installations-Tutorial besitzt keine belastbare H1/H2/H3-Struktur oder Kontrolltabelle.'
283);
285 str_contains($selfTestContent, 'Schnelltest')
286 && str_contains($selfTestContent, 'Kompletttest')
287 && str_contains($selfTestContent, 'JavaScript ohne Node.js')
288 && str_contains($selfTestContent, 'files/sys/selftest')
289 && str_contains($selfTestContent, '--profile=full'),
290 'Die kuratierte dbxSelfTest-Anleitung ist unvollständig.'
291);
292
294 str_contains($doxyfile, 'OUTPUT_DIRECTORY = C:/xampp/htdocs/dbxapp-docs/reference')
295 && str_contains($doxyfile, 'HTML_OUTPUT = current')
296 && str_contains($doxyfile, 'docs/doxygen-generated-main.dox')
297 && !str_contains($doxyfile, 'docs/doxygen-navigation.dox')
298 && !str_contains($doxyfile, 'docs/generated/tutorials'),
299 'Doxygen muss ausschließlich die generierte Referenz veröffentlichen.'
300);
302 str_contains($index, 'session_name(')
303 && str_contains($index, '$sessionHost . \'|\' . $sessionPath'),
304 'Installationsbezogene Sitzungsisolation fehlt.'
305);
307 str_contains($contentDd, "'idx_content_' . \$__dbx_lng_dd . '_folder'"),
308 'Sprachabhängige SQLite-Indexnamen sind nicht eindeutig.'
309);
311 str_contains($contentDd, "\$field['name']='menu_title';"),
312 'Das sprachneutrale DD-Feld für kurze Menütitel fehlt.'
313);
314
315echo "OK dbxdocs CMS navigation, installation, self-test, access, cinematic homepage and embedded reference\n";
docs_portal_read(string $path)
foreach(array('base.css', 'c-form.css', 'c-report.css', 'c-menu.css', 'skin-blau.css', 'theme.css', 'docs-layout.css', 'docs-content.css', 'docs-cinematic.css',) as $css) $asidePosition
docs_portal_assert(bool $condition, string $message)