Vendor lock

This commit is contained in:
2023-06-16 02:08:47 +00:00
parent 7933e70e90
commit 3351b92dd6
4099 changed files with 345789 additions and 0 deletions

20
vendor/kint-php/kint/LICENSE vendored Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

82
vendor/kint-php/kint/README.md vendored Normal file
View File

@ -0,0 +1,82 @@
# Kint - debugging helper for PHP developers
[![](https://travis-ci.org/kint-php/kint.svg?branch=master)](https://travis-ci.org/kint-php/kint)
![Screenshot](https://kint-php.github.io/kint/images/intro.png)
## What am I looking at?
At first glance Kint is just a pretty replacement for **[var_dump()](https://secure.php.net/function.var_dump)**, **[print_r()](https://secure.php.net/function.print_r)** and **[debug_backtrace()](https://secure.php.net/function.debug_backtrace)**.
However, it's much, *much* more than that. You will eventually wonder how you developed without it.
## Installation
One of the main goals of Kint is to be **zero setup**.
[Download the file](https://raw.githubusercontent.com/kint-php/kint/master/build/kint.phar) and simply
```php
<?php
require 'kint.phar';
```
### Or, if you use Composer:
```bash
composer require kint-php/kint --dev
```
## Usage
```php
<?php
Kint::dump($GLOBALS, $_SERVER); // pass any number of parameters
d($GLOBALS, $_SERVER); // or simply use d() as a shorthand
Kint::trace(); // Debug backtrace
d(1); // Debug backtrace shorthand
s($GLOBALS); // Basic output mode
~d($GLOBALS); // Text only output mode
Kint::$enabled_mode = false; // Disable kint
d('Get off my lawn!'); // Debugs no longer have any effect
```
## Tips & Tricks
* Kint is enabled by default, set `Kint::$enabled_mode = false;` to turn it completely off.
The best practice is to enable Kint in a development environment only - so even if you accidentally leave a dump in production, no one will know.
* See the buttons on the right of the output? Click them to open a new tab, show the access path for the value, or show a search box.
* To see the output where you called Kint instead of the docked toolbar at the bottom of the page add the line `Kint\Renderer\RichRenderer::$folder = false;` right after you include Kint.
* There are a couple of real-time modifiers you can use:
* `~d($var)` this call will output in plain text format.
* `+d($var)` will disregard depth level limits and output everything.
*Careful, this can hang your browser on large objects!*
* `!d($var)` will expand the output automatically.
* `-d($var)` will attempt to `ob_clean` the previous output and flush after printing.
* You can combine modifiers too: `~+d($var)`
* Double clicking the <kbd>+</kbd> sign will open/close it and all its children.
* Triple clicking the <kbd>+</kbd> sign in will open/close everything on the page.
* Add heavy classes to the blacklist to improve performance:
`Kint\Parser\BlacklistPlugin::$shallow_blacklist[] = 'Psr\Container\ContainerInterface';`
* To change display theme, use `Kint\Renderer\RichRenderer::$theme = 'theme.css';`. You can pass the absolute path to a CSS file, or use one of the built in themes:
* `original.css` (default)
* `solarized.css`
* `solarized-dark.css`
* `aante-light.css`
* Kint has *keyboard shortcuts*! When Kint is visible, press <kbd>D</kbd> on the keyboard and you will be able to traverse the tree with arrows, <kbd>H</kbd><kbd>J</kbd><kbd>K</kbd><kbd>L</kbd>, and <kbd>TAB</kbd> keys - and expand/collapse nodes with <kbd>SPACE</kbd> or <kbd>ENTER</kbd>.
* You can write plugins and wrapper functions to customize dump behavior!
* Read [the full documentation](https://kint-php.github.io/kint/) for more information
## Authors
[**Jonathan Vollebregt** (jnvsor)](https://github.com/jnvsor)
[**Rokas Šleinius** (raveren)](https://github.com/raveren)
## License
Licensed under the MIT License

83
vendor/kint-php/kint/composer.json vendored Normal file
View File

@ -0,0 +1,83 @@
{
"name": "kint-php/kint",
"description": "Kint - debugging tool for PHP developers",
"keywords": ["kint", "php", "debug"],
"type": "library",
"homepage": "https://kint-php.github.io/kint/",
"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"
}
],
"require": {
"php": ">=5.3.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"phpunit/phpunit": "^4.0",
"symfony/finder": "^2.0 || ^3.0 || ^4.0",
"seld/phar-utils": "^1.0",
"vimeo/psalm": "^3.0"
},
"autoload": {
"files": ["init.php"],
"psr-4": {
"Kint\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Kint\\Test\\": "tests/"
}
},
"config": {
"platform": {
"php": "7.3"
}
},
"scripts": {
"post-update-cmd": "npm ci",
"post-install-cmd": "@post-update-cmd",
"clean": [
"rm -rf resources/compiled/",
"rm -rf build/"
],
"format": [
"@format:php",
"@format:js",
"@format:sass"
],
"format:php": "php-cs-fixer fix",
"format:js": "npm run format:js",
"format:sass": "npm run format:sass",
"build": [
"@build:sass",
"@build:js",
"@build:php"
],
"build:sass": "npm run build:sass",
"build:js": "npm run build:js",
"build:php": "php ./build.php",
"analyze": "psalm --show-info=false"
},
"suggest": {
"kint-php/kint-twig": "Provides d() and s() functions in twig templates",
"kint-php/kint-js": "Provides a simplified dump to console.log()",
"ext-mbstring": "Provides string encoding detection",
"ext-iconv": "Provides fallback detection for ambiguous legacy string encodings such as the Windows and ISO 8859 code pages",
"ext-ctype": "Simple data type tests",
"symfony/polyfill-mbstring": "Replacement for ext-mbstring if missing",
"symfony/polyfill-iconv": "Replacement for ext-iconv if missing",
"symfony/polyfill-ctype": "Replacement for ext-ctype if missing"
}
}

62
vendor/kint-php/kint/init.php vendored Normal file
View File

@ -0,0 +1,62 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
use Kint\Kint;
use Kint\Utils;
if (\defined('KINT_DIR')) {
return;
}
if (\version_compare(PHP_VERSION, '5.3') < 0) {
throw new Exception('Kint 3.0 requires PHP 5.3 or higher');
}
\define('KINT_DIR', __DIR__);
\define('KINT_WIN', DIRECTORY_SEPARATOR !== '/');
\define('KINT_PHP56', (\version_compare(PHP_VERSION, '5.6') >= 0));
\define('KINT_PHP70', (\version_compare(PHP_VERSION, '7.0') >= 0));
\define('KINT_PHP72', (\version_compare(PHP_VERSION, '7.2') >= 0));
\define('KINT_PHP73', (\version_compare(PHP_VERSION, '7.3') >= 0));
\define('KINT_PHP74', (\version_compare(PHP_VERSION, '7.4') >= 0));
// Dynamic default settings
Kint::$file_link_format = \ini_get('xdebug.file_link_format');
if (isset($_SERVER['DOCUMENT_ROOT'])) {
Kint::$app_root_dirs = array(
$_SERVER['DOCUMENT_ROOT'] => '<ROOT>',
\realpath($_SERVER['DOCUMENT_ROOT']) => '<ROOT>',
);
}
Utils::composerSkipFlags();
if ((!\defined('KINT_SKIP_FACADE') || !KINT_SKIP_FACADE) && !\class_exists('Kint')) {
\class_alias('Kint\\Kint', 'Kint');
}
if (!\defined('KINT_SKIP_HELPERS') || !KINT_SKIP_HELPERS) {
require_once __DIR__.'/init_helpers.php';
}

84
vendor/kint-php/kint/init_helpers.php vendored Normal file
View File

@ -0,0 +1,84 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
use Kint\Kint;
if (!\function_exists('d')) {
/**
* Alias of Kint::dump().
*
* @return int|string
*/
function d()
{
$args = \func_get_args();
return \call_user_func_array(array('Kint', 'dump'), $args);
}
Kint::$aliases[] = 'd';
}
if (!\function_exists('s')) {
/**
* Alias of Kint::dump(), however the output is in plain text.
*
* Alias of Kint::dump(), however the output is in plain htmlescaped text
* with some minor visibility enhancements added.
*
* If run in CLI mode, output is not escaped.
*
* To force rendering mode without autodetecting anything:
*
* Kint::$enabled_mode = Kint::MODE_PLAIN;
* Kint::dump( $variable );
*
* @return int|string
*/
function s()
{
if (!Kint::$enabled_mode) {
return 0;
}
$stash = Kint::$enabled_mode;
if (Kint::MODE_TEXT !== Kint::$enabled_mode) {
Kint::$enabled_mode = Kint::MODE_PLAIN;
if (PHP_SAPI === 'cli' && true === Kint::$cli_detection) {
Kint::$enabled_mode = Kint::$mode_default_cli;
}
}
$args = \func_get_args();
$out = \call_user_func_array(array('Kint', 'dump'), $args);
Kint::$enabled_mode = $stash;
return $out;
}
Kint::$aliases[] = 's';
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
void 0===window.kintMicrotimeInitialized&&(window.kintMicrotimeInitialized=1,window.addEventListener("load",function(){"use strict";var c={},i=Array.prototype.slice.call(document.querySelectorAll("[data-kint-microtime-group]"),0);i.forEach(function(i){if(i.querySelector(".kint-microtime-lap")){var t=i.getAttribute("data-kint-microtime-group"),e=parseFloat(i.querySelector(".kint-microtime-lap").innerHTML),r=parseFloat(i.querySelector(".kint-microtime-avg").innerHTML);void 0===c[t]&&(c[t]={}),(void 0===c[t].min||c[t].min>e)&&(c[t].min=e),(void 0===c[t].max||c[t].max<e)&&(c[t].max=e),c[t].avg=r}}),i.forEach(function(i){var t=i.querySelector(".kint-microtime-lap");if(null!==t){var e=parseFloat(t.textContent),r=i.dataset.kintMicrotimeGroup,o=c[r].avg,n=c[r].max,a=c[r].min;e===(i.querySelector(".kint-microtime-avg").textContent=o)&&e===a&&e===n||(t.style.background=o<e?"hsl("+(40-40*((e-o)/(n-o)))+", 100%, 65%)":"hsl("+(40+80*(o===a?0:(o-e)/(o-a)))+", 100%, 65%)")}})}));

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.kint-plain{background:rgba(255,255,255,0.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-lap{font-weight:bold;text-shadow:1px 0 #fff, 0 1px #fff, -1px 0 #fff, 0 -1px #fff}

View File

@ -0,0 +1 @@
void 0===window.kintPlain&&(window.kintPlain=function(){"use strict";var i={initLoad:function(){i.style=window.kintShared.dedupe("style.kint-plain-style",i.style),i.script=window.kintShared.dedupe("script.kint-plain-script",i.script)},style:null,script:null};return i}()),window.kintShared.runOnce(window.kintPlain.initLoad);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
void 0===window.kintShared&&(window.kintShared=function(){"use strict";var e={dedupe:function(e,n){return[].forEach.call(document.querySelectorAll(e),function(e){n&&n.ownerDocument.contains(n)||(n=e),e!==n&&e.parentNode.removeChild(e)}),n},runOnce:function(e){"complete"===document.readyState?e():window.addEventListener("load",e)}};return window.addEventListener("click",function(e){if(e.target.classList.contains("kint-ide-link")){var n=new XMLHttpRequest;n.open("GET",e.target.href),n.send(null),e.preventDefault()}}),e}());

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

473
vendor/kint-php/kint/src/CallFinder.php vendored Normal file
View File

@ -0,0 +1,473 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint;
class CallFinder
{
private static $ignore = array(
T_CLOSE_TAG => true,
T_COMMENT => true,
T_DOC_COMMENT => true,
T_INLINE_HTML => true,
T_OPEN_TAG => true,
T_OPEN_TAG_WITH_ECHO => true,
T_WHITESPACE => true,
);
/**
* Things we need to do specially for operator tokens:
* - Refuse to strip spaces around them
* - Wrap the access path in parentheses if there
* are any of these in the final short parameter.
*/
private static $operator = array(
T_AND_EQUAL => true,
T_BOOLEAN_AND => true,
T_BOOLEAN_OR => true,
T_ARRAY_CAST => true,
T_BOOL_CAST => true,
T_CLONE => true,
T_CONCAT_EQUAL => true,
T_DEC => true,
T_DIV_EQUAL => true,
T_DOUBLE_CAST => true,
T_INC => true,
T_INCLUDE => true,
T_INCLUDE_ONCE => true,
T_INSTANCEOF => true,
T_INT_CAST => true,
T_IS_EQUAL => true,
T_IS_GREATER_OR_EQUAL => true,
T_IS_IDENTICAL => true,
T_IS_NOT_EQUAL => true,
T_IS_NOT_IDENTICAL => true,
T_IS_SMALLER_OR_EQUAL => true,
T_LOGICAL_AND => true,
T_LOGICAL_OR => true,
T_LOGICAL_XOR => true,
T_MINUS_EQUAL => true,
T_MOD_EQUAL => true,
T_MUL_EQUAL => true,
T_NEW => true,
T_OBJECT_CAST => true,
T_OR_EQUAL => true,
T_PLUS_EQUAL => true,
T_REQUIRE => true,
T_REQUIRE_ONCE => true,
T_SL => true,
T_SL_EQUAL => true,
T_SR => true,
T_SR_EQUAL => true,
T_STRING_CAST => true,
T_UNSET_CAST => true,
T_XOR_EQUAL => true,
'!' => true,
'%' => true,
'&' => true,
'*' => true,
'+' => true,
'-' => true,
'.' => true,
'/' => true,
':' => true,
'<' => true,
'=' => true,
'>' => true,
'?' => true,
'^' => true,
'|' => true,
'~' => true,
);
private static $strip = array(
'(' => true,
')' => true,
'[' => true,
']' => true,
'{' => true,
'}' => true,
T_OBJECT_OPERATOR => true,
T_DOUBLE_COLON => true,
T_NS_SEPARATOR => true,
);
public static function getFunctionCalls($source, $line, $function)
{
static $up = array(
'(' => true,
'[' => true,
'{' => true,
T_CURLY_OPEN => true,
T_DOLLAR_OPEN_CURLY_BRACES => true,
);
static $down = array(
')' => true,
']' => true,
'}' => true,
);
static $modifiers = array(
'!' => true,
'@' => true,
'~' => true,
'+' => true,
'-' => true,
);
static $identifier = array(
T_DOUBLE_COLON => true,
T_STRING => true,
T_NS_SEPARATOR => true,
);
if (KINT_PHP56) {
self::$operator[T_POW] = true;
self::$operator[T_POW_EQUAL] = true;
}
if (KINT_PHP70) {
self::$operator[T_SPACESHIP] = true;
}
if (KINT_PHP74) {
self::$operator[T_COALESCE_EQUAL] = true;
}
$tokens = \token_get_all($source);
$cursor = 1;
$function_calls = array();
/** @var array<int, null|array|string> Performance optimization preventing backwards loops */
$prev_tokens = array(null, null, null);
if (\is_array($function)) {
$class = \explode('\\', $function[0]);
$class = \strtolower(\end($class));
$function = \strtolower($function[1]);
} else {
$class = null;
$function = \strtolower($function);
}
// Loop through tokens
foreach ($tokens as $index => $token) {
if (!\is_array($token)) {
continue;
}
// Count newlines for line number instead of using $token[2]
// since certain situations (String tokens after whitespace) may
// not have the correct line number unless you do this manually
$cursor += \substr_count($token[1], "\n");
if ($cursor > $line) {
break;
}
// Store the last real tokens for later
if (isset(self::$ignore[$token[0]])) {
continue;
}
$prev_tokens = array($prev_tokens[1], $prev_tokens[2], $token);
// Check if it's the right type to be the function we're looking for
if (T_STRING !== $token[0] || \strtolower($token[1]) !== $function) {
continue;
}
// Check if it's a function call
$nextReal = self::realTokenIndex($tokens, $index);
if (!isset($nextReal, $tokens[$nextReal]) || '(' !== $tokens[$nextReal]) {
continue;
}
// Check if it matches the signature
if (null === $class) {
if ($prev_tokens[1] && \in_array($prev_tokens[1][0], array(T_DOUBLE_COLON, T_OBJECT_OPERATOR), true)) {
continue;
}
} else {
if (!$prev_tokens[1] || T_DOUBLE_COLON !== $prev_tokens[1][0]) {
continue;
}
if (!$prev_tokens[0] || T_STRING !== $prev_tokens[0][0] || \strtolower($prev_tokens[0][1]) !== $class) {
continue;
}
}
$inner_cursor = $cursor;
$depth = 1; // The depth respective to the function call
$offset = $nextReal + 1; // The start of the function call
$instring = false; // Whether we're in a string or not
$realtokens = false; // Whether the current scope contains anything meaningful or not
$paramrealtokens = false; // Whether the current parameter contains anything meaningful
$params = array(); // All our collected parameters
$shortparam = array(); // The short version of the parameter
$param_start = $offset; // The distance to the start of the parameter
// Loop through the following tokens until the function call ends
while (isset($tokens[$offset])) {
$token = $tokens[$offset];
// Ensure that the $inner_cursor is correct and
// that $token is either a T_ constant or a string
if (\is_array($token)) {
$inner_cursor += \substr_count($token[1], "\n");
}
if (!isset(self::$ignore[$token[0]]) && !isset($down[$token[0]])) {
$paramrealtokens = $realtokens = true;
}
// If it's a token that makes us to up a level, increase the depth
if (isset($up[$token[0]])) {
if (1 === $depth) {
$shortparam[] = $token;
$realtokens = false;
}
++$depth;
} elseif (isset($down[$token[0]])) {
--$depth;
// If this brings us down to the parameter level, and we've had
// real tokens since going up, fill the $shortparam with an ellipsis
if (1 === $depth) {
if ($realtokens) {
$shortparam[] = '...';
}
$shortparam[] = $token;
}
} elseif ('"' === $token[0]) {
// Strings use the same symbol for up and down, but we can
// only ever be inside one string, so just use a bool for that
if ($instring) {
--$depth;
if (1 === $depth) {
$shortparam[] = '...';
}
} else {
++$depth;
}
$instring = !$instring;
$shortparam[] = '"';
} elseif (1 === $depth) {
if (',' === $token[0]) {
$params[] = array(
'full' => \array_slice($tokens, $param_start, $offset - $param_start),
'short' => $shortparam,
);
$shortparam = array();
$paramrealtokens = false;
$param_start = $offset + 1;
} elseif (T_CONSTANT_ENCAPSED_STRING === $token[0] && \strlen($token[1]) > 2) {
$shortparam[] = $token[1][0].'...'.$token[1][0];
} else {
$shortparam[] = $token;
}
}
// Depth has dropped to 0 (So we've hit the closing paren)
if ($depth <= 0) {
if ($paramrealtokens) {
$params[] = array(
'full' => \array_slice($tokens, $param_start, $offset - $param_start),
'short' => $shortparam,
);
}
break;
}
++$offset;
}
// If we're not passed (or at) the line at the end
// of the function call, we're too early so skip it
if ($inner_cursor < $line) {
continue;
}
// Format the final output parameters
foreach ($params as &$param) {
$name = self::tokensFormatted($param['short']);
$expression = false;
foreach ($name as $token) {
if (self::tokenIsOperator($token)) {
$expression = true;
break;
}
}
$param = array(
'name' => self::tokensToString($name),
'path' => self::tokensToString(self::tokensTrim($param['full'])),
'expression' => $expression,
);
}
// Get the modifiers
--$index;
while (isset($tokens[$index])) {
if (!isset(self::$ignore[$tokens[$index][0]]) && !isset($identifier[$tokens[$index][0]])) {
break;
}
--$index;
}
$mods = array();
while (isset($tokens[$index])) {
if (isset(self::$ignore[$tokens[$index][0]])) {
--$index;
continue;
}
if (isset($modifiers[$tokens[$index][0]])) {
$mods[] = $tokens[$index];
--$index;
continue;
}
break;
}
$function_calls[] = array(
'parameters' => $params,
'modifiers' => $mods,
);
}
return $function_calls;
}
private static function realTokenIndex(array $tokens, $index)
{
++$index;
while (isset($tokens[$index])) {
if (!isset(self::$ignore[$tokens[$index][0]])) {
return $index;
}
++$index;
}
return null;
}
/**
* We need a separate method to check if tokens are operators because we
* occasionally add "..." to short parameter versions. If we simply check
* for `$token[0]` then "..." will incorrectly match the "." operator.
*
* @param array|string $token The token to check
*
* @return bool
*/
private static function tokenIsOperator($token)
{
return '...' !== $token && isset(self::$operator[$token[0]]);
}
private static function tokensToString(array $tokens)
{
$out = '';
foreach ($tokens as $token) {
if (\is_string($token)) {
$out .= $token;
} elseif (\is_array($token)) {
$out .= $token[1];
}
}
return $out;
}
private static function tokensTrim(array $tokens)
{
foreach ($tokens as $index => $token) {
if (isset(self::$ignore[$token[0]])) {
unset($tokens[$index]);
} else {
break;
}
}
$tokens = \array_reverse($tokens);
foreach ($tokens as $index => $token) {
if (isset(self::$ignore[$token[0]])) {
unset($tokens[$index]);
} else {
break;
}
}
return \array_reverse($tokens);
}
private static function tokensFormatted(array $tokens)
{
$space = false;
$tokens = self::tokensTrim($tokens);
$output = array();
$last = null;
foreach ($tokens as $index => $token) {
if (isset(self::$ignore[$token[0]])) {
if ($space) {
continue;
}
$next = $tokens[self::realTokenIndex($tokens, $index)];
if (isset(self::$strip[$last[0]]) && !self::tokenIsOperator($next)) {
continue;
}
if (isset(self::$strip[$next[0]]) && $last && !self::tokenIsOperator($last)) {
continue;
}
$token = ' ';
$space = true;
} else {
$space = false;
$last = $token;
}
$output[] = $token;
}
return $output;
}
}

756
vendor/kint-php/kint/src/Kint.php vendored Normal file
View File

@ -0,0 +1,756 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint;
use InvalidArgumentException;
use Kint\Object\BasicObject;
use Kint\Parser\Parser;
use Kint\Parser\Plugin;
use Kint\Renderer\Renderer;
use Kint\Renderer\TextRenderer;
class Kint
{
const MODE_RICH = 'r';
const MODE_TEXT = 't';
const MODE_CLI = 'c';
const MODE_PLAIN = 'p';
/**
* @var mixed Kint mode
*
* false: Disabled
* true: Enabled, default mode selection
* other: Manual mode selection
*/
public static $enabled_mode = true;
/**
* Default mode.
*
* @var string
*/
public static $mode_default = self::MODE_RICH;
/**
* Default mode in CLI with cli_detection on.
*
* @var string
*/
public static $mode_default_cli = self::MODE_CLI;
/**
* @var bool Return output instead of echoing
*/
public static $return;
/**
* @var string format of the link to the source file in trace entries.
*
* Use %f for file path, %l for line number.
*
* [!] EXAMPLE (works with for phpStorm and RemoteCall Plugin):
*
* Kint::$file_link_format = 'http://localhost:8091/?message=%f:%l';
*/
public static $file_link_format = '';
/**
* @var bool whether to display where kint was called from
*/
public static $display_called_from = true;
/**
* @var array base directories of your application that will be displayed instead of the full path.
*
* Keys are paths, values are replacement strings
*
* [!] EXAMPLE (for Laravel 5):
*
* Kint::$app_root_dirs = [
* base_path() => '<BASE>',
* app_path() => '<APP>',
* config_path() => '<CONFIG>',
* database_path() => '<DATABASE>',
* public_path() => '<PUBLIC>',
* resource_path() => '<RESOURCE>',
* storage_path() => '<STORAGE>',
* ];
*
* Defaults to [$_SERVER['DOCUMENT_ROOT'] => '<ROOT>']
*/
public static $app_root_dirs = array();
/**
* @var int max array/object levels to go deep, if zero no limits are applied
*/
public static $max_depth = 6;
/**
* @var bool expand all trees by default for rich view
*/
public static $expanded = false;
/**
* @var bool enable detection when Kint is command line.
*
* Formats output with whitespace only; does not HTML-escape it
*/
public static $cli_detection = true;
/**
* @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces
*/
public static $aliases = array(
array('Kint\\Kint', 'dump'),
array('Kint\\Kint', 'trace'),
array('Kint\\Kint', 'dumpArray'),
);
/**
* @var array<mixed, string> Array of modes to renderer class names
*/
public static $renderers = array(
self::MODE_RICH => 'Kint\\Renderer\\RichRenderer',
self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer',
self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer',
self::MODE_CLI => 'Kint\\Renderer\\CliRenderer',
);
public static $plugins = array(
'Kint\\Parser\\ArrayObjectPlugin',
'Kint\\Parser\\Base64Plugin',
'Kint\\Parser\\BlacklistPlugin',
'Kint\\Parser\\ClassMethodsPlugin',
'Kint\\Parser\\ClassStaticsPlugin',
'Kint\\Parser\\ClosurePlugin',
'Kint\\Parser\\ColorPlugin',
'Kint\\Parser\\DateTimePlugin',
'Kint\\Parser\\FsPathPlugin',
'Kint\\Parser\\IteratorPlugin',
'Kint\\Parser\\JsonPlugin',
'Kint\\Parser\\MicrotimePlugin',
'Kint\\Parser\\SimpleXMLElementPlugin',
'Kint\\Parser\\SplFileInfoPlugin',
'Kint\\Parser\\SplObjectStoragePlugin',
'Kint\\Parser\\StreamPlugin',
'Kint\\Parser\\TablePlugin',
'Kint\\Parser\\ThrowablePlugin',
'Kint\\Parser\\TimestampPlugin',
'Kint\\Parser\\TracePlugin',
'Kint\\Parser\\XmlPlugin',
);
protected static $plugin_pool = array();
protected $parser;
protected $renderer;
public function __construct(Parser $p, Renderer $r)
{
$this->parser = $p;
$this->renderer = $r;
}
public function setParser(Parser $p)
{
$this->parser = $p;
}
public function getParser()
{
return $this->parser;
}
public function setRenderer(Renderer $r)
{
$this->renderer = $r;
}
public function getRenderer()
{
return $this->renderer;
}
public function setStatesFromStatics(array $statics)
{
$this->renderer->setStatics($statics);
$this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false);
$this->parser->clearPlugins();
if (!isset($statics['plugins'])) {
return;
}
$plugins = array();
foreach ($statics['plugins'] as $plugin) {
if ($plugin instanceof Plugin) {
$plugins[] = $plugin;
} elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) {
if (!isset(self::$plugin_pool[$plugin])) {
$p = new $plugin();
self::$plugin_pool[$plugin] = $p;
}
$plugins[] = self::$plugin_pool[$plugin];
}
}
$plugins = $this->renderer->filterParserPlugins($plugins);
foreach ($plugins as $plugin) {
$this->parser->addPlugin($plugin);
}
}
public function setStatesFromCallInfo(array $info)
{
$this->renderer->setCallInfo($info);
if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) {
$this->parser->setDepthLimit(false);
}
$this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null);
}
/**
* Renders a list of vars including the pre and post renders.
*
* @param array $vars Data to dump
* @param BasicObject[] $base Base objects
*
* @return string
*/
public function dumpAll(array $vars, array $base)
{
if (\array_keys($vars) !== \array_keys($base)) {
throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments');
}
$output = $this->renderer->preRender();
if ($vars === array()) {
$output .= $this->renderer->renderNothing();
}
foreach ($vars as $key => $arg) {
if (!$base[$key] instanceof BasicObject) {
throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances');
}
$output .= $this->dumpVar($arg, $base[$key]);
}
$output .= $this->renderer->postRender();
return $output;
}
/**
* Dumps and renders a var.
*
* @param mixed $var Data to dump
* @param BasicObject $base Base object
*
* @return string
*/
public function dumpVar(&$var, BasicObject $base)
{
return $this->renderer->render(
$this->parser->parse($var, $base)
);
}
/**
* Gets all static settings at once.
*
* @return array Current static settings
*/
public static function getStatics()
{
return array(
'aliases' => self::$aliases,
'app_root_dirs' => self::$app_root_dirs,
'cli_detection' => self::$cli_detection,
'display_called_from' => self::$display_called_from,
'enabled_mode' => self::$enabled_mode,
'expanded' => self::$expanded,
'file_link_format' => self::$file_link_format,
'max_depth' => self::$max_depth,
'mode_default' => self::$mode_default,
'mode_default_cli' => self::$mode_default_cli,
'plugins' => self::$plugins,
'renderers' => self::$renderers,
'return' => self::$return,
);
}
/**
* Creates a Kint instances based on static settings.
*
* Also calls setStatesFromStatics for you
*
* @param array $statics array of statics as returned by getStatics
*
* @return null|\Kint\Kint
*/
public static function createFromStatics(array $statics)
{
$mode = false;
if (isset($statics['enabled_mode'])) {
$mode = $statics['enabled_mode'];
if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) {
$mode = $statics['mode_default'];
if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) {
$mode = $statics['mode_default_cli'];
}
}
}
if (!$mode) {
return null;
}
if (!isset($statics['renderers'][$mode])) {
$renderer = new TextRenderer();
} else {
/** @var Renderer */
$renderer = new $statics['renderers'][$mode]();
}
return new self(new Parser(), $renderer);
}
/**
* Creates base objects given parameter info.
*
* @param array $params Parameters as returned from getCallInfo
* @param int $argc Number of arguments the helper was called with
*
* @return BasicObject[] Base objects for the arguments
*/
public static function getBasesFromParamInfo(array $params, $argc)
{
static $blacklist = array(
'null',
'true',
'false',
'array(...)',
'array()',
'[...]',
'[]',
'(...)',
'()',
'"..."',
'b"..."',
"'...'",
"b'...'",
);
$params = \array_values($params);
$bases = array();
for ($i = 0; $i < $argc; ++$i) {
if (isset($params[$i])) {
$param = $params[$i];
} else {
$param = null;
}
if (!isset($param['name']) || \is_numeric($param['name'])) {
$name = null;
} elseif (\in_array(\strtolower($param['name']), $blacklist, true)) {
$name = null;
} else {
$name = $param['name'];
}
if (isset($param['path'])) {
$access_path = $param['path'];
if (!empty($param['expression'])) {
$access_path = '('.$access_path.')';
}
} else {
$access_path = '$'.$i;
}
$bases[] = BasicObject::blank($name, $access_path);
}
return $bases;
}
/**
* Gets call info from the backtrace, alias, and argument count.
*
* Aliases must be normalized beforehand (Utils::normalizeAliases)
*
* @param array $aliases Call aliases as found in Kint::$aliases
* @param array[] $trace Backtrace
* @param int $argc Number of arguments
*
* @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info
*/
public static function getCallInfo(array $aliases, array $trace, $argc)
{
$found = false;
$callee = null;
$caller = null;
$miniTrace = array();
foreach ($trace as $index => $frame) {
if (Utils::traceFrameIsListed($frame, $aliases)) {
$found = true;
$miniTrace = array();
}
if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) {
$miniTrace[] = $frame;
}
}
if ($found) {
$callee = \reset($miniTrace) ?: null;
/** @var null|array Psalm bug workaround */
$caller = \next($miniTrace) ?: null;
}
foreach ($miniTrace as $index => $frame) {
if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) {
unset($frame['object'], $frame['args']);
$miniTrace[$index] = $frame;
} else {
unset($miniTrace[$index]);
}
}
$miniTrace = \array_values($miniTrace);
$call = self::getSingleCall($callee ?: array(), $argc);
$ret = array(
'params' => null,
'modifiers' => array(),
'callee' => $callee,
'caller' => $caller,
'trace' => $miniTrace,
);
if ($call) {
$ret['params'] = $call['parameters'];
$ret['modifiers'] = $call['modifiers'];
}
return $ret;
}
/**
* Dumps a backtrace.
*
* Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
*
* @return int|string
*/
public static function trace()
{
if (!self::$enabled_mode) {
return 0;
}
Utils::normalizeAliases(self::$aliases);
$args = \func_get_args();
$call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
$statics = self::getStatics();
if (\in_array('~', $call_info['modifiers'], true)) {
$statics['enabled_mode'] = self::MODE_TEXT;
}
$kintstance = self::createFromStatics($statics);
if (!$kintstance) {
// Should never happen
return 0; // @codeCoverageIgnore
}
if (\in_array('-', $call_info['modifiers'], true)) {
while (\ob_get_level()) {
\ob_end_clean();
}
}
$kintstance->setStatesFromStatics($statics);
$kintstance->setStatesFromCallInfo($call_info);
$trimmed_trace = array();
$trace = \debug_backtrace(true);
foreach ($trace as $frame) {
if (Utils::traceFrameIsListed($frame, self::$aliases)) {
$trimmed_trace = array();
}
$trimmed_trace[] = $frame;
}
$output = $kintstance->dumpAll(
array($trimmed_trace),
array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)'))
);
if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
return $output;
}
echo $output;
if (\in_array('-', $call_info['modifiers'], true)) {
\flush(); // @codeCoverageIgnore
}
return 0;
}
/**
* Dumps some data.
*
* Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
*
* @return int|string
*/
public static function dump()
{
if (!self::$enabled_mode) {
return 0;
}
Utils::normalizeAliases(self::$aliases);
$args = \func_get_args();
$call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
$statics = self::getStatics();
if (\in_array('~', $call_info['modifiers'], true)) {
$statics['enabled_mode'] = self::MODE_TEXT;
}
$kintstance = self::createFromStatics($statics);
if (!$kintstance) {
// Should never happen
return 0; // @codeCoverageIgnore
}
if (\in_array('-', $call_info['modifiers'], true)) {
while (\ob_get_level()) {
\ob_end_clean();
}
}
$kintstance->setStatesFromStatics($statics);
$kintstance->setStatesFromCallInfo($call_info);
// If the call is Kint::dump(1) then dump a backtrace instead
if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) {
$args = \debug_backtrace(true);
$trace = array();
foreach ($args as $index => $frame) {
if (Utils::traceFrameIsListed($frame, self::$aliases)) {
$trace = array();
}
$trace[] = $frame;
}
if (isset($call_info['callee']['function'])) {
$tracename = $call_info['callee']['function'].'(1)';
if (isset($call_info['callee']['class'], $call_info['callee']['type'])) {
$tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename;
}
} else {
$tracename = 'Kint\\Kint::dump(1)';
}
$tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)');
$output = $kintstance->dumpAll(array($trace), array($tracebase));
} else {
$bases = self::getBasesFromParamInfo(
isset($call_info['params']) ? $call_info['params'] : array(),
\count($args)
);
$output = $kintstance->dumpAll($args, $bases);
}
if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
return $output;
}
echo $output;
if (\in_array('-', $call_info['modifiers'], true)) {
\flush(); // @codeCoverageIgnore
}
return 0;
}
/**
* generic path display callback, can be configured in app_root_dirs; purpose is
* to show relevant path info and hide as much of the path as possible.
*
* @param string $file
*
* @return string
*/
public static function shortenPath($file)
{
$file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen'));
$longest_match = 0;
$match = '/';
foreach (self::$app_root_dirs as $path => $alias) {
if (empty($path)) {
continue;
}
$path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen'));
if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) {
$longest_match = \count($path);
$match = $alias;
}
}
if ($longest_match) {
$file = \array_merge(array($match), \array_slice($file, $longest_match));
return \implode('/', $file);
}
// fallback to find common path with Kint dir
$kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen'));
foreach ($file as $i => $part) {
if (!isset($kint[$i]) || $kint[$i] !== $part) {
return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i));
}
}
return '/'.\implode('/', $file);
}
public static function getIdeLink($file, $line)
{
return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format);
}
/**
* Returns specific function call info from a stack trace frame, or null if no match could be found.
*
* @param array $frame The stack trace frame in question
* @param int $argc The amount of arguments received
*
* @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined
*/
protected static function getSingleCall(array $frame, $argc)
{
if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) {
return null;
}
if (empty($frame['class'])) {
$callfunc = $frame['function'];
} else {
$callfunc = array($frame['class'], $frame['function']);
}
$calls = CallFinder::getFunctionCalls(
\file_get_contents($frame['file']),
$frame['line'],
$callfunc
);
$return = null;
foreach ($calls as $call) {
$is_unpack = false;
// Handle argument unpacking as a last resort
if (KINT_PHP56) {
foreach ($call['parameters'] as $i => &$param) {
if (0 === \strpos($param['name'], '...')) {
if ($i < $argc && $i === \count($call['parameters']) - 1) {
for ($j = 1; $j + $i < $argc; ++$j) {
$call['parameters'][] = array(
'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']',
'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']',
'expression' => false,
);
}
$param['name'] = 'reset('.\substr($param['name'], 3).')';
$param['path'] = 'reset('.\substr($param['path'], 3).')';
$param['expression'] = false;
} else {
$call['parameters'] = \array_slice($call['parameters'], 0, $i);
}
$is_unpack = true;
break;
}
if ($i >= $argc) {
continue 2;
}
}
}
if ($is_unpack || \count($call['parameters']) === $argc) {
if (null === $return) {
$return = $call;
} else {
// If we have multiple calls on the same line with the same amount of arguments,
// we can't be sure which it is so just return null and let them figure it out
return null;
}
}
}
return $return;
}
}

