PHP Classes

File: src/ErrorTemplate.php

Recommend this page to a friend!
  Packages of Boss Ibrahim Mussa   hitilafu   src/ErrorTemplate.php   Download  
File: src/ErrorTemplate.php
Role: Example script
Content type: text/plain
Description: Example script
Class: hitilafu
Error handler that displays the error context
Author: By
Last change:
Date: 3 months ago
Size: 33,786 bytes
 

Contents

Class file image Download
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo htmlspecialchars($this->errorData['type']); ?> - <?php echo htmlspecialchars($this->appName); ?> </title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } :root { --bg-primary: #0d1117; --bg-secondary: #161b22; --bg-tertiary: #1c2128; --bg-hover: #21262d; --text-primary: #e6edf3; --text-secondary: #8b949e; --text-muted: #6e7681; --border-color: #30363d; --accent-primary: #58a6ff; --accent-secondary: #79c0ff; --error-red: #f85149; --warning-yellow: #d29922; --success-green: #3fb950; --code-bg: #0d1117; --highlight-line: rgba(255, 184, 76, 0.15); --shadow: 0 8px 24px rgba(0, 0, 0, 0.4); } body.light-theme { --bg-primary: #ffffff; --bg-secondary: #f6f8fa; --bg-tertiary: #eaeef2; --bg-hover: #dfe3e8; --text-primary: #24292f; --text-secondary: #57606a; --text-muted: #6e7781; --border-color: #d0d7de; --accent-primary: #0969da; --accent-secondary: #0550ae; --error-red: #cf222e; --warning-yellow: #9a6700; --success-green: #1a7f37; --code-bg: #f6f8fa; --highlight-line: rgba(255, 184, 76, 0.25); --shadow: 0 8px 24px rgba(140, 149, 159, 0.2); } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.6; overflow-x: hidden; } .error-container { min-height: 100vh; padding: 20px; } .error-header { background: linear-gradient(135deg, var(--error-red) 0%, #ff6b6b 100%); border-radius: 12px; padding: 30px; margin-bottom: 20px; box-shadow: var(--shadow); position: relative; overflow: hidden; } .error-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M 20 0 L 0 0 0 20" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="1"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>'); opacity: 0.3; } .error-header-content { position: relative; z-index: 1; } .error-type { font-size: 14px; font-weight: 600; color: rgba(255, 255, 255, 0.9); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; } .error-message { font-size: 24px; font-weight: 700; color: #ffffff; margin-bottom: 15px; line-height: 1.4; } .error-location { display: flex; align-items: center; gap: 10px; font-size: 14px; color: rgba(255, 255, 255, 0.85); background: rgba(0, 0, 0, 0.2); padding: 10px 15px; border-radius: 6px; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; } .error-location svg { width: 16px; height: 16px; flex-shrink: 0; } .theme-toggle { position: fixed; top: 20px; right: 20px; z-index: 1000; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 8px; padding: 10px 15px; cursor: pointer; display: flex; align-items: center; gap: 8px; color: var(--text-primary); font-size: 14px; transition: all 0.3s ease; box-shadow: var(--shadow); } .theme-toggle:hover { background: var(--bg-hover); transform: translateY(-2px); } .tabs-container { background: var(--bg-secondary); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; border: 1px solid var(--border-color); } .tabs-header { display: flex; gap: 4px; background: var(--bg-tertiary); padding: 8px; border-bottom: 1px solid var(--border-color); overflow-x: auto; } .tab-button { background: transparent; border: none; padding: 10px 20px; color: var(--text-secondary); cursor: pointer; font-size: 14px; font-weight: 500; border-radius: 6px; transition: all 0.3s ease; white-space: nowrap; display: flex; align-items: center; gap: 8px; } .tab-button:hover { background: var(--bg-hover); color: var(--text-primary); } .tab-button.active { background: var(--bg-secondary); color: var(--accent-primary); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .tab-content { display: none; padding: 20px; animation: fadeIn 0.3s ease; } .tab-content.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .stack-trace-item { background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 8px; margin-bottom: 12px; overflow: hidden; transition: all 0.3s ease; } .stack-trace-item:hover { border-color: var(--accent-primary); box-shadow: 0 4px 12px rgba(88, 166, 255, 0.1); } .stack-trace-header { padding: 15px 20px; cursor: pointer; display: flex; align-items: center; gap: 15px; background: var(--bg-tertiary); transition: background 0.3s ease; } .stack-trace-header:hover { background: var(--bg-hover); } .stack-trace-index { background: var(--accent-primary); color: var(--bg-primary); width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; flex-shrink: 0; } .stack-trace-info { flex: 1; min-width: 0; } .stack-trace-function { font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 14px; color: var(--text-primary); font-weight: 600; margin-bottom: 4px; } .stack-trace-location { font-size: 13px; color: var(--text-secondary); font-family: 'Consolas', 'Monaco', 'Courier New', monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .stack-trace-expand { color: var(--text-secondary); transition: transform 0.3s ease; } .stack-trace-item.expanded .stack-trace-expand { transform: rotate(180deg); } .stack-trace-code { display: none; background: var(--code-bg); border-top: 1px solid var(--border-color); padding: 15px; max-height: 400px; overflow: auto; } .stack-trace-item.expanded .stack-trace-code { display: block; } .code-line { display: flex; padding: 2px 0; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 13px; line-height: 1.5; } .code-line-number { color: var(--text-muted); text-align: right; padding-right: 20px; min-width: 50px; user-select: none; flex-shrink: 0; } .code-line-content { flex: 1; color: var(--text-primary); white-space: pre; overflow-x: auto; } .code-line.highlight { background: var(--highlight-line); border-left: 3px solid var(--error-red); } .code-line.highlight .code-line-number { color: var(--error-red); font-weight: 700; } .data-table { width: 100%; border-collapse: collapse; font-size: 14px; } .data-table th { text-align: left; padding: 12px; background: var(--bg-tertiary); color: var(--text-secondary); font-weight: 600; border-bottom: 1px solid var(--border-color); } .data-table td { padding: 12px; border-bottom: 1px solid var(--border-color); font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 13px; } .data-table tr:hover { background: var(--bg-hover); } .data-key { color: var(--accent-primary); font-weight: 600; } .data-value { color: var(--text-primary); word-break: break-all; } .solution-card { background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); border: 1px solid var(--border-color); border-radius: 10px; padding: 20px; margin-bottom: 15px; position: relative; overflow: hidden; transition: all 0.3s ease; } .solution-card::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: linear-gradient(180deg, var(--success-green) 0%, var(--accent-primary) 100%); } .solution-card:hover { transform: translateX(5px); box-shadow: var(--shadow); } .solution-title { font-size: 16px; font-weight: 700; color: var(--text-primary); margin-bottom: 10px; display: flex; align-items: center; gap: 10px; } .solution-title svg { color: var(--success-green); flex-shrink: 0; } .solution-description { color: var(--text-secondary); line-height: 1.7; margin-bottom: 15px; } .solution-links { display: flex; flex-wrap: wrap; gap: 10px; } .solution-link { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; background: var(--accent-primary); color: var(--bg-primary); text-decoration: none; border-radius: 6px; font-size: 13px; font-weight: 500; transition: all 0.3s ease; } .solution-link:hover { background: var(--accent-secondary); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(88, 166, 255, 0.3); } .empty-state { text-align: center; padding: 60px 20px; color: var(--text-secondary); } .empty-state svg { width: 64px; height: 64px; margin-bottom: 20px; opacity: 0.5; } .empty-state-title { font-size: 18px; font-weight: 600; margin-bottom: 8px; color: var(--text-primary); } .search-box { margin-bottom: 20px; } .search-input { width: 100%; padding: 12px 16px; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-primary); font-size: 14px; transition: all 0.3s ease; } .search-input:focus { outline: none; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.1); } .badge { display: inline-block; padding: 4px 10px; border-radius: 12px; font-size: 12px; font-weight: 600; background: var(--bg-tertiary); color: var(--text-secondary); } .badge-primary { background: rgba(88, 166, 255, 0.2); color: var(--accent-primary); } .badge-success { background: rgba(63, 185, 80, 0.2); color: var(--success-green); } .badge-error { background: rgba(248, 81, 73, 0.2); color: var(--error-red); } .env-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; } .env-card { background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 8px; padding: 15px; transition: all 0.3s ease; } .env-card:hover { border-color: var(--accent-primary); transform: translateY(-2px); } .env-card-label { color: var(--text-secondary); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; } .env-card-value { color: var(--text-primary); font-size: 16px; font-weight: 700; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; } .extensions-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; margin-top: 15px; } .extension-item { background: var(--bg-tertiary); border: 1px solid var(--border-color); padding: 10px 15px; border-radius: 6px; font-size: 13px; color: var(--text-primary); font-family: 'Consolas', 'Monaco', 'Courier New', monospace; } @media (max-width: 768px) { .error-container { padding: 10px; } .error-header { padding: 20px; } .error-message { font-size: 18px; } .tabs-header { overflow-x: auto; } .tab-content { padding: 15px; } .env-grid { grid-template-columns: 1fr; } } .json-viewer { background: var(--code-bg); padding: 15px; border-radius: 8px; overflow: auto; max-height: 500px; } .json-key { color: var(--accent-primary); } .json-string { color: var(--success-green); } .json-number { color: var(--warning-yellow); } .json-boolean { color: var(--accent-secondary); } .json-null { color: var(--text-muted); } </style> </head> <body class="<?php echo $this->theme; ?>-theme"> <div class="theme-toggle" onclick="toggleTheme()"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" /> </svg> <span>Theme</span> </div> <div class="error-container"> <div class="error-header"> <div class="error-header-content"> <div class="error-type"> <?php echo htmlspecialchars($this->errorData['type']); ?> </div> <div class="error-message"> <?php echo htmlspecialchars($this->errorData['message']); ?> </div> <div class="error-location"> <svg viewBox="0 0 16 16" fill="currentColor"> <path d="M2.5 3.5a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-11zm0 3a.5.5 0 0 1 0-1h6a.5.5 0 0 1 0 1h-6zm0 3a.5.5 0 0 1 0-1h6a.5.5 0 0 1 0 1h-6zm0 3a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-11z" /> </svg> <span><?php echo htmlspecialchars($this->errorData['file']); ?>:<?php echo $this->errorData['line']; ?></span> </div> </div> </div> <div class="tabs-container"> <div class="tabs-header"> <button class="tab-button active" onclick="switchTab('stack-trace')"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z" /> </svg> Stack Trace </button> <button class="tab-button" onclick="switchTab('solutions')"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" /> <path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z" /> </svg> Solutions </button> <button class="tab-button" onclick="switchTab('request')"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855.173-.324.33-.682.468-1.068H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z" /> </svg> Request </button> <button class="tab-button" onclick="switchTab('environment')"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M8.186 1.113a.5.5 0 0 0-.372 0L1.846 3.5l2.404.961L10.404 2l-2.218-.887zm3.564 1.426L5.596 5 8 5.961 14.154 3.5l-2.404-.961zm3.25 1.7-6.5 2.6v7.922l6.5-2.6V4.24zM7.5 14.762V6.838L1 4.239v7.923l6.5 2.6zM7.443.184a1.5 1.5 0 0 1 1.114 0l7.129 2.852A.5.5 0 0 1 16 3.5v8.662a1 1 0 0 1-.629.928l-7.185 2.874a.5.5 0 0 1-.372 0L.63 13.09a1 1 0 0 1-.63-.928V3.5a.5.5 0 0 1 .314-.464L7.443.184z" /> </svg> Environment </button> </div> <div id="stack-trace" class="tab-content active"> <div class="search-box"> <input type="text" class="search-input" placeholder="Search in stack trace..." onkeyup="searchStackTrace(this.value)"> </div> <?php foreach ($this->errorData['trace'] as $frame): ?> <div class="stack-trace-item" data-search-content="<?php echo htmlspecialchars($frame['file'] . ' ' . $frame['function']); ?>"> <div class="stack-trace-header" onclick="toggleStackTrace(this)"> <div class="stack-trace-index"><?php echo $frame['index']; ?></div> <div class="stack-trace-info"> <div class="stack-trace-function"> <?php if ($frame['class']) { echo htmlspecialchars($frame['class'] . $frame['type'] . $frame['function']); } else { echo htmlspecialchars($frame['function']); } ?> <?php if ($frame['args']): ?> <span style="color: var(--text-secondary);">(<?php echo htmlspecialchars($frame['args']); ?>)</span> <?php endif; ?> </div> <div class="stack-trace-location"> <?php echo htmlspecialchars($frame['file']); ?> <?php if ($frame['line']): ?> :<?php echo $frame['line']; ?> <?php endif; ?> </div> </div> <div class="stack-trace-expand"> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> </svg> </div> </div> <?php if (!empty($frame['context'])): ?> <div class="stack-trace-code"> <?php foreach ($frame['context'] as $line): ?> <div class="code-line <?php echo $line['highlight'] ? 'highlight' : ''; ?>"> <div class="code-line-number"><?php echo $line['number']; ?></div> <div class="code-line-content"><?php echo htmlspecialchars($line['content']); ?></div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> <?php endforeach; ?> </div> <div id="solutions" class="tab-content"> <?php if (empty($this->errorData['solutions'])): ?> <div class="empty-state"> <svg viewBox="0 0 16 16" fill="currentColor"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" /> <path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z" /> </svg> <div class="empty-state-title">No Solutions Available</div> <div>No automatic solutions could be generated for this error.</div> </div> <?php else: ?> <?php foreach ($this->errorData['solutions'] as $solution): ?> <div class="solution-card"> <div class="solution-title"> <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor"> <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" /> </svg> <?php echo htmlspecialchars($solution['title']); ?> </div> <div class="solution-description"> <?php echo htmlspecialchars($solution['description']); ?> </div> <?php if (!empty($solution['links'])): ?> <div class="solution-links"> <?php foreach ($solution['links'] as $link): ?> <a href="<?php echo htmlspecialchars($link['url']); ?>" class="solution-link" target="_blank" rel="noopener"> <?php echo htmlspecialchars($link['text']); ?> <svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"> <path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z" /> <path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z" /> </svg> </a> <?php endforeach; ?> </div> <?php endif; ?> </div> <?php endforeach; ?> <?php endif; ?> </div> <div id="request" class="tab-content"> <h3 style="margin-bottom: 20px; color: var(--text-primary);">Request Details</h3> <div style="margin-bottom: 20px;"> <span class="badge badge-primary"><?php echo htmlspecialchars($this->errorData['request']['method']); ?></span> <span style="color: var(--text-secondary); margin-left: 10px; font-family: monospace;"> <?php echo htmlspecialchars($this->errorData['request']['url']); ?> </span> </div> <?php $requestSections = [ 'GET Parameters' => $this->errorData['request']['get'], 'POST Data' => $this->errorData['request']['post'], 'Cookies' => $this->errorData['request']['cookies'], 'Session' => $this->errorData['request']['session'], 'Headers' => $this->errorData['request']['headers'] ]; foreach ($requestSections as $title => $data): if (empty($data)) continue; ?> <h4 style="margin: 25px 0 15px; color: var(--text-primary); font-size: 16px;"><?php echo $title; ?></h4> <table class="data-table"> <thead> <tr> <th style="width: 30%;">Key</th> <th>Value</th> </tr> </thead> <tbody> <?php foreach ($data as $key => $value): ?> <tr> <td class="data-key"><?php echo htmlspecialchars($key); ?></td> <td class="data-value"> <?php echo htmlspecialchars(is_array($value) ? json_encode($value, JSON_PRETTY_PRINT) : $value); ?> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php endforeach; ?> </div> <div id="environment" class="tab-content"> <h3 style="margin-bottom: 20px; color: var(--text-primary);">Environment Information</h3> <div class="env-grid"> <div class="env-card"> <div class="env-card-label">PHP Version</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['php_version']); ?></div> </div> <div class="env-card"> <div class="env-card-label">Operating System</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['os']); ?></div> </div> <div class="env-card"> <div class="env-card-label">Server Software</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['server_software']); ?></div> </div> <div class="env-card"> <div class="env-card-label">Memory Limit</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['memory_limit']); ?></div> </div> <div class="env-card"> <div class="env-card-label">Max Execution Time</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['max_execution_time']); ?>s </div> </div> <div class="env-card"> <div class="env-card-label">Timezone</div> <div class="env-card-value"> <?php echo htmlspecialchars($this->errorData['environment']['timezone']); ?></div> </div> </div> <h4 style="margin: 30px 0 15px; color: var(--text-primary);">Loaded Extensions</h4> <div class="extensions-list"> <?php foreach ($this->errorData['environment']['loaded_extensions'] as $ext): ?> <div class="extension-item"><?php echo htmlspecialchars($ext); ?></div> <?php endforeach; ?> </div> </div> </div> </div> <script> function switchTab(tabName) { // Hide all tabs const tabs = document.querySelectorAll('.tab-content'); tabs.forEach(tab => tab.classList.remove('active')); // Deactivate all buttons const buttons = document.querySelectorAll('.tab-button'); buttons.forEach(button => button.classList.remove('active')); // Show selected tab document.getElementById(tabName).classList.add('active'); // Activate clicked button event.target.closest('.tab-button').classList.add('active'); } function toggleStackTrace(element) { const item = element.closest('.stack-trace-item'); item.classList.toggle('expanded'); } function toggleTheme() { const body = document.body; if (body.classList.contains('dark-theme')) { body.classList.remove('dark-theme'); body.classList.add('light-theme'); localStorage.setItem('theme', 'light'); } else { body.classList.remove('light-theme'); body.classList.add('dark-theme'); localStorage.setItem('theme', 'dark'); } } function searchStackTrace(query) { const items = document.querySelectorAll('.stack-trace-item'); const searchLower = query.toLowerCase(); items.forEach(item => { const content = item.getAttribute('data-search-content').toLowerCase(); if (content.includes(searchLower) || searchLower === '') { item.style.display = ''; } else { item.style.display = 'none'; } }); } // Load saved theme document.addEventListener('DOMContentLoaded', function() { const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.body.className = savedTheme + '-theme'; } // Auto-expand first stack trace item const firstItem = document.querySelector('.stack-trace-item'); if (firstItem) { firstItem.classList.add('expanded'); } }); </script> </body> </html>