' . 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 .= "{$listTag}>";
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 .= '| ' . self::escapeHtml($cell) . ' | ';
}
$html .= '
';
}
}
}
$html .= '
';
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 .= '
';
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 '';
}
}