View File

@ -0,0 +1,248 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Kint\Object\Representation\Representation;
class BasicObject
{
const ACCESS_NONE = null;
const ACCESS_PUBLIC = 1;
const ACCESS_PROTECTED = 2;
const ACCESS_PRIVATE = 3;
const OPERATOR_NONE = null;
const OPERATOR_ARRAY = 1;
const OPERATOR_OBJECT = 2;
const OPERATOR_STATIC = 3;
public $name;
public $type;
public $static = false;
public $const = false;
public $access = self::ACCESS_NONE;
public $owner_class;
public $access_path;
public $operator = self::OPERATOR_NONE;
public $reference = false;
public $depth = 0;
public $size;
public $value;
public $hints = array();
protected $representations = array();
public function __construct()
{
}
public function addRepresentation(Representation $rep, $pos = null)
{
if (isset($this->representations[$rep->getName()])) {
return false;
}
if (null === $pos) {
$this->representations[$rep->getName()] = $rep;
} else {
$this->representations = \array_merge(
\array_slice($this->representations, 0, $pos),
array($rep->getName() => $rep),
\array_slice($this->representations, $pos)
);
}
return true;
}
public function replaceRepresentation(Representation $rep, $pos = null)
{
if (null === $pos) {
$this->representations[$rep->getName()] = $rep;
} else {
$this->removeRepresentation($rep);
$this->addRepresentation($rep, $pos);
}
}
public function removeRepresentation($rep)
{
if ($rep instanceof Representation) {
unset($this->representations[$rep->getName()]);
} elseif (\is_string($rep)) {
unset($this->representations[$rep]);
}
}
public function getRepresentation($name)
{
if (isset($this->representations[$name])) {
return $this->representations[$name];
}
}
public function getRepresentations()
{
return $this->representations;
}
public function clearRepresentations()
{
$this->representations = array();
}
public function getType()
{
return $this->type;
}
public function getModifiers()
{
$out = $this->getAccess();
if ($this->const) {
$out .= ' const';
}
if ($this->static) {
$out .= ' static';
}
if (\strlen($out)) {
return \ltrim($out);
}
}
public function getAccess()
{
switch ($this->access) {
case self::ACCESS_PRIVATE:
return 'private';
case self::ACCESS_PROTECTED:
return 'protected';
case self::ACCESS_PUBLIC:
return 'public';
}
}
public function getName()
{
return $this->name;
}
public function getOperator()
{
switch ($this->operator) {
case self::OPERATOR_ARRAY:
return '=>';
case self::OPERATOR_OBJECT:
return '->';
case self::OPERATOR_STATIC:
return '::';
}
}
public function getSize()
{
return $this->size;
}
public function getValueShort()
{
if ($rep = $this->value) {
if ('boolean' === $this->type) {
return $rep->contents ? 'true' : 'false';
}
if ('integer' === $this->type || 'double' === $this->type) {
return $rep->contents;
}
}
}
public function getAccessPath()
{
return $this->access_path;
}
public function transplant(BasicObject $old)
{
$this->name = $old->name;
$this->size = $old->size;
$this->access_path = $old->access_path;
$this->access = $old->access;
$this->static = $old->static;
$this->const = $old->const;
$this->type = $old->type;
$this->depth = $old->depth;
$this->owner_class = $old->owner_class;
$this->operator = $old->operator;
$this->reference = $old->reference;
$this->value = $old->value;
$this->representations += $old->representations;
$this->hints = \array_merge($this->hints, $old->hints);
}
/**
* Creates a new basic object with a name and access path.
*
* @param null|string $name
* @param null|string $access_path
*
* @return \Kint\Object\BasicObject
*/
public static function blank($name = null, $access_path = null)
{
$o = new self();
$o->name = $name;
$o->access_path = $access_path;
return $o;
}
public static function sortByAccess(BasicObject $a, BasicObject $b)
{
static $sorts = array(
self::ACCESS_PUBLIC => 1,
self::ACCESS_PROTECTED => 2,
self::ACCESS_PRIVATE => 3,
self::ACCESS_NONE => 4,
);
return $sorts[$a->access] - $sorts[$b->access];
}
public static function sortByName(BasicObject $a, BasicObject $b)
{
$ret = \strnatcasecmp($a->name, $b->name);
if (0 === $ret) {
return (int) \is_int($b->name) - (int) \is_int($a->name);
}
return $ret;
}
}

View File

