Skip to content

Commit 9befa59

Browse files
Merge branch '4.4' into 5.0
* 4.4: (28 commits) bug #34554 [HttpClient] Fix early cleanup of pushed HTTP/2 responses (lyrixx) Fix tests [Console] Fix commands description with numeric namespaces [HttpFoundation] Fixed typo [DI] Skip unknown method calls for factories in check types pass [EventDispatcher] Better error reporting when arguments to dispatch() are swapped improve upgrade instructions for twig.exception_controller configuration [HttpFoundation] Update CHANGELOG for PdoSessionHandler BC BREAK in 4.4 [Serializer] CsvEncoder::NO_HEADERS_KEY ignored when used in constructor [Form] Keep preferred_choices order for choice groups [Debug] work around failing chdir() on Darwin [PhpUnitBridge] Read configuration CLI directive [DI] Missing test on YamlFileLoader Revert "minor #34608 [Process] add tests for php executable finder if file does not exist (ahmedash95)" Simpler example for Apache basic auth workaround [Console] Fix trying to access array offset on value of type int [Config] Remove extra sprintf arg [HttpKernel] fix typo [HttpKernel] Support typehint to deprecated FlattenException in controller Add preview mode support for Html and Serializer error renderers ...
2 parents 40b4653 + 25b5265 commit 9befa59

File tree

3 files changed

+67
-22
lines changed

3 files changed

+67
-22
lines changed

