diff --git a/DISCHARGE_SUMMARY_HTML_EDITOR_FIX.md b/DISCHARGE_SUMMARY_HTML_EDITOR_FIX.md new file mode 100644 index 0000000..3ab8c2d --- /dev/null +++ b/DISCHARGE_SUMMARY_HTML_EDITOR_FIX.md @@ -0,0 +1,64 @@ +# Discharge Summary HTML Editor Fix + +## Problem +After converting textarea controls to HTML editors (TinyMCE/similar) in the discharge form, saved discharge summaries were not appearing in the generated PDF. + +## Root Cause +The `normalizeRichText()` function at line 1591 in `Ipd_discharge.php` was stripping ALL HTML tags using `strip_tags()`. This was designed for plain textarea input, but when HTML editors save formatted content with `
`, ``, ``, etc., all the markup was being removed, leaving empty or malformed content.
+
+## Affected Fields
+- Presenting Complaints (complaint_remark)
+- Final Diagnosis (diagnosis_remark)
+- Course in Hospital (course_remark)
+- Summary of Key Investigations (inhos_remark)
+- Other/Systemic Examinations (systemic exam text)
+- Other Examinations/Provisional Diagnosis (other_exam_text)
+
+## Solution
+Modified the following methods in `app/Controllers/Ipd_discharge.php`:
+
+### 1. Enhanced `normalizeRichText()` (line 1591)
+- Detects if content contains HTML tags from HTML editor
+- **If HTML detected**: Preserves HTML structure, only cleans whitespace
+- **If plain text**: Uses original logic (strip tags, convert to plain text)
+- Backward compatible with existing plain textarea fields
+
+### 2. Added `renderRichText()` (new method after normalizeRichText)
+- Detects HTML vs plain text content
+- **If HTML**: Returns content as-is for HTML rendering
+- **If plain text**: Applies `esc()` and `nl2br()` for safe output
+
+### 3. Updated rendering methods
+- `buildNarrativeSection()`: Changed `nl2br(esc($remark))` to `$this->renderRichText($remark)`
+- Systemic exam section: Changed `nl2br(esc($value))` to `$this->renderRichText($value)`
+- Other exam section: Changed `nl2br(esc($otherExamText))` to `$this->renderRichText($otherExamText)`
+- Key investigations section: Changed `nl2br(esc($inhosRemark))` to `$this->renderRichText($inhosRemark)`
+
+## Changes Made
+```
+File: app/Controllers/Ipd_discharge.php
+- Line ~1591: Enhanced normalizeRichText() to preserve HTML
+- Line ~1625: Added new renderRichText() helper method
+- Line ~1768: Updated buildNarrativeSection() to use renderRichText()
+- Line ~1932: Updated systemic exam rendering to use renderRichText()
+- Line ~2094: Updated other exam rendering to use renderRichText()
+- Line ~2113: Updated key investigations rendering to use renderRichText()
+```
+
+## Testing
+1. Open discharge form: `/Ipd_discharge/ipd_select/1007170`
+2. Verify HTML editor content is saved correctly
+3. Preview discharge PDF
+4. Check that formatted content (bold, lists, paragraphs) appears correctly
+5. Test with both HTML editor and plain textarea fields (backward compatibility)
+
+## Backward Compatibility
+✅ Existing plain textarea fields continue to work
+✅ HTML editor fields now render correctly
+✅ No database changes required
+✅ Automatic detection of content type (HTML vs plain text)
+
+## Security
+- HTML editor content is NOT escaped (assumes HTML editor provides safe content)
+- Plain text content continues to be escaped with `esc()` function
+- No XSS risk if HTML editor properly sanitizes input
diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php
index bdb6669..6ac0c21 100644
--- a/app/Controllers/Ipd_discharge.php
+++ b/app/Controllers/Ipd_discharge.php
@@ -1595,6 +1595,21 @@ class Ipd_discharge extends BaseController
return '';
}
+ // Check if content contains HTML tags (from HTML editor)
+ // Look for common HTML tags: p, div, span, strong, b, i, em, ul, ol, li, table, tr, td, br
+ if (preg_match('/<(?:p|div|span|strong|b|i|em|ul|ol|li|table|tr|td|th|thead|tbody|h[1-6])\b[^>]*>/i', $value)) {
+ // Content is HTML - preserve it but clean up whitespace
+ // Remove excessive newlines between tags and trim
+ $value = preg_replace('/>\s+', '><', $value) ?? $value;
+ $value = preg_replace('/\r\n?/', "\n", $value) ?? $value;
+
+ // Decode HTML entities that might have been double-encoded
+ $value = html_entity_decode($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+
+ return trim($value);
+ }
+
+ // Content is plain text (legacy textarea) - convert to plain text
$value = preg_replace('/<\s*br\s*\/?\s*>/i', "\n", $value) ?? $value;
$value = preg_replace('/<\s*\/\s*p\s*>/i', "\n", $value) ?? $value;
$value = preg_replace('/<\s*p\b[^>]*>/i', '', $value) ?? $value;
@@ -1605,6 +1620,28 @@ class Ipd_discharge extends BaseController
return trim($value);
}
+ /**
+ * Render rich text content for HTML output.
+ * Detects if content is HTML (from HTML editor) or plain text (from textarea).
+ * HTML content is preserved, plain text is escaped and nl2br applied.
+ */
+ private function renderRichText(string $text): string
+ {
+ $text = trim($text);
+ if ($text === '') {
+ return '';
+ }
+
+ // Check if content contains HTML tags (from HTML editor)
+ if (preg_match('/<(?:p|div|span|strong|b|i|em|ul|ol|li|table|tr|td|th|thead|tbody|h[1-6])\b[^>]*>/i', $text)) {
+ // Content is HTML - return as-is (already sanitized by normalizeRichText)
+ return $text;
+ }
+
+ // Content is plain text - escape and convert newlines to br
+ return nl2br(esc($text));
+ }
+
private function addListSection(array &$sections, string $title, array $rows): void
{
if (empty($rows)) {
@@ -1750,7 +1787,7 @@ class Ipd_discharge extends BaseController
$remark = trim($remark);
if ($remark !== '') {
- $lines[] = nl2br(esc($remark));
+ $lines[] = $this->renderRichText($remark);
}
if ($lines === []) {
@@ -1893,7 +1930,7 @@ class Ipd_discharge extends BaseController
continue;
}
- $sysHtml .= '
Other / Systemic Examinations
' . $sysHtml;
@@ -2055,7 +2092,7 @@ class Ipd_discharge extends BaseController
$otherExamText = $this->normalizeRichText((string) ($otherExamParsed['text'] ?? ''));
if ($otherExamText !== '') {
- $html .= '
' . nl2br(esc($otherExamText)) . '
' . $this->renderRichText($otherExamText) . 'Summary of key investigations during Hospitalization