Skip to content

Commit

Permalink
include VarCloner
Browse files Browse the repository at this point in the history
  • Loading branch information
juliangut committed Aug 2, 2017
1 parent 2e7d040 commit 313dc7a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 13 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"phpstan/phpstan": "~0.8",
"phpunit/phpunit": "^5.7|^6.0",
"sebastian/phpcpd": "^2.0",
"symfony/var-dumper": "^3.0",
"squizlabs/php_codesniffer": "^2.0"
},
"suggest": {
Expand Down
90 changes: 77 additions & 13 deletions src/Handler/Whoops/HtmlHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@

use Fig\Http\Message\StatusCodeInterface;
use Jgut\Slim\Exception\HttpException;
use Symfony\Component\VarDumper\Cloner\AbstractCloner;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Whoops\Exception\FrameCollection;
use Whoops\Handler\Handler;
use Whoops\Handler\PlainTextHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Util\Misc;
use Whoops\Util\TemplateHelper;

/**
* Whoops custom HTML response handler.
*
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
*/
class HtmlHandler extends PrettyPageHandler
{
Expand All @@ -42,17 +48,17 @@ class HtmlHandler extends PrettyPageHandler
*/
public function handle(): int
{
$helper = new TemplateHelper();
$templateHelper = $this->getTemplateHelper();

$templateFile = $this->getResource('views/layout.html.php');
$cssFile = $this->getResource('css/whoops.base.css');
$zeptoFile = $this->getResource('js/zepto.min.js');
$clipboard = $this->getResource('js/clipboard.min.js');
$jsFile = $this->getResource('js/whoops.base.js');

$code = $this->getExceptionCode();
$inspector = $this->getInspector();
$frames = $this->detectApplicationFrames($this->filterInternalFrames($inspector->getFrames()));
$frames = $this->getFrames();
$code = $this->getCode();

// List of variables that will be passed to the layout template.
$vars = [
Expand All @@ -79,7 +85,7 @@ public function handle(): int

'title' => $this->getPageTitle(),
'name' => explode('\\', $inspector->getExceptionName()),
'message' => $inspector->getException()->getMessage(),
'message' => $inspector->getExceptionMessage(),
'code' => $code,
'plain_exception' => $this->formatExceptionText(),
'frames' => $frames,
Expand All @@ -105,23 +111,81 @@ public function handle(): int
$vars['stylesheet'] .= file_get_contents($this->getResource($this->customCss));
}

$extraTables = array_map(function ($table) use ($inspector) {
return $table instanceof \Closure ? $table($inspector) : $table;
}, $this->getDataTables());
$extraTables = array_map(
function ($table) use ($inspector) {
return $table instanceof \Closure ? $table($inspector) : $table;
},
$this->getDataTables()
);
$vars['tables'] = array_merge($extraTables, $vars['tables']);

$helper->setVariables($vars);
$helper->render($templateFile);
$plainTextHandler = new PlainTextHandler();
$plainTextHandler->setException($this->getException());
$plainTextHandler->setInspector($this->getInspector());
$vars['preface'] = sprintf(
"<!--\n\n\n%s\n\n\n\n\n\n\n\n\n\n\n-->",
$templateHelper->escape($plainTextHandler->generateResponse())
);

$templateHelper->setVariables($vars);
$templateHelper->render($templateFile);

return Handler::QUIT;
}

/**
* Get template helper.
*
* @return TemplateHelper
*/
protected function getTemplateHelper(): TemplateHelper
{
$templateHelper = new TemplateHelper();

if (class_exists('Symfony\Component\VarDumper\Cloner\VarCloner')) {
$cloner = new VarCloner();
$cloner->addCasters(['*' => [$this, 'getCustomCaster']]);
$templateHelper->setCloner($cloner);
}

return $templateHelper;
}

/**
* Add caster for VarCloner.
*
* @param mixed $obj
* @param array $cast
* @param Stub $stub
* @param bool $isNested
* @param int $filter
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return array
*/
public function getCustomCaster($obj, array $cast, Stub $stub, bool $isNested, int $filter = 0)
{
// Only dump object internals if a custom caster exists.
$class = $stub->class;
$classes = [$class => $class] + class_parents($class) + class_implements($class);

foreach ($classes as $class) {
if (isset(AbstractCloner::$defaultCasters[$class])) {
return $cast;
}
}

// Remove all internals
return [];
}

/**
* Get exception code.
*
* @return string
*/
protected function getExceptionCode(): string
protected function getCode(): string
{
/* @var HttpException $exception */
$exception = $this->getException();
Expand All @@ -144,12 +208,12 @@ protected function getExceptionCode(): string
/**
* Detect frames that belong to the application.
*
* @param FrameCollection $frames
*
* @return FrameCollection
*/
protected function detectApplicationFrames(FrameCollection $frames): FrameCollection
protected function getFrames(): FrameCollection
{
$frames = $this->filterInternalFrames($this->getInspector()->getFrames());

if ($this->getApplicationPaths()) {
foreach ($frames as $frame) {
foreach ($this->getApplicationPaths() as $path) {
Expand Down

0 comments on commit 313dc7a

Please sign in to comment.