diff --git a/app/TrainingResource.php b/app/TrainingResource.php
index 7ea71a36e..86edd4852 100644
--- a/app/TrainingResource.php
+++ b/app/TrainingResource.php
@@ -277,42 +277,61 @@ public function renderedPdfLinksSectionForLocale(?string $locale = null): string
}
$noteHtml = ''.e(__('training.discover_digital_key_one_pagers_note')).'';
+ $headingHtml = '
';
if (str_contains($section, '[[key_one_pagers_locale_note]]')) {
$section = str_replace('[[key_one_pagers_locale_note]]', $noteHtml, $section);
- if ($this->slug === 'discover-digital-programme' && ! $this->hasKeyOnePagersHeading($section)) {
- $section = ''.$section;
- }
-
- return $section;
}
- // Discover Digital: inject the note even when locale overrides omit the placeholder.
if ($this->slug !== 'discover-digital-programme') {
return $section;
}
- $headingPatterns = [
- '/(]*\bid=(["\'])key-one-pagers\2[^>]*>.*?<\/h2>)/is',
- '/(]*>\s*Key one-pagers\s*<\/h2>)/is',
- '/((?:]*>\s*)?
\s*Key one-pagers\s*<\/strong>(?:\s*<\/div>)?)/is',
- ];
+ // Collapse any existing Key one-pagers title variants (h2 / strong / Trix wrappers)
+ // into a single h2, then place the locale note immediately after it.
+ $titlePattern = '/(?:<(?:div|p)[^>]*>\s*)?(?:]*(?:\bid=(["\'])key-one-pagers\1)?[^>]*>\s*Key one-pagers\s*<\/h2>|(?:<(?:strong|b)>\s*)Key one-pagers(?:\s*<\/(?:strong|b)>))(?:\s*<\/(?:div|p)>)?/iu';
- foreach ($headingPatterns as $pattern) {
- if (preg_match($pattern, $section) === 1) {
- return preg_replace($pattern, '$1'.$noteHtml, $section, 1) ?? $section;
- }
+ if (preg_match($titlePattern, $section) === 1) {
+ $replaced = false;
+ $section = preg_replace_callback($titlePattern, function (array $matches) use ($headingHtml, $noteHtml, &$replaced) {
+ if ($replaced) {
+ return '';
+ }
+ $replaced = true;
+
+ return $headingHtml.$noteHtml;
+ }, $section) ?? $section;
+
+ // If the note was already injected via placeholder before the title, drop the extra copy.
+ return $this->dedupeKeyOnePagersNote($section, $noteHtml);
+ }
+
+ if (! str_contains($section, $noteHtml) && ! str_contains($section, '[[key_one_pagers_locale_note]]')) {
+ return $headingHtml.$noteHtml.$section;
+ }
+
+ return $headingHtml.$section;
+ }
+
+ protected function dedupeKeyOnePagersNote(string $section, string $noteHtml): string
+ {
+ $pos = strpos($section, $noteHtml);
+ if ($pos === false) {
+ return $section;
+ }
+
+ $afterFirst = substr($section, $pos + strlen($noteHtml));
+ if (! str_contains($afterFirst, $noteHtml)) {
+ return $section;
}
- // Always restore the heading when missing. Do not use a plain-text search for
- // "key one-pagers" — the supporting-detail paragraph also mentions that phrase.
- return ''.$noteHtml.$section;
+ return substr($section, 0, $pos + strlen($noteHtml)).str_replace($noteHtml, '', $afterFirst);
}
protected function hasKeyOnePagersHeading(string $html): bool
{
return preg_match('/]*\bid=(["\'])key-one-pagers\1[^>]*>/is', $html) === 1
|| preg_match('/]*>\s*Key one-pagers\s*<\/h2>/is', $html) === 1
- || preg_match('/(?:
]*>\s*)?\s*Key one-pagers\s*<\/strong>/is', $html) === 1;
+ || preg_match('/<(?:strong|b)>\s*Key one-pagers\s*<\/(?:strong|b)>/is', $html) === 1;
}
}