@ -0,0 +1,177 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
class BlobObject extends BasicObject
{
/**
* @var array Character encodings to detect
*
* @see https://secure.php.net/function.mb-detect-order
*
* In practice, mb_detect_encoding can only successfully determine the
* difference between the following common charsets at once without
* breaking things for one of the other charsets:
* - ASCII
* - UTF-8
* - SJIS
* - EUC-JP
*
* The order of the charsets is significant. If you put UTF-8 before ASCII
* it will never match ASCII, because UTF-8 is a superset of ASCII.
* Similarly, SJIS and EUC-JP frequently match UTF-8 strings, so you should
* check UTF-8 first. SJIS and EUC-JP seem to work either way, but SJIS is
* more common so it should probably be first.
*
* While you're free to experiment with other charsets, remember to keep
* this behavior in mind when setting up your char_encodings array.
*
* This depends on the mbstring extension
*/
public static $char_encodings = array(
'ASCII',
'UTF-8',
);
/**
* @var array Legacy character encodings to detect
*
* @see https://secure.php.net/function.iconv
*
* Assuming the other encoding checks fail, this will perform a
* simple iconv conversion to check for invalid bytes. If any are
* found it will not match.
*
* This can be useful for ambiguous single byte encodings like
* windows-125x and iso-8859-x which have practically undetectable
* differences because they use every single byte available.
*
* This is *NOT* reliable and should not be trusted implicitly. As
* with char_encodings, the order of the charsets is significant.
*
* This depends on the iconv extension
*/
public static $legacy_encodings = array();
public $type = 'string';
public $encoding = false;
public $hints = array('string');
public function getType()
{
if (false === $this->encoding) {
return 'binary '.$this->type;
}
if ('ASCII' === $this->encoding) {
return $this->type;
}
return $this->encoding.' '.$this->type;
}
public function getValueShort()
{
if ($rep = $this->value) {
return '"'.$rep->contents.'"';
}
}
public function transplant(BasicObject $old)
{
parent::transplant($old);
if ($old instanceof self) {
$this->encoding = $old->encoding;
}
}
public static function strlen($string, $encoding = false)
{
if (\function_exists('mb_strlen')) {
if (false === $encoding) {
$encoding = self::detectEncoding($string);
}
if ($encoding && 'ASCII' !== $encoding) {
return \mb_strlen($string, $encoding);
}
}
return \strlen($string);
}
public static function substr($string, $start, $length = null, $encoding = false)
{
if (\function_exists('mb_substr')) {
if (false === $encoding) {
$encoding = self::detectEncoding($string);
}
if ($encoding && 'ASCII' !== $encoding) {
return \mb_substr($string, $start, $length, $encoding);
}
}
// Special case for substr/mb_substr discrepancy
if ('' === $string) {
return '';
}
return \substr($string, $start, isset($length) ? $length : PHP_INT_MAX);
}
public static function detectEncoding($string)
{
if (\function_exists('mb_detect_encoding')) {
if ($ret = \mb_detect_encoding($string, self::$char_encodings, true)) {
return $ret;
}
}
// Pretty much every character encoding uses first 32 bytes as control
// characters. If it's not a multi-byte format it's safe to say matching
// any control character besides tab, nl, and cr means it's binary.
if (\preg_match('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', $string)) {
return false;
}
if (\function_exists('iconv')) {
foreach (self::$legacy_encodings as $encoding) {
if (@\iconv($encoding, $encoding, $string) === $string) {
return $encoding;
}
}
} elseif (!\function_exists('mb_detect_encoding')) { // @codeCoverageIgnore
// If a user has neither mb_detect_encoding, nor iconv, nor the
// polyfills, there's not much we can do about it...
// Pretend it's ASCII and pray the browser renders it properly.
return 'ASCII'; // @codeCoverageIgnore
}
return false;
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
class ClosureObject extends InstanceObject
{
public $parameters = array();
public $hints = array('object', 'callable', 'closure');
private $paramcache;
public function getAccessPath()
{
if (null !== $this->access_path) {
return parent::getAccessPath().'('.$this->getParams().')';
}
}
public function getSize()
{
}
public function getParams()
{
if (null !== $this->paramcache) {
return $this->paramcache;
}
$out = array();
foreach ($this->parameters as $p) {
$type = $p->getType();
$ref = $p->reference ? '&' : '';
if ($type) {
$out[] = $type.' '.$ref.$p->getName();
} else {
$out[] = $ref.$p->getName();
}
}
return $this->paramcache = \implode(', ', $out);
}
}

View File

@ -0,0 +1,53 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use DateTime;
class DateTimeObject extends InstanceObject
{
public $dt;
public $hints = array('object', 'datetime');
public function __construct(DateTime $dt)
{
parent::__construct();
$this->dt = clone $dt;
}
public function getValueShort()
{
$stamp = $this->dt->format('Y-m-d H:i:s');
if ((int) ($micro = $this->dt->format('u'))) {
$stamp .= '.'.$micro;
}
$stamp .= $this->dt->format('P T');
return $stamp;
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
class InstanceObject extends BasicObject
{
public $type = 'object';
public $classname;
public $hash;
public $filename;
public $startline;
public $hints = array('object');
public function getType()
{
return $this->classname;
}
public function transplant(BasicObject $old)
{
parent::transplant($old);
if ($old instanceof self) {
$this->classname = $old->classname;
$this->hash = $old->hash;
$this->filename = $old->filename;
$this->startline = $old->startline;
}
}
public static function sortByHierarchy($a, $b)
{
if (\is_string($a) && \is_string($b)) {
$aclass = $a;
$bclass = $b;
} elseif (!($a instanceof BasicObject) || !($b instanceof BasicObject)) {
return 0;
} elseif ($a instanceof self && $b instanceof self) {
$aclass = $a->classname;
$bclass = $b->classname;
} else {
return 0;
}
if (\is_subclass_of($aclass, $bclass)) {
return -1;
}
if (\is_subclass_of($bclass, $aclass)) {
return 1;
}
return 0;
}
}

View File

@ -0,0 +1,253 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Kint\Object\Representation\DocstringRepresentation;
use Kint\Utils;
use ReflectionFunctionAbstract;
use ReflectionMethod;
class MethodObject extends BasicObject
{
public $type = 'method';
public $filename;
public $startline;
public $endline;
public $parameters = array();
public $abstract;
public $final;
public $internal;
public $docstring;
public $returntype;
public $return_reference = false;
public $hints = array('callable', 'method');
public $showparams = true;
private $paramcache;
public function __construct(ReflectionFunctionAbstract $method)
{
parent::__construct();
$this->name = $method->getName();
$this->filename = $method->getFileName();
$this->startline = $method->getStartLine();
$this->endline = $method->getEndLine();
$this->internal = $method->isInternal();
$this->docstring = $method->getDocComment();
$this->return_reference = $method->returnsReference();
foreach ($method->getParameters() as $param) {
$this->parameters[] = new ParameterObject($param);
}
if (KINT_PHP70) {
$this->returntype = $method->getReturnType();
if ($this->returntype) {
$this->returntype = Utils::getTypeString($this->returntype);
}
}
if ($method instanceof ReflectionMethod) {
$this->static = $method->isStatic();
$this->operator = $this->static ? BasicObject::OPERATOR_STATIC : BasicObject::OPERATOR_OBJECT;
$this->abstract = $method->isAbstract();
$this->final = $method->isFinal();
$this->owner_class = $method->getDeclaringClass()->name;
$this->access = BasicObject::ACCESS_PUBLIC;
if ($method->isProtected()) {
$this->access = BasicObject::ACCESS_PROTECTED;
} elseif ($method->isPrivate()) {
$this->access = BasicObject::ACCESS_PRIVATE;
}
}
if ($this->internal) {
return;
}
$docstring = new DocstringRepresentation(
$this->docstring,
$this->filename,
$this->startline
);
$docstring->implicit_label = true;
$this->addRepresentation($docstring);
$this->value = $docstring;
}
public function setAccessPathFrom(InstanceObject $parent)
{
static $magic = array(
'__call' => true,
'__callstatic' => true,
'__clone' => true,
'__construct' => true,
'__debuginfo' => true,
'__destruct' => true,
'__get' => true,
'__invoke' => true,
'__isset' => true,
'__set' => true,
'__set_state' => true,
'__sleep' => true,
'__tostring' => true,
'__unset' => true,
'__wakeup' => true,
);
$name = \strtolower($this->name);
if ('__construct' === $name) {
$this->access_path = 'new \\'.$parent->getType();
} elseif ('__invoke' === $name) {
$this->access_path = $parent->access_path;
} elseif ('__clone' === $name) {
$this->access_path = 'clone '.$parent->access_path;
$this->showparams = false;
} elseif ('__tostring' === $name) {
$this->access_path = '(string) '.$parent->access_path;
$this->showparams = false;
} elseif (isset($magic[$name])) {
$this->access_path = null;
} elseif ($this->static) {
$this->access_path = '\\'.$this->owner_class.'::'.$this->name;
} else {
$this->access_path = $parent->access_path.'->'.$this->name;
}
}
public function getValueShort()
{
if (!$this->value || !($this->value instanceof DocstringRepresentation)) {
return parent::getValueShort();
}
$ds = $this->value->getDocstringWithoutComments();
if (!$ds) {
return null;
}
$ds = \explode("\n", $ds);
$out = '';
foreach ($ds as $line) {
if (0 === \strlen(\trim($line)) || '@' === $line[0]) {
break;
}
$out .= $line.' ';
}
if (\strlen($out)) {
return \rtrim($out);
}
}
public function getModifiers()
{
$mods = array(
$this->abstract ? 'abstract' : null,
$this->final ? 'final' : null,
$this->getAccess(),
$this->static ? 'static' : null,
);
$out = '';
foreach ($mods as $word) {
if (null !== $word) {
$out .= $word.' ';
}
}
if (\strlen($out)) {
return \rtrim($out);
}
}
public function getAccessPath()
{
if (null !== $this->access_path) {
if ($this->showparams) {
return parent::getAccessPath().'('.$this->getParams().')';
}
return parent::getAccessPath();
}
}
public function getParams()
{
if (null !== $this->paramcache) {
return $this->paramcache;
}
$out = array();
foreach ($this->parameters as $p) {
$type = $p->getType();
if ($type) {
$type .= ' ';
}
$default = $p->getDefault();
if ($default) {
$default = ' = '.$default;
}
$ref = $p->reference ? '&' : '';
$out[] = $type.$ref.$p->getName().$default;
}
return $this->paramcache = \implode(', ', $out);
}
public function getPhpDocUrl()
{
if (!$this->internal) {
return null;
}
if ($this->owner_class) {
$class = \strtolower($this->owner_class);
} else {
$class = 'function';
}
$funcname = \str_replace('_', '-', \strtolower($this->name));
if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) {
$funcname = \substr($funcname, 2);
}
return 'https://secure.php.net/'.$class.'.'.$funcname;
}
}

View File

@ -0,0 +1,100 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Kint\Utils;
use ReflectionException;
use ReflectionParameter;
class ParameterObject extends BasicObject
{
public $type_hint;
public $default;
public $position;
public $hints = array('parameter');
public function __construct(ReflectionParameter $param)
{
parent::__construct();
if (KINT_PHP70) {
if ($type = $param->getType()) {
$this->type_hint = Utils::getTypeString($type);
}
} else {
if ($param->isArray()) {
$this->type_hint = 'array';
} else {
try {
if ($this->type_hint = $param->getClass()) {
$this->type_hint = $this->type_hint->name;
}
} catch (ReflectionException $e) {
\preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/s', $param->__toString(), $matches);
$this->type_hint = isset($matches[1]) ? $matches[1] : '';
}
}
}
$this->reference = $param->isPassedByReference();
$this->name = $param->getName();
$this->position = $param->getPosition();
if ($param->isDefaultValueAvailable()) {
/** @var mixed Psalm bug workaround */
$default = $param->getDefaultValue();
switch (\gettype($default)) {
case 'NULL':
$this->default = 'null';
break;
case 'boolean':
$this->default = $default ? 'true' : 'false';
break;
case 'array':
$this->default = \count($default) ? 'array(...)' : 'array()';
break;
default:
$this->default = \var_export($default, true);
break;
}
}
}
public function getType()
{
return $this->type_hint;
}
public function getName()
{
return '$'.$this->name;
}
public function getDefault()
{
return $this->default;
}
}

View File

@ -0,0 +1,576 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
use InvalidArgumentException;
class ColorRepresentation extends Representation
{
const COLOR_NAME = 1;
const COLOR_HEX_3 = 2;
const COLOR_HEX_6 = 3;
const COLOR_RGB = 4;
const COLOR_RGBA = 5;
const COLOR_HSL = 6;
const COLOR_HSLA = 7;
const COLOR_HEX_4 = 8;
const COLOR_HEX_8 = 9;
public static $color_map = array(
'aliceblue' => 'f0f8ff',
'antiquewhite' => 'faebd7',
'aqua' => '00ffff',
'aquamarine' => '7fffd4',
'azure' => 'f0ffff',
'beige' => 'f5f5dc',
'bisque' => 'ffe4c4',
'black' => '000000',
'blanchedalmond' => 'ffebcd',
'blue' => '0000ff',
'blueviolet' => '8a2be2',
'brown' => 'a52a2a',
'burlywood' => 'deb887',
'cadetblue' => '5f9ea0',
'chartreuse' => '7fff00',
'chocolate' => 'd2691e',
'coral' => 'ff7f50',
'cornflowerblue' => '6495ed',
'cornsilk' => 'fff8dc',
'crimson' => 'dc143c',
'cyan' => '00ffff',
'darkblue' => '00008b',
'darkcyan' => '008b8b',
'darkgoldenrod' => 'b8860b',
'darkgray' => 'a9a9a9',
'darkgreen' => '006400',
'darkgrey' => 'a9a9a9',
'darkkhaki' => 'bdb76b',
'darkmagenta' => '8b008b',
'darkolivegreen' => '556b2f',
'darkorange' => 'ff8c00',
'darkorchid' => '9932cc',
'darkred' => '8b0000',
'darksalmon' => 'e9967a',
'darkseagreen' => '8fbc8f',
'darkslateblue' => '483d8b',
'darkslategray' => '2f4f4f',
'darkslategrey' => '2f4f4f',
'darkturquoise' => '00ced1',
'darkviolet' => '9400d3',
'deeppink' => 'ff1493',
'deepskyblue' => '00bfff',
'dimgray' => '696969',
'dimgrey' => '696969',
'dodgerblue' => '1e90ff',
'firebrick' => 'b22222',
'floralwhite' => 'fffaf0',
'forestgreen' => '228b22',
'fuchsia' => 'ff00ff',
'gainsboro' => 'dcdcdc',
'ghostwhite' => 'f8f8ff',
'gold' => 'ffd700',
'goldenrod' => 'daa520',
'gray' => '808080',
'green' => '008000',
'greenyellow' => 'adff2f',
'grey' => '808080',
'honeydew' => 'f0fff0',
'hotpink' => 'ff69b4',
'indianred' => 'cd5c5c',
'indigo' => '4b0082',
'ivory' => 'fffff0',
'khaki' => 'f0e68c',
'lavender' => 'e6e6fa',
'lavenderblush' => 'fff0f5',
'lawngreen' => '7cfc00',
'lemonchiffon' => 'fffacd',
'lightblue' => 'add8e6',
'lightcoral' => 'f08080',
'lightcyan' => 'e0ffff',
'lightgoldenrodyellow' => 'fafad2',
'lightgray' => 'd3d3d3',
'lightgreen' => '90ee90',
'lightgrey' => 'd3d3d3',
'lightpink' => 'ffb6c1',
'lightsalmon' => 'ffa07a',
'lightseagreen' => '20b2aa',
'lightskyblue' => '87cefa',
'lightslategray' => '778899',
'lightslategrey' => '778899',
'lightsteelblue' => 'b0c4de',
'lightyellow' => 'ffffe0',
'lime' => '00ff00',
'limegreen' => '32cd32',
'linen' => 'faf0e6',
'magenta' => 'ff00ff',
'maroon' => '800000',
'mediumaquamarine' => '66cdaa',
'mediumblue' => '0000cd',
'mediumorchid' => 'ba55d3',
'mediumpurple' => '9370db',
'mediumseagreen' => '3cb371',
'mediumslateblue' => '7b68ee',
'mediumspringgreen' => '00fa9a',
'mediumturquoise' => '48d1cc',
'mediumvioletred' => 'c71585',
'midnightblue' => '191970',
'mintcream' => 'f5fffa',
'mistyrose' => 'ffe4e1',
'moccasin' => 'ffe4b5',
'navajowhite' => 'ffdead',
'navy' => '000080',
'oldlace' => 'fdf5e6',
'olive' => '808000',
'olivedrab' => '6b8e23',
'orange' => 'ffa500',
'orangered' => 'ff4500',
'orchid' => 'da70d6',
'palegoldenrod' => 'eee8aa',
'palegreen' => '98fb98',
'paleturquoise' => 'afeeee',
'palevioletred' => 'db7093',
'papayawhip' => 'ffefd5',
'peachpuff' => 'ffdab9',
'peru' => 'cd853f',
'pink' => 'ffc0cb',
'plum' => 'dda0dd',
'powderblue' => 'b0e0e6',
'purple' => '800080',
'rebeccapurple' => '663399',
'red' => 'ff0000',
'rosybrown' => 'bc8f8f',
'royalblue' => '4169e1',
'saddlebrown' => '8b4513',
'salmon' => 'fa8072',
'sandybrown' => 'f4a460',
'seagreen' => '2e8b57',
'seashell' => 'fff5ee',
'sienna' => 'a0522d',
'silver' => 'c0c0c0',
'skyblue' => '87ceeb',
'slateblue' => '6a5acd',
'slategray' => '708090',
'slategrey' => '708090',
'snow' => 'fffafa',
'springgreen' => '00ff7f',
'steelblue' => '4682b4',
'tan' => 'd2b48c',
'teal' => '008080',
'thistle' => 'd8bfd8',
'tomato' => 'ff6347',
// To quote MDN:
// "Technically, transparent is a shortcut for rgba(0,0,0,0)."
'transparent' => '00000000',
'turquoise' => '40e0d0',
'violet' => 'ee82ee',
'wheat' => 'f5deb3',
'white' => 'ffffff',
'whitesmoke' => 'f5f5f5',
'yellow' => 'ffff00',
'yellowgreen' => '9acd32',
);
public $r = 0;
public $g = 0;
public $b = 0;
public $a = 1.0;
public $variant;
public $implicit_label = true;
public $hints = array('color');
public function __construct($value)
{
parent::__construct('Color');
$this->contents = $value;
$this->setValues($value);
}
public function getColor($variant = null)
{
if (!$variant) {
$variant = $this->variant;
}
switch ($variant) {
case self::COLOR_NAME:
$hex = \sprintf('%02x%02x%02x', $this->r, $this->g, $this->b);
$hex_alpha = \sprintf('%02x%02x%02x%02x', $this->r, $this->g, $this->b, \round($this->a * 0xFF));
return \array_search($hex, self::$color_map, true) ?: \array_search($hex_alpha, self::$color_map, true);
case self::COLOR_HEX_3:
if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11) {
return \sprintf(
'#%1X%1X%1X',
\round($this->r / 0x11),
\round($this->g / 0x11),
\round($this->b / 0x11)
);
}
return false;
case self::COLOR_HEX_6:
return \sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b);
case self::COLOR_RGB:
if (1.0 === $this->a) {
return \sprintf('rgb(%d, %d, %d)', $this->r, $this->g, $this->b);
}
return \sprintf('rgb(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4));
case self::COLOR_RGBA:
return \sprintf('rgba(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4));
case self::COLOR_HSL:
$val = self::rgbToHsl($this->r, $this->g, $this->b);
if (1.0 === $this->a) {
return \vsprintf('hsl(%d, %d%%, %d%%)', $val);
}
return \sprintf('hsl(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4));
case self::COLOR_HSLA:
$val = self::rgbToHsl($this->r, $this->g, $this->b);
return \sprintf('hsla(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4));
case self::COLOR_HEX_4:
if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11 && 0 === ($this->a * 255) % 0x11) {
return \sprintf(
'#%1X%1X%1X%1X',
\round($this->r / 0x11),
\round($this->g / 0x11),
\round($this->b / 0x11),
\round($this->a * 0xF)
);
}
return false;
case self::COLOR_HEX_8:
return \sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, \round($this->a * 0xFF));
}
return false;
}
public function hasAlpha($variant = null)
{
if (null === $variant) {
$variant = $this->variant;
}
switch ($variant) {
case self::COLOR_NAME:
case self::COLOR_RGB:
case self::COLOR_HSL:
return \abs($this->a - 1) >= 0.0001;
case self::COLOR_RGBA:
case self::COLOR_HSLA:
case self::COLOR_HEX_4:
case self::COLOR_HEX_8:
return true;
default:
return false;
}
}
protected function setValues($value)
{
$value = \strtolower(\trim($value));
// Find out which variant of color input it is
if (isset(self::$color_map[$value])) {
if (!$this->setValuesFromHex(self::$color_map[$value])) {
return;
}
$variant = self::COLOR_NAME;
} elseif ('#' === $value[0]) {
$variant = $this->setValuesFromHex(\substr($value, 1));
if (!$variant) {
return;
}
} else {
$variant = $this->setValuesFromFunction($value);
if (!$variant) {
return;
}
}
// If something has gone horribly wrong
if ($this->r > 0xFF || $this->g > 0xFF || $this->b > 0xFF || $this->a > 1) {
$this->variant = null; // @codeCoverageIgnore
} else {
$this->variant = $variant;
$this->r = (int) $this->r;
$this->g = (int) $this->g;
$this->b = (int) $this->b;
$this->a = (float) $this->a;
}
}
protected function setValuesFromHex($hex)
{
if (!\ctype_xdigit($hex)) {
return null;
}
switch (\strlen($hex)) {
case 3:
$variant = self::COLOR_HEX_3;
break;
case 6:
$variant = self::COLOR_HEX_6;
break;
case 4:
$variant = self::COLOR_HEX_4;
break;
case 8:
$variant = self::COLOR_HEX_8;
break;
default:
return null;
}
switch ($variant) {
case self::COLOR_HEX_4:
$this->a = \hexdec($hex[3]) / 0xF;
// no break
case self::COLOR_HEX_3:
$this->r = \hexdec($hex[0]) * 0x11;
$this->g = \hexdec($hex[1]) * 0x11;
$this->b = \hexdec($hex[2]) * 0x11;
break;
case self::COLOR_HEX_8:
$this->a = \hexdec(\substr($hex, 6, 2)) / 0xFF;
// no break
case self::COLOR_HEX_6:
$hex = \str_split($hex, 2);
$this->r = \hexdec($hex[0]);
$this->g = \hexdec($hex[1]);
$this->b = \hexdec($hex[2]);
break;
}
return $variant;
}
protected function setValuesFromFunction($value)
{
if (!\preg_match('/^((?:rgb|hsl)a?)\\s*\\(([0-9\\.%,\\s\\/\\-]+)\\)$/i', $value, $match)) {
return null;
}
switch (\strtolower($match[1])) {
case 'rgb':
$variant = self::COLOR_RGB;
break;
case 'rgba':
$variant = self::COLOR_RGBA;
break;
case 'hsl':
$variant = self::COLOR_HSL;
break;
case 'hsla':
$variant = self::COLOR_HSLA;
break;
default:
return null; // @codeCoverageIgnore
}
$params = \preg_replace('/[,\\s\\/]+/', ',', \trim($match[2]));
$params = \explode(',', $params);
$params = \array_map('trim', $params);
if (\count($params) < 3 || \count($params) > 4) {
return null;
}
foreach ($params as $i => &$color) {
if (false !== \strpos($color, '%')) {
$color = (float) \str_replace('%', '', $color);
if (3 === $i) {
$color = $color / 100;
} elseif (\in_array($variant, array(self::COLOR_RGB, self::COLOR_RGBA), true)) {
$color = \round($color / 100 * 0xFF);
}
}
$color = (float) $color;
if (0 === $i && \in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA), true)) {
$color = ($color % 360 + 360) % 360;
}
}
/** @var float[] Psalm bug workaround */
$params = \array_map('floatval', $params);
switch ($variant) {
case self::COLOR_RGBA:
case self::COLOR_RGB:
if (\min($params) < 0 || \max($params) > 0xFF) {
return null;
}
break;
case self::COLOR_HSLA:
case self::COLOR_HSL:
if (\min($params) < 0 || $params[0] > 360 || \max($params[1], $params[2]) > 100) {
return null;
}
break;
}
if (4 === \count($params)) {
if ($params[3] > 1) {
return null;
}
$this->a = $params[3];
}
if (self::COLOR_HSLA === $variant || self::COLOR_HSL === $variant) {
$params = self::hslToRgb($params[0], $params[1], $params[2]);
}
list($this->r, $this->g, $this->b) = $params;
return $variant;
}
/**
* Turns HSL color to RGB. Black magic.
*
* @param float $h Hue
* @param float $s Saturation
* @param float $l Lightness
*
* @return int[] RGB array
*/
public static function hslToRgb($h, $s, $l)
{
if (\min($h, $s, $l) < 0) {
throw new InvalidArgumentException('The parameters for hslToRgb should be no less than 0');
}
if ($h > 360 || \max($s, $l) > 100) {
throw new InvalidArgumentException('The parameters for hslToRgb should be no more than 360, 100, and 100 respectively');
}
$h /= 360;
$s /= 100;
$l /= 100;
$m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l * $s;
$m1 = $l * 2 - $m2;
return array(
(int) \round(self::hueToRgb($m1, $m2, $h + 1 / 3) * 0xFF),
(int) \round(self::hueToRgb($m1, $m2, $h) * 0xFF),
(int) \round(self::hueToRgb($m1, $m2, $h - 1 / 3) * 0xFF),
);
}
/**
* Converts RGB to HSL. Color inversion of previous black magic is white magic?
*
* @param float|int $red Red
* @param float|int $green Green
* @param float|int $blue Blue
*
* @return float[] HSL array
*/
public static function rgbToHsl($red, $green, $blue)
{
if (\min($red, $green, $blue) < 0) {
throw new InvalidArgumentException('The parameters for rgbToHsl should be no less than 0');
}
if (\max($red, $green, $blue) > 0xFF) {
throw new InvalidArgumentException('The parameters for rgbToHsl should be no more than 255');
}
$clrMin = \min($red, $green, $blue);
$clrMax = \max($red, $green, $blue);
$deltaMax = $clrMax - $clrMin;
$L = ($clrMax + $clrMin) / 510;
if (0 == $deltaMax) {
$H = 0;
$S = 0;
} else {
if (0.5 > $L) {
$S = $deltaMax / ($clrMax + $clrMin);
} else {
$S = $deltaMax / (510 - $clrMax - $clrMin);
}
if ($clrMax === $red) {
$H = ($green - $blue) / (6.0 * $deltaMax);
if (0 > $H) {
$H += 1.0;
}
} elseif ($clrMax === $green) {
$H = 1 / 3 + ($blue - $red) / (6.0 * $deltaMax);
} else {
$H = 2 / 3 + ($red - $green) / (6.0 * $deltaMax);
}
}
return array(
(float) ($H * 360 % 360),
(float) ($S * 100),
(float) ($L * 100),
);
}
/**
* Helper function for hslToRgb. Even blacker magic.
*
*
* @param float $m1
* @param float $m2
* @param float $hue
*
* @return float Color value
*/
private static function hueToRgb($m1, $m2, $hue)
{
$hue = ($hue < 0) ? $hue + 1 : (($hue > 1) ? $hue - 1 : $hue);
if ($hue * 6 < 1) {
return $m1 + ($m2 - $m1) * $hue * 6;
}
if ($hue * 2 < 1) {
return $m2;
}
if ($hue * 3 < 2) {
return $m1 + ($m2 - $m1) * (2 / 3 - $hue) * 6;
}
return $m1;
}
}

View File

@ -0,0 +1,73 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
class DocstringRepresentation extends Representation
{
public $file;
public $line;
public $class;
public $hints = array('docstring');
public function __construct($docstring, $file, $line, $class = null)
{
parent::__construct('Docstring');
$this->file = $file;
$this->line = $line;
$this->class = $class;
$this->contents = $docstring;
}
/**
* Returns the representation's docstring without surrounding comments.
*
* Note that this will not work flawlessly.
*
* On comments with whitespace after the stars the lines will begin with
* whitespace, since we can't accurately guess how much of an indentation
* is required.
*
* And on lines without stars on the left this may eat bullet points.
*
* Long story short: If you want the docstring read the contents. If you
* absolutely must have it without comments (ie renderValueShort) this will
* probably do.
*
* @return null|string Docstring with comments stripped
*/
public function getDocstringWithoutComments()
{
if (!$this->contents) {
return null;
}
$string = \substr($this->contents, 3, -2);
$string = \preg_replace('/^\\s*\\*\\s*?(\\S|$)/m', '\\1', $string);
return \trim($string);
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
use DateTime;
class MicrotimeRepresentation extends Representation
{
public $seconds;
public $microseconds;
public $group;
public $lap;
public $total;
public $avg;
public $i = 0;
public $mem = 0;
public $mem_real = 0;
public $mem_peak = 0;
public $mem_peak_real = 0;
public $hints = array('microtime');
public function __construct($seconds, $microseconds, $group, $lap = null, $total = null, $i = 0)
{
parent::__construct('Microtime');
$this->seconds = (int) $seconds;
$this->microseconds = (int) $microseconds;
$this->group = $group;
$this->lap = $lap;
$this->total = $total;
$this->i = $i;
if ($i) {
$this->avg = $total / $i;
}
$this->mem = \memory_get_usage();
$this->mem_real = \memory_get_usage(true);
$this->mem_peak = \memory_get_peak_usage();
$this->mem_peak_real = \memory_get_peak_usage(true);
}
public function getDateTime()
{
return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad($this->microseconds, 6, '0', STR_PAD_LEFT));
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
class Representation
{
public $label;
public $implicit_label = false;
public $hints = array();
public $contents = array();
protected $name;
public function __construct($label, $name = null)
{
$this->label = $label;
if (null === $name) {
$name = $label;
}
$this->setName($name);
}
public function getLabel()
{
if (\is_array($this->contents) && \count($this->contents) > 1) {
return $this->label.' ('.\count($this->contents).')';
}
return $this->label;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name));
}
public function labelIsImplicit()
{
return $this->implicit_label;
}
}

View File

@ -0,0 +1,72 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
class SourceRepresentation extends Representation
{
public $hints = array('source');
public $source = array();
public $filename;
public $line = 0;
public $showfilename = false;
public function __construct($filename, $line, $padding = 7)
{
parent::__construct('Source');
$this->filename = $filename;
$this->line = $line;
$start_line = \max($line - $padding, 1);
$length = $line + $padding + 1 - $start_line;
$this->source = self::getSource($filename, $start_line, $length);
if (null !== $this->source) {
$this->contents = \implode("\n", $this->source);
}
}
/**
* Gets section of source code.
*
* @param string $filename Full path to file
* @param int $start_line The first line to display (1 based)
* @param null|int $length Amount of lines to show
*
* @return null|array
*/
public static function getSource($filename, $start_line = 1, $length = null)
{
if (!$filename || !\file_exists($filename) || !\is_readable($filename)) {
return null;
}
$source = \preg_split("/\r\n|\n|\r/", \file_get_contents($filename));
$source = \array_combine(\range(1, \count($source)), $source);
$source = \array_slice($source, $start_line - 1, $length, true);
return $source;
}
}

View File

@ -0,0 +1,177 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object\Representation;
use Kint\Utils;
use SplFileInfo;
class SplFileInfoRepresentation extends Representation
{
public $perms;
public $flags;
public $path;
public $realpath;
public $linktarget;
public $size;
public $is_dir = false;
public $is_file = false;
public $is_link = false;
public $owner;
public $group;
public $ctime;
public $mtime;
public $typename = 'Unknown file';
public $typeflag = '-';
public $hints = array('fspath');
public function __construct(SplFileInfo $fileInfo)
{
parent::__construct('SplFileInfo');
if ($fileInfo->getRealPath()) {
$this->realpath = $fileInfo->getRealPath();
$this->perms = $fileInfo->getPerms();
$this->size = $fileInfo->getSize();
$this->owner = $fileInfo->getOwner();
$this->group = $fileInfo->getGroup();
$this->ctime = $fileInfo->getCTime();
$this->mtime = $fileInfo->getMTime();
}
$this->path = $fileInfo->getPathname();
$this->is_dir = $fileInfo->isDir();
$this->is_file = $fileInfo->isFile();
$this->is_link = $fileInfo->isLink();
if ($this->is_link) {
$this->linktarget = $fileInfo->getLinkTarget();
}
switch ($this->perms & 0xF000) {
case 0xC000:
$this->typename = 'Socket';
$this->typeflag = 's';
break;
case 0x6000:
$this->typename = 'Block device';
$this->typeflag = 'b';
break;
case 0x2000:
$this->typename = 'Character device';
$this->typeflag = 'c';
break;
case 0x1000:
$this->typename = 'Named pipe';
$this->typeflag = 'p';
break;
default:
if ($this->is_file) {
if ($this->is_link) {
$this->typename = 'File symlink';
$this->typeflag = 'l';
} else {
$this->typename = 'File';
$this->typeflag = '-';
}
} elseif ($this->is_dir) {
if ($this->is_link) {
$this->typename = 'Directory symlink';
$this->typeflag = 'l';
} else {
$this->typename = 'Directory';
$this->typeflag = 'd';
}
}
break;
}
$this->flags = array($this->typeflag);
// User
$this->flags[] = (($this->perms & 0400) ? 'r' : '-');
$this->flags[] = (($this->perms & 0200) ? 'w' : '-');
if ($this->perms & 0100) {
$this->flags[] = ($this->perms & 04000) ? 's' : 'x';
} else {
$this->flags[] = ($this->perms & 04000) ? 'S' : '-';
}
// Group
$this->flags[] = (($this->perms & 0040) ? 'r' : '-');
$this->flags[] = (($this->perms & 0020) ? 'w' : '-');
if ($this->perms & 0010) {
$this->flags[] = ($this->perms & 02000) ? 's' : 'x';
} else {
$this->flags[] = ($this->perms & 02000) ? 'S' : '-';
}
// Other
$this->flags[] = (($this->perms & 0004) ? 'r' : '-');
$this->flags[] = (($this->perms & 0002) ? 'w' : '-');
if ($this->perms & 0001) {
$this->flags[] = ($this->perms & 01000) ? 's' : 'x';
} else {
$this->flags[] = ($this->perms & 01000) ? 'S' : '-';
}
$this->contents = \implode($this->flags).' '.$this->owner.' '.$this->group;
$this->contents .= ' '.$this->getSize().' '.$this->getMTime().' ';
if ($this->is_link && $this->linktarget) {
$this->contents .= $this->path.' -> '.$this->linktarget;
} elseif (null !== $this->realpath && \strlen($this->realpath) < \strlen($this->path)) {
$this->contents .= $this->realpath;
} else {
$this->contents .= $this->path;
}
}
public function getLabel()
{
return $this->typename.' ('.$this->getSize().')';
}
public function getSize()
{
if ($this->size) {
$size = Utils::getHumanReadableBytes($this->size);
return \round($size['value'], 2).$size['unit'];
}
}
public function getMTime()
{
$year = \date('Y', $this->mtime);
if ($year !== \date('Y')) {
return \date('M d Y', $this->mtime);
}
return \date('M d H:i', $this->mtime);
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
class ResourceObject extends BasicObject
{
public $resource_type;
public function getType()
{
if ($this->resource_type) {
return $this->resource_type.' resource';
}
return 'resource';
}
public function transplant(BasicObject $old)
{
parent::transplant($old);
if ($old instanceof self) {
$this->resource_type = $old->resource_type;
}
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Kint\Kint;
class StreamObject extends ResourceObject
{
public $stream_meta;
public function __construct(array $meta = null)
{
parent::__construct();
$this->stream_meta = $meta;
}
public function getValueShort()
{
if (empty($this->stream_meta['uri'])) {
return;
}
$uri = $this->stream_meta['uri'];
if (\stream_is_local($uri)) {
return Kint::shortenPath($uri);
}
return $uri;
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Exception;
use InvalidArgumentException;
use Throwable;
class ThrowableObject extends InstanceObject
{
public $message;
public $hints = array('object', 'throwable');
public function __construct($throw)
{
if (!$throw instanceof Exception && (!KINT_PHP70 || !$throw instanceof Throwable)) {
throw new InvalidArgumentException('ThrowableObject must be constructed with a Throwable');
}
parent::__construct();
$this->message = $throw->getMessage();
}
public function getValueShort()
{
if (\strlen($this->message)) {
return '"'.$this->message.'"';
}
}
}

View File

@ -0,0 +1,100 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
use Kint\Object\Representation\Representation;
use Kint\Object\Representation\SourceRepresentation;
use ReflectionFunction;
use ReflectionMethod;
class TraceFrameObject extends BasicObject
{
public $trace;
public $hints = array('trace_frame');
public function __construct(BasicObject $base, array $raw_frame)
{
parent::__construct();
$this->transplant($base);
$this->trace = array(
'function' => isset($raw_frame['function']) ? $raw_frame['function'] : null,
'line' => isset($raw_frame['line']) ? $raw_frame['line'] : null,
'file' => isset($raw_frame['file']) ? $raw_frame['file'] : null,
'class' => isset($raw_frame['class']) ? $raw_frame['class'] : null,
'type' => isset($raw_frame['type']) ? $raw_frame['type'] : null,
'object' => null,
'args' => null,
);
if ($this->trace['class'] && \method_exists($this->trace['class'], $this->trace['function'])) {
$func = new ReflectionMethod($this->trace['class'], $this->trace['function']);
$this->trace['function'] = new MethodObject($func);
} elseif (!$this->trace['class'] && \function_exists($this->trace['function'])) {
$func = new ReflectionFunction($this->trace['function']);
$this->trace['function'] = new MethodObject($func);
}
foreach ($this->value->contents as $frame_prop) {
if ('object' === $frame_prop->name) {
$this->trace['object'] = $frame_prop;
$this->trace['object']->name = null;
$this->trace['object']->operator = BasicObject::OPERATOR_NONE;
}
if ('args' === $frame_prop->name) {
$this->trace['args'] = $frame_prop->value->contents;
if ($this->trace['function'] instanceof MethodObject) {
foreach (\array_values($this->trace['function']->parameters) as $param) {
if (isset($this->trace['args'][$param->position])) {
$this->trace['args'][$param->position]->name = $param->getName();
}
}
}
}
}
$this->clearRepresentations();
if (isset($this->trace['file'], $this->trace['line']) && \is_readable($this->trace['file'])) {
$this->addRepresentation(new SourceRepresentation($this->trace['file'], $this->trace['line']));
}
if ($this->trace['args']) {
$args = new Representation('Arguments');
$args->contents = $this->trace['args'];
$this->addRepresentation($args);
}
if ($this->trace['object']) {
$callee = new Representation('object');
$callee->label = 'Callee object ['.$this->trace['object']->classname.']';
$callee->contents[] = $this->trace['object'];
$this->addRepresentation($callee);
}
}
}

View File

@ -0,0 +1,45 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Object;
class TraceObject extends BasicObject
{
public $hints = array('trace');
public function getType()
{
return 'Debug Backtrace';
}
public function getSize()
{
if (!$this->size) {
return 'empty';
}
return parent::getSize();
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use ArrayObject;
use Kint\Object\BasicObject;
class ArrayObjectPlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_BEGIN;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof ArrayObject) {
return;
}
$flags = $var->getFlags();
if (ArrayObject::STD_PROP_LIST === $flags) {
return;
}
$var->setFlags(ArrayObject::STD_PROP_LIST);
$o = $this->parser->parse($var, $o);
$var->setFlags($flags);
$this->parser->haltParse();
}
}

View File

@ -0,0 +1,95 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class Base64Plugin extends Plugin
{
/**
* The minimum length before a string will be considered for base64 decoding.
*
* @var int
*/
public static $min_length_hard = 16;
/**
* The minimum length before the base64 decoding will take precedence.
*
* @var int
*/
public static $min_length_soft = 50;
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) < self::$min_length_hard || \strlen($var) % 4) {
return;
}
if (\preg_match('/^[A-Fa-f0-9]+$/', $var)) {
return;
}
if (!\preg_match('/^[A-Za-z0-9+\\/=]+$/', $var)) {
return;
}
/** @var false|string */
$data = \base64_decode($var, true);
if (false === $data) {
return;
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = 'base64_decode('.$o->name.')';
if ($o->access_path) {
$base_obj->access_path = 'base64_decode('.$o->access_path.')';
}
$r = new Representation('Base64');
$r->contents = $this->parser->parse($data, $base_obj);
if (\strlen($var) > self::$min_length_soft) {
$o->addRepresentation($r, 0);
} else {
$o->addRepresentation($r);
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
class BinaryPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof BlobObject || !\in_array($o->encoding, array('ASCII', 'UTF-8'), true)) {
$o->value->hints[] = 'binary';
}
}
}

View File

@ -0,0 +1,143 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
class BlacklistPlugin extends Plugin
{
/**
* List of classes and interfaces to blacklist.
*
* @var array
*/
public static $blacklist = array();
/**
* List of classes and interfaces to blacklist except when dumped directly.
*
* @var array
*/
public static $shallow_blacklist = array();
/**
* Maximum size of arrays before blacklisting.
*
* @var int
*/
public static $array_limit = 10000;
/**
* Maximum size of arrays before blacklisting except when dumped directly.
*
* @var int
*/
public static $shallow_array_limit = 1000;
public function getTypes()
{
return array('object', 'array');
}
public function getTriggers()
{
return Parser::TRIGGER_BEGIN;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\is_object($var)) {
return $this->parseObject($var, $o);
}
if (\is_array($var)) {
return $this->parseArray($var, $o);
}
}
protected function parseObject(&$var, BasicObject &$o)
{
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
return $this->blacklistObject($var, $o);
}
}
if ($o->depth <= 0) {
return;
}
foreach (self::$shallow_blacklist as $class) {
if ($var instanceof $class) {
return $this->blacklistObject($var, $o);
}
}
}
protected function blacklistObject(&$var, BasicObject &$o)
{
$object = new InstanceObject();
$object->transplant($o);
$object->classname = \get_class($var);
$object->hash = \spl_object_hash($var);
$object->clearRepresentations();
$object->value = null;
$object->size = null;
$object->hints[] = 'blacklist';
$o = $object;
$this->parser->haltParse();
}
protected function parseArray(array &$var, BasicObject &$o)
{
if (\count($var) > self::$array_limit) {
return $this->blacklistArray($var, $o);
}
if ($o->depth <= 0) {
return;
}
if (\count($var) > self::$shallow_array_limit) {
return $this->blacklistArray($var, $o);
}
}
protected function blacklistArray(array &$var, BasicObject &$o)
{
$object = new BasicObject();
$object->transplant($o);
$object->value = null;
$object->size = \count($var);
$object->hints[] = 'blacklist';
$o = $object;
$this->parser->haltParse();
}
}

View File

@ -0,0 +1,113 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\MethodObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
class ClassMethodsPlugin extends Plugin
{
private static $cache = array();
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$class = \get_class($var);
// assuming class definition will not change inside one request
if (!isset(self::$cache[$class])) {
$methods = array();
$reflection = new ReflectionClass($class);
foreach ($reflection->getMethods() as $method) {
$methods[] = new MethodObject($method);
}
\usort($methods, array('Kint\\Parser\\ClassMethodsPlugin', 'sort'));
self::$cache[$class] = $methods;
}
if (!empty(self::$cache[$class])) {
$rep = new Representation('Available methods', 'methods');
// Can't cache access paths
foreach (self::$cache[$class] as $m) {
$method = clone $m;
$method->depth = $o->depth + 1;
if (!$this->parser->childHasPath($o, $method)) {
$method->access_path = null;
} else {
$method->setAccessPathFrom($o);
}
if ($method->owner_class !== $class && $ds = $method->getRepresentation('docstring')) {
$ds = clone $ds;
$ds->class = $method->owner_class;
$method->replaceRepresentation($ds);
}
$rep->contents[] = $method;
}
$o->addRepresentation($rep);
}
}
private static function sort(MethodObject $a, MethodObject $b)
{
$sort = ((int) $a->static) - ((int) $b->static);
if ($sort) {
return $sort;
}
$sort = BasicObject::sortByAccess($a, $b);
if ($sort) {
return $sort;
}
$sort = InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class);
if ($sort) {
return $sort;
}
return $a->startline - $b->startline;
}
}

