2declare(strict_types=1);
6if (PHP_SAPI !==
'cli') {
7 fwrite(STDERR,
"Dieses Werkzeug darf nur auf der Kommandozeile laufen.\n");
14 fwrite(STDERR,
"--write und --check dürfen nicht gemeinsam verwendet werden.\n");
26define(
'dbxSystem',
'dbxWebApp');
27define(
'dbxRunAsAdmin', 1);
29require
$root .
'/dbx/vendor/autoload.php';
30require_once
$root .
'/dbx/include/dbxKernel.php';
31require_once
$root .
'/dbx/modules/dbxContent/include/dbxContent_bootstrap_sync.php';
37 $token = strtolower(trim($permalink));
40 return 'dbxcontent_tutorial_' . (
$token !==
'' ?
$token :
'seite');
48 array(
'dbXApp',
'dbXapp',
'DBXapp',
'DBXApp'),
61 array(
' fuer ',
'Gefuehrter',
'gefuehrter'),
62 array(
' für ',
'Geführter',
'geführter'),
68 return htmlspecialchars(
$value, ENT_QUOTES | ENT_SUBSTITUTE,
'UTF-8');
74 return trim((
string)
$value,
'.-');
78 $path = trim((string)($row[
'file_path'] ??
''));
79 $extension = strtolower((
string)pathinfo($path, PATHINFO_EXTENSION));
80 if (!preg_match(
'/^[a-z0-9]{2,8}$/', $extension)) {
87 return 'dbxcontent-media-' . (int)($row[
'id'] ?? 0) .
'-' . $title .
'.' . $extension;
104 'id,active,title,alt,caption,file_name,file_path,mime,size,width,height',
108 || (
int)($row[
'id'] ?? 0) !==
$mediaId
109 || (
int)($row[
'active'] ?? 0) !== 1) {
134 $relative = str_replace(
'\\',
'/', trim((
string)($row[
'file_path'] ??
'')));
135 $relative = ltrim($relative,
'/');
137 . str_replace(
'/', DIRECTORY_SEPARATOR, $relative);
138 $sourceReal = realpath(
$source);
140 if ($sourceReal ===
false
141 || $fileRootReal ===
false
142 || strpos(strtolower($sourceReal), strtolower(rtrim($fileRootReal,
'/\\') . DIRECTORY_SEPARATOR)) !== 0
143 || !is_file($sourceReal)) {
150 'source' => $sourceReal,
151 'target' =>
$assetDir . DIRECTORY_SEPARATOR . $assetName,
173 $html = preg_replace(
'#<script\b[^>]*>.*?</script>#is',
'',
$html);
174 $html = preg_replace(
'#<style\b[^>]*>.*?</style>#is',
'', (
string)
$html);
175 $html = preg_replace(
'/\s+on[a-z]+\s*=\s*(["\']).*?\1/is',
'', (
string)
$html);
176 $html = preg_replace(
'#<h1\b([^>]*)>(.*?)</h1>#is',
'<h2$1>$2</h2>', (
string)
$html);
178 $html = preg_replace_callback(
179 '#(<img\b[^>]*\bsrc=)(["\'])([^"\']+)\2#i',
180 static function(array $match) use (
189 $src = html_entity_decode((
string)$match[3], ENT_QUOTES | ENT_HTML5,
'UTF-8');
190 if (!preg_match(
'/(?:[?&]|\b)dbx_mid=([0-9]+)/i', $src, $idMatch)) {
203 if ($assetName ===
'') {
207 return $match[1] . $match[2] . $assetName . $match[2];
212 $html = preg_replace_callback(
213 '#<a\b([^>]*)\bhref=(["\'])([^"\']+)\2([^>]*)>(.*?)</a>#is',
214 static function(array $match) use (
$labelMap):
string {
215 $href = html_entity_decode(trim((
string)$match[3]), ENT_QUOTES | ENT_HTML5,
'UTF-8');
216 $permalink = trim((
string)
parse_url($href, PHP_URL_PATH),
'/');
218 $text = trim(preg_replace(
'/\s+/u',
' ', strip_tags((
string)$match[5])));
223 if (strpos($href,
'?dbx_') === 0 || strpos($href,
'index.php?dbx_') === 0) {
224 $text = trim(preg_replace(
'/\s+/u',
' ', strip_tags((
string)$match[5])));
225 return '<span class="dbx-runtime-route"><strong>'
234 $html = preg_replace_callback(
235 '#\[modul=([^\]]+)\](.*?)\[/modul\]#is',
236 static function(array $match):
string {
237 return '<pre class="dbx-runtime-example"><code>'
244 return trim((
string)
$html);
248 $alt = trim((string)(
$media[
'alt'] ??
''));
250 $alt = trim((
string)(
$media[
'title'] ??
'Screenshot'));
252 $caption = trim((
string)(
$media[
'caption'] ??
''));
253 if ($caption ===
'') {
254 $caption = trim((
string)(
$media[
'title'] ??
''));
258 $caption = trim(preg_replace(
'/\s+/u',
' ', strip_tags($caption)));
259 $caption = str_replace(array(
'\\',
'"'), array(
'\\\\',
"'"), $caption);
260 return '@image html ' . $assetName . ($caption !==
'' ?
' "' . $caption .
'"' :
'');
264if (!is_object(
$db) || !
$db->connect_db_server(
'dbx|dbxContent.db3')) {
265 fwrite(STDERR,
"Die Content-Datenbank konnte nicht über dbxDB verbunden werden.\n");
272 'folder = 15 AND activ = 1',
273 'id,folder,sorter,title,permalink,description,content,update_date',
282 fwrite(STDERR,
"Im deutschen Tutorial-Ordner wurden keine aktiven Seiten gefunden.\n");
291 $permalink = trim((
string)(
$page[
'permalink'] ??
''));
292 if ($permalink !==
'') {
306 $id = (int)(
$page[
'id'] ?? 0);
307 $permalink = trim((
string)(
$page[
'permalink'] ??
''));
308 if ($id <= 0 || $permalink ===
'' || !isset(
$labelMap[$permalink])) {
312 $inlineMedia = array();
314 (
string)(
$page[
'content'] ??
''),
325 $usageRows =
$db->select(
327 'content_id = ' . $id .
' AND active = 1',
328 'id,media_id,slot,sorter',
337 $seenUsage = array();
338 foreach (is_array($usageRows) ? $usageRows : array() as $usage) {
340 $mediaId = (int)($usage[
'media_id'] ?? 0);
346 if (isset($inlineMedia[
$mediaId])) {
360 if ($assetName ===
'' || !
$media || strpos(strtolower((
string)(
$media[
'mime'] ??
'')),
'image/') !== 0) {
435 $documents[$fileName] = implode(
"\n", $lines);
445 fwrite(STDERR,
"Das Doxygen-Tutorialverzeichnis konnte nicht angelegt werden.\n");
448 foreach (array_merge(
454 foreach (glob(
$assetDir .
'/dbxcontent-media-*') ?: array() as $oldAsset) {
459 fwrite(STDERR,
"Tutorial konnte nicht geschrieben werden: {$fileName}\n");
465 if (!copy((
string)$asset[
'source'], (
string)$asset[
'target'])) {
466 fwrite(STDERR,
"Tutorialmedium konnte nicht kopiert werden: {$asset['source']}\n");
476 if (!is_file($path) || (
string)file_get_contents($path) !==
$content) {
477 $stale[] = str_replace(
'\\',
'/', substr($path, strlen(
$root) + 1));
480 foreach (
$assets as $assetName => $asset) {
481 $target = (string)$asset[
'target'];
482 $source = (string)$asset[
'source'];
485 || hash_file(
'sha256',
$target) !== hash_file(
'sha256',
$source)) {
486 $stale[] =
'docs/generated/tutorials/assets/' . $assetName;
499 'unique_media_assets' => count(
$assets),
505echo json_encode(
$result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
parse_url($data)
Zerlegt URL-/Parameterdaten in einen Array.
$_SERVER['REQUEST_METHOD']
if(strpos($mainRule, 'dbx-page-gears-v1.svg')===false||strpos($mainRule, 'background-repeat:no-repeat, no-repeat, repeat !important')===false||strpos($mainRule, 'background-size:100vw auto')===false) $assets
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
dbxDoxygenFigure(array $media, string $assetName)
dbxDoxygenMediaRow($db, int $mediaId, array &$cache)
Liefert einen Medien-Datensatz ausschließlich über dbxDB.
dbxDoxygenMediaAssetName(array $row)
foreach($pages as $page) $stale
dbxDoxygenRegisterMedia( $db, int $mediaId, array &$mediaCache, array &$assets, array &$missingMedia, string $fileRoot, string $assetDir)
Registriert eine lokale Mediendatei für den generierten Doxygen-Bestand.
dbxDoxygenNormalizeBrand(string $value)
Vereinheitlicht ausschließlich die Produktbezeichnung in der Exportkopie.
dbxDoxygenNormalizeDisplayText(string $value)
Korrigiert bekannte alte ASCII-Umschriften in sichtbaren Metadaten.
dbxDoxygenHtml(string $value)
dbxDoxygenTutorialLabel(string $permalink)
Erzeugt einen stabilen Doxygen-Bezeichner aus einem Permalink.
foreach($pages as $page) $documents
dbxDoxygenPrepareContent(string $html, $db, array $labelMap, array &$inlineMedia, array &$mediaCache, array &$assets, array &$missingMedia, string $fileRoot, string $assetDir)
Entfernt aktive Browserbestandteile, normalisiert Überschriften und wandelt dbxContent-interne Links ...
dbxDoxygenSafeFileToken(string $value)
if(!is_array($pages)||! $pages) $outputDir
if(PHP_SAPI !=='cli') $write
DBX schema administration.
if($cinematic===''||!str_contains($cinematic, 'data-dbx-cinema')) $page
for( $step=0;$step< 1000;$step++) if(($schema['status'] ?? '') !=='finished') $media