3class dbxContentPageCacheTestApi {
4 public array $system = array();
5 public array $request = array();
8 'default_design_user' =>
'dbxapp',
10 public int $effectiveUser = 0;
11 private string $fileDir;
12 private string $baseDir;
15 $this->fileDir = rtrim($fileDir,
'/\\') . DIRECTORY_SEPARATOR;
16 $this->baseDir = $this->fileDir .
'app' . DIRECTORY_SEPARATOR;
17 $this->writeConfigFile();
21 return $this->fileDir;
25 return $this->baseDir;
29 return (string)($this->
system[
'dbx_base_url'] ??
'');
32 public function os_path(
string $path): string {
33 return str_replace(array(
'/',
'\\'), DIRECTORY_SEPARATOR, $path);
36 public function get_config(
string $module, ?
string $key =
null) {
38 return $key ===
null ? array() :
'undef';
40 return $key ===
null ? $this->config : ($this->config[$key] ??
'undef');
48 $this->writeConfigFile();
52 private function writeConfigFile(): void {
53 $dir = $this->baseDir .
'dbx' . DIRECTORY_SEPARATOR .
'modules' . DIRECTORY_SEPARATOR
54 .
'dbx' . DIRECTORY_SEPARATOR .
'cfg';
56 mkdir(
$dir, 0755,
true);
59 $dir . DIRECTORY_SEPARATOR .
'config.php',
60 "<?php\n\$config['cache_content'] = " . (
int)($this->config[
'cache_content'] ?? 1) .
";\n"
64 public function get_request_var(
string $key, $default =
'',
string $type =
'') {
65 $value = $this->request[$key] ?? $default;
69 public function get_system_var(
string $key, $default =
'',
string $type =
'') {
74 public function set_system_var(
string $key,
$value): void {
79 $skin = strtolower(trim($skin));
80 return preg_match(
'/^[a-z0-9_-]+$/', $skin) ? $skin :
'blau';
84 return in_array(
$design, array(
'dbxapp',
'flowers'), true);
87 public function user(): int {
88 return $this->effectiveUser;
92$testRoot = rtrim(sys_get_temp_dir(),
'/\\') . DIRECTORY_SEPARATOR
93 .
'dbx-page-cache-test-' . getmypid() .
'-' . bin2hex(random_bytes(4));
94if (!mkdir($testRoot, 0755,
true) && !is_dir($testRoot)) {
95 fwrite(STDERR,
"FAIL: Testverzeichnis konnte nicht erstellt werden.\n");
99$deleteTree =
static function (
string $path) use (&$deleteTree):
void {
101 if (
$resolved ===
false || !str_starts_with(basename(
$resolved),
'dbx-page-cache-test-')) {
104 $iterator =
new RecursiveIteratorIterator(
105 new RecursiveDirectoryIterator(
$resolved, FilesystemIterator::SKIP_DOTS),
106 RecursiveIteratorIterator::CHILD_FIRST
109 $item->isDir() ? @rmdir($item->getPathname()) : @unlink($item->getPathname());
114$fail =
static function (
string $message,
int $code = 2) use ($deleteTree, $testRoot):
void {
115 $deleteTree($testRoot);
116 fwrite(STDERR,
"FAIL: $message\n");
120$GLOBALS[
'dbxContentPageCacheTestApi'] =
new dbxContentPageCacheTestApi($testRoot);
121function dbx(): dbxContentPageCacheTestApi {
122 return
$GLOBALS[
'dbxContentPageCacheTestApi'];
125require_once dirname(__DIR__) .
'/include/dbxContentPageCache.class.php';
131$_SERVER[
'SCRIPT_NAME'] =
'/dbxapp/index.php';
135$_SESSION = array(
'dbx' => array(
'current_user' => array(
'id' => 0)));
139 'dbx_permalink' =>
'abc/def',
141 'dbx_design' =>
'dbxapp',
142 'dbx_color' =>
'blau',
146 'dbx_base_url' =>
'http://localhost/dbxapp/',
149$slashPath = dbxContentPageCache::fullPagePath(
'abc/def',
'de',
'dbxapp',
'blau');
150$dashPath = dbxContentPageCache::fullPagePath(
'abc-def',
'de',
'dbxapp',
'blau');
151if ($slashPath === $dashPath) {
152 $fail(
'abc/def und abc-def kollidieren weiterhin im Dateinamen.');
154if (!preg_match(
'/-[a-f0-9]{24}_de_dbxapp_blau_[a-f0-9]{16}_[a-f0-9]{24}_v3\.htm$/', basename($slashPath))) {
155 $fail(
'Der V3-Dateiname enthaelt nicht alle erwarteten Hash-/Variantenanteile.');
159$publicHostPath = dbxContentPageCache::fullPagePath(
'abc/def',
'de',
'dbxapp',
'blau');
161if ($publicHostPath === $slashPath) {
162 $fail(
'Caches verschiedener Hosts verwenden denselben Dateinamen.');
165$legacyV2 = dirname($slashPath) . DIRECTORY_SEPARATOR .
'legacy_de_dbxapp_blau_v2.htm';
166file_put_contents($legacyV2,
'<!doctype html><html></html>');
167dbxContentPageCache::ensureDirs();
168if (is_file($legacyV2)) {
169 $fail(
'Unsichere V2-Datei wurde nicht entfernt.');
172$staleV3 = preg_replace(
173 '/_[a-f0-9]{24}_v3\.htm$/',
174 '_000000000000000000000000_v3.htm',
177if (!is_string($staleV3) || $staleV3 === $slashPath) {
178 $fail(
'Testdatei einer alten Cache-Generation konnte nicht abgeleitet werden.');
180file_put_contents($staleV3,
'<!doctype html><html></html>');
181if (dbxContentPageCache::purgeStaleFullPages() !== 1 || is_file($staleV3)) {
182 $fail(
'V3-Datei einer alten Cache-Generation wurde nicht bereinigt.');
185if (!dbxContentPageCache::prepareFullPageRequest()) {
186 $fail(
'Gueltiger Gast-Permalink wurde nicht fuer den Cache vorbereitet.');
188$api->system[
'dbx_content_permalink_request'] = 1;
189$api->system[
'dbx_content_route_cid'] = 51;
190$api->system[
'dbx_master_modul'] =
'dbxContent';
191if (!dbxContentPageCache::attachResolvedContentRoute()) {
192 $fail(
'Aufgeloeste Content-Route wurde nicht an den Cache gebunden.');
195$html =
"<!doctype html><html><head><base href=\"http://localhost/dbxapp/\"/></head><body>Unveraendert: & <script>window.x = '<tag>';</script></body></html>";
196http_response_code(200);
197if (!dbxContentPageCache::writeFullPage(
$html)) {
198 $fail(
'Vollstaendige Gastseite wurde nicht atomar gespeichert.');
200if (dbxContentPageCache::readFullPage() !==
$html) {
201 $fail(
'Cache-Lesen veraendert oder escaped die gespeicherten Bytes.');
204$baseCheckedPath = (string)
$api->system[
'dbx_full_page_cache_path'];
205$wrongBaseHtml = str_replace(
206 'http://localhost/dbxapp/',
207 'https://dbxapp.de/',
210file_put_contents($baseCheckedPath, $wrongBaseHtml);
211if (dbxContentPageCache::readFullPage() !==
null || is_file($baseCheckedPath)) {
212 $fail(
'Cache-Datei mit falschem base href wurde gelesen oder nicht geloescht.');
214if (dbxContentPageCache::writeFullPage($wrongBaseHtml)) {
215 $fail(
'HTML mit falschem base href wurde erneut in den Cache geschrieben.');
217if (!dbxContentPageCache::writeFullPage(
$html) || dbxContentPageCache::readFullPage() !==
$html) {
218 $fail(
'Nach ungueltigem base href wurde die korrekte Seite nicht neu gecacht.');
221$oldPath = (string)
$api->system[
'dbx_full_page_cache_path'];
222$oldGeneration = (string)
$api->system[
'dbx_full_page_cache_generation'];
223dbxContentPageCache::invalidateAllFullPages();
224if (dbxContentPageCache::writeFullPage(
$html)) {
225 $fail(
'Ein vor der Invalidierung gestarteter Request konnte veraltetes HTML nachschreiben.');
228if (!dbxContentPageCache::prepareFullPageRequest()) {
229 $fail(
'Cache konnte nach Generationwechsel nicht neu vorbereitet werden.');
231$api->system[
'dbx_content_permalink_request'] = 1;
232$api->system[
'dbx_content_route_cid'] = 51;
233$api->system[
'dbx_master_modul'] =
'dbxContent';
234dbxContentPageCache::attachResolvedContentRoute();
235$newPath = (string)
$api->system[
'dbx_full_page_cache_path'];
236$newGeneration = (string)
$api->system[
'dbx_full_page_cache_generation'];
237if ($oldPath === $newPath || $oldGeneration === $newGeneration) {
238 $fail(
'Invalidierung hat die Cache-Generation nicht gewechselt.');
240if (!dbxContentPageCache::writeFullPage(
$html)) {
241 $fail(
'Neue Cache-Generation konnte nicht geschrieben werden.');
244if (!dbxContentPageCache::setConfigEnabled(
false)) {
245 $fail(
'Cache-Konfiguration konnte im Test nicht ausgeschaltet werden.');
247if (!is_file($newPath) || dbxContentPageCache::readFullPage() !==
$html) {
248 $fail(
'Ausschalten des Cache-Schreibens hat einen vorhandenen Treffer entfernt oder deaktiviert.');
250if (dbxContentPageCache::isWriteEnabled()) {
251 $fail(
'Ausgeschaltetes Cache-Schreiben wird weiterhin als aktiv gemeldet.');
253if (dbxContentPageCache::writeFullPage(str_replace(
'Unveraendert',
'Neu',
$html))) {
254 $fail(
'Bei ausgeschaltetem Cache-Schreiben wurde eine Seite gespeichert.');
256if ((
string)file_get_contents($newPath) !==
$html) {
257 $fail(
'Vorhandene Cache-Datei wurde bei ausgeschaltetem Schreiben veraendert.');
259$afterTogglePath = dbxContentPageCache::fullPagePath(
'abc/def',
'de',
'dbxapp',
'blau');
260if ($afterTogglePath !== $newPath) {
261 $fail(
'Ausschalten des Cache-Schreibens hat die bestehende Generation gewechselt.');
266dbxContentPageCache::invalidateAllFullPages();
267if (is_file($newPath)) {
268 $fail(
'Inhaltsinvalidierung hat bei pausiertem Schreiben eine alte Seite behalten.');
270$afterInvalidationPath = dbxContentPageCache::fullPagePath(
'abc/def',
'de',
'dbxapp',
'blau');
271if ($afterInvalidationPath === $newPath) {
272 $fail(
'Inhaltsinvalidierung hat die Generation bei pausiertem Schreiben nicht gewechselt.');
274if (!dbxContentPageCache::prepareFullPageRequest()) {
275 $fail(
'Lesepfad konnte bei pausiertem Schreiben nicht vorbereitet werden.');
277$api->system[
'dbx_content_permalink_request'] = 1;
278$api->system[
'dbx_content_route_cid'] = 51;
279$api->system[
'dbx_master_modul'] =
'dbxContent';
280dbxContentPageCache::attachResolvedContentRoute();
281if (dbxContentPageCache::readFullPage() !==
null || dbxContentPageCache::writeFullPage(
$html)) {
282 $fail(
'Cache-MISS wurde bei pausiertem Schreiben nicht ausschliesslich live behandelt.');
285if (!dbxContentPageCache::setConfigEnabled(
true) || !dbxContentPageCache::isWriteEnabled()) {
286 $fail(
'Cache-Schreiben konnte nicht wieder eingeschaltet werden.');
289$api->effectiveUser = 1;
290if (dbxContentPageCache::isEnabled()) {
291 $fail(
'Effektiver Admin-/Bypass-Benutzer wird als Gast behandelt.');
293$api->effectiveUser = 7;
294$_SESSION[
'dbx'][
'current_user'][
'id'] =
'7';
295if (dbxContentPageCache::isEnabled()) {
296 $fail(
'Numerische Benutzer-ID als String wird als Gast behandelt.');
298$api->effectiveUser = 0;
299$_SESSION[
'dbx'][
'current_user'][
'id'] = 0;
300$_SESSION[
'dbxShop_cart'] = array(12 => 2);
301if (dbxContentPageCache::isEnabled()) {
302 $fail(
'Gast mit Warenkorb wuerde weiterhin einen gemeinsamen Cache verwenden.');
306$deleteTree($testRoot);
307echo
"OK dbxContent full-page cache\n";
user($key='id')
Liest einen Wert des aktuellen Benutzers.
os_path(string $path)
Normalisiert einen Pfad fuer das aktuelle Betriebssystem.
set_config(string $modul, array $config)
Speichert die Konfiguration eines Moduls.
get_base_dir(int $cutData=0)
Liefert das Basisverzeichnis der Installation.
get_file_dir()
Liefert das files/-Verzeichnis der Installation.
is_design($design, $page='default')
Prueft, ob ein Design fuer die angegebene Seite existiert.
normalize_skin(string $skin='', string $design='')
Normalisiert Skin-/Farbnamen auf gueltige Skin-IDs.
get_base_url()
Liefert die Basis-URL des aktuellen Requests.
$_SERVER['REQUEST_METHOD']
if($stored !=='files/test/') $resolved
if($resolved !==$expectedBase . 'files/test/') $config
$api system['dbx_permalink']
$GLOBALS['dbxMissingResourcesTestApi']
if(trim($second) !=='second') $design
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
DBX schema administration.