View File

@ -0,0 +1,122 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
use ReflectionProperty;
class ClassStaticsPlugin extends Plugin
{
private static $cache = array();
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$class = \get_class($var);
$reflection = new ReflectionClass($class);
// Constants
// TODO: PHP 7.1 allows private consts but reflection doesn't have a way to check them yet
if (!isset(self::$cache[$class])) {
$consts = array();
foreach ($reflection->getConstants() as $name => $val) {
$const = BasicObject::blank($name, '\\'.$class.'::'.$name);
$const->const = true;
$const->depth = $o->depth + 1;
$const->owner_class = $class;
$const->operator = BasicObject::OPERATOR_STATIC;
$const = $this->parser->parse($val, $const);
$consts[] = $const;
}
self::$cache[$class] = $consts;
}
$statics = new Representation('Static class properties', 'statics');
$statics->contents = self::$cache[$class];
foreach ($reflection->getProperties(ReflectionProperty::IS_STATIC) as $static) {
$prop = new BasicObject();
$prop->name = '$'.$static->getName();
$prop->depth = $o->depth + 1;
$prop->static = true;
$prop->operator = BasicObject::OPERATOR_STATIC;
$prop->owner_class = $static->getDeclaringClass()->name;
$prop->access = BasicObject::ACCESS_PUBLIC;
if ($static->isProtected()) {
$prop->access = BasicObject::ACCESS_PROTECTED;
} elseif ($static->isPrivate()) {
$prop->access = BasicObject::ACCESS_PRIVATE;
}
if ($this->parser->childHasPath($o, $prop)) {
$prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name;
}
$static->setAccessible(true);
$static = $static->getValue();
$statics->contents[] = $this->parser->parse($static, $prop);
}
if (empty($statics->contents)) {
return;
}
\usort($statics->contents, array('Kint\\Parser\\ClassStaticsPlugin', 'sort'));
$o->addRepresentation($statics);
}
private static function sort(BasicObject $a, BasicObject $b)
{
$sort = ((int) $a->const) - ((int) $b->const);
if ($sort) {
return $sort;
}
$sort = BasicObject::sortByAccess($a, $b);
if ($sort) {
return $sort;
}
return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class);
}
}

View File

@ -0,0 +1,94 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Closure;
use Kint\Object\BasicObject;
use Kint\Object\ClosureObject;
use Kint\Object\ParameterObject;
use Kint\Object\Representation\Representation;
use ReflectionFunction;
class ClosurePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Closure) {
return;
}
$object = new ClosureObject();
$object->transplant($o);
$o = $object;
$object->removeRepresentation('properties');
$closure = new ReflectionFunction($var);
$o->filename = $closure->getFileName();
$o->startline = $closure->getStartLine();
foreach ($closure->getParameters() as $param) {
$o->parameters[] = new ParameterObject($param);
}
$p = new Representation('Parameters');
$p->contents = &$o->parameters;
$o->addRepresentation($p, 0);
$statics = array();
if (\method_exists($closure, 'getClosureThis') && $v = $closure->getClosureThis()) {
$statics = array('this' => $v);
}
if (\count($statics = $statics + $closure->getStaticVariables())) {
$statics_parsed = array();
foreach ($statics as $name => &$static) {
$obj = BasicObject::blank('$'.$name);
$obj->depth = $o->depth + 1;
$statics_parsed[$name] = $this->parser->parse($static, $obj);
if (null === $statics_parsed[$name]->value) {
$statics_parsed[$name]->access_path = null;
}
}
$r = new Representation('Uses');
$r->contents = $statics_parsed;
$o->addRepresentation($r, 0);
}
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\ColorRepresentation;
class ColorPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) > 32) {
return;
}
$trimmed = \strtolower(\trim($var));
if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)[^\\)]{6,}\\)|#[0-9a-fA-F]{3,8})$/', $trimmed)) {
return;
}
$rep = new ColorRepresentation($var);
if ($rep->variant) {
$o->removeRepresentation($o->value);
$o->addRepresentation($rep, 0);
$o->hints[] = 'color';
}
}
}

View File