DebugClassLoader.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,11 @@ private function darwinRealpath(string $real): string
723723
$real = self::$darwinCache[$kDir][0];
724724
} else {
725725
$dir = getcwd();
726-
chdir($real);
726+
727+
if (!@chdir($real)) {
728+
return $real.$file;
729+
}
730+
727731
$real = getcwd().'/';
728732
chdir($dir);
729733

ErrorRenderer/HtmlErrorRenderer.php

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,28 @@ class HtmlErrorRenderer implements ErrorRendererInterface
3636
private $charset;
3737
private $fileLinkFormat;
3838
private $projectDir;
39-
private $requestStack;
39+
private $outputBuffer;
4040
private $logger;
4141

42-
public function __construct(bool $debug = false, string $charset = null, $fileLinkFormat = null, string $projectDir = null, RequestStack $requestStack = null, LoggerInterface $logger = null)
42+
/**
43+
* @param bool|callable $debug The debugging mode as a boolean or a callable that should return it
44+
* @param bool|callable $outputBuffer The output buffer as a string or a callable that should return it
45+
*/
46+
public function __construct($debug = false, string $charset = null, $fileLinkFormat = null, string $projectDir = null, $outputBuffer = '', LoggerInterface $logger = null)
4347
{
48+
if (!\is_bool($debug) && !\is_callable($debug)) {
49+
throw new \TypeError(sprintf('Argument 1 passed to %s() must be a boolean or a callable, %s given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
50+
}
51+
52+
if (!\is_string($outputBuffer) && !\is_callable($outputBuffer)) {
53+
throw new \TypeError(sprintf('Argument 5 passed to %s() must be a string or a callable, %s given.', __METHOD__, \is_object($outputBuffer) ? \get_class($outputBuffer) : \gettype($outputBuffer)));
54+
}
55+
4456
$this->debug = $debug;
4557
$this->charset = $charset ?: (ini_get('default_charset') ?: 'UTF-8');
4658
$this->fileLinkFormat = $fileLinkFormat ?: (ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'));
4759
$this->projectDir = $projectDir;
48-
$this->requestStack = $requestStack;
60+
$this->outputBuffer = $outputBuffer;
4961
$this->logger = $logger;
5062
}
5163

@@ -57,7 +69,7 @@ public function render(\Throwable $exception): FlattenException
5769
$exception = FlattenException::createFromThrowable($exception, null, [
5870
'Content-Type' => 'text/html; charset='.$this->charset,
5971
]);
60-
72+
6173
return $exception->setAsString($this->renderException($exception));
6274
}
6375

@@ -81,42 +93,61 @@ public function getStylesheet(): string
8193
return $this->include('assets/css/exception.css');
8294
}
8395

96+
public static function isDebug(RequestStack $requestStack, bool $debug): \Closure
97+
{
98+
return static function () use ($requestStack, $debug): bool {
99+
if (!$request = $requestStack->getCurrentRequest()) {
100+
return $debug;
101+
}
102+
103+
return $debug && $request->attributes->getBoolean('showException', true);
104+
};
105+
}
106+
107+
public static function getAndCleanOutputBuffer(RequestStack $requestStack): \Closure
108+
{
109+
return static function () use ($requestStack): string {
110+
if (!$request = $requestStack->getCurrentRequest()) {
111+
return '';
112+
}
113+
114+
$startObLevel = $request->headers->get('X-Php-Ob-Level', -1);
115+
116+
if (ob_get_level() <= $startObLevel) {
117+
return '';
118+
}
119+
120+
Response::closeOutputBuffers($startObLevel + 1, true);
121+
122+
return ob_get_clean();
123+
};
124+
}
125+
84126
private function renderException(FlattenException $exception, string $debugTemplate = 'views/exception_full.html.php'): string
85127
{
128+
$debug = \is_bool($this->debug) ? $this->debug : ($this->debug)($exception);
86129
$statusText = $this->escape($exception->getStatusText());
87130
$statusCode = $this->escape($exception->getStatusCode());
88131

89-
if (!$this->debug) {
132+
if (!$debug) {
90133
return $this->include('views/error.html.php', [
91134
'statusText' => $statusText,
92135
'statusCode' => $statusCode,
93136
]);
94137
}
95138

96139
$exceptionMessage = $this->escape($exception->getMessage());
97-
$request = $this->requestStack ? $this->requestStack->getCurrentRequest() : null;
98140

99141
return $this->include($debugTemplate, [
100142
'exception' => $exception,
101143
'exceptionMessage' => $exceptionMessage,
102144
'statusText' => $statusText,
103145
'statusCode' => $statusCode,
104146
'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null,
105-
'currentContent' => $request ? $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1)) : '',
147+
'currentContent' => \is_string($this->outputBuffer) ? $this->outputBuffer : ($this->outputBuffer)(),
106148
]);
107149
}
108150

109-
private function getAndCleanOutputBuffering(int $startObLevel): string
110-
{
111-
if (ob_get_level() <= $startObLevel) {
112-
return '';
113-
}
114-
115-
Response::closeOutputBuffers($startObLevel + 1, true);
116-
117-
return ob_get_clean();
118-
}
119-
120151
/**
121152
* Formats an array as a string.
122153
*/
@@ -312,7 +343,7 @@ private function include(string $name, array $context = []): string
312343
{
313344
extract($context, EXTR_SKIP);
314345
ob_start();
315-
include __DIR__ . '/../Resources/' .$name;
346+
include __DIR__.'/../Resources/'.$name;
316347

317348
return trim(ob_get_clean());
318349
}

ErrorRenderer/SerializerErrorRenderer.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,26 @@ class SerializerErrorRenderer implements ErrorRendererInterface
2626
private $serializer;
2727
private $format;
2828
private $fallbackErrorRenderer;
29+
private $debug;
2930

3031
/**
3132
* @param string|callable(FlattenException) $format The format as a string or a callable that should return it
33+
* @param bool|callable $debug The debugging mode as a boolean or a callable that should return it
3234
*/
33-
public function __construct(SerializerInterface $serializer, $format, ErrorRendererInterface $fallbackErrorRenderer = null)
35+
public function __construct(SerializerInterface $serializer, $format, ErrorRendererInterface $fallbackErrorRenderer = null, $debug = false)
3436
{
3537
if (!\is_string($format) && !\is_callable($format)) {
3638
throw new \TypeError(sprintf('Argument 2 passed to %s() must be a string or a callable, %s given.', __METHOD__, \is_object($format) ? \get_class($format) : \gettype($format)));
3739
}
3840

41+
if (!\is_bool($debug) && !\is_callable($debug)) {
42+
throw new \TypeError(sprintf('Argument 4 passed to %s() must be a boolean or a callable, %s given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
43+
}
44+
3945
$this->serializer = $serializer;
4046
$this->format = $format;
4147
$this->fallbackErrorRenderer = $fallbackErrorRenderer ?? new HtmlErrorRenderer();
48+
$this->debug = $debug;
4249
}
4350

4451
/**
@@ -51,7 +58,10 @@ public function render(\Throwable $exception): FlattenException
5158
try {
5259
$format = \is_string($this->format) ? $this->format : ($this->format)($flattenException);
5360

54-
return $flattenException->setAsString($this->serializer->serialize($flattenException, $format, ['exception' => $exception]));
61+
return $flattenException->setAsString($this->serializer->serialize($flattenException, $format, [
62+
'exception' => $exception,
63+
'debug' => \is_bool($this->debug) ? $this->debug : ($this->debug)($exception),
64+
]));
5565
} catch (NotEncodableValueException $e) {
5666
return $this->fallbackErrorRenderer->render($exception);
5767
}

0 commit comments

Comments
 (0)