Final Class Yiisoft\ErrorHandler\Renderer\HtmlRenderer
| Inheritance | Yiisoft\ErrorHandler\Renderer\HtmlRenderer |
|---|---|
| Implements | Yiisoft\ErrorHandler\ThrowableRendererInterface |
Formats throwable into HTML string.
Psalm Types
| Name | Value |
|---|---|
| TraceLinkClosure | callable |
Public Properties
| Property | Type | Description | Defined By |
|---|---|---|---|
| $traceHeaderLine | string|null | The trace header line with placeholders to be substituted. | Yiisoft\ErrorHandler\Renderer\HtmlRenderer |
| $traceLinkGenerator | Closure | Yiisoft\ErrorHandler\Renderer\HtmlRenderer |
Public Methods
Constants
| Constant | Value | Description | Defined By |
|---|---|---|---|
| CONTENT_TYPE | 'text/html' | Yiisoft\ErrorHandler\Renderer\HtmlRenderer | |
| DEFAULT_ERROR_MESSAGE | 'An internal server error occurred.' | Yiisoft\ErrorHandler\ThrowableRendererInterface |
Property Details
The trace header line with placeholders to be substituted. Defaults to null.
The placeholders are {file}, {line} and {icon}. A typical use case is the creation of IDE-specific links, since when you click on a trace header link, it opens directly in the IDE. You can also insert custom content.
Example IDE link:
<a href="ide://open?file={file}&line={line}">{icon}</a>
Method Details
| public mixed __construct ( array $settings = [], string|null $template = null, string|null $verboseTemplate = null, integer|null $maxSourceLines = null, integer|null $maxTraceLines = null, string|null $traceHeaderLine = null, Closure|string|null $traceLink = null ) | ||
| $settings | array |
(deprecated) Settings can have the following keys:
|
| $template | string|null |
The full path of the template file for rendering exceptions without call stack information. |
| $verboseTemplate | string|null |
The full path of the template file for rendering exceptions with call stack information. |
| $maxSourceLines | integer|null |
The maximum number of source code lines to be displayed. Defaults to 19. |
| $maxTraceLines | integer|null |
The maximum number of trace source code lines to be displayed. Defaults to 13. |
| $traceHeaderLine | string|null |
Deprecated, use {@see \Yiisoft\ErrorHandler\Renderer\traceLink} instead. The trace header line with placeholders to be substituted. Defaults to null. |
| $traceLink | Closure|string|null |
The trace link. It can be a string with placeholders
|
public function __construct(
array $settings = [],
?string $template = null,
?string $verboseTemplate = null,
?int $maxSourceLines = null,
?int $maxTraceLines = null,
?string $traceHeaderLine = null,
string|Closure|null $traceLink = null,
) {
$this->markdownParser = new GithubMarkdown();
$this->markdownParser->html5 = true;
$this->defaultTemplatePath = dirname(__DIR__, 2) . '/templates';
$this->template = $template
?? $settings['template']
?? $this->defaultTemplatePath . '/production.php';
$this->verboseTemplate = $verboseTemplate
?? $settings['verboseTemplate']
?? $this->defaultTemplatePath . '/development.php';
$this->maxSourceLines = $maxSourceLines
?? $settings['maxSourceLines']
?? 19;
$this->maxTraceLines = $maxTraceLines
?? $settings['maxTraceLines']
?? 13;
$this->traceHeaderLine = $traceHeaderLine
?? $settings['traceHeaderLine']
?? null;
$this->traceLinkGenerator = $this->createTraceLinkGenerator($traceLink);
}
Converts arguments array to its string representation.
| public string argumentsToString ( array $args, boolean $truncate = true ) | ||
| $args | array |
Arguments array to be converted |
| $truncate | boolean | |
| return | string |
The string representation of the arguments array. |
|---|---|---|
public function argumentsToString(array $args, bool $truncate = true): string
{
$count = 0;
$isAssoc = $args !== array_values($args);
/**
* @var mixed $value
*/
foreach ($args as $key => $value) {
$count++;
if ($truncate && $count >= 5) {
if ($count > 5) {
unset($args[$key]);
} else {
$args[$key] = '...';
}
continue;
}
if (is_object($value)) {
$args[$key] = '<span class="title">' . $this->htmlEncode($this->removeAnonymous($value::class) . '#' . spl_object_id($value)) . '</span>';
} elseif (is_bool($value)) {
$args[$key] = '<span class="keyword">' . ($value ? 'true' : 'false') . '</span>';
} elseif (is_string($value)) {
$fullValue = $this->htmlEncode($value);
if ($truncate && mb_strlen($value, 'UTF-8') > 32) {
$displayValue = $this->htmlEncode(mb_substr($value, 0, 32, 'UTF-8')) . '...';
$args[$key] = "<span class=\"string\" title=\"$fullValue\">'$displayValue'</span>";
} else {
$args[$key] = "<span class=\"string\">'$fullValue'</span>";
}
} elseif (is_array($value)) {
unset($args[$key]);
$args[$key] = '[' . $this->argumentsToString($value, $truncate) . ']';
} elseif ($value === null) {
$args[$key] = '<span class="keyword">null</span>';
} elseif (is_resource($value)) {
$args[$key] = '<span class="keyword">resource</span>';
} else {
$args[$key] = '<span class="number">' . (string) $value . '</span>';
}
if (is_string($key)) {
$args[$key] = '<span class="string">\'' . $this->htmlEncode($key) . "'</span> => $args[$key]";
} elseif ($isAssoc) {
$args[$key] = "<span class=\"number\">$key</span> => $args[$key]";
}
}
/** @var string[] $args */
ksort($args);
return implode(', ', $args);
}
Creates string containing HTML link which refers to the home page of determined web-server software and its full name.
| public string createServerInformationLink ( \Psr\Http\Message\ServerRequestInterface $request ) | ||
| $request | \Psr\Http\Message\ServerRequestInterface | |
| return | string |
The server software information hyperlink. |
|---|---|---|
public function createServerInformationLink(ServerRequestInterface $request): string
{
$serverSoftware = (string) ($request->getServerParams()['SERVER_SOFTWARE'] ?? '');
if ($serverSoftware === '') {
return '';
}
$serverUrls = [
'https://httpd.apache.org/' => ['apache'],
'https://nginx.org/' => ['nginx'],
'https://lighttpd.net/' => ['lighttpd'],
'https://iis.net/' => ['iis', 'services'],
'https://www.php.net/manual/en/features.commandline.webserver.php' => ['development'],
];
foreach ($serverUrls as $url => $keywords) {
foreach ($keywords as $keyword) {
if (stripos($serverSoftware, $keyword) !== false) {
return '<a href="' . $url . '" target="_blank" rel="noopener noreferrer">'
. $this->htmlEncode($serverSoftware) . '</a>';
}
}
}
return '';
}
Returns the name of the throwable instance.
| public string getThrowableName ( Throwable $throwable ) | ||
| $throwable | Throwable | |
| return | string |
The name of the throwable instance. |
|---|---|---|
public function getThrowableName(Throwable $throwable): string
{
$name = $throwable::class;
if ($throwable instanceof FriendlyExceptionInterface) {
$name = $throwable->getName() . ' (' . $name . ')';
}
return $name;
}
Encodes special characters into HTML entities for use as a content.
| public string htmlEncode ( string $content ) | ||
| $content | string |
The content to be encoded. |
| return | string |
Encoded content. |
|---|---|---|
public function htmlEncode(string $content): string
{
return htmlspecialchars($content, ENT_QUOTES, 'UTF-8');
}
| public string parseMarkdown ( string $content ) | ||
| $content | string | |
public function parseMarkdown(string $content): string
{
$html = $this->markdownParser->parse($content);
/**
* @psalm-suppress InvalidArgument
*
* @link https://github.com/vimeo/psalm/issues/4317
*/
return strip_tags($html, [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'hr',
'pre',
'code',
'blockquote',
'table',
'tr',
'td',
'th',
'thead',
'tbody',
'strong',
'em',
'b',
'i',
'u',
's',
'span',
'a',
'p',
'br',
'nobr',
'ul',
'ol',
'li',
'img',
]);
}
| public string removeAnonymous ( string $value ) | ||
| $value | string | |
public function removeAnonymous(string $value): string
{
$anonymousPosition = strpos($value, '@anonymous');
return $anonymousPosition !== false ? substr($value, 0, $anonymousPosition) : $value;
}
| public Yiisoft\ErrorHandler\ErrorData render ( Throwable $t, \Psr\Http\Message\ServerRequestInterface|null $request = null ) | ||
| $t | Throwable | |
| $request | \Psr\Http\Message\ServerRequestInterface|null | |
public function render(Throwable $t, ?ServerRequestInterface $request = null): ErrorData
{
return new ErrorData(
$this->renderTemplate($this->template, [
'request' => $request,
'throwable' => $t,
]),
[Header::CONTENT_TYPE => self::CONTENT_TYPE],
);
}
Renders call stack.
| public string renderCallStack ( Throwable $t, array $trace = [] ) | ||
| $t | Throwable |
The exception to get call stack from. |
| $trace | array | |
| return | string |
HTML content of the rendered call stack. |
|---|---|---|
| throws | Throwable | |
public function renderCallStack(Throwable $t, array $trace = []): string
{
$application = $vendor = [];
$application[1] = $this->renderCallStackItem(
$t->getFile(),
$t->getLine(),
null,
null,
[],
1,
false,
[],
);
$index = 1;
if ($t instanceof ErrorException) {
$index = 0;
}
foreach ($trace as $traceItem) {
$file = !empty($traceItem['file']) ? $traceItem['file'] : null;
$line = !empty($traceItem['line']) ? $traceItem['line'] : null;
$class = !empty($traceItem['class']) ? $traceItem['class'] : null;
$args = !empty($traceItem['args']) ? $traceItem['args'] : [];
$parameters = [];
$function = null;
if (!empty($traceItem['function']) && $traceItem['function'] !== 'unknown') {
$function = $traceItem['function'];
if (!str_contains($function, '{closure}')) {
try {
if ($class !== null && class_exists($class)) {
$parameters = (new \ReflectionMethod($class, $function))->getParameters();
} elseif (function_exists($function)) {
$parameters = (new \ReflectionFunction($function))->getParameters();
}
} catch (\ReflectionException) {
// pass
}
}
}
$index++;
if ($this->isVendorFile($file)) {
$vendor[$index] = $this->renderCallStackItem(
$file,
$line,
$class,
$function,
$args,
$index,
true,
$parameters,
);
} else {
$application[$index] = $this->renderCallStackItem(
$file,
$line,
$class,
$function,
$args,
$index,
false,
$parameters,
);
}
}
return $this->renderTemplate($this->defaultTemplatePath . '/_call-stack-items.php', [
'applicationItems' => $application,
'vendorItemGroups' => $this->groupVendorCallStackItems($vendor),
]);
}
Renders the information about curl request.
| public string renderCurl ( \Psr\Http\Message\ServerRequestInterface $request ) | ||
| $request | \Psr\Http\Message\ServerRequestInterface | |
| return | string |
The rendering result. |
|---|---|---|
public function renderCurl(ServerRequestInterface $request): string
{
try {
$output = (new Command())
->setRequest($request)
->build();
} catch (Throwable $e) {
return 'Error generating curl command: ' . $e->getMessage();
}
return $output;
}
Renders the previous exception stack for a given Exception.
| public string renderPreviousExceptions ( Throwable $t ) | ||
| $t | Throwable |
The exception whose precursors should be rendered. |
| return | string |
HTML content of the rendered previous exceptions. Empty string if there are none. |
|---|---|---|
| throws | Throwable | |
public function renderPreviousExceptions(Throwable $t): string
{
$templatePath = $this->defaultTemplatePath . '/_previous-exception.php';
if ($t instanceof CompositeException) {
$result = [];
foreach ($t->getPreviousExceptions() as $exception) {
$result[] = $this->renderTemplate($templatePath, ['throwable' => $exception]);
}
return implode('', $result);
}
if ($t->getPrevious() !== null) {
return $this->renderTemplate($templatePath, ['throwable' => $t->getPrevious()]);
}
return '';
}
Renders the information about request.
| public string renderRequest ( \Psr\Http\Message\ServerRequestInterface $request ) | ||
| $request | \Psr\Http\Message\ServerRequestInterface | |
| return | string |
The rendering result. |
|---|---|---|
public function renderRequest(ServerRequestInterface $request): string
{
$output = $request->getMethod() . ' ' . $request->getUri() . "\n";
$headers = $request->getHeaders();
unset($headers['Host']);
ksort($headers);
foreach ($headers as $name => $values) {
foreach ($values as $value) {
$output .= "$name: $value\n";
}
}
$body = (string)$request->getBody();
if (!empty($body)) {
$output .= "\n" . $body . "\n\n";
}
return $output;
}
| public Yiisoft\ErrorHandler\ErrorData renderVerbose ( Throwable $t, \Psr\Http\Message\ServerRequestInterface|null $request = null ) | ||
| $t | Throwable | |
| $request | \Psr\Http\Message\ServerRequestInterface|null | |
public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData
{
return new ErrorData(
$this->renderTemplate($this->verboseTemplate, [
'request' => $request,
'throwable' => $t,
]),
[Header::CONTENT_TYPE => self::CONTENT_TYPE],
);
}
Signup or Login in order to comment.