@ -0,0 +1,328 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DOMNamedNodeMap;
use DOMNode;
use DOMNodeList;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
/**
* The DOMDocument parser plugin is particularly useful as it is both the only
* way to see inside the DOMNode without print_r, and the only way to see mixed
* text and node inside XML (SimpleXMLElement will strip out the text).
*/
class DOMDocumentPlugin extends Plugin
{
/**
* List of properties to skip parsing.
*
* The properties of a DOMNode can do a *lot* of damage to debuggers. The
* DOMNode contains not one, not two, not three, not four, not 5, not 6,
* not 7 but 8 different ways to recurse into itself:
* * firstChild
* * lastChild
* * previousSibling
* * nextSibling
* * ownerDocument
* * parentNode
* * childNodes
* * attributes
*
* All of this combined: the tiny SVGs used as the caret in Kint are already
* enough to make parsing and rendering take over a second, and send memory
* usage over 128 megs. So we blacklist every field we don't strictly need
* and hope that that's good enough.
*
* In retrospect - this is probably why print_r does the same
*
* @var array
*/
public static $blacklist = array(
'parentNode' => 'DOMNode',
'firstChild' => 'DOMNode',
'lastChild' => 'DOMNode',
'previousSibling' => 'DOMNode',
'nextSibling' => 'DOMNode',
'ownerDocument' => 'DOMDocument',
);
/**
* Show all properties and methods.
*
* @var bool
*/
public static $verbose = false;
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof InstanceObject) {
return;
}
if ($var instanceof DOMNamedNodeMap || $var instanceof DOMNodeList) {
return $this->parseList($var, $o, $trigger);
}
if ($var instanceof DOMNode) {
return $this->parseNode($var, $o);
}
}
protected function parseList(&$var, InstanceObject &$o, $trigger)
{
// Recursion should never happen, should always be stopped at the parent
// DOMNode. Depth limit on the other hand we're going to skip since
// that would show an empty iterator and rather useless. Let the depth
// limit hit the children (DOMNodeList only has DOMNode as children)
if ($trigger & Parser::TRIGGER_RECURSION) {
return;
}
$o->size = $var->length;
if (0 === $o->size) {
$o->replaceRepresentation(new Representation('Iterator'));
$o->size = null;
return;
}
// Depth limit
// Make empty iterator representation since we need it in DOMNode to point out depth limits
if ($this->parser->getDepthLimit() && $o->depth + 1 >= $this->parser->getDepthLimit()) {
$b = new BasicObject();
$b->name = $o->classname.' Iterator Contents';
$b->access_path = 'iterator_to_array('.$o->access_path.')';
$b->depth = $o->depth + 1;
$b->hints[] = 'depth_limit';
$r = new Representation('Iterator');
$r->contents = array($b);
$o->replaceRepresentation($r, 0);
return;
}
$data = \iterator_to_array($var);
$r = new Representation('Iterator');
$o->replaceRepresentation($r, 0);
foreach ($data as $key => $item) {
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $item->nodeName;
if ($o->access_path) {
if ($var instanceof DOMNamedNodeMap) {
$base_obj->access_path = $o->access_path.'->getNamedItem('.\var_export($key, true).')';
} elseif ($var instanceof DOMNodeList) {
$base_obj->access_path = $o->access_path.'->item('.\var_export($key, true).')';
} else {
$base_obj->access_path = 'iterator_to_array('.$o->access_path.')';
}
}
$r->contents[] = $this->parser->parse($item, $base_obj);
}
}
protected function parseNode(&$var, InstanceObject &$o)
{
// Fill the properties
// They can't be enumerated through reflection or casting,
// so we have to trust the docs and try them one at a time
$known_properties = array(
'nodeValue',
'childNodes',
'attributes',
);
if (self::$verbose) {
$known_properties = array(
'nodeName',
'nodeValue',
'nodeType',
'parentNode',
'childNodes',
'firstChild',
'lastChild',
'previousSibling',
'nextSibling',
'attributes',
'ownerDocument',
'namespaceURI',
'prefix',
'localName',
'baseURI',
'textContent',
);
}
$childNodes = array();
$attributes = array();
$rep = $o->value;
foreach ($known_properties as $prop) {
$prop_obj = $this->parseProperty($o, $prop, $var);
$rep->contents[] = $prop_obj;
if ('childNodes' === $prop) {
$childNodes = $prop_obj->getRepresentation('iterator');
} elseif ('attributes' === $prop) {
$attributes = $prop_obj->getRepresentation('iterator');
}
}
if (!self::$verbose) {
$o->removeRepresentation('methods');
$o->removeRepresentation('properties');
}
// Attributes and comments and text nodes don't
// need children or attributes of their own
if (\in_array($o->classname, array('DOMAttr', 'DOMText', 'DOMComment'), true)) {
return;
}
// Set the attributes
if ($attributes) {
$a = new Representation('Attributes');
foreach ($attributes->contents as $attribute) {
$a->contents[] = self::textualNodeToString($attribute);
}
$o->addRepresentation($a, 0);
}
// Set the children
if ($childNodes) {
$c = new Representation('Children');
if (1 === \count($childNodes->contents) && ($node = \reset($childNodes->contents)) && \in_array('depth_limit', $node->hints, true)) {
$n = new InstanceObject();
$n->transplant($node);
$n->name = 'childNodes';
$n->classname = 'DOMNodeList';
$c->contents = array($n);
} else {
foreach ($childNodes->contents as $index => $node) {
// Shortcircuit text nodes to plain strings
if ('DOMText' === $node->classname || 'DOMComment' === $node->classname) {
$node = self::textualNodeToString($node);
// And remove them if they're empty
if (\ctype_space($node->value->contents) || '' === $node->value->contents) {
continue;
}
}
$c->contents[] = $node;
}
}
$o->addRepresentation($c, 0);
}
if (isset($c) && \count($c->contents)) {
$o->size = \count($c->contents);
}
if (!$o->size) {
$o->size = null;
}
}
protected function parseProperty(InstanceObject $o, $prop, &$var)
{
// Duplicating (And slightly optimizing) the Parser::parseObject() code here
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->owner_class = $o->classname;
$base_obj->name = $prop;
$base_obj->operator = BasicObject::OPERATOR_OBJECT;
$base_obj->access = BasicObject::ACCESS_PUBLIC;
if (null !== $o->access_path) {
$base_obj->access_path = $o->access_path;
if (\preg_match('/^[A-Za-z0-9_]+$/', $base_obj->name)) {
$base_obj->access_path .= '->'.$base_obj->name;
} else {
$base_obj->access_path .= '->{'.\var_export($base_obj->name, true).'}';
}
}
if (!isset($var->{$prop})) {
$base_obj->type = 'null';
} elseif (isset(self::$blacklist[$prop])) {
$b = new InstanceObject();
$b->transplant($base_obj);
$base_obj = $b;
$base_obj->hints[] = 'blacklist';
$base_obj->classname = self::$blacklist[$prop];
} elseif ('attributes' === $prop) {
$base_obj = $this->parser->parseDeep($var->{$prop}, $base_obj);
} else {
$base_obj = $this->parser->parse($var->{$prop}, $base_obj);
}
return $base_obj;
}
protected static function textualNodeToString(InstanceObject $o)
{
if (empty($o->value) || empty($o->value->contents) || empty($o->classname)) {
return;
}
if (!\in_array($o->classname, array('DOMText', 'DOMAttr', 'DOMComment'), true)) {
return;
}
foreach ($o->value->contents as $property) {
if ('nodeValue' === $property->name) {
$ret = clone $property;
$ret->name = $o->name;
return $ret;
}
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DateTime;
use Kint\Object\BasicObject;
use Kint\Object\DateTimeObject;
class DateTimePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof DateTime) {
return;
}
$object = new DateTimeObject($var);
$object->transplant($o);
$o = $object;
}
}

View File

@ -0,0 +1,72 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SplFileInfoRepresentation;
use SplFileInfo;
class FsPathPlugin extends Plugin
{
public static $blacklist = array('/', '.');
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) > 2048) {
return;
}
if (!\preg_match('/[\\/\\'.DIRECTORY_SEPARATOR.']/', $var)) {
return;
}
if (\preg_match('/[?<>"*|]/', $var)) {
return;
}
if (!@\file_exists($var)) {
return;
}
if (\in_array($var, self::$blacklist, true)) {
return;
}
$r = new SplFileInfoRepresentation(new SplFileInfo($var));
$r->hints[] = 'fspath';
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,110 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use Traversable;
class IteratorPlugin extends Plugin
{
/**
* List of classes and interfaces to blacklist.
*
* Certain classes (Such as PDOStatement) irreversibly lose information
* when traversed. Others are just huge. Either way, put them in here
* and you won't have to worry about them being parsed.
*
* @var array
*/
public static $blacklist = array(
'DOMNamedNodeMap',
'DOMNodeList',
'mysqli_result',
'PDOStatement',
'SplFileObject',
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Traversable) {
return;
}
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
$b = new BasicObject();
$b->name = $class.' Iterator Contents';
$b->access_path = 'iterator_to_array('.$o->access_path.', true)';
$b->depth = $o->depth + 1;
$b->hints[] = 'blacklist';
$r = new Representation('Iterator');
$r->contents = array($b);
$o->addRepresentation($r);
return;
}
}
/** @var array|false */
$data = \iterator_to_array($var);
if (false === $data) {
return;
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'iterator_to_array('.$o->access_path.')';
}
$r = new Representation('Iterator');
$r->contents = $this->parser->parse($data, $base_obj);
$r->contents = $r->contents->value->contents;
$primary = $o->getRepresentations();
$primary = \reset($primary);
if ($primary && $primary === $o->value && $primary->contents === array()) {
$o->addRepresentation($r, 0);
} else {
$o->addRepresentation($r);
}
}
}

View File

@ -0,0 +1,73 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class JsonPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!isset($var[0]) || ('{' !== $var[0] && '[' !== $var[0])) {
return;
}
$json = \json_decode($var, true);
if (!$json) {
return;
}
$json = (array) $json;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'json_decode('.$o->access_path.', true)';
}
$r = new Representation('Json');
$r->contents = $this->parser->parse($json, $base_obj);
if (!\in_array('depth_limit', $r->contents->hints, true)) {
$r->contents = $r->contents->value->contents;
}
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,105 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\MicrotimeRepresentation;
class MicrotimePlugin extends Plugin
{
private static $last = null;
private static $start = null;
private static $times = 0;
private static $group = 0;
public function getTypes()
{
return array('string', 'double');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (0 !== $o->depth) {
return;
}
if (\is_string($var)) {
if ('microtime()' !== $o->name || !\preg_match('/^0\\.[0-9]{8} [0-9]{10}$/', $var)) {
return;
}
$usec = (int) \substr($var, 2, 6);
$sec = (int) \substr($var, 11, 10);
} else {
if ('microtime(...)' !== $o->name) {
return;
}
$sec = \floor($var);
$usec = $var - $sec;
$usec = \floor($usec * 1000000);
}
$time = $sec + ($usec / 1000000);
if (null !== self::$last) {
$last_time = self::$last[0] + (self::$last[1] / 1000000);
$lap = $time - $last_time;
++self::$times;
} else {
$lap = null;
self::$start = $time;
}
self::$last = array($sec, $usec);
if (null !== $lap) {
$total = $time - self::$start;
$r = new MicrotimeRepresentation($sec, $usec, self::$group, $lap, $total, self::$times);
} else {
$r = new MicrotimeRepresentation($sec, $usec, self::$group);
}
$r->contents = $var;
$r->implicit_label = true;
$o->removeRepresentation($o->value);
$o->addRepresentation($r);
$o->hints[] = 'microtime';
}
public static function clean()
{
self::$last = null;
self::$start = null;
self::$times = 0;
++self::$group;
}
}

View File

@ -0,0 +1,129 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Mysqli;
/**
* Adds support for Mysqli object parsing.
*
* Due to the way mysqli is implemented in PHP, this will cause
* warnings on certain Mysqli objects if screaming is enabled.
*/
class MysqliPlugin extends Plugin
{
// These 'properties' are actually globals
protected $always_readable = array(
'client_version' => true,
'connect_errno' => true,
'connect_error' => true,
);
// These are readable on empty mysqli objects, but not on failed connections
protected $empty_readable = array(
'client_info' => true,
'errno' => true,
'error' => true,
);
// These are only readable on connected mysqli objects
protected $connected_readable = array(
'affected_rows' => true,
'error_list' => true,
'field_count' => true,
'host_info' => true,
'info' => true,
'insert_id' => true,
'server_info' => true,
'server_version' => true,
'stat' => true,
'sqlstate' => true,
'protocol_version' => true,
'thread_id' => true,
'warning_count' => true,
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Mysqli) {
return;
}
$connected = false;
$empty = false;
if (\is_string(@$var->sqlstate)) {
$connected = true;
} elseif (\is_string(@$var->client_info)) {
$empty = true;
}
foreach ($o->value->contents as $key => $obj) {
if (isset($this->connected_readable[$obj->name])) {
if (!$connected) {
continue;
}
} elseif (isset($this->empty_readable[$obj->name])) {
if (!$connected && !$empty) {
continue;
}
} elseif (!isset($this->always_readable[$obj->name])) {
continue;
}
if ('null' !== $obj->type) {
continue;
}
$param = $var->{$obj->name};
if (null === $param) {
continue;
}
$base = BasicObject::blank($obj->name, $obj->access_path);
$base->depth = $obj->depth;
$base->owner_class = $obj->owner_class;
$base->operator = $obj->operator;
$base->access = $obj->access;
$base->reference = $obj->reference;
$o->value->contents[$key] = $this->parser->parse($param, $base);
}
}
}

View File

@ -0,0 +1,604 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DomainException;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
use Kint\Object\ResourceObject;
use ReflectionObject;
use stdClass;
class Parser
{
/**
* Plugin triggers.
*
* These are constants indicating trigger points for plugins
*
* BEGIN: Before normal parsing
* SUCCESS: After successful parsing
* RECURSION: After parsing cancelled by recursion
* DEPTH_LIMIT: After parsing cancelled by depth limit
* COMPLETE: SUCCESS | RECURSION | DEPTH_LIMIT
*
* While a plugin's getTriggers may return any of these
*/
const TRIGGER_NONE = 0;
const TRIGGER_BEGIN = 1;
const TRIGGER_SUCCESS = 2;
const TRIGGER_RECURSION = 4;
const TRIGGER_DEPTH_LIMIT = 8;
const TRIGGER_COMPLETE = 14;
protected $caller_class;
protected $depth_limit = false;
protected $marker;
protected $object_hashes = array();
protected $parse_break = false;
protected $plugins = array();
/**
* @param false|int $depth_limit Maximum depth to parse data
* @param null|string $caller Caller class name
*/
public function __construct($depth_limit = false, $caller = null)
{
$this->marker = \uniqid("kint\0", true);
$this->caller_class = $caller;
if ($depth_limit) {
$this->depth_limit = $depth_limit;
}
}
/**
* Set the caller class.
*
* @param null|string $caller Caller class name
*/
public function setCallerClass($caller = null)
{
$this->noRecurseCall();
$this->caller_class = $caller;
}
public function getCallerClass()
{
return $this->caller_class;
}
/**
* Set the depth limit.
*
* @param false|int $depth_limit Maximum depth to parse data
*/
public function setDepthLimit($depth_limit = false)
{
$this->noRecurseCall();
$this->depth_limit = $depth_limit;
}
public function getDepthLimit()
{
return $this->depth_limit;
}
/**
* Disables the depth limit and parses a variable.
*
* This should not be used unless you know what you're doing!
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
public function parseDeep(&$var, BasicObject $o)
{
$depth_limit = $this->depth_limit;
$this->depth_limit = false;
$out = $this->parse($var, $o);
$this->depth_limit = $depth_limit;
return $out;
}
/**
* Parses a variable into a Kint object structure.
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
public function parse(&$var, BasicObject $o)
{
$o->type = \strtolower(\gettype($var));
if (!$this->applyPlugins($var, $o, self::TRIGGER_BEGIN)) {
return $o;
}
switch ($o->type) {
case 'array':
return $this->parseArray($var, $o);
case 'boolean':
case 'double':
case 'integer':
case 'null':
return $this->parseGeneric($var, $o);
case 'object':
return $this->parseObject($var, $o);
case 'resource':
return $this->parseResource($var, $o);
case 'string':
return $this->parseString($var, $o);
default:
return $this->parseUnknown($var, $o);
}
}
public function addPlugin(Plugin $p)
{
if (!$types = $p->getTypes()) {
return false;
}
if (!$triggers = $p->getTriggers()) {
return false;
}
$p->setParser($this);
foreach ($types as $type) {
if (!isset($this->plugins[$type])) {
$this->plugins[$type] = array(
self::TRIGGER_BEGIN => array(),
self::TRIGGER_SUCCESS => array(),
self::TRIGGER_RECURSION => array(),
self::TRIGGER_DEPTH_LIMIT => array(),
);
}
foreach ($this->plugins[$type] as $trigger => &$pool) {
if ($triggers & $trigger) {
$pool[] = $p;
}
}
}
return true;
}
public function clearPlugins()
{
$this->plugins = array();
}
public function haltParse()
{
$this->parse_break = true;
}
public function childHasPath(InstanceObject $parent, BasicObject $child)
{
if ('object' === $parent->type && (null !== $parent->access_path || $child->static || $child->const)) {
if (BasicObject::ACCESS_PUBLIC === $child->access) {
return true;
}
if (BasicObject::ACCESS_PRIVATE === $child->access && $this->caller_class) {
if ($this->caller_class === $child->owner_class) {
return true;
}
} elseif (BasicObject::ACCESS_PROTECTED === $child->access && $this->caller_class) {
if ($this->caller_class === $child->owner_class) {
return true;
}
if (\is_subclass_of($this->caller_class, $child->owner_class)) {
return true;
}
if (\is_subclass_of($child->owner_class, $this->caller_class)) {
return true;
}
}
}
return false;
}
/**
* Returns an array without the recursion marker in it.
*
* DO NOT pass an array that has had it's marker removed back
* into the parser, it will result in an extra recursion
*
* @param array $array Array potentially containing a recursion marker
*
* @return array Array with recursion marker removed
*/
public function getCleanArray(array $array)
{
unset($array[$this->marker]);
return $array;
}
protected function noRecurseCall()
{
$bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
$caller_frame = array(
'function' => __FUNCTION__,
);
while (isset($bt[0]['object']) && $bt[0]['object'] === $this) {
$caller_frame = \array_shift($bt);
}
foreach ($bt as $frame) {
if (isset($frame['object']) && $frame['object'] === $this) {
throw new DomainException(__CLASS__.'::'.$caller_frame['function'].' cannot be called from inside a parse');
}
}
}
private function parseGeneric(&$var, BasicObject $o)
{
$rep = new Representation('Contents');
$rep->contents = $var;
$rep->implicit_label = true;
$o->addRepresentation($rep);
$o->value = $rep;
$this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
return $o;
}
/**
* Parses a string into a Kint BlobObject structure.
*
* @param string $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseString(&$var, BasicObject $o)
{
$string = new BlobObject();
$string->transplant($o);
$string->encoding = BlobObject::detectEncoding($var);
$string->size = BlobObject::strlen($var, $string->encoding);
$rep = new Representation('Contents');
$rep->contents = $var;
$rep->implicit_label = true;
$string->addRepresentation($rep);
$string->value = $rep;
$this->applyPlugins($var, $string, self::TRIGGER_SUCCESS);
return $string;
}
/**
* Parses an array into a Kint object structure.
*
* @param array $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseArray(array &$var, BasicObject $o)
{
$array = new BasicObject();
$array->transplant($o);
$array->size = \count($var);
if (isset($var[$this->marker])) {
--$array->size;
$array->hints[] = 'recursion';
$this->applyPlugins($var, $array, self::TRIGGER_RECURSION);
return $array;
}
$rep = new Representation('Contents');
$rep->implicit_label = true;
$array->addRepresentation($rep);
$array->value = $rep;
if (!$array->size) {
$this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
return $array;
}
if ($this->depth_limit && $o->depth >= $this->depth_limit) {
$array->hints[] = 'depth_limit';
$this->applyPlugins($var, $array, self::TRIGGER_DEPTH_LIMIT);
return $array;
}
$copy = \array_values($var);
// It's really really hard to access numeric string keys in arrays,
// and it's really really hard to access integer properties in
// objects, so we just use array_values and index by counter to get
// at it reliably for reference testing. This also affects access
// paths since it's pretty much impossible to access these things
// without complicated stuff you should never need to do.
$i = 0;
// Set the marker for recursion
$var[$this->marker] = $array->depth;
$refmarker = new stdClass();
foreach ($var as $key => &$val) {
if ($key === $this->marker) {
continue;
}
$child = new BasicObject();
$child->name = $key;
$child->depth = $array->depth + 1;
$child->access = BasicObject::ACCESS_NONE;
$child->operator = BasicObject::OPERATOR_ARRAY;
if (null !== $array->access_path) {
if (\is_string($key) && (string) (int) $key === $key) {
$child->access_path = 'array_values('.$array->access_path.')['.$i.']'; // @codeCoverageIgnore
} else {
$child->access_path = $array->access_path.'['.\var_export($key, true).']';
}
}
$stash = $val;
$copy[$i] = $refmarker;
if ($val === $refmarker) {
$child->reference = true;
$val = $stash;
}
$rep->contents[] = $this->parse($val, $child);
++$i;
}
$this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
unset($var[$this->marker]);
return $array;
}
/**
* Parses an object into a Kint InstanceObject structure.
*
* @param object $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseObject(&$var, BasicObject $o)
{
$hash = \spl_object_hash($var);
$values = (array) $var;
$object = new InstanceObject();
$object->transplant($o);
$object->classname = \get_class($var);
$object->hash = $hash;
$object->size = \count($values);
if (isset($this->object_hashes[$hash])) {
$object->hints[] = 'recursion';
$this->applyPlugins($var, $object, self::TRIGGER_RECURSION);
return $object;
}
$this->object_hashes[$hash] = $object;
if ($this->depth_limit && $o->depth >= $this->depth_limit) {
$object->hints[] = 'depth_limit';
$this->applyPlugins($var, $object, self::TRIGGER_DEPTH_LIMIT);
unset($this->object_hashes[$hash]);
return $object;
}
$reflector = new ReflectionObject($var);
if ($reflector->isUserDefined()) {
$object->filename = $reflector->getFileName();
$object->startline = $reflector->getStartLine();
}
$rep = new Representation('Properties');
$copy = \array_values($values);
$refmarker = new stdClass();
$i = 0;
// Reflection will not show parent classes private properties, and if a
// property was unset it will happly trigger a notice looking for it.
foreach ($values as $key => &$val) {
// Casting object to array:
// private properties show in the form "\0$owner_class_name\0$property_name";
// protected properties show in the form "\0*\0$property_name";
// public properties show in the form "$property_name";
// http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
$child = new BasicObject();
$child->depth = $object->depth + 1;
$child->owner_class = $object->classname;
$child->operator = BasicObject::OPERATOR_OBJECT;
$child->access = BasicObject::ACCESS_PUBLIC;
$split_key = \explode("\0", $key, 3);
if (3 === \count($split_key) && '' === $split_key[0]) {
$child->name = $split_key[2];
if ('*' === $split_key[1]) {
$child->access = BasicObject::ACCESS_PROTECTED;
} else {
$child->access = BasicObject::ACCESS_PRIVATE;
$child->owner_class = $split_key[1];
}
} elseif (KINT_PHP72) {
$child->name = (string) $key;
} else {
$child->name = $key; // @codeCoverageIgnore
}
if ($this->childHasPath($object, $child)) {
$child->access_path = $object->access_path;
if (!KINT_PHP72 && \is_int($child->name)) {
$child->access_path = 'array_values((array) '.$child->access_path.')['.$i.']'; // @codeCoverageIgnore
} elseif (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $child->name)) {
$child->access_path .= '->'.$child->name;
} else {
$child->access_path .= '->{'.\var_export((string) $child->name, true).'}';
}
}
$stash = $val;
$copy[$i] = $refmarker;
if ($val === $refmarker) {
$child->reference = true;
$val = $stash;
}
$rep->contents[] = $this->parse($val, $child);
++$i;
}
$object->addRepresentation($rep);
$object->value = $rep;
$this->applyPlugins($var, $object, self::TRIGGER_SUCCESS);
unset($this->object_hashes[$hash]);
return $object;
}
/**
* Parses a resource into a Kint ResourceObject structure.
*
* @param resource $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseResource(&$var, BasicObject $o)
{
$resource = new ResourceObject();
$resource->transplant($o);
$resource->resource_type = \get_resource_type($var);
$this->applyPlugins($var, $resource, self::TRIGGER_SUCCESS);
return $resource;
}
/**
* Parses an unknown into a Kint object structure.
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseUnknown(&$var, BasicObject $o)
{
$o->type = 'unknown';
$this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
return $o;
}
/**
* Applies plugins for an object type.
*
* @param mixed $var variable
* @param BasicObject $o Kint object parsed so far
* @param int $trigger The trigger to check for the plugins
*
* @return bool Continue parsing
*/
private function applyPlugins(&$var, BasicObject &$o, $trigger)
{
$break_stash = $this->parse_break;
/** @var bool Psalm bug workaround */
$this->parse_break = false;
$plugins = array();
if (isset($this->plugins[$o->type][$trigger])) {
$plugins = $this->plugins[$o->type][$trigger];
}
foreach ($plugins as $plugin) {
try {
$plugin->parse($var, $o, $trigger);
} catch (Exception $e) {
\trigger_error(
'An exception ('.\get_class($e).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing Kint Parser Plugin "'.\get_class($plugin).'". Error message: '.$e->getMessage(),
E_USER_WARNING
);
}
if ($this->parse_break) {
$this->parse_break = $break_stash;
return false;
}
}
$this->parse_break = $break_stash;
return true;
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
abstract class Plugin
{
protected $parser;
public function setParser(Parser $p)
{
$this->parser = $p;
}
/**
* An array of types (As returned by gettype) for all data this plugin can operate on.
*
* @return array List of types
*/
public function getTypes()
{
return array();
}
public function getTriggers()
{
return Parser::TRIGGER_NONE;
}
abstract public function parse(&$variable, BasicObject &$o, $trigger);
}

View File

@ -0,0 +1,66 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use InvalidArgumentException;
use Kint\Object\BasicObject;
class ProxyPlugin extends Plugin
{
protected $types;
protected $triggers;
protected $callback;
public function __construct(array $types, $triggers, $callback)
{
if (!\is_int($triggers)) {
throw new InvalidArgumentException('ProxyPlugin triggers must be an int bitmask');
}
if (!\is_callable($callback)) {
throw new InvalidArgumentException('ProxyPlugin callback must be callable');
}
$this->types = $types;
$this->triggers = $triggers;
$this->callback = $callback;
}
public function getTypes()
{
return $this->types;
}
public function getTriggers()
{
return $this->triggers;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
return \call_user_func_array($this->callback, array(&$var, &$o, $trigger, $this->parser));
}
}

View File

@ -0,0 +1,108 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class SerializePlugin extends Plugin
{
/**
* Disables automatic unserialization on arrays and objects.
*
* As the PHP manual notes:
*
* > Unserialization can result in code being loaded and executed due to
* > object instantiation and autoloading, and a malicious user may be able
* > to exploit this.
*
* The natural way to stop that from happening is to just refuse to unserialize
* stuff by default. Which is what we're doing for anything that's not scalar.
*
* @var bool
*/
public static $safe_mode = true;
public static $options = array(true);
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$trimmed = \rtrim($var);
if ('N;' !== $trimmed && !\preg_match('/^(?:[COabis]:\\d+[:;]|d:\\d+(?:\\.\\d+);)/', $trimmed)) {
return;
}
if (!self::$safe_mode || !\in_array($trimmed[0], array('C', 'O', 'a'), true)) {
// Second parameter only supported on PHP 7
if (KINT_PHP70) {
// Suppress warnings on unserializeable variable
$data = @\unserialize($trimmed, self::$options);
} else {
$data = @\unserialize($trimmed);
}
if (false === $data && 'b:0;' !== \substr($trimmed, 0, 4)) {
return;
}
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = 'unserialize('.$o->name.')';
if ($o->access_path) {
$base_obj->access_path = 'unserialize('.$o->access_path;
if (!KINT_PHP70 || self::$options === array(true)) {
$base_obj->access_path .= ')';
} elseif (self::$options === array(false)) {
$base_obj->access_path .= ', false)';
} else {
$base_obj->access_path .= ', Serialize::$options)';
}
}
$r = new Representation('Serialized');
if (isset($data)) {
$r->contents = $this->parser->parse($data, $base_obj);
} else {
$base_obj->hints[] = 'blacklist';
$r->contents = $base_obj;
}
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,154 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\Representation\Representation;
use SimpleXMLElement;
class SimpleXMLElementPlugin extends Plugin
{
/**
* Show all properties and methods.
*
* @var bool
*/
public static $verbose = false;
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SimpleXMLElement) {
return;
}
$o->hints[] = 'simplexml_element';
if (!self::$verbose) {
$o->removeRepresentation('properties');
$o->removeRepresentation('iterator');
$o->removeRepresentation('methods');
}
// Attributes
$a = new Representation('Attributes');
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = '(string) '.$o->access_path;
}
if ($attribs = $var->attributes()) {
$attribs = \iterator_to_array($attribs);
$attribs = \array_map('strval', $attribs);
} else {
$attribs = array();
}
// XML attributes are by definition strings and don't have children,
// so up the depth limit in case we're just below the limit since
// there won't be any recursive stuff anyway.
$a->contents = $this->parser->parseDeep($attribs, $base_obj)->value->contents;
$o->addRepresentation($a, 0);
// Children
// We need to check children() separately from the values we already parsed because
// text contents won't show up in children() but they will show up in properties.
//
// Why do we still need to check for attributes if we already have an attributes()
// method? Hell if I know!
$children = $var->children();
if ($o->value) {
$c = new Representation('Children');
foreach ($o->value->contents as $value) {
if ('@attributes' === $value->name) {
continue;
}
if (isset($children->{$value->name})) {
$i = 0;
while (isset($children->{$value->name}[$i])) {
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $value->name;
if ($value->access_path) {
$base_obj->access_path = $value->access_path.'['.$i.']';
}
$value = $this->parser->parse($children->{$value->name}[$i], $base_obj);
if ($value->access_path && 'string' === $value->type) {
$value->access_path = '(string) '.$value->access_path;
}
$c->contents[] = $value;
++$i;
}
}
}
$o->size = \count($c->contents);
if (!$o->size) {
$o->size = null;
if (\strlen((string) $var)) {
$base_obj = new BlobObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $o->name;
if ($o->access_path) {
$base_obj->access_path = '(string) '.$o->access_path;
}
$value = (string) $var;
$c = new Representation('Contents');
$c->implicit_label = true;
$c->contents = array($this->parser->parseDeep($value, $base_obj));
}
}
$o->addRepresentation($c, 0);
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SplFileInfoRepresentation;
use SplFileInfo;
use SplFileObject;
class SplFileInfoPlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SplFileInfo || $var instanceof SplFileObject) {
return;
}
$r = new SplFileInfoRepresentation(clone $var);
$o->addRepresentation($r, 0);
$o->size = $r->getSize();
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use SplObjectStorage;
class SplObjectStoragePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SplObjectStorage || !($r = $o->getRepresentation('iterator'))) {
return;
}
$r = $o->getRepresentation('iterator');
if ($r) {
$o->size = !\is_array($r->contents) ? null : \count($r->contents);
}
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use Kint\Object\ResourceObject;
use Kint\Object\StreamObject;
class StreamPlugin extends Plugin
{
public function getTypes()
{
return array('resource');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof ResourceObject || 'stream' !== $o->resource_type) {
return;
}
if (!$meta = \stream_get_meta_data($var)) {
return;
}
$rep = new Representation('Stream');
$rep->implicit_label = true;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'stream_get_meta_data('.$o->access_path.')';
}
$rep->contents = $this->parser->parse($meta, $base_obj);
if (!\in_array('depth_limit', $rep->contents->hints, true)) {
$rep->contents = $rep->contents->value->contents;
}
$o->addRepresentation($rep, 0);
$o->value = $rep;
$stream = new StreamObject($meta);
$stream->transplant($o);
$o = $stream;
}
}

