dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
doxygen_structure_test.php
Go to the documentation of this file.
1<?php
2
3$root = dirname(__DIR__, 3);
4$doxyfile = $root . '/Doxyfile';
5$mainFile = $root . '/docs/doxygen-generated-main.dox';
6$referenceFile = $root . '/25_Verbindliches_Modulhandbuch.md';
7$referenceModule = $root . '/dbx/modules/myInvoices';
8$navigationFile = $root . '/docs/doxygen-navigation.dox';
9$updateUserFile = $root . '/docs/dbxapp-system-update-user.dox';
10$kiAreasFile = $root . '/28_KI_Bereiche.md';
11$tutorialExport = $root . '/dbx/modules/dbxContent/tools/export_doxygen_tutorials_de.php';
12$tutorialDir = $root . '/docs/generated/tutorials';
13$brandingHeader = $root . '/docs/doxygen-awesome/header.html';
14$brandingCss = $root . '/docs/doxygen-awesome/dbxapp-doxygen.css';
15$utf8Filter = $root . '/docs/tools/doxygen_php_utf8_filter.php';
16$releaseVersion = trim((string)file_get_contents($root . '/VERSION'));
17
18$fail = static function (string $message, int $code): void {
19 fwrite(STDERR, "FAIL: {$message}\n");
20 exit($code);
21};
22
23foreach ([
34] as $requiredFile) {
35 if (!is_file($requiredFile)) {
36 $fail('Erforderliche Doxygen-Datei fehlt: ' . $requiredFile, 1);
37 }
38}
39
40foreach (array(
41 'myInvoices.class.php',
42 'cfg/config.php',
43 'dd/invoice.dd.php',
44 'dd/invoiceItem.dd.php',
45 'fd/invoice-form.fd.php',
46 'fd/rpt-invoice-selection.fd.php',
47 'include/myInvoicesFixtures.class.php',
48 'include/myInvoicesService.class.php',
49 'tpl/htm/invoice-form.htm',
50 'tpl/htm/invoice-report.htm',
51 'tpl/htm/invoice-items-report.htm',
52 'tpl/htm/invoice-row-action.htm',
53 'tpl/htm/invoice-install.htm',
54 'tools/install_demo.php',
55 'tests/myInvoices_contract_test.php',
56 'tests/myInvoices_integration_test.php',
57 'README.md',
58) as $relative) {
59 if (!is_file($referenceModule . '/' . $relative)) {
60 $fail('Ausführbares Referenzmodul ist unvollständig: ' . $relative, 16);
61 }
62}
63
64$docs = glob($root . '/[0-9][0-9]_*.md');
65if (!is_array($docs) || count($docs) < 25) {
66 $fail('Die nummerierte Doxygen-Dokumentation ist unvollstaendig.', 2);
67}
68sort($docs);
69
70$anchors = array();
71$references = array();
73
74foreach ($docs as $doc) {
75 $content = (string)file_get_contents($doc);
76
77 if (preg_match_all('/\{#(dbxapp_[A-Za-z0-9_]+)\}/', $content, $matches)) {
78 foreach ($matches[1] as $anchor) {
79 if (isset($anchors[$anchor])) {
80 $duplicateAnchors[$anchor] = array($anchors[$anchor], basename($doc));
81 continue;
82 }
83 $anchors[$anchor] = basename($doc);
84 }
85 }
86
87 if (preg_match_all('/@ref\s+(dbxapp_[A-Za-z0-9_]+)/', $content, $matches)) {
88 foreach ($matches[1] as $reference) {
89 $references[$reference][] = basename($doc);
90 }
91 }
92}
93
94foreach (array($navigationFile, $updateUserFile) as $doxygenPageFile) {
95 $content = (string)file_get_contents($doxygenPageFile);
96 if (preg_match_all('/@page\s+(dbxapp_[A-Za-z0-9_]+)/', $content, $matches)) {
97 foreach ($matches[1] as $anchor) {
98 if (isset($anchors[$anchor])) {
99 $duplicateAnchors[$anchor] = array(
100 $anchors[$anchor],
101 basename($doxygenPageFile),
102 );
103 continue;
104 }
105 $anchors[$anchor] = basename($doxygenPageFile);
106 }
107 }
108}
109
111 $fail(
112 'Doppelte Doxygen-Anker: ' . implode(', ', array_keys($duplicateAnchors)),
113 3
114 );
115}
116
117$missingReferences = array_diff(array_keys($references), array_keys($anchors));
119 $fail(
120 'Unbekannte Doxygen-Referenzen: ' . implode(', ', $missingReferences),
121 4
122 );
123}
124
125$doxyContent = (string)file_get_contents($doxyfile);
126foreach (array(
127 'docs/doxygen-navigation.dox',
128 'docs/dbxapp-system-update-user.dox',
129 'docs/generated/tutorials',
130 '25_Verbindliches_Modulhandbuch.md',
131 'files/doku',
132) as $editorialInput) {
133 if (strpos($doxyContent, $editorialInput) !== false) {
134 $fail('Redaktioneller CMS-Inhalt darf nicht mehr Doxygen-INPUT sein: ' . $editorialInput, 5);
135 }
136}
137
138$mainContent = (string)file_get_contents($mainFile);
139foreach (array(
140 '@mainpage dbxapp Quellcode-Referenz',
141 '@ref annotated "Klassen"',
142 '@ref namespaces "Namespaces"',
143 '@ref files "Dateien"',
144 '@ref examples "Beispiele"',
145 'dbxapp-Dokumentationsportal öffnen',
146) as $needle) {
147 if (strpos($mainContent, $needle) === false) {
148 $fail('Mainpage-Vertrag fehlt: ' . $needle, 7);
149 }
150}
151
152$navigationContent = (string)file_get_contents($navigationFile);
153foreach (array(
154 '@page dbxapp_user_docs Anwenderdokumentation',
155 '@page dbxapp_user_start Einstieg und Bedienung',
156 '@page dbxapp_user_admin Administration und Systemstatus',
157 '@subpage dbxapp_user_system_update',
158 '@page dbxapp_user_content Inhalte, CMS und Medien',
159 '@page dbxapp_user_shop Shop bedienen und administrieren',
160 '@page dbxapp_user_workflows Workflows erstellen und benutzen',
161 '@page dbxapp_user_design Designs manuell und mit KI erstellen',
162 '@page dbxapp_user_ki_content KI-Bereich 1: Content',
163 '@page dbxapp_user_ki_design KI-Bereich 2: Design',
164 '@page dbxapp_user_ki_modules KI-Bereich 3: Module',
165 '@page dbxapp_developer_docs Entwicklerdokumentation',
166 '@page dbxapp_dev_orientation Architektur und Laufzeit',
167 '@page dbxapp_dev_modules Verbindliche Modulentwicklung',
168 '@page dbxapp_dev_pipelines Kernpipelines und Bibliotheken',
169 '@page dbxapp_dev_content_design CMS, KI, Design und Fachmodule',
170 '@page dbxapp_dev_operations Installation, Updates und Betrieb',
171) as $needle) {
172 if (strpos($navigationContent, $needle) === false) {
173 $fail('Doxygen-Navigation ist unvollständig: ' . $needle, 19);
174 }
175}
176
177$updateUserContent = (string)file_get_contents($updateUserFile);
178foreach (array(
179 '@page dbxapp_user_system_update System-Update sicher durchführen',
180 'Update automatisch vorbereiten',
181 'Update stoppen',
182 'Jetzt sicher installieren',
183 'Letztes Update zurückrollen',
184 'DB3, MySQL und gemischte Installationen',
185 'System → System-Selbsttest',
186 'dokumentation-selbsttest',
187 'files/dbxError.log',
188 'dbxapp_install_update_dd_bindings.html',
189) as $needle) {
190 if (strpos($updateUserContent, $needle) === false) {
191 $fail('Anwender-Updateanleitung ist unvollständig: ' . $needle, 32);
192 }
193}
194
195$kiAreasContent = (string)file_get_contents($kiAreasFile);
196foreach (array(
197 '<span class="dbx-area-number">1</span>',
198 '<h2>Content</h2>',
199 '<span class="dbx-area-number">2</span>',
200 '<h2>Design</h2>',
201 '<span class="dbx-area-number">3</span>',
202 '<h2>Module</h2>',
203 '@subpage dbxapp_user_ki_content',
204 '@subpage dbxapp_user_ki_design',
205 '@subpage dbxapp_user_ki_modules',
206) as $needle) {
207 if (strpos($kiAreasContent, $needle) === false) {
208 $fail('Trennung der drei KI-Bereiche fehlt: ' . $needle, 20);
209 }
210}
211
212$tutorialFiles = glob($tutorialDir . '/*.dox');
213if (!is_array($tutorialFiles) || count($tutorialFiles) !== 18) {
214 $fail('Der generierte dbxContent-Tutorialbestand muss 18 Seiten enthalten.', 21);
215}
216
218foreach ($tutorialFiles as $tutorialFile) {
219 $tutorialContent = (string)file_get_contents($tutorialFile);
220 if (!preg_match('/^\/\*\*\s+@page\s+(dbxcontent_tutorial_[a-z0-9_]+)\s+/s', $tutorialContent, $match)) {
221 $fail('Generierte Tutorialseite besitzt keinen stabilen @page-Anker: '
222 . basename($tutorialFile), 22);
223 }
224 if (strpos($tutorialContent, 'dbxContent #') === false
225 || strpos($tutorialContent, '@note Quelle: deutsche dbxContent-Seite') === false) {
226 $fail('Quellnachweis der Tutorialseite fehlt: ' . basename($tutorialFile), 23);
227 }
228 $tutorialLabels[$match[1]] = true;
229}
230if (count($tutorialLabels) !== 18) {
231 $fail('Generierte Tutorial-Anker sind nicht eindeutig.', 24);
232}
233
234$tutorialOverview = (string)file_get_contents(
235 $tutorialDir . '/0010-tutorials-dbxapp.dox'
236);
237preg_match_all('/@image html (dbxcontent-media-[^\s"]+)/', $tutorialOverview, $overviewMedia);
238if (count($overviewMedia[1] ?? array()) === 0) {
239 $fail('Die Tutorialübersicht enthält keine zugeordneten Medien.', 31);
240}
241foreach (array_unique($overviewMedia[1]) as $asset) {
242 if (!is_file($tutorialDir . '/assets/' . $asset)) {
243 $fail('Der Tutorialübersicht fehlt die exportierte Mediendatei: ' . $asset, 31);
244 }
245}
246
247foreach (array_keys($tutorialLabels) as $tutorialLabel) {
248 if (strpos($navigationContent, $tutorialLabel) === false) {
249 $fail('Tutorial ist keiner Doxygen-Navigation zugeordnet: ' . $tutorialLabel, 25);
250 }
251}
252
253$tutorialExportContent = (string)file_get_contents($tutorialExport);
254foreach (array(
255 "get_system_obj('dbxDB')",
256 "dbxContentLng::ddContent('de')",
257 "'folder = 15 AND activ = 1'",
258 "'dbxMediaUsage'",
259 "'dbxMedia'",
260 "'--write'",
261 "'--check'",
262) as $needle) {
263 if (strpos($tutorialExportContent, $needle) === false) {
264 $fail('Tutorial-Exportvertrag ist unvollständig: ' . $needle, 26);
265 }
266}
267foreach (array('/\bPDO\b/', '/\bmysqli?\b/i', '/\bSQLite3\b/') as $forbiddenPattern) {
268 if (preg_match($forbiddenPattern, $tutorialExportContent)) {
269 $fail('Tutorial-Export umgeht dbxDB: ' . $forbiddenPattern, 27);
270 }
271}
272
273foreach (array(
274 'PROJECT_NAME = "dbxapp"',
275 'PROJECT_NUMBER = "' . $releaseVersion . '"',
276 'PROJECT_LOGO = dbXapp-Logo.jpeg',
277 'FULL_SIDEBAR = YES',
278 'FULL_PATH_NAMES = NO',
279 'PAGE_OUTLINE_PANEL = NO',
280 'STRIP_FROM_PATH = .',
281 'FILTER_PATTERNS = *dbxApi.php="php -n docs/tools/doxygen_php_utf8_filter.php"',
282 '*dbxUpload.class.php="php -n docs/tools/doxygen_php_utf8_filter.php"',
283 'FILTER_SOURCE_FILES = YES',
284 'docs/doxygen-generated-main.dox',
285 'docs/doxygen-awesome/header.html',
286 'docs/doxygen-awesome/dbxapp-doxygen.css',
287) as $needle) {
288 if (strpos($doxyContent, $needle) === false) {
289 $fail('Doxygen-Branding- oder Strukturkonfiguration fehlt: ' . $needle, 28);
290 }
291}
292
293$headerContent = (string)file_get_contents($brandingHeader);
294$cssContent = (string)file_get_contents($brandingCss);
295foreach (array(
296 'Anwender',
297 'Entwickler',
298 'KI-Bereiche',
299 'data-dbx-section="user"',
300 'dbx-doc-nav-icon',
301 'dbx-doc-tools',
302 'dbx-doc-embedded',
303) as $needle) {
304 if (strpos($headerContent, $needle) === false) {
305 $fail('Zielgruppen-Navigation im dbxapp-Header fehlt: ' . $needle, 29);
306 }
307}
308foreach (array(
309 '--dbx-brand-navy',
310 '--dbx-brand-red',
311 '.dbx-doc-hero',
312 '.dbx-audience-grid',
313 '#dbx-doc-audience a.is-active',
314 '.dbx-doc-nav-icon',
315 '.dbx-doc-tools',
316 '.dbx-user-nav-grid',
317 '.dbx-update-steps',
318 '.dbx-update-state-grid',
319 'html.dbx-doc-embedded #doc-content',
320) as $needle) {
321 if (strpos($cssContent, $needle) === false) {
322 $fail('dbxapp-Branding-CSS ist unvollständig: ' . $needle, 30);
323 }
324}
325
326$referenceContent = (string)file_get_contents($referenceFile);
327foreach (array(
328 'dbxTPL',
329 'dbxDB',
330 'dbxDD',
331 'dbxForm',
332 'dbxReport',
333 'DD',
334 'FD',
335 'dbxAjax',
336 'dbxConfirm',
337 'Kombination aus `delete` und `rid` automatisch',
338 'action_url',
339 'invoice_report_next_record',
340 'invoice_items_report_next_record',
341 '{rpt:colspan}',
342 'add_rep()',
343 "\$report->_mode = 'table'",
344 "'sum' => 'Summe'",
345 '{report_total}',
346 '[modul=myInvoices]dbx_run1=positions&invoice_id=',
347 '{rpt:col_count}',
348 '<tfoot>',
349 '[dbx:form]',
350 'dbx_split',
351 'Verbindliche Arbeitsanweisung',
352 'Mindesttestmatrix',
353 'myInvoices_contract_test.php',
354 'myInvoices_integration_test.php',
355 'include/myInvoicesFixtures.class.php',
356 'Browserkonsole',
357 '@include dbx/modules/myInvoices/dd/invoice.dd.php',
358 '@include dbx/modules/myInvoices/dd/invoiceItem.dd.php',
359 'dbxapp-Exportformat',
360) as $needle) {
361 if (strpos($referenceContent, $needle) === false) {
362 $fail('Referenzmodul ist unvollstaendig: ' . $needle, 8);
363 }
364}
365
366$actualService = (string)file_get_contents(
367 $referenceModule . '/include/myInvoicesService.class.php'
368);
369$actualFixtures = (string)file_get_contents(
370 $referenceModule . '/include/myInvoicesFixtures.class.php'
371);
372foreach (array(
373 '/\bPDO\b/',
374 '/\bmysqli?_/',
375 '/->(?:query|exec|prepare)\s*\‍(/',
376 '/private function (?:db|tpl|h)\s*\‍(/',
377) as $forbiddenPattern) {
378 if (preg_match($forbiddenPattern, $actualService . "\n" . $actualFixtures)) {
379 $fail(
380 'Ausführbares Referenzmodul verletzt den Daten-/Wrappervertrag: '
381 . $forbiddenPattern,
382 17
383 );
384 }
385}
386foreach (array(
387 'create_date',
388 'create_uid',
389 'update_date',
390 'update_uid',
391 'owner',
392) as $systemField) {
393 if (preg_match(
394 '/[\'"]' . preg_quote($systemField, '/') . '[\'"]\s*=>/',
396 )) {
397 $fail(
398 'Fixture setzt automatisches dbxDB-Systemfeld: ' . $systemField,
399 18
400 );
401 }
402}
403
404if (!preg_match_all('/```php\s*(<\?php.*?)(?=```)/s', $referenceContent, $phpBlocks)
405 || count($phpBlocks[1]) < 5
406) {
407 $fail('Zu wenige vollstaendige PHP-Dateibeispiele im Referenzmodul.', 9);
408}
409
410foreach ($phpBlocks[1] as $index => $phpBlock) {
411 try {
412 token_get_all($phpBlock, TOKEN_PARSE);
413 } catch (ParseError $e) {
414 $fail(
415 'PHP-Beispiel ' . ($index + 1) . ' ist syntaktisch ungueltig: '
416 . $e->getMessage(),
417 10
418 );
419 }
420}
421
422if (!preg_match('/class myInvoicesService.*?\?>/s', $referenceContent, $serviceMatch)) {
423 $fail('Servicebeispiel im Referenzmodul nicht gefunden.', 11);
424}
425
426$serviceExample = $serviceMatch[0];
427foreach (array(
428 '/private function (?:db|tpl|h)\s*\‍(/',
429 '/(?:private|protected|public) function \w+\s*\‍([^)]*\‍)[^{]*\{\s*return\s+dbx\‍(\‍)->get_system_obj\s*\‍(/s',
430 '/dbx\‍(\‍)->esc\s*\‍(/',
431 '/htmlspecialchars\s*\‍(/',
432 '/[\'"](?:create_date|create_uid|update_date|update_uid|owner)[\'"]\s*=>\s*(?:date|dbx\‍(\‍)->user)/',
433) as $forbiddenPattern) {
434 if (preg_match($forbiddenPattern, $serviceExample)) {
435 $fail(
436 'Servicebeispiel enthaelt ein unzulaessiges Wrapper-, Escape- '
437 . 'oder Systemfeldmuster: ' . $forbiddenPattern,
438 12
439 );
440 }
441}
442
443foreach (array(
444 'automatisch von `dbxDB` gesetzt',
445 'Kernel-Funktionen nicht durch eigene Methoden nachbauen',
446 'Werte nicht pauschal escapen',
447 'Endsumme der Positionen',
448 'geschützte Modulvariablen',
449) as $requiredContract) {
450 if (strpos($referenceContent, $requiredContract) === false) {
451 $fail('Vereinfachungsvertrag fehlt: ' . $requiredContract, 13);
452 }
453}
454
455$modulePatternContent = (string)file_get_contents(
456 $root . '/08_Modulaufbau_Patterns.md'
457);
458$formGuideContent = (string)file_get_contents(
459 $root . '/06_dbxForm_Leitfaden.md'
460);
461
462foreach (array(
463 '/private function (?:db|tpl|h)\s*\‍(/',
464 '/dbx\‍(\‍)->esc\s*\‍(/',
465 '/htmlspecialchars\s*\‍(/',
466) as $forbiddenPattern) {
467 if (preg_match($forbiddenPattern, $modulePatternContent)) {
468 $fail(
469 'Modulpattern enthaelt einen unzulaessigen Alias oder '
470 . 'pauschales Escaping: ' . $forbiddenPattern,
471 14
472 );
473 }
474}
475
476if (preg_match(
477 '/set_post\s*\‍(\s*[\'"](?:create_date|create_uid|update_date|update_uid|owner)[\'"]/',
479)) {
480 $fail('Formleitfaden setzt automatische dbxDB-Systemfelder manuell.', 15);
481}
482
483echo 'OK Doxygen structure: '
484 . count($docs) . ' pages, '
485 . count($anchors) . ' anchors, '
486 . count($references) . ' references, '
487 . count($phpBlocks[1]) . " PHP examples\n";
foreach(array( 'forms', 'reports', 'dd', 'db', 'audit', 'objects', 'escaping', 'get', 'action_links') as $requiredKey) foreach(array('{fid}_{event}-Callback-Defaults', 'add_rep()', '{rpt:colspan}') as $requiredReportRule) $reference
if($missingReferences) $doxyContent
foreach(array(' @page dbxapp_user_docs Anwenderdokumentation', ' @page dbxapp_user_start Einstieg und Bedienung', ' @page dbxapp_user_admin Administration und Systemstatus', ' @subpage dbxapp_user_system_update', ' @page dbxapp_user_content Inhalte, CMS und Medien', ' @page dbxapp_user_shop Shop bedienen und administrieren', ' @page dbxapp_user_workflows Workflows erstellen und benutzen', ' @page dbxapp_user_design Designs manuell und mit KI erstellen', ' @page dbxapp_user_ki_content KI-Bereich 1:Content', ' @page dbxapp_user_ki_design KI-Bereich 2:Design', ' @page dbxapp_user_ki_modules KI-Bereich 3:Module', ' @page dbxapp_developer_docs Entwicklerdokumentation', ' @page dbxapp_dev_orientation Architektur und Laufzeit', ' @page dbxapp_dev_modules Verbindliche Modulentwicklung', ' @page dbxapp_dev_pipelines Kernpipelines und Bibliotheken', ' @page dbxapp_dev_content_design CMS, KI, Design und Fachmodule', ' @page dbxapp_dev_operations Installation, Updates und Betrieb',) as $needle) $updateUserContent
if(!preg_match_all('/```php\s *(<\?php.*?)(?=```)/s', $referenceContent, $phpBlocks)||count($phpBlocks[1])< 5) foreach( $phpBlocks[1] as $index=> $phpBlock) if(!preg_match('/class myInvoicesService.*?\?>/s', $referenceContent, $serviceMatch)) $serviceExample
foreach(array( 'Anwender', 'Entwickler', 'KI-Bereiche', 'data-dbx-section="user"', 'dbx-doc-nav-icon', 'dbx-doc-tools', 'dbx-doc-embedded',) as $needle) foreach(array('--dbx-brand-navy', '--dbx-brand-red', '.dbx-doc-hero', '.dbx-audience-grid', '#dbx-doc-audience a.is-active', '.dbx-doc-nav-icon', '.dbx-doc-tools', '.dbx-user-nav-grid', '.dbx-update-steps', '.dbx-update-state-grid', 'html.dbx-doc-embedded #doc-content',) as $needle) $referenceContent
foreach(array('dbxTPL', 'dbxDB', 'dbxDD', 'dbxForm', 'dbxReport', 'DD', 'FD', 'dbxAjax', 'dbxConfirm', 'Kombination aus `delete` und `rid` automatisch', 'action_url', 'invoice_report_next_record', 'invoice_items_report_next_record', '{rpt:colspan}', 'add_rep()', "\$report->_mode = 'table'", "'sum' => 'Summe'", '{report_total}', '[modul=myInvoices]dbx_run1=positions &invoice_id=', '{rpt:col_count}', '< tfoot >', '[dbx:form]', 'dbx_split', 'Verbindliche Arbeitsanweisung', 'Mindesttestmatrix', 'myInvoices_contract_test.php', 'myInvoices_integration_test.php', 'include/myInvoicesFixtures.class.php', 'Browserkonsole', ' @include dbx/modules/myInvoices/dd/invoice.dd.php', ' @include dbx/modules/myInvoices/dd/invoiceItem.dd.php', 'dbxapp-Exportformat',) as $needle) $actualService
foreach( $tutorialFiles as $tutorialFile) if(count($tutorialLabels) !==18) $tutorialOverview
if(count($overviewMedia[1] ?? array())===0) foreach(array_unique( $overviewMedia[1]) as $asset) foreach(array_keys($tutorialLabels) as $tutorialLabel) $tutorialExportContent
foreach($docs as $doc) foreach(array( $navigationFile, $updateUserFile) as $doxygenPageFile) if($duplicateAnchors) $missingReferences
foreach(array(' @page dbxapp_user_system_update System-Update sicher durchführen', 'Update automatisch vorbereiten', 'Update stoppen', 'Jetzt sicher installieren', 'Letztes Update zurückrollen', 'DB3, MySQL und gemischte Installationen', 'System → System-Selbsttest', 'dokumentation-selbsttest', 'files/dbxError.log', 'dbxapp_install_update_dd_bindings.html',) as $needle) $kiAreasContent
foreach([ $doxyfile, $mainFile, $referenceFile, $navigationFile, $updateUserFile, $kiAreasFile, $tutorialExport, $brandingHeader, $brandingCss, $utf8Filter,] as $requiredFile) foreach(array('myInvoices.class.php', 'cfg/config.php', 'dd/invoice.dd.php', 'dd/invoiceItem.dd.php', 'fd/invoice-form.fd.php', 'fd/rpt-invoice-selection.fd.php', 'include/myInvoicesFixtures.class.php', 'include/myInvoicesService.class.php', 'tpl/htm/invoice-form.htm', 'tpl/htm/invoice-report.htm', 'tpl/htm/invoice-items-report.htm', 'tpl/htm/invoice-row-action.htm', 'tpl/htm/invoice-install.htm', 'tools/install_demo.php', 'tests/myInvoices_contract_test.php', 'tests/myInvoices_integration_test.php', 'README.md',) as $relative) $docs
foreach(array('docs/doxygen-navigation.dox', 'docs/dbxapp-system-update-user.dox', 'docs/generated/tutorials', '25_Verbindliches_Modulhandbuch.md', 'files/doku',) as $editorialInput) $mainContent
foreach(array(' @mainpage dbxapp Quellcode-Referenz', ' @ref annotated "Klassen"', ' @ref namespaces "Namespaces"', ' @ref files "Dateien"', ' @ref examples "Beispiele"', 'dbxapp-Dokumentationsportal öffnen',) as $needle) $navigationContent
if(!is_array($tutorialFiles)||count($tutorialFiles) !==18) $tutorialLabels
foreach(array("get_system_obj('dbxDB')", "dbxContentLng::ddContent('de')", "'folder = 15 AND activ = 1'", "'dbxMediaUsage'", "'dbxMedia'", "'--write'", "'--check'",) as $needle) foreach(array('/\bPDO\b/', '/\bmysqli?\b/i', '/\bSQLite3\b/') as $forbiddenPattern) foreach(array('PROJECT_NAME="dbxapp"', 'PROJECT_NUMBER="' . $releaseVersion . '"', 'PROJECT_LOGO=dbXapp-Logo.jpeg', 'FULL_SIDEBAR=YES', 'FULL_PATH_NAMES=NO', 'PAGE_OUTLINE_PANEL=NO', 'STRIP_FROM_PATH=.', 'FILTER_PATTERNS= *dbxApi.php="php -n docs/tools/doxygen_php_utf8_filter.php"', ' *dbxUpload.class.php="php -n docs/tools/doxygen_php_utf8_filter.php"', 'FILTER_SOURCE_FILES=YES', 'docs/doxygen-generated-main.dox', 'docs/doxygen-awesome/header.html', 'docs/doxygen-awesome/dbxapp-doxygen.css',) as $needle $headerContent)
foreach(array('< span class="dbx-area-number">1</span >', '< h2 >Content</h2 >', '< span class="dbx-area-number">2</span >', '< h2 >Design</h2 >', '< span class="dbx-area-number">3</span >', '< h2 >Module</h2 >', ' @subpage dbxapp_user_ki_content', ' @subpage dbxapp_user_ki_design', ' @subpage dbxapp_user_ki_modules',) as $needle) $tutorialFiles
exit
Definition index.php:146