dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxHomepageMedia_contract_test.php
Go to the documentation of this file.
1<?php
2declare(strict_types=1);
3
4$base = dirname(__DIR__, 3);
5chdir($base);
6$_SERVER['REQUEST_URI'] = '/dbxapp/';
7$_SERVER['HTTP_HOST'] = 'localhost';
8$_SERVER['HTTPS'] = 'on';
9$_SERVER['SCRIPT_NAME'] = '/dbxapp/index.php';
10
11define('dbxSystem', 'dbxWebApp');
12define('dbxRunAsAdmin', 1);
13
14require $base . '/dbx/vendor/autoload.php';
15require_once $base . '/dbx/include/dbxKernel.php';
16
17$db = dbx()->get_system_obj('dbxDB');
18$failures = array();
19$assert = static function (bool $condition, string $message) use (&$failures): void {
20 if (!$condition) {
21 $failures[] = $message;
22 }
23};
24
25$hasRuntimeFixtures = is_file($base . '/dbx/modules/dbx/db/dbxContent.db3')
26 && filesize($base . '/dbx/modules/dbx/db/dbxContent.db3') > 0
27 && is_file($base . '/dbx/modules/dbx/db/dbxMedia.db3')
28 && filesize($base . '/dbx/modules/dbx/db/dbxMedia.db3') > 0;
29
31$pages = $db->select(
32 'dbx|content_de',
33 array('permalink' => 'home'),
34 '*',
35 'id',
36 'ASC',
37 '',
38 1,
39 0,
40 0
41);
42$page = is_array($pages) && isset($pages[0]) ? $pages[0] : array();
43$content = (string)($page['content'] ?? '');
44
45$assert((int)($page['id'] ?? 0) > 0, 'German homepage is missing.');
47 (string)($page['template'] ?? '') === 'c-title-hero_header-body1-footer'
48 && (string)($page['hero_template'] ?? '') === 'image-hero'
49 && (int)($page['hero_image_id'] ?? 0) === 166,
50 'Homepage does not use the CMS Hero template and Hero media #166.'
51);
52$heroMarkerPosition = strpos($content, 'data-dbx-marker="dbx:hero"');
53$heroTextPosition = strpos($content, 'Eine Plattform. Klare Abläufe.');
55 $heroTextPosition !== false
56 && $heroMarkerPosition !== false
57 && $heroTextPosition < $heroMarkerPosition,
58 'Homepage Hero text is not stored before the dbx:hero marker.'
59);
61 !str_contains($content, 'dbx_mid=166') && !str_contains($content, 'data-cms-media-id="166"'),
62 'Hero media #166 must not be embedded as an inline image.'
63);
64$assert(str_contains($content, 'Eine Plattform in Bewegung.'), 'Homepage video introduction is missing.');
66 str_contains($content, 'Bestehende Systeme lassen sich leicht nachbilden und optimieren.'),
67 'Required statement about rebuilding and optimizing existing systems is missing.'
68);
69$videoIntroPosition = strpos($content, 'Eine Plattform in Bewegung.');
70$videoPosition = strpos($content, 'dbx-cms-inline-video-block');
72 str_contains($content, '<div class="row g-4 mb-5">')
73 && substr_count($content, '<div class="col-12">') >= 2
74 && $videoIntroPosition !== false
75 && $videoPosition !== false
76 && $videoIntroPosition < $videoPosition,
77 'Homepage video introduction and video are not arranged as editable stacked columns.'
78);
79foreach (array(371, 432) as $mediaId) {
80 $assert(
81 str_contains($content, 'dbx_mid=' . $mediaId),
82 'Homepage does not reference replacement media #' . $mediaId . '.'
83 );
84}
85
86$usageRows = $db->select(
87 'dbx|dbxMediaUsage',
88 'content_id = ' . (int)($page['id'] ?? 0) . ' AND active = 1',
89 '*',
90 'sorter,id',
91 'ASC',
92 '',
93 0,
94 0,
95 0
96);
97$heroUsage = array_values(array_filter(is_array($usageRows) ? $usageRows : array(), static function (array $row): bool {
98 return (string)($row['slot'] ?? '') === 'hero' && (int)($row['media_id'] ?? 0) === 166;
99}));
100$assert(count($heroUsage) === 1, 'Homepage must have exactly one active Hero usage for media #166.');
101
102$expected = array(
103 166 => 'media/img/hero/dbxapp-platform-hero-20260728.webp',
104 371 => 'media/img/images/dbxapp-systeme-neu-denken-20260728.webp',
105 432 => 'media/img/images/dbxapp-modular-wachsen-20260728.webp',
106);
107foreach ($expected as $mediaId => $path) {
108 $rows = $db->select('dbx|dbxMedia', array('id' => $mediaId), '*', 'id', 'ASC', '', 1, 0, 0);
109 $row = is_array($rows) && isset($rows[0]) ? $rows[0] : array();
110 $assert((string)($row['file_path'] ?? '') === $path, 'Unexpected file path for media #' . $mediaId . '.');
111 $assert(is_file($base . '/files/' . $path), 'Replacement file is missing: ' . $path);
112}
113
114$videos = $db->select(
115 'dbx|dbxMedia',
116 array('file_path' => 'media/video/dbxapp-tvspot-20260731-v4.mp4'),
117 '*',
118 'id',
119 'ASC',
120 '',
121 1,
122 0,
123 0
124);
125$video = is_array($videos) && isset($videos[0]) ? $videos[0] : array();
126$videoId = (int)($video['id'] ?? 0);
127$videoFile = $base . '/files/' . (string)($video['file_path'] ?? '');
128$assert($videoId > 0, 'Homepage video is not registered in dbxMedia.');
129$assert(str_contains($content, 'dbx_mid=' . $videoId), 'Homepage does not reference the registered video.');
130$assert(
131 preg_match(
132 '/<figure\b[^>]*\bdbx-cms-inline-video-block\b[^>]*\bdata-cms-media-id="' . $videoId . '"[^>]*>/i',
134 ) === 1,
135 'Homepage video does not use the CMS-stable inline-video placeholder.'
136);
137
138$inlineUsageIds = array_values(array_unique(array_map(
139 static fn(array $row): int => (int)($row['media_id'] ?? 0),
140 array_filter(is_array($usageRows) ? $usageRows : array(), static fn(array $row): bool => (string)($row['slot'] ?? '') === 'inline')
141)));
142sort($inlineUsageIds);
143$expectedInlineUsageIds = array($videoId, 371, 432);
144sort($expectedInlineUsageIds);
145$assert($inlineUsageIds === $expectedInlineUsageIds, 'Homepage inline media usages do not match the actual editor content.');
146$assert(is_file($videoFile), 'Homepage video file is missing.');
147$assert(!is_file($videoFile) || filesize($videoFile) <= 12 * 1024 * 1024, 'Homepage video exceeds 12 MiB.');
148$assert(
149 (string)($video['thumb_file_path'] ?? '') === 'media/img/images/dbxapp-tvspot-poster-20260731-v4.webp',
150 'Homepage video poster is not registered as the video thumbnail.'
151);
152$assert(
153 is_file($base . '/files/media/video/dbxapp-tvspot-20260731-v4-license.txt'),
154 'Homepage TV spot license provenance is missing.'
155);
156$assert(
157 is_file($base . '/files/media/video/dbxapp-tvspot-20260731-v4-manifest.json'),
158 'Homepage TV spot build manifest is missing.'
159);
160} else {
161 // Ein öffentlicher Checkout enthält absichtlich weder Inhaltsdatenbank
162 // noch Medien. Die portablen CMS-/Renderer-Verträge werden trotzdem
163 // vollständig geprüft.
164 $videoId = 777;
165}
166
167require_once $base . '/dbx/modules/dbxContent_admin/include/dbxContent_cms.class.php';
169 $cmsClass = new ReflectionClass(\dbx\dbxContent_admin\dbxContent_cms::class);
170 $cms = $cmsClass->newInstanceWithoutConstructor();
171 $normalize = $cmsClass->getMethod('normalize_content_media_urls');
172 $normalize->setAccessible(true);
173 $legacyVideo = '<div class="ratio ratio-16x9"><video controls>'
174 . '<source src="index.php?dbx_modul=dbxContent&amp;dbx_run1=media&amp;dbx_mid=' . $videoId . '" type="video/mp4">'
175 . '</video></div>';
176 $normalizedVideo = (string)$normalize->invoke($cms, $legacyVideo);
177 $assert(
178 str_contains($normalizedVideo, 'dbx-cms-inline-video-block')
179 && str_contains($normalizedVideo, 'data-cms-media-id="' . $videoId . '"'),
180 'Legacy CMS video markup is not converted to a stable media placeholder.'
181 );
182 $placeholderWithoutWrapperId = '<figure class="dbx-cms-inline-media dbx-cms-inline-video-block">'
183 . '<img src="index.php?dbx_modul=dbxContent&amp;dbx_run1=media&amp;dbx_mid=' . $videoId . '"'
184 . ' data-cms-media-id="' . $videoId . '"></figure>';
185 $normalizedPlaceholder = (string)$normalize->invoke($cms, $placeholderWithoutWrapperId);
186 $assert(
187 preg_match(
188 '/<figure\b[^>]*\bdbx-cms-inline-video-block\b[^>]*\bdata-cms-media-id="' . $videoId . '"[^>]*>/i',
189 $normalizedPlaceholder
190 ) === 1,
191 'CMS video wrapper does not recover its media ID from the contained placeholder.'
192 );
193} else {
194 $cmsSource = (string)file_get_contents(
195 $base . '/dbx/modules/dbxContent_admin/include/dbxContent_cms.class.php'
196 );
197 $assert(
198 str_contains($cmsSource, 'normalize_content_media_urls')
199 && str_contains($cmsSource, 'dbx-cms-inline-video-block')
200 && str_contains($cmsSource, 'data-cms-media-id'),
201 'Portable CMS video normalization contract is incomplete.'
202 );
203}
204
205foreach (array('dbxapp', 'dbxdocs', 'steal') as $design) {
206 $contentCss = (string)file_get_contents($base . '/dbx/design/' . $design . '/css/c-content.css');
207 $cmsCss = (string)file_get_contents($base . '/dbx/design/' . $design . '/css/c-cms.css');
208 $assert(
209 str_contains($contentCss, '.ratio > .dbx-content-inline-video')
210 && str_contains($contentCss, 'position: absolute;'),
211 'Frontend video is not compatible with ratio containers in design ' . $design . '.'
212 );
213 $assert(
214 str_contains($cmsCss, '.jodit-wysiwyg .ratio > .dbx-cms-inline-video-block')
215 && str_contains($cmsCss, 'resize: none;'),
216 'CMS video preview is not compatible with ratio containers in design ' . $design . '.'
217 );
218}
219
220if ($failures !== array()) {
221 fwrite(STDERR, "FAIL\n- " . implode("\n- ", $failures) . "\n");
222 exit(1);
223}
224
226 ? 'OK homepage uses the native CMS Hero, matching inline media usages and a registered web video.'
227 : 'OK portable homepage media contracts; local content/media fixtures are not part of the public checkout.')
228 . PHP_EOL;
$_SERVER['REQUEST_METHOD']
foreach( $iterator as $file) if(! $groups) $expected
if(trim($second) !=='second') $design
exit
Definition index.php:146
DBX schema administration.
if($cinematic===''||!str_contains($cinematic, 'data-dbx-cinema')) $page