From 2fdf90519a4d9d4bfa6dcacea7eb3d98619c5f4d Mon Sep 17 00:00:00 2001 From: Edwin Noorlander Date: Tue, 21 Jul 2026 13:46:54 +0200 Subject: [PATCH] Fix auto-link nested tag protection and add feature flag check --- cms/core/class/CodePressCMS.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/cms/core/class/CodePressCMS.php b/cms/core/class/CodePressCMS.php index bad9132..de1eaaf 100644 --- a/cms/core/class/CodePressCMS.php +++ b/cms/core/class/CodePressCMS.php @@ -598,7 +598,9 @@ class CodePressCMS { // Auto-link page titles to existing content pages (but not in H1 tags) - $body = $this->autoLinkPageTitles($body, $cleanName); + if ($this->config['features']['auto_link_pages'] ?? true) { + $body = $this->autoLinkPageTitles($body, $cleanName); + } // Convert relative internal links to clean URLs (skip already-prefixed URLs) $body = preg_replace('/href="\/blog\/([^"]+)"/', 'href="/' . $this->currentLanguage . '/blog/$1"', $body); @@ -620,15 +622,6 @@ class CodePressCMS { * @return string Content with auto-linked page titles */ private function autoLinkPageTitles($content, $excludeTitle = '') { - // Protect existing tags and

content with placeholders - $placeholders = []; - $content = preg_replace_callback('/]*>.*?<\/a>|]*>.*?<\/h1>|\[([^\]]*)\]\(([^)]*)\)|^#{1,6}\s.*$/m', function($m) use (&$placeholders) { - $key = '@@LINK_' . count($placeholders) . '@@'; - $placeholders[$key] = $m[0]; - return $key; - }, $content); - - // Get all available pages with their titles $pages = $this->getAllPageTitles(); foreach ($pages as $pagePath => $pageTitle) { @@ -636,16 +629,22 @@ class CodePressCMS { continue; } + // Protect existing tags,

content, and markdown links before each replacement + $placeholders = []; + $protected = preg_replace_callback('/]*>.*?<\/a>|]*>.*?<\/h1>|\[([^\]]*)\]\(([^)]*)\)|^#{1,6}\s.*$/m', function($m) use (&$placeholders) { + $key = '@@ALINK_' . count($placeholders) . '@@'; + $placeholders[$key] = $m[0]; + return $key; + }, $content); + $pattern = '/\b' . preg_quote($pageTitle, '/') . '\b/i'; - $content = preg_replace_callback($pattern, function($matches) use ($pageTitle, $pagePath) { + $protected = preg_replace_callback($pattern, function($matches) use ($pageTitle, $pagePath) { return '' . $matches[0] . ''; - }, $content); - } - - // Restore protected placeholders - foreach ($placeholders as $key => $value) { - $content = str_replace($key, $value, $content); + }, $protected); + + // Restore placeholders + $content = str_replace(array_keys($placeholders), array_values($placeholders), $protected); } return $content;