Implement improved var dumping on dev instances.

This commit is contained in:
Buster "Silver Eagle" Neece 2020-09-16 08:50:00 -05:00
parent 18daed36b0
commit 69e48dd965
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
7 changed files with 149 additions and 93 deletions

View File

@ -92,14 +92,14 @@
"codeception/module-rest": "^1.0",
"filp/whoops": "^2",
"flow/jsonpath": "^0.5",
"kint-php/kint": "^3.3",
"mockery/mockery": "^1.0",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-doctrine": "^0.12",
"phpunit/php-timer": "^5.0",
"phpunit/phpunit": "^9.2",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "3.*"
"squizlabs/php_codesniffer": "3.*",
"symfony/var-dumper": "^5.1"
},
"replace": {
"symfony/polyfill-php71": "1.99",

162
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "340ce72e10ffba438017513fbda1a484",
"content-hash": "b7a692cf1ebded166ad9b7c29a64e910",
"packages": [
{
"name": "aws/aws-sdk-php",
@ -9043,76 +9043,6 @@
],
"time": "2020-05-27T16:41:55+00:00"
},
{
"name": "kint-php/kint",
"version": "3.3",
"source": {
"type": "git",
"url": "https://github.com/kint-php/kint.git",
"reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kint-php/kint/zipball/335ac1bcaf04d87df70d8aa51e8887ba2c6d203b",
"reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b",
"shasum": ""
},
"require": {
"php": ">=5.3.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"phpunit/phpunit": "^4.0",
"seld/phar-utils": "^1.0",
"symfony/finder": "^2.0 || ^3.0 || ^4.0",
"vimeo/psalm": "^3.0"
},
"suggest": {
"ext-ctype": "Simple data type tests",
"ext-iconv": "Provides fallback detection for ambiguous legacy string encodings such as the Windows and ISO 8859 code pages",
"ext-mbstring": "Provides string encoding detection",
"kint-php/kint-js": "Provides a simplified dump to console.log()",
"kint-php/kint-twig": "Provides d() and s() functions in twig templates",
"symfony/polyfill-ctype": "Replacement for ext-ctype if missing",
"symfony/polyfill-iconv": "Replacement for ext-iconv if missing",
"symfony/polyfill-mbstring": "Replacement for ext-mbstring if missing"
},
"type": "library",
"autoload": {
"files": [
"init.php"
],
"psr-4": {
"Kint\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonathan Vollebregt",
"homepage": "https://github.com/jnvsor"
},
{
"name": "Rokas Šleinius",
"homepage": "https://github.com/raveren"
},
{
"name": "Contributors",
"homepage": "https://github.com/kint-php/kint/graphs/contributors"
}
],
"description": "Kint - debugging tool for PHP developers",
"homepage": "https://kint-php.github.io/kint/",
"keywords": [
"debug",
"kint",
"php"
],
"time": "2019-10-17T18:05:24+00:00"
},
{
"name": "mockery/mockery",
"version": "1.4.2",
@ -11528,6 +11458,96 @@
],
"time": "2020-08-12T08:45:47+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v5.1.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "b43a3905262bcf97b2510f0621f859ca4f5287be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/b43a3905262bcf97b2510f0621f859ca4f5287be",
"reference": "b43a3905262bcf97b2510f0621f859ca4f5287be",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"phpunit/phpunit": "<5.4.3",
"symfony/console": "<4.4"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^4.4|^5.0",
"symfony/process": "^4.4|^5.0",
"twig/twig": "^2.4|^3.0"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
"bin": [
"Resources/bin/var-dump-server"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"autoload": {
"files": [
"Resources/functions/dump.php"
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony mechanism for exploring and dumping PHP variables",
"homepage": "https://symfony.com",
"keywords": [
"debug",
"dump"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-17T07:42:30+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.2.0",

View File

@ -34,6 +34,9 @@ class Assets
/** @var array The loaded domains that should be included in the CSP header. */
protected array $csp_domains;
/** @var ServerRequestInterface|null The current request (if it's available) */
protected ?ServerRequestInterface $request = null;
/**
* Assets constructor.
*
@ -58,6 +61,26 @@ class Assets
$this->csp_domains = [];
}
/**
* Create a new copy of this object for a specific request.
*
* @param ServerRequestInterface $request
*
* @return $this
*/
public function withRequest(ServerRequestInterface $request): self
{
$newAssets = clone $this;
$newAssets->setRequest($request);
return $newAssets;
}
public function setRequest(ServerRequestInterface $request): void
{
$this->request = $request;
}
protected function addVueComponents(array $vueComponents = [])
{
if (!empty($vueComponents['entrypoints'])) {
@ -352,11 +375,9 @@ class Assets
/**
* Return any inline JavaScript.
*
* @param ServerRequestInterface $request
*
* @return string
*/
public function inlineJs(ServerRequestInterface $request): string
public function inlineJs(): string
{
$this->_sort();
@ -365,7 +386,7 @@ class Assets
if (!empty($item['inline']['js'])) {
foreach ($item['inline']['js'] as $inline) {
if (is_callable($inline)) {
$inline = $inline($request);
$inline = $inline($this->request);
}
if (!empty($inline)) {

View File

@ -5,6 +5,8 @@ use App\Http\ServerRequest;
use Doctrine\Inflector\InflectorFactory;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
class ViewFactory
{
@ -32,28 +34,28 @@ class ViewFactory
$this->assets = $assets;
}
public function create(?ServerRequestInterface $request = null): View
public function create(ServerRequestInterface $request): View
{
$view = new View($this->settings[Settings::VIEWS_DIR], 'phtml');
// Add non-request-dependent content.
$view->addData([
'settings' => $this->settings,
'assets' => $this->assets,
'version' => $this->version,
]);
// Add request-dependent content.
if (null !== $request) {
$view->addData([
'request' => $request,
'router' => $request->getAttribute(ServerRequest::ATTR_ROUTER),
'auth' => $request->getAttribute(ServerRequest::ATTR_AUTH),
'acl' => $request->getAttribute(ServerRequest::ATTR_ACL),
'customization' => $request->getAttribute(ServerRequest::ATTR_CUSTOMIZATION),
'flash' => $request->getAttribute(ServerRequest::ATTR_SESSION_FLASH),
]);
}
$assets = $this->assets->withRequest($request);
$view->addData([
'request' => $request,
'router' => $request->getAttribute(ServerRequest::ATTR_ROUTER),
'auth' => $request->getAttribute(ServerRequest::ATTR_AUTH),
'acl' => $request->getAttribute(ServerRequest::ATTR_ACL),
'customization' => $request->getAttribute(ServerRequest::ATTR_CUSTOMIZATION),
'flash' => $request->getAttribute(ServerRequest::ATTR_SESSION_FLASH),
'assets' => $assets,
]);
$view->registerFunction('service', function ($service) {
return $this->di->get($service);
@ -63,6 +65,19 @@ class ViewFactory
return json_encode($string, JSON_THROW_ON_ERROR, 512);
});
$view->registerFunction('dump', function ($value) {
if (class_exists(VarCloner::class)) {
$varCloner = new VarCloner();
$dumper = new CliDumper;
$dumpedValue = $dumper->dump($varCloner->cloneVar($value), true);
} else {
$dumpedValue = json_encode($value, \JSON_PRETTY_PRINT);
}
return '<pre>' . htmlspecialchars($dumpedValue) . '</pre>';
});
$view->registerFunction('mailto', function ($address, $link_text = null) {
$address = substr(chunk_split(bin2hex(" $address"), 2, ';&#x'), 3, -3);
$link_text = $link_text ?? $address;

View File

@ -39,7 +39,7 @@ $user = $request->getUser();
?>
</head>
<body class="page-full <?=$page_class?> <?php if (!empty($sidebar)): ?>has-sidebar<?php endif; ?>">
<?=$assets->inlineJs($request)?>
<?=$assets->inlineJs()?>
<a class="sr-only sr-only-focusable" href="#content"><?=__('Skip to main content')?></a>

View File

@ -39,7 +39,7 @@ $page_class .= ' theme-' . $customization->getPublicTheme();
</head>
<body class="page-minimal <?=$page_class?>">
<?=$assets->inlineJs($request)?>
<?=$assets->inlineJs()?>
<?=$this->section('content')?>

View File

@ -37,11 +37,11 @@ $this->layout('main', ['title' => $title, 'manual' => true]);
<div class="card-body">
<?php foreach ($row['context'] as $context_header => $context_value): ?>
<h4 class="card-subtitle"><?=$context_header?></h4>
<pre><?=json_encode($context_value, \JSON_PRETTY_PRINT)?></pre>
<?=$this->dump($context_value)?>
<?php endforeach; ?>
<?php foreach ($row['extra'] as $context_header => $context_value): ?>
<h4 class="card-subtitle"><?=$context_header?></h4>
<pre><?=json_encode($context_value, \JSON_PRETTY_PRINT)?></pre>
<?=$this->dump($context_value)?>
<?php endforeach; ?>
</div>
</div>