View File

@ -0,0 +1,87 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class TablePlugin extends Plugin
{
public function getTypes()
{
return array('array');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (empty($o->value->contents)) {
return;
}
$array = $this->parser->getCleanArray($var);
if (\count($array) < 2) {
return;
}
// Ensure this is an array of arrays and that all child arrays have the
// same keys. We don't care about their children - if there's another
// "table" inside we'll just make another one down the value tab
$keys = null;
foreach ($array as $elem) {
if (!\is_array($elem) || \count($elem) < 2) {
return;
}
if (null === $keys) {
$keys = \array_keys($elem);
} elseif (\array_keys($elem) !== $keys) {
return;
}
}
// Ensure none of the child arrays are recursion or depth limit. We
// don't care if their children are since they are the table cells
foreach ($o->value->contents as $childarray) {
if (empty($childarray->value->contents)) {
return;
}
}
// Objects by reference for the win! We can do a copy-paste of the value
// representation contents and just slap a new hint on there and hey
// presto we have our table representation with no extra memory used!
$table = new Representation('Table');
$table->contents = $o->value->contents;
$table->hints[] = 'table';
$o->addRepresentation($table, 0);
}
}

View File

@ -0,0 +1,60 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SourceRepresentation;
use Kint\Object\ThrowableObject;
use Throwable;
class ThrowablePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Exception && (!KINT_PHP70 || !$var instanceof Throwable)) {
return;
}
$throw = new ThrowableObject($var);
$throw->transplant($o);
$r = new SourceRepresentation($var->getFile(), $var->getLine());
$r->showfilename = true;
$throw->addRepresentation($r, 0);
$o = $throw;
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
class TimestampPlugin extends Plugin
{
public static $blacklist = array(
2147483648,
2147483647,
1073741824,
1073741823,
);
public function getTypes()
{
return array('string', 'integer');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\is_string($var) && !\ctype_digit($var)) {
return;
}
if (\in_array($var, self::$blacklist, true)) {
return;
}
$len = \strlen($var);
// Guess for anything between March 1973 and November 2286
if (9 === $len || 10 === $len) {
// If it's an int or string that's this short it probably has no other meaning
// Additionally it's highly unlikely the shortValue will be clipped for length
// If you're writing a plugin that interferes with this, just put your
// parser plugin further down the list so that it gets loaded afterwards.
$o->value->label = 'Timestamp';
$o->value->hints[] = 'timestamp';
}
}
}

View File

@ -0,0 +1,67 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
class ToStringPlugin extends Plugin
{
public static $blacklist = array(
'SimpleXMLElement',
'SplFileObject',
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$reflection = new ReflectionClass($var);
if (!$reflection->hasMethod('__toString')) {
return;
}
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
return;
}
}
$r = new Representation('toString');
$r->contents = (string) $var;
$o->addRepresentation($r);
}
}

View File

@ -0,0 +1,92 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\TraceFrameObject;
use Kint\Object\TraceObject;
use Kint\Utils;
class TracePlugin extends Plugin
{
public static $blacklist = array('spl_autoload_call');
public function getTypes()
{
return array('array');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o->value) {
return;
}
$trace = $this->parser->getCleanArray($var);
if (\count($trace) !== \count($o->value->contents) || !Utils::isTrace($trace)) {
return;
}
$traceobj = new TraceObject();
$traceobj->transplant($o);
$rep = $traceobj->value;
$old_trace = $rep->contents;
Utils::normalizeAliases(self::$blacklist);
$rep->contents = array();
foreach ($old_trace as $frame) {
$index = $frame->name;
if (!isset($trace[$index]['function'])) {
// Something's very very wrong here, but it's probably a plugin's fault
continue;
}
if (Utils::traceFrameIsListed($trace[$index], self::$blacklist)) {
continue;
}
$rep->contents[$index] = new TraceFrameObject($frame, $trace[$index]);
}
\ksort($rep->contents);
$rep->contents = \array_values($rep->contents);
$traceobj->clearRepresentations();
$traceobj->addRepresentation($rep);
$traceobj->size = \count($rep->contents);
$o = $traceobj;
}
}

View File

@ -0,0 +1,150 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DOMDocument;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class XmlPlugin extends Plugin
{
/**
* Which method to parse the variable with.
*
* DOMDocument provides more information including the text between nodes,
* however it's memory usage is very high and it takes longer to parse and
* render. Plus it's a pain to work with. So SimpleXML is the default.
*
* @var string
*/
public static $parse_method = 'SimpleXML';
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if ('<?xml' !== \substr($var, 0, 5)) {
return;
}
if (!\method_exists(\get_class($this), 'xmlTo'.self::$parse_method)) {
return;
}
$xml = \call_user_func(array(\get_class($this), 'xmlTo'.self::$parse_method), $var, $o->access_path);
if (empty($xml)) {
return;
}
list($xml, $access_path, $name) = $xml;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $name;
$base_obj->access_path = $access_path;
$r = new Representation('XML');
$r->contents = $this->parser->parse($xml, $base_obj);
$o->addRepresentation($r, 0);
}
protected static function xmlToSimpleXML($var, $parent_path)
{
try {
$errors = \libxml_use_internal_errors(true);
$xml = \simplexml_load_string($var);
\libxml_use_internal_errors($errors);
} catch (Exception $e) {
if (isset($errors)) {
\libxml_use_internal_errors($errors);
}
return;
}
if (!$xml) {
return;
}
if (null === $parent_path) {
$access_path = null;
} else {
$access_path = 'simplexml_load_string('.$parent_path.')';
}
$name = $xml->getName();
return array($xml, $access_path, $name);
}
/**
* Get the DOMDocument info.
*
* The documentation of DOMDocument::loadXML() states that while you can
* call it statically, it will give an E_STRICT warning. On my system it
* actually gives an E_DEPRECATED warning, but it works so we'll just add
* an error-silencing '@' to the access path.
*
* If it errors loading then we wouldn't have gotten this far in the first place.
*
* @param string $var The XML string
* @param null|string $parent_path The path to the parent, in this case the XML string
*
* @return null|array The root element DOMNode, the access path, and the root element name
*/
protected static function xmlToDOMDocument($var, $parent_path)
{
// There's no way to check validity in DOMDocument without making errors. For shame!
if (!self::xmlToSimpleXML($var, $parent_path)) {
return null;
}
$xml = new DOMDocument();
$xml->loadXML($var);
$xml = $xml->firstChild;
if (null === $parent_path) {
$access_path = null;
} else {
$access_path = '@\\DOMDocument::loadXML('.$parent_path.')->firstChild';
}
$name = $xml->nodeName;
return array($xml, $access_path, $name);
}
}

View File

@ -0,0 +1,152 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer;
use Kint\Object\BasicObject;
class CliRenderer extends TextRenderer
{
/**
* @var bool enable colors when Kint is run in *UNIX* command line
*/
public static $cli_colors = true;
/**
* Forces utf8 output on windows.
*
* @var bool
*/
public static $force_utf8 = false;
/**
* Detects the terminal width on startup.
*
* @var bool
*/
public static $detect_width = true;
/**
* The minimum width to detect terminal size as.
*
* Less than this is ignored and falls back to default width.
*
* @var int
*/
public static $min_terminal_width = 40;
protected static $terminal_width = null;
protected $windows_output = false;
protected $colors = false;
public function __construct()
{
parent::__construct();
if (!self::$force_utf8) {
$this->windows_output = KINT_WIN;
}
if (!self::$terminal_width) {
if (!KINT_WIN && self::$detect_width) {
self::$terminal_width = \exec('tput cols');
}
if (self::$terminal_width < self::$min_terminal_width) {
self::$terminal_width = self::$default_width;
}
}
$this->colors = $this->windows_output ? false : self::$cli_colors;
$this->header_width = self::$terminal_width;
}
public function colorValue($string)
{
if (!$this->colors) {
return $string;
}
return "\x1b[32m".\str_replace("\n", "\x1b[0m\n\x1b[32m", $string)."\x1b[0m";
}
public function colorType($string)
{
if (!$this->colors) {
return $string;
}
return "\x1b[35;1m".\str_replace("\n", "\x1b[0m\n\x1b[35;1m", $string)."\x1b[0m";
}
public function colorTitle($string)
{
if (!$this->colors) {
return $string;
}
return "\x1b[36m".\str_replace("\n", "\x1b[0m\n\x1b[36m", $string)."\x1b[0m";
}
public function renderTitle(BasicObject $o)
{
if ($this->windows_output) {
return $this->utf8ToWindows(parent::renderTitle($o));
}
return parent::renderTitle($o);
}
public function preRender()
{
return PHP_EOL;
}
public function postRender()
{
if ($this->windows_output) {
return $this->utf8ToWindows(parent::postRender());
}
return parent::postRender();
}
public function escape($string, $encoding = false)
{
return \str_replace("\x1b", '\\x1b', $string);
}
protected function utf8ToWindows($string)
{
return \str_replace(
array('┌', '═', '┐', '│', '└', '─', '┘'),
array("\xda", "\xdc", "\xbf", "\xb3", "\xc0", "\xc4", "\xd9"),
$string
);
}
}

View File

@ -0,0 +1,237 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer;
use Kint\Kint;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
class PlainRenderer extends TextRenderer
{
public static $pre_render_sources = array(
'script' => array(
array('Kint\\Renderer\\PlainRenderer', 'renderJs'),
array('Kint\\Renderer\\Text\\MicrotimePlugin', 'renderJs'),
),
'style' => array(
array('Kint\\Renderer\\PlainRenderer', 'renderCss'),
),
'raw' => array(),
);
/**
* Path to the CSS file to load by default.
*
* @var string
*/
public static $theme = 'plain.css';
/**
* Output htmlentities instead of utf8.
*
* @var bool
*/
public static $disable_utf8 = false;
public static $needs_pre_render = true;
public static $always_pre_render = false;
protected $force_pre_render = false;
protected $pre_render;
public function __construct()
{
parent::__construct();
$this->pre_render = self::$needs_pre_render;
if (self::$always_pre_render) {
$this->setPreRender(true);
}
}
public function setCallInfo(array $info)
{
parent::setCallInfo($info);
if (\in_array('@', $this->call_info['modifiers'], true)) {
$this->setPreRender(true);
}
}
public function setStatics(array $statics)
{
parent::setStatics($statics);
if (!empty($statics['return'])) {
$this->setPreRender(true);
}
}
public function setPreRender($pre_render)
{
$this->pre_render = $pre_render;
$this->force_pre_render = true;
}
public function getPreRender()
{
return $this->pre_render;
}
public function colorValue($string)
{
return '<i>'.$string.'</i>';
}
public function colorType($string)
{
return '<b>'.$string.'</b>';
}
public function colorTitle($string)
{
return '<u>'.$string.'</u>';
}
public function renderTitle(BasicObject $o)
{
if (self::$disable_utf8) {
return $this->utf8ToHtmlentity(parent::renderTitle($o));
}
return parent::renderTitle($o);
}
public function preRender()
{
$output = '';
if ($this->pre_render) {
foreach (self::$pre_render_sources as $type => $values) {
$contents = '';
foreach ($values as $v) {
$contents .= \call_user_func($v, $this);
}
if (!\strlen($contents)) {
continue;
}
switch ($type) {
case 'script':
$output .= '<script class="kint-plain-script">'.$contents.'</script>';
break;
case 'style':
$output .= '<style class="kint-plain-style">'.$contents.'</style>';
break;
default:
$output .= $contents;
}
}
// Don't pre-render on every dump
if (!$this->force_pre_render) {
self::$needs_pre_render = false;
}
}
return $output.'<div class="kint-plain">';
}
public function postRender()
{
if (self::$disable_utf8) {
return $this->utf8ToHtmlentity(parent::postRender()).'</div>';
}
return parent::postRender().'</div>';
}
public function ideLink($file, $line)
{
$path = $this->escape(Kint::shortenPath($file)).':'.$line;
$ideLink = Kint::getIdeLink($file, $line);
if (!$ideLink) {
return $path;
}
$class = '';
if (\preg_match('/https?:\\/\\//i', $ideLink)) {
$class = 'class="kint-ide-link" ';
}
return '<a '.$class.'href="'.$this->escape($ideLink).'">'.$path.'</a>';
}
public function escape($string, $encoding = false)
{
if (false === $encoding) {
$encoding = BlobObject::detectEncoding($string);
}
$original_encoding = $encoding;
if (false === $encoding || 'ASCII' === $encoding) {
$encoding = 'UTF-8';
}
$string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding);
// this call converts all non-ASCII characters into numeirc htmlentities
if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) {
$string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding);
}
return $string;
}
protected function utf8ToHtmlentity($string)
{
return \str_replace(
array('┌', '═', '┐', '│', '└', '─', '┘'),
array('&#9484;', '&#9552;', '&#9488;', '&#9474;', '&#9492;', '&#9472;', '&#9496;'),
$string
);
}
protected static function renderJs()
{
return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/plain.js');
}
protected static function renderCss()
{
if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) {
return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme);
}
return \file_get_contents(self::$theme);
}
}

View File

@ -0,0 +1,185 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
abstract class Renderer
{
const SORT_NONE = 0;
const SORT_VISIBILITY = 1;
const SORT_FULL = 2;
protected $call_info = array();
protected $statics = array();
protected $show_trace = true;
abstract public function render(BasicObject $o);
abstract public function renderNothing();
public function setCallInfo(array $info)
{
if (!isset($info['params'])) {
$info['params'] = null;
}
if (!isset($info['modifiers']) || !\is_array($info['modifiers'])) {
$info['modifiers'] = array();
}
if (!isset($info['callee'])) {
$info['callee'] = null;
}
if (!isset($info['caller'])) {
$info['caller'] = null;
}
if (!isset($info['trace']) || !\is_array($info['trace'])) {
$info['trace'] = array();
}
$this->call_info = array(
'params' => $info['params'],
'modifiers' => $info['modifiers'],
'callee' => $info['callee'],
'caller' => $info['caller'],
'trace' => $info['trace'],
);
}
public function getCallInfo()
{
return $this->call_info;
}
public function setStatics(array $statics)
{
$this->statics = $statics;
$this->setShowTrace(!empty($statics['display_called_from']));
}
public function getStatics()
{
return $this->statics;
}
public function setShowTrace($show_trace)
{
$this->show_trace = $show_trace;
}
public function getShowTrace()
{
return $this->show_trace;
}
/**
* Returns the first compatible plugin available.
*
* @param array $plugins Array of hints to class strings
* @param array $hints Array of object hints
*
* @return array Array of hints to class strings filtered and sorted by object hints
*/
public function matchPlugins(array $plugins, array $hints)
{
$out = array();
foreach ($hints as $key) {
if (isset($plugins[$key])) {
$out[$key] = $plugins[$key];
}
}
return $out;
}
public function filterParserPlugins(array $plugins)
{
return $plugins;
}
public function preRender()
{
return '';
}
public function postRender()
{
return '';
}
public static function sortPropertiesFull(BasicObject $a, BasicObject $b)
{
$sort = BasicObject::sortByAccess($a, $b);
if ($sort) {
return $sort;
}
$sort = BasicObject::sortByName($a, $b);
if ($sort) {
return $sort;
}
return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class);
}
/**
* Sorts an array of BasicObject.
*
* @param BasicObject[] $contents Object properties to sort
* @param int $sort
*
* @return BasicObject[]
*/
public static function sortProperties(array $contents, $sort)
{
switch ($sort) {
case self::SORT_VISIBILITY:
/** @var array<array-key, BasicObject[]> Containers to quickly stable sort by type */
$containers = array(
BasicObject::ACCESS_PUBLIC => array(),
BasicObject::ACCESS_PROTECTED => array(),
BasicObject::ACCESS_PRIVATE => array(),
BasicObject::ACCESS_NONE => array(),
);
foreach ($contents as $item) {
$containers[$item->access][] = $item;
}
return \call_user_func_array('array_merge', $containers);
case self::SORT_FULL:
\usort($contents, array('Kint\\Renderer\\Renderer', 'sortPropertiesFull'));
// no break
default:
return $contents;
}
}
}

View File

@ -0,0 +1,51 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\Representation\Representation;
class BinaryPlugin extends Plugin implements TabPluginInterface
{
public static $line_length = 0x10;
public static $chunk_length = 0x4;
public function renderTab(Representation $r)
{
$out = '<pre>';
$chunks = \str_split($r->contents, self::$line_length);
foreach ($chunks as $index => $chunk) {
$out .= \sprintf('%08X', $index * self::$line_length).":\t";
$out .= \implode(' ', \str_split(\str_pad(\bin2hex($chunk), 2 * self::$line_length, ' '), self::$chunk_length));
$out .= "\t".\preg_replace('/[^\\x20-\\x7E]/', '.', $chunk)."\n";
}
$out .= '</pre>';
return $out;
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
class BlacklistPlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
return '<dl>'.$this->renderLockedHeader($o, '<var>Blacklisted</var>').'</dl>';
}
}

View File

