' . self::escapeHtml($block['data']['text'] ?? '') . '

'; break; case 'header': $level = $block['data']['level'] ?? 2; $text = self::escapeHtml($block['data']['text'] ?? ''); $html .= "{$text}"; break; case 'list': $style = $block['data']['style'] ?? 'unordered'; $listTag = ($style === 'ordered') ? 'ol' : 'ul'; $html .= "<{$listTag}>"; if (isset($block['data']['items']) && is_array($block['data']['items'])) { foreach ($block['data']['items'] as $item) { $html .= '
  • ' . self::escapeHtml($item) . '
  • '; } } $html .= ""; break; case 'quote': $text = self::escapeHtml($block['data']['text'] ?? ''); $caption = isset($block['data']['caption']) ? self::escapeHtml($block['data']['caption']) : ''; $html .= '

    ' . $text . '

    '; if ($caption) { $html .= '' . $caption . ''; } $html .= '
    '; break; case 'code': $code = self::escapeHtml($block['data']['code'] ?? ''); $html .= '
    ' . $code . '
    '; break; case 'table': $html .= ''; if (isset($block['data']['content']) && is_array($block['data']['content'])) { foreach ($block['data']['content'] as $row) { if (is_array($row)) { $html .= ''; foreach ($row as $cell) { $html .= ''; } $html .= ''; } } } $html .= '
    ' . self::escapeHtml($cell) . '
    '; break; case 'delimiter': $html .= '
    '; break; case 'image': $url = self::escapeHtml($block['data']['file']['url'] ?? ''); $caption = isset($block['data']['caption']) ? self::escapeHtml($block['data']['caption']) : ''; if ($url) { $html .= '
    ' . $caption . ''; if ($caption) { $html .= '
    ' . $caption . '
    '; } $html .= '
    '; } break; case 'linkTool': $link = self::escapeHtml($block['data']['link'] ?? ''); $title = isset($block['data']['meta']['title']) ? self::escapeHtml($block['data']['meta']['title']) : $link; if ($link) { $html .= ''; } break; default: // Unknown block type - ignore safely log_message('debug', 'Unknown Editor.js block type: ' . ($block['type'] ?? 'unknown')); break; } } return $html; } /** * Escape HTML special characters * * @param string $text * @return string */ protected static function escapeHtml(string $text): string { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); } /** * Extract excerpt from blocks (first paragraph) * * @param array $blocks * @param int $length * @return string */ public static function extractExcerpt(array $blocks, int $length = 160): string { foreach ($blocks as $block) { if ($block['type'] === 'paragraph' && isset($block['data']['text'])) { $text = strip_tags($block['data']['text']); return mb_substr($text, 0, $length); } } return ''; } }