9 $configFile = dirname(__DIR__, 2) .
'/dbx/cfg/config.php';
10 if (is_file($configFile) && is_readable($configFile)) {
11 $readConfig =
static function(
string $path): array {
16 $fileConfig = $readConfig($configFile);
17 if (array_key_exists(
'cache_content', $fileConfig)) {
18 return (
int)$fileConfig[
'cache_content'] === 1;
22 $enabled =
dbx()->get_config(
'dbx',
'cache_content');
23 if ($enabled ===
'undef' || $enabled ===
'' || $enabled ===
null) {
27 return (
int) $enabled === 1;
36 $config[
'cache_content'] = $enabled ? 1 : 0;
37 return (
int)
dbx()->set_config(
'dbx',
$config) > 0;
41 $method = strtoupper(trim((string)(
$_SERVER[
'REQUEST_METHOD'] ??
'GET')));
42 if ($method !==
'GET' && $method !==
'HEAD') {
46 if ((
int)
dbx()->get_request_var(
'dbx_sync', 1,
'int') !== 1) {
50 if ((
int)
dbx()->get_system_var(
'dbx_edit', 0,
'int') > 0) {
54 if ((
int)
dbx()->get_system_var(
'dbx_ajax', 0,
'int')) {
58 if ((
int)
dbx()->get_system_var(
'dbx_window', 0,
'int')) {
62 return self::isConfigEnabled();
66 if (
dbx()->get_system_var(
'dbx_modul') !==
'dbxContent') {
70 $action = (string)
dbx()->get_system_var(
'dbx_run1',
'');
71 return $action ===
'show';
79 if ((
int)
dbx()->get_system_var(
'dbx_content_permalink_request', 0,
'int') !== 1) {
83 return (
int)
dbx()->get_system_var(
'dbx_content_route_cid', 0,
'int') > 0;
86 public static function baseDir(): string {
87 $dir = rtrim(
dbx()->get_file_dir(),
'/\\') .
'/cache/';
92 return
'flat-' . ((int) $flat === 0 ? 0 : 1);
95 public static function menuVariantLoad(
int $deep = 9,
string $mode =
'',
string $label =
''): string {
96 $deep = max(1, (int) $deep);
97 $mode = strtolower(trim($mode));
101 $mode = self::safeToken($mode,
'default');
102 $label = trim((
string) $label);
103 $labelKey = $label !==
'' ? substr(sha1($label), 0, 8) :
'menu';
105 return 'load-' . $deep .
'-' . $mode .
'-' . $labelKey;
109 $lng = trim((string)
dbx()->get_system_var(
'dbx_lng',
'de'));
110 return $lng !==
'' ? $lng :
'de';
114 foreach (array(
'content',
'meta') as $sub) {
115 $dir = self::baseDir() . $sub;
117 @mkdir(
$dir, 0755,
true);
121 self::purgeLegacyMenuCache();
122 self::purgeLegacyPageCache();
126 private static function purgeLegacyPageCache(): void {
128 self::baseDir() .
'meta/pages/*.json',
129 self::baseDir() .
'meta/permalinks_*.json',
130 self::baseDir() .
'meta/home_*.json',
132 foreach (glob($pattern) ?: array() as $file) {
137 $contentDir = self::baseDir() .
'content/';
138 foreach (array_merge(glob($contentDir .
'*.htm') ?: array(), glob($contentDir .
'*.html') ?: array()) as $file) {
139 if (preg_match(
'/^cid-\d+\.[a-z]{2,3}\.htm$/i', basename($file))) {
154 foreach (glob(
$dir .
'*.html') ?: array() as $path) {
155 if (@unlink($path)) {
163 public static function contentPath(
int $cid,
string $lng): string {
165 $lng = self::safeToken($lng,
'de');
166 return self::baseDir() .
'content/cid-' . $cid .
'.' . $lng .
'.htm';
170 $permalink = self::permalinkFileToken($permalink);
171 $lng = self::safeToken($lng,
'de');
173 return self::baseDir() .
'content/' . $permalink .
'.' . $lng .
'.htm';
176 public static function menuPath(
int $root,
string $lng,
string $variant =
'flat-1'): string {
178 $lng = self::safeToken($lng,
'de');
179 $variant = self::safeToken($variant,
'flat-1');
181 return self::baseDir() .
'menu/' .
$root .
'_' . $lng .
'_' . $variant .
'.html';
185 return self::
baseDir() .
'meta/pages/' . (int) $cid .
'.json';
188 public static function readContent(
int $cid,
string $lng =
''): ?string {
194 $lng = self::currentLng();
197 $path = self::contentPath($cid, $lng);
198 if (!is_file($path) || !is_readable($path)) {
202 $html = file_get_contents($path);
203 if (!is_string($html)) {
207 require_once __DIR__ .
'/dbxContentRenderer.class.php';
208 (
new dbxContentRenderer())->applySeoMeta($cid);
217 public static function writeContent(
int $cid,
string $html, array $meta = array(),
string $lng =
''): bool {
223 if ($cid <= 0 || trim($html) ===
'') {
228 $lng = self::currentLng();
232 $path = self::contentPath($cid, $lng);
233 return (
bool) @file_put_contents($path, $html, LOCK_EX);
236 public static function readMenu(
int $root,
string $variant =
'flat-1',
string $lng =
''): ?string {
240 public static function writeMenu(
string $html,
int $root,
string $variant =
'flat-1',
string $lng =
''): bool {
245 $meta = self::buildContentMeta($cid, self::
currentLng());
246 return count($meta) ? $meta :
null;
249 private static function readPageMetaFile(
int $cid): ?array {
250 $path = self::pageMetaPath($cid);
251 if (!is_file($path) || !is_readable($path)) {
255 $json = file_get_contents($path);
256 if (!is_string($json) || $json ===
'') {
260 $data = json_decode($json,
true);
261 return is_array($data) ? $data :
null;
275 $permalinks = array();
276 $meta = self::readPageMetaFile($cid);
277 if (is_array($meta)) {
278 $permalink = trim((
string) ($meta[
'permalink'] ??
''));
279 $lng = trim((
string) ($meta[
'lng'] ??
''));
280 if ($permalink !==
'') {
281 $permalinks[] = array(
'permalink' => $permalink,
'lng' => $lng);
285 foreach (glob(self::baseDir() .
'meta/permalinks_*.json') ?: array() as $indexFile) {
286 $json = file_get_contents($indexFile);
287 if (!is_string($json) || $json ===
'') {
290 $index = json_decode($json,
true);
295 if (preg_match(
'/^permalinks_([a-z]{2,3})\.json$/i', basename($indexFile), $match)) {
296 $lng = strtolower($match[1]);
298 foreach (
$index as $permalink => $row) {
299 if (is_array($row) && (
int) ($row[
'cid'] ?? 0) === $cid) {
300 $permalinks[] = array(
'permalink' => (
string) $permalink,
'lng' => $lng);
306 foreach ($permalinks as $item) {
307 $permalink = trim((
string) ($item[
'permalink'] ??
''));
308 if ($permalink ===
'') {
311 $lng = trim((
string) ($item[
'lng'] ??
''));
312 $token = self::permalinkFileToken($permalink);
313 $key = $token .
'|' . $lng;
314 if (isset($seen[$key])) {
318 $legacyToken = self::legacyPermalinkFileToken($permalink);
319 $pattern = $lng !==
''
320 ? self::baseDir() .
'content/' . $token .
'.' . self::safeToken($lng,
'de') .
'.htm'
321 : self::baseDir() .
'content/' . $token .
'.*.htm';
322 foreach (glob($pattern) ?: array() as $file) {
326 self::baseDir() .
'content/' . $legacyToken .
'.*.htm',
327 self::baseDir() .
'content/' . $legacyToken .
'__*.html',
328 ) as $legacyPattern) {
329 foreach (glob($legacyPattern) ?: array() as $file) {
335 foreach (glob(self::baseDir() .
'content/cid-' . $cid .
'.*.htm') ?: array() as $file) {
338 foreach (glob(self::baseDir() .
'content/' . $cid .
'_*.html') ?: array() as $file) {
342 @unlink(self::pageMetaPath($cid));
343 if (class_exists(__NAMESPACE__ .
'\\dbxContentSitemap')) {
344 dbxContentSitemap::invalidate();
350 $pattern = self::baseDir() .
'menu/' .
$root .
'_*.html';
351 foreach (glob($pattern) ?: array() as $file) {
357 foreach (glob(self::
baseDir() .
'menu/*.html') ?: array() as $file) {
360 self::invalidateSitemap();
364 if (class_exists(__NAMESPACE__ .
'\\dbxContentSitemap')) {
369 @unlink(self::baseDir() .
'meta/sitemap.xml');
379 foreach (array(
'*.htm',
'*.html') as $pattern) {
380 foreach (glob(self::baseDir() .
'content/' . $pattern) ?: array() as $file) {
381 if (@unlink($file)) {
387 foreach (glob(self::baseDir() .
'menu/*.html') ?: array() as $file) {
388 if (@unlink($file)) {
393 foreach (glob(self::baseDir() .
'meta/pages/*.json') ?: array() as $file) {
394 if (@unlink($file)) {
399 foreach (glob(self::baseDir() .
'meta/permalinks_*.json') ?: array() as $file) {
400 if (@unlink($file)) {
405 foreach (glob(self::baseDir() .
'meta/home_*.json') ?: array() as $file) {
406 if (@unlink($file)) {
416 $content = array_values(array_filter(
417 glob(self::baseDir() .
'content/cid-*.*.htm') ?: array(),
418 static fn(
string $path):
bool => (
bool) preg_match(
'/^cid-\d+\.[a-z]{2,3}\.htm$/i', basename($path))
420 $sitemapPath = self::baseDir() .
'meta/sitemap.xml';
423 'content' => count($content),
428 'sitemap' => is_file($sitemapPath) ? 1 : 0,
429 'base_dir' => self::baseDir(),
434 if (!is_object(
$db)) {
438 $folderId = (int) $folderId;
439 self::invalidateMenu($folderId);
440 self::invalidateMenu(0);
442 $folderIds = self::collectFolderIds(
$db, $folderId);
443 foreach ($folderIds as $id) {
444 self::invalidateMenu((
int) $id);
447 $pages =
$db->select(dbxContentLng::ddContent(),
'folder IN (' . implode(
',', array_map(
'intval', $folderIds)) .
')',
'id',
'id',
'ASC',
'', 0, 0, 0);
448 if (is_array($pages)) {
449 foreach ($pages as $page) {
450 self::invalidateContent((
int) ($page[
'id'] ?? 0));
455 private static function collectFolderIds(
$db,
int $folderId): array {
456 $folderId = (int) $folderId;
457 $ids = array($folderId);
458 $queue = array($folderId);
460 while (count($queue)) {
461 $current = (int) array_shift($queue);
462 $rows =
$db->select(dbxContentLng::ddFolder(),
'parent_id = ' . $current,
'id',
'id',
'ASC',
'', 0, 0, 0);
463 if (!is_array($rows)) {
466 foreach ($rows as $row) {
467 $id = (int) ($row[
'id'] ?? 0);
468 if ($id > 0 && !in_array($id, $ids,
true)) {
478 private static function buildContentMeta(
int $cid,
string $lng =
''): array {
486 $currentLng = (string)
dbx()->get_system_var(
'dbx_lng',
'de');
487 if ($lng !== $currentLng) {
488 $prevLng = $currentLng;
489 dbx()->set_system_var(
'dbx_lng', $lng);
493 require_once __DIR__ .
'/dbxContentRenderer.class.php';
494 $db =
dbx()->get_system_obj(
'dbxDB');
495 if (!is_object(
$db)) {
496 if ($prevLng !==
null) {
497 dbx()->set_system_var(
'dbx_lng', $prevLng);
502 $rec =
$db->select1(dbxContentLng::ddContent(), $cid,
'permalink,activ,folder,title,seo_title,description,keywords,meta_robots,seo_image_id,update_date,lng_uid', 0);
503 if (!is_array($rec)) {
504 if ($prevLng !==
null) {
505 dbx()->set_system_var(
'dbx_lng', $prevLng);
510 $renderer =
new dbxContentRenderer();
511 $rights = $renderer->getPublicFolderRights((
int)($rec[
'folder'] ?? 0));
514 'permalink' => (
string)($rec[
'permalink'] ??
''),
516 'activ' => (
int)($rec[
'activ'] ?? 1),
517 'seo' => dbxContentRenderer::seoMetaFromRecord($rec),
519 if ($prevLng !==
null) {
520 dbx()->set_system_var(
'dbx_lng', $prevLng);
525 private static function safeToken(
string $value,
string $fallback): string {
526 $value = strtolower(trim($value));
527 if ($value ===
'' || !preg_match(
'/^[a-z0-9_-]+$/', $value)) {
533 private static function permalinkFileToken(
string $permalink): string {
534 $permalink = strtolower(trim(str_replace(
'\\',
'/', $permalink),
'/'));
535 if ($permalink ===
'') {
539 $token = preg_replace(
'/[^a-z0-9_-]+/i',
'-', $permalink);
540 $token = trim((
string) $token,
'-_');
545 if (strlen($token) > 160) {
546 $token = substr($token, 0, 160);
549 return strtolower($token);
552 private static function legacyPermalinkFileToken(
string $permalink): string {
553 $permalink = strtolower(trim(str_replace(
'\\',
'/', $permalink),
'/'));
554 if ($permalink ===
'') {
558 $token = preg_replace(
'/[^a-z0-9_-]+/i',
'-', $permalink);
559 $token = trim((
string) $token,
'-_');
564 $hash = substr(sha1($permalink), 0, 8);
565 if (strlen($token) > 80) {
566 $token = substr($token, 0, 80);
569 return strtolower($token .
'-' . $hash);
static setConfigEnabled(bool $enabled)
static permalinkContentPath(string $permalink, string $lng)
static invalidateFolderTree($db, int $folderId)
static readPermalinkContent(string $permalink, string $lng='')
static contentPath(int $cid, string $lng)
static invalidateMenu(int $root)
static readPageMeta(int $cid)
static writeMenu(string $html, int $root, string $variant='flat-1', string $lng='')
static readMenu(int $root, string $variant='flat-1', string $lng='')
static invalidateContent(int $cid)
static isPermalinkPageRequest()
static writeContent(int $cid, string $html, array $meta=array(), string $lng='')
static menuVariantLoad(int $deep=9, string $mode='', string $label='')
static readContent(int $cid, string $lng='')
static menuPath(int $root, string $lng, string $variant='flat-1')
static writePageMeta(int $cid, array $meta)
static menuVariantFlat(int $flat=1)
static purgeLegacyMenuCache()
Entfernt den nicht mehr verwendeten Menu-Cache.
static pageMetaPath(int $cid)