@ -0,0 +1,174 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\ClosureObject;
use Kint\Object\MethodObject;
use Kint\Renderer\RichRenderer;
class CallablePlugin extends Plugin implements ObjectPluginInterface
{
protected static $method_cache = array();
public function renderObject(BasicObject $o)
{
if ($o instanceof MethodObject) {
return $this->renderMethod($o);
}
if ($o instanceof ClosureObject) {
return $this->renderClosure($o);
}
return $this->renderCallable($o);
}
protected function renderClosure(ClosureObject $o)
{
$children = $this->renderer->renderChildren($o);
$header = '';
if (null !== ($s = $o->getModifiers())) {
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$header .= '<dfn>'.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')</dfn>';
}
if (null !== ($s = $o->getValueShort())) {
if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
$s = \substr($s, 0, RichRenderer::$strlen_max).'...';
}
$header .= ' '.$this->renderer->escape($s);
}
return '<dl>'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'</dl>';
}
protected function renderCallable(BasicObject $o)
{
$children = $this->renderer->renderChildren($o);
$header = '';
if (null !== ($s = $o->getModifiers())) {
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$header .= '<dfn>'.$this->renderer->escape($s).'</dfn>';
}
if (null !== ($s = $o->getValueShort())) {
if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
$s = \substr($s, 0, RichRenderer::$strlen_max).'...';
}
$header .= ' '.$this->renderer->escape($s);
}
return '<dl>'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'</dl>';
}
protected function renderMethod(MethodObject $o)
{
if (!empty(self::$method_cache[$o->owner_class][$o->name])) {
$children = self::$method_cache[$o->owner_class][$o->name]['children'];
$header = $this->renderer->renderHeaderWrapper(
$o,
(bool) \strlen($children),
self::$method_cache[$o->owner_class][$o->name]['header']
);
return '<dl>'.$header.$children.'</dl>';
}
$children = $this->renderer->renderChildren($o);
$header = '';
if (null !== ($s = $o->getModifiers()) || $o->return_reference) {
$header .= '<var>'.$s;
if ($o->return_reference) {
if ($s) {
$header .= ' ';
}
$header .= $this->renderer->escape('&');
}
$header .= '</var> ';
}
if (null !== ($s = $o->getName())) {
$function = $this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')';
if (null !== ($url = $o->getPhpDocUrl())) {
$function = '<a href="'.$url.'" target=_blank>'.$function.'</a>';
}
$header .= '<dfn>'.$function.'</dfn>';
}
if (!empty($o->returntype)) {
$header .= ': <var>';
if ($o->return_reference) {
$header .= $this->renderer->escape('&');
}
$header .= $this->renderer->escape($o->returntype).'</var>';
} elseif ($o->docstring) {
if (\preg_match('/@return\\s+(.*)\\r?\\n/m', $o->docstring, $matches)) {
if (\trim($matches[1])) {
$header .= ': <var>'.$this->renderer->escape(\trim($matches[1])).'</var>';
}
}
}
if (null !== ($s = $o->getValueShort())) {
if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
$s = \substr($s, 0, RichRenderer::$strlen_max).'...';
}
$header .= ' '.$this->renderer->escape($s);
}
if (\strlen($o->owner_class) && \strlen($o->name)) {
self::$method_cache[$o->owner_class][$o->name] = array(
'header' => $header,
'children' => $children,
);
}
$header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
return '<dl>'.$header.$children.'</dl>';
}
}

View File

@ -0,0 +1,59 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Kint;
use Kint\Object\BasicObject;
use Kint\Object\ClosureObject;
class ClosurePlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
$children = $this->renderer->renderChildren($o);
if (!($o instanceof ClosureObject)) {
$header = $this->renderer->renderHeader($o);
} else {
$header = '';
if (null !== ($s = $o->getModifiers())) {
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$header .= '<dfn>'.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')</dfn> ';
}
$header .= '<var>Closure</var> ';
$header .= $this->renderer->escape(Kint::shortenPath($o->filename)).':'.(int) $o->startline;
}
$header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
return '<dl>'.$header.$children.'</dl>';
}
}

View File

@ -0,0 +1,100 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
use Kint\Object\Representation\ColorRepresentation;
use Kint\Object\Representation\Representation;
class ColorPlugin extends Plugin implements TabPluginInterface, ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
$r = $o->getRepresentation('color');
if (!$r instanceof ColorRepresentation) {
return;
}
$children = $this->renderer->renderChildren($o);
$header = $this->renderer->renderHeader($o);
$header .= '<div class="kint-color-preview"><div style="background:';
$header .= $r->getColor(ColorRepresentation::COLOR_RGBA);
$header .= '"></div></div>';
$header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
return '<dl>'.$header.$children.'</dl>';
}
public function renderTab(Representation $r)
{
if (!$r instanceof ColorRepresentation) {
return;
}
$out = '';
if ($color = $r->getColor(ColorRepresentation::COLOR_NAME)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_3)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_6)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($r->hasAlpha()) {
if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_4)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_8)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_RGBA)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_HSLA)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
} else {
if ($color = $r->getColor(ColorRepresentation::COLOR_RGB)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
if ($color = $r->getColor(ColorRepresentation::COLOR_HSL)) {
$out .= '<dfn>'.$color."</dfn>\n";
}
}
if (!\strlen($out)) {
return false;
}
return '<pre>'.$out.'</pre>';
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
class DepthLimitPlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
return '<dl>'.$this->renderLockedHeader($o, '<var>Depth Limit</var>').'</dl>';
}
}

View File

@ -0,0 +1,70 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Kint;
use Kint\Object\Representation\DocstringRepresentation;
use Kint\Object\Representation\Representation;
class DocstringPlugin extends Plugin implements TabPluginInterface
{
public function renderTab(Representation $r)
{
if (!($r instanceof DocstringRepresentation)) {
return false;
}
$docstring = array();
foreach (\explode("\n", $r->contents) as $line) {
$docstring[] = \trim($line);
}
$docstring = \implode("\n", $docstring);
$location = array();
if ($r->class) {
$location[] = 'Inherited from '.$this->renderer->escape($r->class);
}
if ($r->file && $r->line) {
$location[] = 'Defined in '.$this->renderer->escape(Kint::shortenPath($r->file)).':'.((int) $r->line);
}
$location = \implode("\n", $location);
if ($location) {
if (\strlen($docstring)) {
$docstring .= "\n\n";
}
$location = '<small>'.$location.'</small>';
} elseif (0 === \strlen($docstring)) {
return '';
}
return '<pre>'.$this->renderer->escape($docstring).$location.'</pre>';
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\Representation\MicrotimeRepresentation;
use Kint\Object\Representation\Representation;
use Kint\Utils;
class MicrotimePlugin extends Plugin implements TabPluginInterface
{
public function renderTab(Representation $r)
{
if (!($r instanceof MicrotimeRepresentation)) {
return false;
}
$out = $r->getDateTime()->format('Y-m-d H:i:s.u');
if (null !== $r->lap) {
$out .= '<br><b>SINCE LAST CALL:</b> <span class="kint-microtime-lap">'.\round($r->lap, 4).'</span>s.';
}
if (null !== $r->total) {
$out .= '<br><b>SINCE START:</b> '.\round($r->total, 4).'s.';
}
if (null !== $r->avg) {
$out .= '<br><b>AVERAGE DURATION:</b> <span class="kint-microtime-avg">'.\round($r->avg, 4).'</span>s.';
}
$bytes = Utils::getHumanReadableBytes($r->mem);
$out .= '<br><b>MEMORY USAGE:</b> '.$r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$bytes = Utils::getHumanReadableBytes($r->mem_real);
$out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$bytes = Utils::getHumanReadableBytes($r->mem_peak);
$out .= '<br><b>PEAK MEMORY USAGE:</b> '.$r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$bytes = Utils::getHumanReadableBytes($r->mem_peak_real);
$out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')';
return '<pre data-kint-microtime-group="'.$r->group.'">'.$out.'</pre>';
}
public static function renderJs()
{
return \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js');
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
interface ObjectPluginInterface extends PluginInterface
{
public function renderObject(BasicObject $o);
}

View File

@ -0,0 +1,90 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
use Kint\Renderer\RichRenderer;
abstract class Plugin implements PluginInterface
{
protected $renderer;
public function __construct(RichRenderer $r)
{
$this->renderer = $r;
}
/**
* Renders a locked header.
*
* @param BasicObject $o
* @param string $content
*/
public function renderLockedHeader(BasicObject $o, $content)
{
$header = '<dt class="kint-parent kint-locked">';
if (RichRenderer::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) {
$header .= '<span class="kint-access-path-trigger" title="Show access path">&rlarr;</span>';
}
$header .= '<span class="kint-popup-trigger" title="Open in new window">&boxbox;</span><nav></nav>';
if (null !== ($s = $o->getModifiers())) {
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$header .= '<dfn>'.$this->renderer->escape($s).'</dfn> ';
if ($s = $o->getOperator()) {
$header .= $this->renderer->escape($s, 'ASCII').' ';
}
}
if (null !== ($s = $o->getType())) {
$s = $this->renderer->escape($s);
if ($o->reference) {
$s = '&amp;'.$s;
}
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getSize())) {
$header .= '('.$this->renderer->escape($s).') ';
}
$header .= $content;
if (!empty($ap)) {
$header .= '<div class="access-path">'.$this->renderer->escape($ap).'</div>';
}
return $header.'</dt>';
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Renderer\RichRenderer;
interface PluginInterface
{
public function __construct(RichRenderer $r);
}

View File

@ -0,0 +1,36 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
class RecursionPlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
return '<dl>'.$this->renderLockedHeader($o, '<var>Recursion</var>').'</dl>';
}
}

View File

@ -0,0 +1,81 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Renderer\RichRenderer;
class SimpleXMLElementPlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
$children = $this->renderer->renderChildren($o);
$header = '';
if (null !== ($s = $o->getModifiers())) {
$header .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$header .= '<dfn>'.$this->renderer->escape($s).'</dfn> ';
if ($s = $o->getOperator()) {
$header .= $this->renderer->escape($s, 'ASCII').' ';
}
}
if (null !== ($s = $o->getType())) {
$s = $this->renderer->escape($s);
if ($o->reference) {
$s = '&amp;'.$s;
}
$header .= '<var>'.$this->renderer->escape($s).'</var> ';
}
if (null !== ($s = $o->getSize())) {
$header .= '('.$this->renderer->escape($s).') ';
}
if (null === $s && $c = $o->getRepresentation('contents')) {
$c = \reset($c->contents);
if ($c && null !== ($s = $c->getValueShort())) {
if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
$s = \substr($s, 0, RichRenderer::$strlen_max).'...';
}
$header .= $this->renderer->escape($s);
}
}
$header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
return '<dl>'.$header.$children.'</dl>';
}
}

View File

