This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/Debug/ExceptionHandler.php

467 lines
44 KiB
PHP
Raw Normal View History

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Debug;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
2016-09-19 13:07:31 +01:00
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
/**
* ExceptionHandler converts an exception to a Response object.
*
* It is mostly useful in debug mode to replace the default PHP/XDebug
* output with something prettier and more useful.
*
* As this class is mainly used during Kernel boot, where nothing is yet
* available, the Response content is always HTML.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Nicolas Grekas <p@tchwork.com>
*
* @final since Symfony 4.3
*/
class ExceptionHandler
{
2019-02-14 08:56:06 +00:00
private const GHOST_ADDONS = [
2019-02-20 23:39:50 +00:00
'02-14' => self::GHOST_HEART,
'02-29' => self::GHOST_PLUS,
'10-18' => self::GHOST_GIFT,
2019-02-14 08:56:06 +00:00
];
2019-02-20 23:39:50 +00:00
private const GHOST_GIFT = 'M124.00534057617188,5.3606138080358505 C124.40059661865234,4.644828304648399 125.1237564086914,3.712414965033531 123.88127899169922,3.487462028861046 C123.53517150878906,3.3097832053899765 123.18894958496094,2.9953975528478622 122.8432846069336,3.345616325736046 C122.07421112060547,3.649444565176964 121.40750122070312,4.074306473135948 122.2164306640625,4.869479164481163 C122.57514953613281,5.3830065578222275 122.90142822265625,6.503447040915489 123.3077621459961,6.626829609274864 C123.55027770996094,6.210384353995323 123.7774658203125,5.785196766257286 124.00534057617188,5.3606138080358505 zM122.30630493164062,7.336987480521202 C121.60028076171875,6.076864704489708 121.03211975097656,4.72498320043087 120.16796875,3.562500938773155 C119.11695098876953,2.44033907353878 117.04605865478516,2.940566048026085 116.57544708251953,4.387995228171349 C115.95028686523438,5.819030746817589 117.2991714477539,7.527640804648399 118.826171875,7.348545059561729 C119.98493194580078,7.367936596274376 121.15027618408203,7.420116886496544 122.30630493164062,7.336987480521202 zM128.1732177734375,7.379541382193565 C129.67486572265625,7.17823551595211 130.53842163085938,5.287807449698448 129.68344116210938,4.032590612769127 C128.92578125,2.693056806921959 126.74605560302734,2.6463639587163925 125.98509216308594,4.007616028189659 C125.32617950439453,5.108129009604454 124.75428009033203,6.258124336600304 124.14962768554688,7.388818249106407 C125.48638916015625,7.465229496359825 126.8357162475586,7.447416767477989 128.1732177734375,7.379541382193565 zM130.6601104736328,8.991325363516808 C131.17202758789062,8.540884003043175 133.1543731689453,8.009847149252892 131.65304565429688,7.582054600119591 C131.2811279296875,7.476506695151329 130.84751892089844,6.99234913289547 130.5132598876953,7.124847874045372 C129.78744506835938,8.02728746831417 128.67140197753906,8.55669592320919 127.50616455078125,8.501235947012901 C127.27806091308594,8.576229080557823 126.11459350585938,8.38720129430294 126.428955078125,8.601900085806847 C127.25099182128906,9.070617660880089 128.0523223876953,9.579657539725304 128.902587890625,9.995706543326378 C129.49813842773438,9.678531631827354 130.0761260986328,9.329126343131065 130.6601104736328,8.991325363516808 zM118.96446990966797,9.246344551444054 C119.4022445678711,8.991325363516808 119.84001922607422,8.736305221915245 120.27779388427734,8.481284126639366 C118.93965911865234,8.414779648184776 117.40827941894531,8.607666000723839 116.39698791503906,7.531384453177452 C116.11186981201172,7.212117180228233 115.83845520019531,6.846597656607628 115.44329071044922,7.248530372977257 C114.96995544433594,7.574637398123741 113.5140609741211,7.908811077475548 114.63501739501953,8.306883797049522 C115.61112976074219,8.883499130606651 116.58037567138672,9.474181160330772 117.58061218261719,10.008124336600304 C118.05723571777344,9.784612640738487 118.50651550292969,9.5052699893713 118.96446990966797,9.246344551444054 zM125.38018035888672,12.091858848929405 C125.9474868774414,11.636047348380089 127.32159423828125,11.201767906546593 127.36749267578125,10.712632164359093 C126.08487701416016,9.974547371268272 124.83960723876953,9.152772888541222 123.49772644042969,8.528907760977745 C123.03594207763672,8.353693947196007 122.66152954101562,8.623294815421104 122.28982543945312,8.857431396842003 C121.19065856933594,9.51122473180294 120.06505584716797,10.12446115911007 119.00167083740234,10.835315689444542 C120.39238739013672,11.69529627263546 121.79983520507812,12.529837593436241 123.22095489501953,13.338589653372765 C123.94580841064453,12.932025894522667 124.66128540039062,12.508862480521202 125.38018035888672,12.091858848929405 zM131.07164001464844,13.514615997672081 C131.66018676757812,13.143282875418663 132.2487335205078,12.771927818655968 132.8372802734375,12.400571808218956 C132.8324737548828,11.156818374991417 132.8523406982422,9.912529930472374 132.81829833984375,8.669195160269737 C131.63046264648438,9.332009300589561 130.45948791503906,10.027913078665733 129.30828857421875,10.752535805106163 C129.18237304
private const GHOST_HEART = 'M125.91386369681868,8.305165958366445 C128.95033202169043,-0.40540639102854037 140.8469835342744,8.305165958366445 125.91386369681868,19.504526138305664 C110.98208663272044,8.305165958366445 122.87795231771452,-0.40540639102854037 125.91386369681868,8.305165958366445 z';
private const GHOST_PLUS = 'M111.36824226379395,8.969108581542969 L118.69175148010254,8.969108581542969 L118.69175148010254,1.6455793380737305 L126.20429420471191,1.6455793380737305 L126.20429420471191,8.969108581542969 L133.52781105041504,8.969108581542969 L133.52781105041504,16.481630325317383 L126.20429420471191,16.481630325317383 L126.20429420471191,23.805158615112305 L118.69175148010254,23.805158615112305 L118.69175148010254,16.481630325317383 L111.36824226379395,16.481630325317383 z';
private $debug;
private $charset;
private $handler;
private $caughtBuffer;
private $caughtLength;
private $fileLinkFormat;
2017-10-28 19:15:32 +01:00
public function __construct(bool $debug = true, string $charset = null, $fileLinkFormat = null)
{
$this->debug = $debug;
$this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
$this->fileLinkFormat = $fileLinkFormat;
}
/**
* Registers the exception handler.
*
* @param bool $debug Enable/disable debug mode, where the stack trace is displayed
* @param string|null $charset The charset used by exception messages
* @param string|null $fileLinkFormat The IDE link template
*
* @return static
*/
public static function register($debug = true, $charset = null, $fileLinkFormat = null)
{
$handler = new static($debug, $charset, $fileLinkFormat);
2019-01-16 09:39:14 +00:00
$prev = set_exception_handler([$handler, 'handle']);
if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
2014-05-26 11:29:25 +01:00
restore_exception_handler();
2019-01-16 09:39:14 +00:00
$prev[0]->setExceptionHandler([$handler, 'handle']);
2014-05-26 11:29:25 +01:00
}
return $handler;
}
/**
* Sets a user exception handler.
*
* @param callable $handler An handler that will be called on Exception
*
* @return callable|null The previous exception handler if any
*/
public function setHandler(callable $handler = null)
{
$old = $this->handler;
$this->handler = $handler;
return $old;
}
/**
* Sets the format for links to source files.
*
Fix @param in PHPDoc Errors reported by Sami API Doc generator on branch 3.2 ERROR: The "factory" @param tag variable name is wrong (should be "objectLoader") on "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader::__construct" in src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php:68 ERROR: The "objectLoader" @param tag variable name is wrong (should be "factory") on "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader::__construct" in src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php:68 ERROR: "7" @param tags are expected but only "6" found on "Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController::__construct" in src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php:50 ERROR: "3" @param tags are expected but only "2" found on "Symfony\Component\Asset\PathPackage::__construct" in src/Symfony/Component/Asset/PathPackage.php:35 ERROR: "2" @param tags are expected but only "1" found on "Symfony\Component\Cache\Adapter\PhpArrayAdapter::create" in src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php:64 ERROR: "3" @param tags are expected but only "1" found on "Symfony\Component\Cache\Adapter\RedisAdapter::__construct" in src/Symfony/Component/Cache/Adapter/RedisAdapter.php:39 ERROR: The "format" @param tag variable name is wrong (should be "fileLinkFormat") on "Symfony\Component\Debug\ExceptionHandler::setFileLinkFormat" in src/Symfony/Component/Debug/ExceptionHandler.php:90 ERROR: "2" @param tags are expected but only "3" found on "Symfony\Component\DependencyInjection\Compiler\Compiler::addPass" in src/Symfony/Component/DependencyInjection/Compiler/Compiler.php:73 ERROR: "2" @param tags are expected but only "3" found on "Symfony\Component\DependencyInjection\Compiler\PassConfig::addPass" in src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php:97 ERROR: "2" @param tags are expected but only "3" found on "Symfony\Component\DependencyInjection\ContainerBuilder::addCompilerPass" in src/Symfony/Component/DependencyInjection/ContainerBuilder.php:311 ERROR: "2" @param tags are expected but only "3" found on "Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface::getProxyFactoryCode" in src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/DumperInterface.php:41 ERROR: "0" @param tags are expected but only "1" found on "Symfony\Component\HttpFoundation\Request::isMethodSafe" in src/Symfony/Component/HttpFoundation/Request.php:1458 ERROR: "5" @param tags are expected but only "6" found on "Symfony\Component\Serializer\Normalizer\AbstractNormalizer::instantiateObject" in src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php:291
2017-03-28 22:38:21 +01:00
* @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
*
* @return string The previous file link format
*/
public function setFileLinkFormat($fileLinkFormat)
{
$old = $this->fileLinkFormat;
$this->fileLinkFormat = $fileLinkFormat;
return $old;
}
/**
* Sends a response for the given Exception.
*
* To be as fail-safe as possible, the exception is first handled
* by our simple exception handler, then by the user exception handler.
* The latter takes precedence and any output from the former is cancelled,
* if and only if nothing bad happens in this handling path.
*/
public function handle(\Exception $exception)
{
if (null === $this->handler || $exception instanceof OutOfMemoryException) {
$this->sendPhpResponse($exception);
return;
}
$caughtLength = $this->caughtLength = 0;
2015-09-03 20:36:13 +01:00
ob_start(function ($buffer) {
2014-12-03 22:04:33 +00:00
$this->caughtBuffer = $buffer;
return '';
});
$this->sendPhpResponse($exception);
while (null === $this->caughtBuffer && ob_end_flush()) {
// Empty loop, everything is in the condition
}
if (isset($this->caughtBuffer[0])) {
2015-09-03 20:36:13 +01:00
ob_start(function ($buffer) {
2014-12-03 22:04:33 +00:00
if ($this->caughtLength) {
// use substr_replace() instead of substr() for mbstring overloading resistance
$cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
if (isset($cleanBuffer[0])) {
$buffer = $cleanBuffer;
}
}
return $buffer;
});
echo $this->caughtBuffer;
$caughtLength = ob_get_length();
}
$this->caughtBuffer = null;
try {
($this->handler)($exception);
$this->caughtLength = $caughtLength;
} catch (\Exception $e) {
if (!$caughtLength) {
// All handlers failed. Let PHP handle that now.
throw $exception;
}
}
}
/**
* Sends the error associated with the given Exception as a plain PHP response.
*
* This method uses plain PHP functions like header() and echo to output
* the response.
*
* @param \Exception|FlattenException $exception An \Exception or FlattenException instance
*/
public function sendPhpResponse($exception)
{
if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
}
if (!headers_sent()) {
header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
foreach ($exception->getHeaders() as $name => $value) {
header($name.': '.$value, false);
}
header('Content-Type: text/html; charset='.$this->charset);
}
echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
}
/**
* Gets the full HTML content associated with the given exception.
*
* @param \Exception|FlattenException $exception An \Exception or FlattenException instance
*
* @return string The HTML content as a string
*/
public function getHtml($exception)
{
if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
}
return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
}
/**
* Gets the HTML content associated with the given exception.
*
* @return string The content as a string
*/
public function getContent(FlattenException $exception)
{
switch ($exception->getStatusCode()) {
case 404:
$title = 'Sorry, the page you are looking for could not be found.';
break;
default:
$title = $this->debug ? $this->escapeHtml($exception->getMessage()) : 'Whoops, looks like something went wrong.';
}
2018-06-26 09:45:54 +01:00
if (!$this->debug) {
return <<<EOF
<div class="container">
<h1>$title</h1>
</div>
EOF;
}
$content = '';
2018-06-26 09:45:54 +01:00
try {
$count = \count($exception->getAllPrevious());
2018-06-26 09:45:54 +01:00
$total = $count + 1;
foreach ($exception->toArray() as $position => $e) {
$ind = $count - $position + 1;
$class = $this->formatClass($e['class']);
$message = nl2br($this->escapeHtml($e['message']));
$content .= sprintf(<<<'EOF'
<div class="trace trace-as-html">
<table class="trace-details">
<thead class="trace-head"><tr><th>
<h3 class="trace-class">
<span class="text-muted">(%d/%d)</span>
<span class="exception_title">%s</span>
</h3>
<p class="break-long-words trace-message">%s</p>
</th></tr></thead>
<tbody>
EOF
2018-06-26 09:45:54 +01:00
, $ind, $total, $class, $message);
foreach ($e['trace'] as $trace) {
$content .= '<tr><td>';
if ($trace['function']) {
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
}
2018-06-26 09:45:54 +01:00
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);
}
$content .= "</td></tr>\n";
}
2018-06-26 09:45:54 +01:00
$content .= "</tbody>\n</table>\n</div>\n";
}
} catch (\Exception $e) {
// something nasty happened and we cannot throw an exception anymore
if ($this->debug) {
2018-08-17 10:19:56 +01:00
$e = FlattenException::create($e);
$title = sprintf('Exception thrown when handling an exception (%s: %s)', $e->getClass(), $this->escapeHtml($e->getMessage()));
2018-06-26 09:45:54 +01:00
} else {
$title = 'Whoops, looks like something went wrong.';
}
}
$symfonyGhostImageContents = $this->getSymfonyGhostAsSvg();
return <<<EOF
<div class="exception-summary">
<div class="container">
<div class="exception-message-wrapper">
<h1 class="break-long-words exception-message">$title</h1>
<div class="exception-illustration hidden-xs-down">$symfonyGhostImageContents</div>
</div>
</div>
</div>
<div class="container">
$content
</div>
EOF;
}
/**
* Gets the stylesheet associated with the given exception.
*
* @return string The stylesheet as a string
*/
public function getStylesheet(FlattenException $exception)
{
2018-06-26 09:45:54 +01:00
if (!$this->debug) {
return <<<'EOF'
body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
.container { margin: 30px; max-width: 600px; }
h1 { color: #dc3545; font-size: 24px; }
EOF;
}
2015-12-21 11:01:57 +00:00
return <<<'EOF'
body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }
a { cursor: pointer; text-decoration: none; }
a:hover { text-decoration: underline; }
abbr[title] { border-bottom: none; cursor: help; text-decoration: none; }
code, pre { font: 13px/1.5 Consolas, Monaco, Menlo, "Ubuntu Mono", "Liberation Mono", monospace; }
table, tr, th, td { background: #FFF; border-collapse: collapse; vertical-align: top; }
table { background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2); margin: 1em 0; width: 100%; }
table th, table td { border: solid #E0E0E0; border-width: 1px 0; padding: 8px 10px; }
table th { background-color: #E0E0E0; font-weight: bold; text-align: left; }
.hidden-xs-down { display: none; }
.block { display: block; }
.break-long-words { -ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; }
.text-muted { color: #999; }
.container { max-width: 1024px; margin: 0 auto; padding: 0 15px; }
.container::after { content: ""; display: table; clear: both; }
.exception-summary { background: #B0413E; border-bottom: 2px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, .3); flex: 0 0 auto; margin-bottom: 30px; }
.exception-message-wrapper { display: flex; align-items: center; min-height: 70px; }
.exception-message { flex-grow: 1; padding: 30px 0; }
.exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; }
.exception-message.long { font-size: 18px; }
.exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; }
.exception-message a:hover { border-bottom-color: #ffffff; }
.exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
.trace + .trace { margin-top: 30px; }
.trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }
.trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }
.trace-file-path, .trace-file-path a { color: #222; margin-top: 3px; font-size: 13px; }
.trace-class { color: #B0413E; }
.trace-type { padding: 0 2px; }
.trace-method { color: #B0413E; font-weight: bold; }
.trace-arguments { color: #777; font-weight: normal; padding-left: 2px; }
@media (min-width: 575px) {
.hidden-xs-down { display: initial; }
}
EOF;
}
private function decorate($content, $css)
{
return <<<EOF
<!DOCTYPE html>
<html>
<head>
<meta charset="{$this->charset}" />
<meta name="robots" content="noindex,nofollow" />
<style>$css</style>
</head>
<body>
$content
</body>
</html>
EOF;
}
private function formatClass($class)
{
$parts = explode('\\', $class);
2015-04-16 08:01:03 +01:00
return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
}
private function formatPath($path, $line)
{
$file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path);
$fmt = $this->fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
if (!$fmt) {
return sprintf('<span class="block trace-file-path">in <span title="%s%3$s"><strong>%s</strong>%s</span></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
}
if (\is_string($fmt)) {
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
2019-01-16 09:39:14 +00:00
$fmt = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 1; isset($fmt[$i]); ++$i) {
if (0 === strpos($path, $k = $fmt[$i++])) {
$path = substr_replace($path, $fmt[$i], 0, \strlen($k));
break;
}
}
2019-01-16 09:39:14 +00:00
$link = strtr($fmt[0], ['%f' => $path, '%l' => $line]);
} else {
try {
$link = $fmt->format($path, $line);
} catch (\Exception $e) {
return sprintf('<span class="block trace-file-path">in <span title="%s%3$s"><strong>%s</strong>%s</span></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
}
}
return sprintf('<span class="block trace-file-path">in <a href="%s" title="Go to source"><strong>%s</string>%s</a></span>', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : '');
}
/**
* Formats an array as a string.
*
* @param array $args The argument array
*
* @return string
*/
private function formatArgs(array $args)
{
2019-01-16 09:39:14 +00:00
$result = [];
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
Merge branch '2.3' into 2.6 * 2.3: Fix small coding style [2.3] Static Code Analysis for Components [Form] fixed phpdoc CS: Convert double quotes to single quotes Fixed MongoODM entity loader. Improved loading behavior of entities and documents by reusing entity loader. [Validator] added Japanese translation for unmatched charset (id: 80) [DependencyInjection] Highest precedence for user parameters [Translation][MoFileLoader] fixed load empty translation. bumped Symfony version to 2.3.27 updated VERSION for 2.3.26 update CONTRIBUTORS for 2.3.26 updated CHANGELOG for 2.3.26 Conflicts: src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php src/Symfony/Bundle/TwigBundle/Command/LintCommand.php src/Symfony/Component/Config/Definition/ReferenceDumper.php src/Symfony/Component/Debug/ExceptionHandler.php src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php src/Symfony/Component/Filesystem/Filesystem.php src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php src/Symfony/Component/HttpKernel/Kernel.php src/Symfony/Component/Serializer/Encoder/XmlEncoder.php src/Symfony/Component/Translation/PluralizationRules.php src/Symfony/Component/Validator/Constraints/IssnValidator.php src/Symfony/Component/Validator/Resources/translations/validators.ja.xlf src/Symfony/Component/Yaml/Tests/InlineTest.php
2015-03-22 16:55:57 +00:00
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
} elseif ('array' === $item[0]) {
$formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
} elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>';
} elseif ('boolean' === $item[0]) {
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
} elseif ('resource' === $item[0]) {
$formattedValue = '<em>resource</em>';
} else {
$formattedValue = str_replace("\n", '', $this->escapeHtml(var_export($item[1], true)));
}
$result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
}
return implode(', ', $result);
}
2014-05-26 11:29:25 +01:00
/**
* HTML-encodes a string.
2014-05-26 11:29:25 +01:00
*/
private function escapeHtml($str)
2014-05-26 11:29:25 +01:00
{
2016-05-22 19:00:58 +01:00
return htmlspecialchars($str, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset);
2014-05-26 11:29:25 +01:00
}
private function getSymfonyGhostAsSvg()
{
2019-02-14 08:56:06 +00:00
return '<svg viewBox="0 0 136 81" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M92.358 20.403a23.168 23.168 0 0 1 9.003 1.881 23.67 23.67 0 0 1 5.197 3.079 24.257 24.257 0 0 1 3.457 3.296 24.771 24.771 0 0 1 5.042 9.396c.486 1.72.78 3.492.895 5.28l.008.142.028.158.015.246v13.875c.116.034.232.065.348.098.193.054.383.116.577.168.487.125.989.191 1.49.215.338.016.689.023 1.021-.059.021-.005.032-.029.048-.044l.095-.1c.243-.265.461-.552.663-.851.277-.408.523-.837.746-1.279l.042-.087c-.066-.012-.131-.026-.197-.04l-.099-.023a5.536 5.536 0 0 1-.694-.242 5.649 5.649 0 0 1-2.374-1.845 5.694 5.694 0 0 1-.824-1.594 6.514 6.514 0 0 1-.267-2.781c.045-.394.126-.779.233-1.159.079-.278.162-.562.307-.812.094-.163.129-.196.247-.341l.79-.882c.143-.143.174-.186.34-.303.249-.174.536-.289.834-.333.074-.011.15-.014.224-.02l1.188-.037c.173.004.217-.002.388.028s.211.05.375.105l.018.007c.059.026.119.05.176.079.151.076.179.104.313.2l.006-.021c.073-.187.084-.238.187-.41.077-.129.167-.249.27-.357.051-.054.108-.103.162-.154l1.124-.95c.14-.107.172-.14.327-.224.155-.085.199-.094.363-.154l.019-.006c.169-.043.211-.06.385-.077.174-.016.218-.007.392.003l1.446.158c.193.033.244.033.43.098.278.097.534.259.744.47.053.053.1.112.149.167l.923 1.158.149.213.028.054.017-.014.184-.125c.196-.104.196-.104.402-.184l1.386-.451c.064-.018.126-.038.19-.052.129-.028.259-.042.39-.043.16-.002.321.017.478.047.364.069.711.21 1.032.396.162.094.316.199.469.308.088.063.176.132.27.188l.021.011c.19.123.245.146.409.305.185.178.336.393.443.63.035.079.061.162.091.243l.439 1.428c.045.175.062.219.081.4.02.193.006.381-.015.573a7.79 7.79 0 0 1-.101.645c-.09.455-.212.901-.365 1.339-.128.366-.273.73-.445 1.077-.658 1.335-1.652 2.512-2.917 3.265a6.399 6.399 0 0 1-1.019.489 6.097 6.097 0 0 1-.631.203c-.226.058-.455.1-.686.134l-.096.012-.061.007c-.01.176-.022.352-.036.528-.034.39-.082.778-.153 1.163a14.258 14.258 0 0 1-.574 2.114c-.229.654-.484 1.306-.806 1.918a9.16 9.16 0 0 1-.386.656c-.219.348-.451.686-.697 1.013-.448.594-.946 1.148-1.521 1.614-.255.207-.52.397-.808.553-.9.489-1.919.648-2.921.735-.493.038-.986.059-1.478.099-.162.015-.324.033-.486.049-.145.011-.289.022-.434.03a15.768 15.768 0 0 1-2.778-.118c0 1.416.007 2.832-.001 4.248a9.737 9.737 0 0 1-.684 3.479 9.615 9.615 0 0 1-1.72 2.804 9.326 9.326 0 0 1-3.04 2.279 9.046 9.046 0 0 1-5.33.715 9.064 9.064 0 0 1-2.988-1.079 9.363 9.363 0 0 1-2.761-2.429 10.078 10.078 0 0 1-1.05 1.16 9.281 9.281 0 0 1-1.871 1.358 9.033 9.033 0 0 1-2.495.926 9.04 9.04 0 0 1-6.462-1.072 9.395 9.395 0 0 1-2.602-2.292l-.062-.08a10.896 10.896 0 0 1-.53.635 9.266 9.266 0 0 1-2.671 2.032 9.028 9.028 0 0 1-6.044.751 9.048 9.048 0 0 1-2.436-.934 9.343 9.343 0 0 1-2.286-1.803 9.572 9.572 0 0 1-1.783-2.757 9.705 9.705 0 0 1-.773-3.693V67.244c-.157.024-.314.047-.472.067-.487.06-.977.103-1.469.109-.313.004-.627-.009-.94-.028-.426-.025-.85-.065-1.273-.125-1.833-.264-3.65-.92-5.109-2.117a8.172 8.172 0 0 1-1.064-1.049 10.155 10.155 0 0 1-.878-1.236 15.277 15.277 0 0 1-.7-1.274 20.835 20.835 0 0 1-1.889-6.194l-.018-.142-.008-.061a6.47 6.47 0 0 1-.99-.297 6.135 6.135 0 0 1-.61-.285 6.587 6.587 0 0 1-.889-.562c-1.228-.924-2.124-2.259-2.668-3.711a9.947 9.947 0 0 1-.307-.99 10.288 10.288 0 0 1-.318-1.923c-.009-.147-.011-.293-.015-.44v-.037c.008-.175.004-.22.037-.393.033-.173.053-.213.11-.378l.561-1.417c.031-.068.06-.139.095-.206a2.028 2.028 0 0 1 .771-.803c.093-.054.194-.095.289-.145l.311-.179c.352-.194.714-.358 1.107-.44.213-.044.426-.061.643-.061l.034.001c.177.014.223.01.396.052.174.041.214.065.379.132l1.347.635c.073.04.15.076.221.121.142.091.272.2.388.325.154.166.176.222.297.414l.022.047.722-.762.168-.158c.165-.122.202-.161.385-.253.206-.102.429-.168.656-.193.076-.008.152-.008.228-.011l1.46.013c.177.011.223.007.397.046.175.038.215.061.381.126l.018.008c.154.08.196.094.338.196.142.102.169.137.294.259l.853.912.152-.067.191-.063.019-.005.196-.042c.177-.019.222-.031.401-.022.066.003.133.013.199.02l1.185.182c.073.016.147.027.219.047.288.08.558.227.784.428.151.135.177.181.303.339l.714 1.0
}
private function addElementToGhost()
{
2019-02-20 23:39:50 +00:00
if (!isset(self::GHOST_ADDONS[\date('m-d')])) {
return;
}
return '<path d="'.self::GHOST_ADDONS[\date('m-d')].'" fill="#fff" fill-opacity="0.6"></path>';
}
}