10) { return '
Max depth reached
'; } $html = ''; if (!is_array($data)) { $safe = esc($data); return "
$safe
"; } // Check if it's an indexed array of similar items (like commits) $isIndexedArray = array_keys($data) === range(0, count($data) - 1); if ($isIndexedArray && count($data) > 0) { // Render as a list of items foreach ($data as $index => $item) { if (is_array($item)) { $html .= '
'; $html .= '
Item ' . ($index + 1) . '
'; $html .= ''; foreach ($item as $key => $value) { $keySafe = htmlspecialchars($key, ENT_QUOTES, 'UTF-8'); if (is_array($value)) { $html .= ''; $html .= ''; $html .= ''; $html .= ''; } else { $valueSafe = esc($value); $html .= ''; $html .= ''; $html .= ''; $html .= ''; } } $html .= ''; $html .= '
'; } else { $valueSafe = esc($item); $html .= '
• ' . $valueSafe . '
'; } } } else { // Render as key-value table $html .= ''; foreach ($data as $key => $value) { $keySafe = htmlspecialchars($key, ENT_QUOTES, 'UTF-8'); if (is_array($value) && !empty($value)) { // Close current table and start a subsection $html .= ''; $html .= '
'; $html .= '
' . $keySafe . '
'; $html .= renderDataAsTable($value, $depth + 1); $html .= '
'; $html .= ''; } else if (is_array($value) && empty($value)) { $html .= ''; $html .= ''; $html .= ''; $html .= ''; } else { $valueSafe = esc($value); $html .= ''; $html .= ''; $html .= ''; $html .= ''; } } $html .= ''; } return $html; } /** * Shared email chrome: one stylesheet, one header, one footer, for every template. * * @param string $title Header text (already HTML-safe) * @param string $stamp Timestamp line (already HTML-safe) * @param string $body Inner HTML made of .section / .metadata / .data-box blocks * @param string $footer Footer sentence * @return string Complete HTML document */ function emailShell($title, $stamp, $body, $footer = 'Automatically forwarded to your inbox.') { $host = htmlspecialchars($_SERVER['HTTP_HOST'] ?? 'webhook', ENT_QUOTES, 'UTF-8'); $plainTitle = strip_tags($title); $mono = "ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace"; $sans = "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif"; return << $plainTitle
HTML; }