@ -0,0 +1,79 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\Representation\Representation;
use Kint\Object\Representation\SourceRepresentation;
class SourcePlugin extends Plugin implements TabPluginInterface
{
public function renderTab(Representation $r)
{
if (!($r instanceof SourceRepresentation) || empty($r->source)) {
return false;
}
$source = $r->source;
// Trim empty lines from the start and end of the source
foreach ($source as $linenum => $line) {
if (\strlen(\trim($line)) || $linenum === $r->line) {
break;
}
unset($source[$linenum]);
}
foreach (\array_reverse($source, true) as $linenum => $line) {
if (\strlen(\trim($line)) || $linenum === $r->line) {
break;
}
unset($source[$linenum]);
}
$output = '';
foreach ($source as $linenum => $line) {
if ($linenum === $r->line) {
$output .= '<div class="kint-highlight">'.$this->renderer->escape($line)."\n".'</div>';
} else {
$output .= '<div>'.$this->renderer->escape($line)."\n".'</div>';
}
}
if ($output) {
\reset($source);
$data = '';
if ($r->showfilename) {
$data = ' data-kint-filename="'.$this->renderer->escape($r->filename).'"';
}
return '<div><pre class="kint-source"'.$data.' style="counter-reset: kint-l '.((int) \key($source) - 1).';">'.$output.'</pre></div><div></div>';
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\Representation\Representation;
interface TabPluginInterface extends PluginInterface
{
public function renderTab(Representation $o);
}

View File

@ -0,0 +1,133 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BlobObject;
use Kint\Object\Representation\Representation;
use Kint\Renderer\RichRenderer;
class TablePlugin extends Plugin implements TabPluginInterface
{
public static $respect_str_length = true;
public function renderTab(Representation $r)
{
$out = '<pre><table><thead><tr><th></th>';
$firstrow = \reset($r->contents);
foreach ($firstrow->value->contents as $field) {
$out .= '<th>'.$this->renderer->escape($field->name).'</th>';
}
$out .= '</tr></thead><tbody>';
foreach ($r->contents as $row) {
$out .= '<tr><th>';
$out .= $this->renderer->escape($row->name);
$out .= '</th>';
foreach ($row->value->contents as $field) {
$out .= '<td';
$type = '';
$size = '';
$ref = '';
if (null !== ($s = $field->getType())) {
$type = $this->renderer->escape($s);
if ($field->reference) {
$ref = '&amp;';
$type = $ref.$type;
}
if (null !== ($s = $field->getSize())) {
$size .= ' ('.$this->renderer->escape($s).')';
}
}
if ($type) {
$out .= ' title="'.$type.$size.'"';
}
$out .= '>';
switch ($field->type) {
case 'boolean':
$out .= $field->value->contents ? '<var>'.$ref.'true</var>' : '<var>'.$ref.'false</var>';
break;
case 'integer':
case 'double':
$out .= (string) $field->value->contents;
break;
case 'null':
$out .= '<var>'.$ref.'null</var>';
break;
case 'string':
if ($field->encoding) {
$val = $field->value->contents;
if (RichRenderer::$strlen_max && self::$respect_str_length && BlobObject::strlen($val) > RichRenderer::$strlen_max) {
$val = \substr($val, 0, RichRenderer::$strlen_max).'...';
}
$out .= $this->renderer->escape($val);
} else {
$out .= '<var>'.$type.'</var>';
}
break;
case 'array':
$out .= '<var>'.$ref.'array</var>'.$size;
break;
case 'object':
$out .= '<var>'.$ref.$this->renderer->escape($field->classname).'</var>'.$size;
break;
case 'resource':
$out .= '<var>'.$ref.'resource</var>';
break;
default:
$out .= '<var>'.$ref.'unknown</var>';
break;
}
if (\in_array('blacklist', $field->hints, true)) {
$out .= ' <var>Blacklisted</var>';
} elseif (\in_array('recursion', $field->hints, true)) {
$out .= ' <var>Recursion</var>';
} elseif (\in_array('depth_limit', $field->hints, true)) {
$out .= ' <var>Depth Limit</var>';
}
$out .= '</td>';
}
$out .= '</tr>';
}
$out .= '</tbody></table></pre>';
return $out;
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use DateTime;
use DateTimeZone;
use Kint\Object\Representation\Representation;
class TimestampPlugin extends Plugin implements TabPluginInterface
{
public function renderTab(Representation $r)
{
$dt = DateTime::createFromFormat('U', $r->contents);
if ($dt) {
return '<pre>'.$dt->setTimeZone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s T').'</pre>';
}
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Rich;
use Kint\Object\BasicObject;
use Kint\Object\TraceFrameObject;
class TraceFramePlugin extends Plugin implements ObjectPluginInterface
{
public function renderObject(BasicObject $o)
{
if (!$o instanceof TraceFrameObject) {
return;
}
if (!empty($o->trace['file']) && !empty($o->trace['line'])) {
$header = '<var>'.$this->renderer->ideLink($o->trace['file'], (int) $o->trace['line']).'</var> ';
} else {
$header = '<var>PHP internal call</var> ';
}
if ($o->trace['class']) {
$header .= $this->renderer->escape($o->trace['class'].$o->trace['type']);
}
if (\is_string($o->trace['function'])) {
$function = $this->renderer->escape($o->trace['function'].'()');
} else {
$function = $this->renderer->escape(
$o->trace['function']->getName().'('.$o->trace['function']->getParams().')'
);
if (null !== ($url = $o->trace['function']->getPhpDocUrl())) {
$function = '<a href="'.$url.'" target=_blank>'.$function.'</a>';
}
}
$header .= '<dfn>'.$function.'</dfn>';
$children = $this->renderer->renderChildren($o);
$header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
return '<dl>'.$header.$children.'</dl>';
}
}

View File

@ -0,0 +1,612 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer;
use Kint\Kint;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
use Kint\Utils;
class RichRenderer extends Renderer
{
/**
* RichRenderer object plugins should implement Kint\Renderer\Rich\ObjectPluginInterface.
*/
public static $object_plugins = array(
'blacklist' => 'Kint\\Renderer\\Rich\\BlacklistPlugin',
'callable' => 'Kint\\Renderer\\Rich\\CallablePlugin',
'closure' => 'Kint\\Renderer\\Rich\\ClosurePlugin',
'color' => 'Kint\\Renderer\\Rich\\ColorPlugin',
'depth_limit' => 'Kint\\Renderer\\Rich\\DepthLimitPlugin',
'recursion' => 'Kint\\Renderer\\Rich\\RecursionPlugin',
'simplexml_element' => 'Kint\\Renderer\\Rich\\SimpleXMLElementPlugin',
'trace_frame' => 'Kint\\Renderer\\Rich\\TraceFramePlugin',
);
/**
* RichRenderer tab plugins should implement Kint\Renderer\Rich\TabPluginInterface.
*/
public static $tab_plugins = array(
'binary' => 'Kint\\Renderer\\Rich\\BinaryPlugin',
'color' => 'Kint\\Renderer\\Rich\\ColorPlugin',
'docstring' => 'Kint\\Renderer\\Rich\\DocstringPlugin',
'microtime' => 'Kint\\Renderer\\Rich\\MicrotimePlugin',
'source' => 'Kint\\Renderer\\Rich\\SourcePlugin',
'table' => 'Kint\\Renderer\\Rich\\TablePlugin',
'timestamp' => 'Kint\\Renderer\\Rich\\TimestampPlugin',
);
public static $pre_render_sources = array(
'script' => array(
array('Kint\\Renderer\\RichRenderer', 'renderJs'),
array('Kint\\Renderer\\Rich\\MicrotimePlugin', 'renderJs'),
),
'style' => array(
array('Kint\\Renderer\\RichRenderer', 'renderCss'),
),
'raw' => array(),
);
/**
* Whether or not to render access paths.
*
* Access paths can become incredibly heavy with very deep and wide
* structures. Given mostly public variables it will typically make
* up one quarter of the output HTML size.
*
* If this is an unacceptably large amount and your browser is groaning
* under the weight of the access paths - your first order of buisiness
* should be to get a new browser. Failing that, use this to turn them off.
*
* @var bool
*/
public static $access_paths = true;
/**
* The maximum length of a string before it is truncated.
*
* Falsey to disable
*
* @var int
*/
public static $strlen_max = 80;
/**
* Path to the CSS file to load by default.
*
* @var string
*/
public static $theme = 'original.css';
/**
* Assume types and sizes don't need to be escaped.
*
* Turn this off if you use anything but ascii in your class names,
* but it'll cause a slowdown of around 10%
*
* @var bool
*/
public static $escape_types = false;
/**
* Move all dumps to a folder at the bottom of the body.
*
* @var bool
*/
public static $folder = true;
/**
* Sort mode for object properties.
*
* @var int
*/
public static $sort = self::SORT_NONE;
public static $needs_pre_render = true;
public static $needs_folder_render = true;
public static $always_pre_render = false;
protected $plugin_objs = array();
protected $expand = false;
protected $force_pre_render = false;
protected $pre_render;
protected $use_folder;
public function __construct()
{
$this->pre_render = self::$needs_pre_render;
$this->use_folder = self::$folder;
if (self::$always_pre_render) {
$this->setForcePreRender();
}
}
public function setCallInfo(array $info)
{
parent::setCallInfo($info);
if (\in_array('!', $this->call_info['modifiers'], true)) {
$this->setExpand(true);
$this->use_folder = false;
}
if (\in_array('@', $this->call_info['modifiers'], true)) {
$this->setForcePreRender();
}
}
public function setStatics(array $statics)
{
parent::setStatics($statics);
if (!empty($statics['expanded'])) {
$this->setExpand(true);
}
if (!empty($statics['return'])) {
$this->setForcePreRender();
}
}
public function setExpand($expand)
{
$this->expand = $expand;
}
public function getExpand()
{
return $this->expand;
}
public function setForcePreRender()
{
$this->force_pre_render = true;
$this->pre_render = true;
}
public function setPreRender($pre_render)
{
$this->setForcePreRender(); // TODO: Remove line in next major version
$this->pre_render = $pre_render;
}
public function getPreRender()
{
return $this->pre_render;
}
public function setUseFolder($use_folder)
{
$this->use_folder = $use_folder;
}
public function getUseFolder()
{
return $this->use_folder;
}
public function render(BasicObject $o)
{
if ($plugin = $this->getPlugin(self::$object_plugins, $o->hints)) {
if (\strlen($output = $plugin->renderObject($o))) {
return $output;
}
}
$children = $this->renderChildren($o);
$header = $this->renderHeaderWrapper($o, (bool) \strlen($children), $this->renderHeader($o));
return '<dl>'.$header.$children.'</dl>';
}
public function renderNothing()
{
return '<dl><dt><var>No argument</var></dt></dl>';
}
public function renderHeaderWrapper(BasicObject $o, $has_children, $contents)
{
$out = '<dt';
if ($has_children) {
$out .= ' class="kint-parent';
if ($this->expand) {
$out .= ' kint-show';
}
$out .= '"';
}
$out .= '>';
if (self::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) {
$out .= '<span class="kint-access-path-trigger" title="Show access path">&rlarr;</span>';
}
if ($has_children) {
$out .= '<span class="kint-popup-trigger" title="Open in new window">&boxbox;</span>';
if (0 === $o->depth) {
$out .= '<span class="kint-search-trigger" title="Show search box">&telrec;</span>';
$out .= '<input type="text" class="kint-search" value="">';
}
$out .= '<nav></nav>';
}
$out .= $contents;
if (!empty($ap)) {
$out .= '<div class="access-path">'.$this->escape($ap).'</div>';
}
return $out.'</dt>';
}
public function renderHeader(BasicObject $o)
{
$output = '';
if (null !== ($s = $o->getModifiers())) {
$output .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getName())) {
$output .= '<dfn>'.$this->escape($s).'</dfn> ';
if ($s = $o->getOperator()) {
$output .= $this->escape($s, 'ASCII').' ';
}
}
if (null !== ($s = $o->getType())) {
if (self::$escape_types) {
$s = $this->escape($s);
}
if ($o->reference) {
$s = '&amp;'.$s;
}
$output .= '<var>'.$s.'</var> ';
}
if (null !== ($s = $o->getSize())) {
if (self::$escape_types) {
$s = $this->escape($s);
}
$output .= '('.$s.') ';
}
if (null !== ($s = $o->getValueShort())) {
$s = \preg_replace('/\\s+/', ' ', $s);
if (self::$strlen_max) {
$s = Utils::truncateString($s, self::$strlen_max);
}
$output .= $this->escape($s);
}
return \trim($output);
}
public function renderChildren(BasicObject $o)
{
$contents = array();
$tabs = array();
foreach ($o->getRepresentations() as $rep) {
$result = $this->renderTab($o, $rep);
if (\strlen($result)) {
$contents[] = $result;
$tabs[] = $rep;
}
}
if (empty($tabs)) {
return '';
}
$output = '<dd>';
if (1 === \count($tabs) && $tabs[0]->labelIsImplicit()) {
$output .= \reset($contents);
} else {
$output .= '<ul class="kint-tabs">';
foreach ($tabs as $i => $tab) {
if (0 === $i) {
$output .= '<li class="kint-active-tab">';
} else {
$output .= '<li>';
}
$output .= $this->escape($tab->getLabel()).'</li>';
}
$output .= '</ul><ul>';
foreach ($contents as $tab) {
$output .= '<li>'.$tab.'</li>';
}
$output .= '</ul>';
}
return $output.'</dd>';
}
public function preRender()
{
$output = '';
if ($this->pre_render) {
foreach (self::$pre_render_sources as $type => $values) {
$contents = '';
foreach ($values as $v) {
$contents .= \call_user_func($v, $this);
}
if (!\strlen($contents)) {
continue;
}
switch ($type) {
case 'script':
$output .= '<script class="kint-rich-script">'.$contents.'</script>';
break;
case 'style':
$output .= '<style class="kint-rich-style">'.$contents.'</style>';
break;
default:
$output .= $contents;
}
}
// Don't pre-render on every dump
if (!$this->force_pre_render) {
self::$needs_pre_render = false;
}
}
$output .= '<div class="kint-rich';
if ($this->use_folder) {
$output .= ' kint-file';
if (self::$needs_folder_render || $this->force_pre_render) {
$output = $this->renderFolder().$output;
if (!$this->force_pre_render) {
self::$needs_folder_render = false;
}
}
}
$output .= '">';
return $output;
}
public function postRender()
{
if (!$this->show_trace) {
return '</div>';
}
$output = '<footer>';
$output .= '<span class="kint-popup-trigger" title="Open in new window">&boxbox;</span> ';
if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) {
$output .= '<nav></nav>';
}
if (isset($this->call_info['callee']['file'])) {
$output .= 'Called from '.$this->ideLink(
$this->call_info['callee']['file'],
$this->call_info['callee']['line']
);
}
if (isset($this->call_info['callee']['function']) && (
!empty($this->call_info['callee']['class']) ||
!\in_array(
$this->call_info['callee']['function'],
array('include', 'include_once', 'require', 'require_once'),
true
)
)
) {
$output .= ' [';
if (isset($this->call_info['callee']['class'])) {
$output .= $this->call_info['callee']['class'];
}
if (isset($this->call_info['callee']['type'])) {
$output .= $this->call_info['callee']['type'];
}
$output .= $this->call_info['callee']['function'].'()]';
}
if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) {
$output .= '<ol>';
foreach ($this->call_info['trace'] as $index => $step) {
if (!$index) {
continue;
}
$output .= '<li>'.$this->ideLink($step['file'], $step['line']); // closing tag not required
if (isset($step['function'])
&& !\in_array($step['function'], array('include', 'include_once', 'require', 'require_once'), true)
) {
$output .= ' [';
if (isset($step['class'])) {
$output .= $step['class'];
}
if (isset($step['type'])) {
$output .= $step['type'];
}
$output .= $step['function'].'()]';
}
}
$output .= '</ol>';
}
$output .= '</footer></div>';
return $output;
}
public function escape($string, $encoding = false)
{
if (false === $encoding) {
$encoding = BlobObject::detectEncoding($string);
}
$original_encoding = $encoding;
if (false === $encoding || 'ASCII' === $encoding) {
$encoding = 'UTF-8';
}
$string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding);
// this call converts all non-ASCII characters into numeirc htmlentities
if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) {
$string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding);
}
return $string;
}
public function ideLink($file, $line)
{
$path = $this->escape(Kint::shortenPath($file)).':'.$line;
$ideLink = Kint::getIdeLink($file, $line);
if (!$ideLink) {
return $path;
}
$class = '';
if (\preg_match('/https?:\\/\\//i', $ideLink)) {
$class = 'class="kint-ide-link" ';
}
return '<a '.$class.'href="'.$this->escape($ideLink).'">'.$path.'</a>';
}
protected function renderTab(BasicObject $o, Representation $rep)
{
if ($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) {
if (\strlen($output = $plugin->renderTab($rep))) {
return $output;
}
}
if (\is_array($rep->contents)) {
$output = '';
if ($o instanceof InstanceObject && 'properties' === $rep->getName()) {
foreach (self::sortProperties($rep->contents, self::$sort) as $obj) {
$output .= $this->render($obj);
}
} else {
foreach ($rep->contents as $obj) {
$output .= $this->render($obj);
}
}
return $output;
}
if (\is_string($rep->contents)) {
$show_contents = false;
// If it is the value representation of a string and its whitespace
// was truncated in the header, always display the full string
if ('string' !== $o->type || $o->value !== $rep) {
$show_contents = true;
} else {
if (\preg_match('/(:?[\\r\\n\\t\\f\\v]| {2})/', $rep->contents)) {
$show_contents = true;
} elseif (self::$strlen_max && BlobObject::strlen($o->getValueShort()) > self::$strlen_max) {
$show_contents = true;
}
if (empty($o->encoding)) {
$show_contents = false;
}
}
if ($show_contents) {
return '<pre>'.$this->escape($rep->contents)."\n</pre>";
}
}
if ($rep->contents instanceof BasicObject) {
return $this->render($rep->contents);
}
}
protected function getPlugin(array $plugins, array $hints)
{
if ($plugins = $this->matchPlugins($plugins, $hints)) {
$plugin = \end($plugins);
if (!isset($this->plugin_objs[$plugin])) {
$this->plugin_objs[$plugin] = new $plugin($this);
}
return $this->plugin_objs[$plugin];
}
}
protected static function renderJs()
{
return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/rich.js');
}
protected static function renderCss()
{
if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) {
return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme);
}
return \file_get_contents(self::$theme);
}
protected static function renderFolder()
{
return '<div class="kint-rich kint-folder"><dl><dt class="kint-parent"><nav></nav>Kint</dt><dd class="kint-folder"></dd></dl></div>';
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
class BlacklistPlugin extends Plugin
{
public function render(BasicObject $o)
{
$out = '';
if (0 == $o->depth) {
$out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('BLACKLISTED').PHP_EOL;
return $out;
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
class DepthLimitPlugin extends Plugin
{
public function render(BasicObject $o)
{
$out = '';
if (0 == $o->depth) {
$out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('DEPTH LIMIT').PHP_EOL;
return $out;
}
}

View File

@ -0,0 +1,128 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
use Kint\Object\Representation\MicrotimeRepresentation;
use Kint\Renderer\PlainRenderer;
use Kint\Renderer\Rich\MicrotimePlugin as RichPlugin;
use Kint\Renderer\TextRenderer;
use Kint\Utils;
class MicrotimePlugin extends Plugin
{
protected $useJs = false;
public function __construct(TextRenderer $r)
{
parent::__construct($r);
if ($this->renderer instanceof PlainRenderer) {
$this->useJs = true;
}
}
public function render(BasicObject $o)
{
$r = $o->getRepresentation('microtime');
if (!$r instanceof MicrotimeRepresentation) {
return false;
}
$out = '';
if (0 == $o->depth) {
$out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderer->renderHeader($o);
$out .= $this->renderer->renderChildren($o).PHP_EOL;
$indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width);
if ($this->useJs) {
$out .= '<span data-kint-microtime-group="'.$r->group.'">';
}
$out .= $indent.$this->renderer->colorType('TIME:').' ';
$out .= $this->renderer->colorValue($r->getDateTime()->format('Y-m-d H:i:s.u')).PHP_EOL;
if (null !== $r->lap) {
$out .= $indent.$this->renderer->colorType('SINCE LAST CALL:').' ';
$lap = \round($r->lap, 4);
if ($this->useJs) {
$lap = '<span class="kint-microtime-lap">'.$lap.'</span>';
}
$out .= $this->renderer->colorValue($lap.'s').'.'.PHP_EOL;
}
if (null !== $r->total) {
$out .= $indent.$this->renderer->colorType('SINCE START:').' ';
$out .= $this->renderer->colorValue(\round($r->total, 4).'s').'.'.PHP_EOL;
}
if (null !== $r->avg) {
$out .= $indent.$this->renderer->colorType('AVERAGE DURATION:').' ';
$avg = \round($r->avg, 4);
if ($this->useJs) {
$avg = '<span class="kint-microtime-avg">'.$avg.'</span>';
}
$out .= $this->renderer->colorValue($avg.'s').'.'.PHP_EOL;
}
$bytes = Utils::getHumanReadableBytes($r->mem);
$mem = $r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$bytes = Utils::getHumanReadableBytes($r->mem_real);
$mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$out .= $indent.$this->renderer->colorType('MEMORY USAGE:').' ';
$out .= $this->renderer->colorValue($mem).'.'.PHP_EOL;
$bytes = Utils::getHumanReadableBytes($r->mem_peak);
$mem = $r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$bytes = Utils::getHumanReadableBytes($r->mem_peak_real);
$mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')';
$out .= $indent.$this->renderer->colorType('PEAK MEMORY USAGE:').' ';
$out .= $this->renderer->colorValue($mem).'.'.PHP_EOL;
if ($this->useJs) {
$out .= '</span>';
}
return $out;
}
public static function renderJs()
{
return RichPlugin::renderJs();
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
use Kint\Renderer\TextRenderer;
abstract class Plugin
{
protected $renderer;
public function __construct(TextRenderer $r)
{
$this->renderer = $r;
}
abstract public function render(BasicObject $o);
}

View File

@ -0,0 +1,44 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
class RecursionPlugin extends Plugin
{
public function render(BasicObject $o)
{
$out = '';
if (0 == $o->depth) {
$out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('RECURSION').PHP_EOL;
return $out;
}
}

View File

@ -0,0 +1,111 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer\Text;
use Kint\Object\BasicObject;
use Kint\Object\MethodObject;
class TracePlugin extends Plugin
{
public function render(BasicObject $o)
{
$out = '';
if (0 == $o->depth) {
$out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderer->renderHeader($o).':'.PHP_EOL;
$indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width);
$i = 1;
foreach ($o->value->contents as $frame) {
$framedesc = $indent.\str_pad($i.': ', 4, ' ');
if ($frame->trace['file']) {
$framedesc .= $this->renderer->ideLink($frame->trace['file'], $frame->trace['line']).PHP_EOL;
} else {
$framedesc .= 'PHP internal call'.PHP_EOL;
}
$framedesc .= $indent.' ';
if ($frame->trace['class']) {
$framedesc .= $this->renderer->escape($frame->trace['class']);
if ($frame->trace['object']) {
$framedesc .= $this->renderer->escape('->');
} else {
$framedesc .= '::';
}
}
if (\is_string($frame->trace['function'])) {
$framedesc .= $this->renderer->escape($frame->trace['function']).'(...)';
} elseif ($frame->trace['function'] instanceof MethodObject) {
$framedesc .= $this->renderer->escape($frame->trace['function']->getName());
$framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')';
}
$out .= $this->renderer->colorType($framedesc).PHP_EOL.PHP_EOL;
if ($source = $frame->getRepresentation('source')) {
$line_wanted = $source->line;
$source = $source->source;
// Trim empty lines from the start and end of the source
foreach ($source as $linenum => $line) {
if (\trim($line) || $linenum === $line_wanted) {
break;
}
unset($source[$linenum]);
}
foreach (\array_reverse($source, true) as $linenum => $line) {
if (\trim($line) || $linenum === $line_wanted) {
break;
}
unset($source[$linenum]);
}
foreach ($source as $lineno => $line) {
if ($lineno == $line_wanted) {
$out .= $indent.$this->renderer->colorValue($this->renderer->escape($line)).PHP_EOL;
} else {
$out .= $indent.$this->renderer->escape($line).PHP_EOL;
}
}
}
++$i;
}
return $out;
}
}

View File

@ -0,0 +1,346 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Renderer;
use Kint\Kint;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Utils;
class TextRenderer extends Renderer
{
/**
* TextRenderer plugins should be instances of Kint\Renderer\Text\Plugin.
*/
public static $plugins = array(
'blacklist' => 'Kint\\Renderer\\Text\\BlacklistPlugin',
'depth_limit' => 'Kint\\Renderer\\Text\\DepthLimitPlugin',
'microtime' => 'Kint\\Renderer\\Text\\MicrotimePlugin',
'recursion' => 'Kint\\Renderer\\Text\\RecursionPlugin',
'trace' => 'Kint\\Renderer\\Text\\TracePlugin',
);
/**
* Parser plugins must be instanceof one of these or
* it will be removed for performance reasons.
*/
public static $parser_plugin_whitelist = array(
'Kint\\Parser\\BlacklistPlugin',
'Kint\\Parser\\MicrotimePlugin',
'Kint\\Parser\\StreamPlugin',
'Kint\\Parser\\TracePlugin',
);
/**
* The maximum length of a string before it is truncated.
*
* Falsey to disable
*
* @var int
*/
public static $strlen_max = 0;
/**
* The default width of the terminal for headers.
*
* @var int
*/
public static $default_width = 80;
/**
* Indentation width.
*
* @var int
*/
public static $default_indent = 4;
/**
* Decorate the header and footer.
*
* @var bool
*/
public static $decorations = true;
/**
* Sort mode for object properties.
*
* @var int
*/
public static $sort = self::SORT_NONE;
public $header_width = 80;
public $indent_width = 4;
protected $plugin_objs = array();
public function __construct()
{
$this->header_width = self::$default_width;
$this->indent_width = self::$default_indent;
}
public function render(BasicObject $o)
{
if ($plugin = $this->getPlugin(self::$plugins, $o->hints)) {
if (\strlen($output = $plugin->render($o))) {
return $output;
}
}
$out = '';
if (0 == $o->depth) {
$out .= $this->colorTitle($this->renderTitle($o)).PHP_EOL;
}
$out .= $this->renderHeader($o);
$out .= $this->renderChildren($o).PHP_EOL;
return $out;
}
public function renderNothing()
{
if (self::$decorations) {
return $this->colorTitle(
$this->boxText('No argument', $this->header_width)
).PHP_EOL;
}
return $this->colorTitle('No argument').PHP_EOL;
}
public function boxText($text, $width)
{
$out = '┌'.\str_repeat('─', $width - 2).'┐'.PHP_EOL;
if (\strlen($text)) {
$text = Utils::truncateString($text, $width - 4);
$text = \str_pad($text, $width - 4);
$out .= '│ '.$this->escape($text).' │'.PHP_EOL;
}
$out .= '└'.\str_repeat('─', $width - 2).'┘';
return $out;
}
public function renderTitle(BasicObject $o)
{
$name = (string) $o->getName();
if (self::$decorations) {
return $this->boxText($name, $this->header_width);
}
return Utils::truncateString($name, $this->header_width);
}
public function renderHeader(BasicObject $o)
{
$output = array();
if ($o->depth) {
if (null !== ($s = $o->getModifiers())) {
$output[] = $s;
}
if (null !== $o->name) {
$output[] = $this->escape(\var_export($o->name, true));
if (null !== ($s = $o->getOperator())) {
$output[] = $this->escape($s);
}
}
}
if (null !== ($s = $o->getType())) {
if ($o->reference) {
$s = '&'.$s;
}
$output[] = $this->colorType($this->escape($s));
}
if (null !== ($s = $o->getSize())) {
$output[] = '('.$this->escape($s).')';
}
if (null !== ($s = $o->getValueShort())) {
if (self::$strlen_max) {
$s = Utils::truncateString($s, self::$strlen_max);
}
$output[] = $this->colorValue($this->escape($s));
}
return \str_repeat(' ', $o->depth * $this->indent_width).\implode(' ', $output);
}
public function renderChildren(BasicObject $o)
{
if ('array' === $o->type) {
$output = ' [';
} elseif ('object' === $o->type) {
$output = ' (';
} else {
return '';
}
$children = '';
if ($o->value && \is_array($o->value->contents)) {
if ($o instanceof InstanceObject && 'properties' === $o->value->getName()) {
foreach (self::sortProperties($o->value->contents, self::$sort) as $obj) {
$children .= $this->render($obj);
}
} else {
foreach ($o->value->contents as $child) {
$children .= $this->render($child);
}
}
}
if ($children) {
$output .= PHP_EOL.$children;
$output .= \str_repeat(' ', $o->depth * $this->indent_width);
}
if ('array' === $o->type) {
$output .= ']';
} else {
$output .= ')';
}
return $output;
}
public function colorValue($string)
{
return $string;
}
public function colorType($string)
{
return $string;
}
public function colorTitle($string)
{
return $string;
}
public function postRender()
{
if (self::$decorations) {
$output = \str_repeat('═', $this->header_width);
} else {
$output = '';
}
if (!$this->show_trace) {
return $this->colorTitle($output);
}
if ($output) {
$output .= PHP_EOL;
}
return $this->colorTitle($output.$this->calledFrom().PHP_EOL);
}
public function filterParserPlugins(array $plugins)
{
$return = array();
foreach ($plugins as $index => $plugin) {
foreach (self::$parser_plugin_whitelist as $whitelist) {
if ($plugin instanceof $whitelist) {
$return[] = $plugin;
continue 2;
}
}
}
return $return;
}
public function ideLink($file, $line)
{
return $this->escape(Kint::shortenPath($file)).':'.$line;
}
public function escape($string, $encoding = false)
{
return $string;
}
protected function calledFrom()
{
$output = '';
if (isset($this->call_info['callee']['file'])) {
$output .= 'Called from '.$this->ideLink(
$this->call_info['callee']['file'],
$this->call_info['callee']['line']
);
}
if (isset($this->call_info['callee']['function']) && (
!empty($this->call_info['callee']['class']) ||
!\in_array(
$this->call_info['callee']['function'],
array('include', 'include_once', 'require', 'require_once'),
true
)
)
) {
$output .= ' [';
if (isset($this->call_info['callee']['class'])) {
$output .= $this->call_info['callee']['class'];
}
if (isset($this->call_info['callee']['type'])) {
$output .= $this->call_info['callee']['type'];
}
$output .= $this->call_info['callee']['function'].'()]';
}
return $output;
}
protected function getPlugin(array $plugins, array $hints)
{
if ($plugins = $this->matchPlugins($plugins, $hints)) {
$plugin = \end($plugins);
if (!isset($this->plugin_objs[$plugin])) {
$this->plugin_objs[$plugin] = new $plugin($this);
}
return $this->plugin_objs[$plugin];
}
}
}

240
vendor/kint-php/kint/src/Utils.php vendored Normal file
View File

@ -0,0 +1,240 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint;
use InvalidArgumentException;
use Kint\Object\BlobObject;
use ReflectionNamedType;
use ReflectionType;
/**
* A collection of utility methods. Should all be static methods with no dependencies.
*/
final class Utils
{
/**
* @codeCoverageIgnore
*/
private function __construct()
{
}
/**
* Turns a byte value into a human-readable representation.
*
* @param int $value Amount of bytes
*
* @return array Human readable value and unit
*/
public static function getHumanReadableBytes($value)
{
static $unit = array('B', 'KB', 'MB', 'GB', 'TB');
$i = \floor(\log($value, 1024));
$i = \min($i, 4); // Only go up to TB
return array(
'value' => (float) ($value / \pow(1024, $i)),
'unit' => $unit[$i],
);
}
public static function isSequential(array $array)
{
return \array_keys($array) === \range(0, \count($array) - 1);
}
public static function composerGetExtras($key = 'kint')
{
$extras = array();
if (0 === \strpos(KINT_DIR, 'phar://')) {
// Only run inside phar file, so skip for code coverage
return $extras; // @codeCoverageIgnore
}
$folder = KINT_DIR.'/vendor';
for ($i = 0; $i < 4; ++$i) {
$installed = $folder.'/composer/installed.json';
if (\file_exists($installed) && \is_readable($installed)) {
$packages = \json_decode(\file_get_contents($installed), true);
foreach ($packages as $package) {
if (isset($package['extra'][$key]) && \is_array($package['extra'][$key])) {
$extras = \array_replace($extras, $package['extra'][$key]);
}
}
$folder = \dirname($folder);
if (\file_exists($folder.'/composer.json') && \is_readable($folder.'/composer.json')) {
$composer = \json_decode(\file_get_contents($folder.'/composer.json'), true);
if (isset($composer['extra'][$key]) && \is_array($composer['extra'][$key])) {
$extras = \array_replace($extras, $composer['extra'][$key]);
}
}
break;
}
$folder = \dirname($folder);
}
return $extras;
}
/**
* @codeCoverageIgnore
*/
public static function composerSkipFlags()
{
$extras = self::composerGetExtras();
if (!empty($extras['disable-facade']) && !\defined('KINT_SKIP_FACADE')) {
\define('KINT_SKIP_FACADE', true);
}
if (!empty($extras['disable-helpers']) && !\defined('KINT_SKIP_HELPERS')) {
\define('KINT_SKIP_HELPERS', true);
}
}
public static function isTrace(array $trace)
{
if (!self::isSequential($trace)) {
return false;
}
static $bt_structure = array(
'function' => 'string',
'line' => 'integer',
'file' => 'string',
'class' => 'string',
'object' => 'object',
'type' => 'string',
'args' => 'array',
);
$file_found = false;
foreach ($trace as $frame) {
if (!\is_array($frame) || !isset($frame['function'])) {
return false;
}
foreach ($frame as $key => $val) {
if (!isset($bt_structure[$key])) {
return false;
}
if (\gettype($val) !== $bt_structure[$key]) {
return false;
}
if ('file' === $key) {
$file_found = true;
}
}
}
return $file_found;
}
public static function traceFrameIsListed(array $frame, array $matches)
{
if (isset($frame['class'])) {
$called = array(\strtolower($frame['class']), \strtolower($frame['function']));
} else {
$called = \strtolower($frame['function']);
}
return \in_array($called, $matches, true);
}
public static function normalizeAliases(array &$aliases)
{
static $name_regex = '[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*';
foreach ($aliases as $index => &$alias) {
if (\is_array($alias) && 2 === \count($alias)) {
$alias = \array_values(\array_filter($alias, 'is_string'));
if (2 === \count($alias) &&
\preg_match('/^'.$name_regex.'$/', $alias[1]) &&
\preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias[0])
) {
$alias = array(
\strtolower(\ltrim($alias[0], '\\')),
\strtolower($alias[1]),
);
} else {
unset($aliases[$index]);
continue;
}
} elseif (\is_string($alias)) {
if (\preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias)) {
$alias = \explode('\\', \strtolower($alias));
$alias = \end($alias);
} else {
unset($aliases[$index]);
continue;
}
} else {
unset($aliases[$index]);
}
}
$aliases = \array_values($aliases);
}
public static function truncateString($input, $length = PHP_INT_MAX, $end = '...', $encoding = false)
{
$length = (int) $length;
$endlength = BlobObject::strlen($end);
if ($endlength >= $length) {
throw new InvalidArgumentException('Can\'t truncate a string to '.$length.' characters if ending with string '.$endlength.' characters long');
}
if (BlobObject::strlen($input, $encoding) > $length) {
return BlobObject::substr($input, 0, $length - $endlength, $encoding).$end;
}
return $input;
}
public static function getTypeString(ReflectionType $type)
{
if ($type instanceof ReflectionNamedType) {
return $type->getName();
}
return (string) $type; // @codeCoverageIgnore
}
}