--- /dev/null
+<?php
+/**
+ * Kint is a zero-setup debugging tool to output information about variables and stack traces prettily and comfortably.
+ *
+ * https://github.com/raveren/kint
+ */
+
+
+if ( defined( 'KINT_DIR' ) ) return;
+
+
+define( 'KINT_DIR', dirname( __FILE__ ) . '/' );
+define( 'KINT_PHP53', version_compare( PHP_VERSION, '5.3.0' ) >= 0 );
+
+require KINT_DIR . 'config.default.php';
+require KINT_DIR . 'inc/kintVariableData.class.php';
+require KINT_DIR . 'inc/kintParser.class.php';
+require KINT_DIR . 'inc/kintObject.class.php';
+require KINT_DIR . 'decorators/rich.php';
+require KINT_DIR . 'decorators/plain.php';
+
+if ( is_readable( KINT_DIR . 'config.php' ) ) {
+ require KINT_DIR . 'config.php';
+}
+
+# init settings
+if ( !empty( $GLOBALS['_kint_settings'] ) ) {
+ Kint::enabled( $GLOBALS['_kint_settings']['enabled'] );
+
+ foreach ( $GLOBALS['_kint_settings'] as $key => $val ) {
+ property_exists( 'Kint', $key ) and Kint::$$key = $val;
+ }
+
+ unset( $GLOBALS['_kint_settings'], $key, $val );
+}
+
+class Kint
+{
+ // these are all public and 1:1 config array keys so you can switch them easily
+ private static $_enabledMode; # stores mode and active statuses
+
+ public static $returnOutput;
+ public static $fileLinkFormat;
+ public static $displayCalledFrom;
+ public static $charEncodings;
+ public static $maxStrLength;
+ public static $appRootDirs;
+ public static $maxLevels;
+ public static $theme;
+ public static $expandedByDefault;
+
+ public static $cliDetection;
+ public static $cliColors;
+
+ const MODE_RICH = 'r';
+ const MODE_WHITESPACE = 'w';
+ const MODE_CLI = 'c';
+ const MODE_PLAIN = 'p';
+
+
+ public static $aliases = array(
+ 'methods' => array(
+ array( 'kint', 'dump' ),
+ array( 'kint', 'trace' ),
+ ),
+ 'functions' => array(
+ 'd',
+ 'dd',
+ 'ddd',
+ 's',
+ 'sd',
+ )
+ );
+
+ private static $_firstRun = true;
+
+ /**
+ * Enables or disables Kint, can globally enforce the rendering mode. If called without parameters, returns the
+ * current mode.
+ *
+ * @param mixed $forceMode
+ * null or void - return current mode
+ * false - disable (no output)
+ * true - enable and detect cli automatically
+ * Kint::MODE_* - enable and force selected mode disregarding detection and function
+ * shorthand (s()/d()), note that you can still override this
+ * with the "~" modifier
+ *
+ * @return mixed previously set value if a new one is passed
+ */
+ public static function enabled( $forceMode = null )
+ {
+ # act both as a setter...
+ if ( isset( $forceMode ) ) {
+ $before = self::$_enabledMode;
+ self::$_enabledMode = $forceMode;
+
+ return $before;
+ }
+
+ # ...and a getter
+ return self::$_enabledMode;
+ }
+
+ /**
+ * Prints a debug backtrace, same as Kint::dump(1)
+ *
+ * @param array $trace [OPTIONAL] you can pass your own trace, otherwise, `debug_backtrace` will be called
+ *
+ * @return mixed
+ */
+ public static function trace( $trace = null )
+ {
+ if ( !self::enabled() ) return '';
+
+ return self::dump( isset( $trace ) ? $trace : debug_backtrace( true ) );
+ }
+
+
+ /**
+ * Dump information about variables, accepts any number of parameters, supports modifiers:
+ *
+ * clean up any output before kint and place the dump at the top of page:
+ * - Kint::dump()
+ * *****
+ * expand all nodes on display:
+ * ! Kint::dump()
+ * *****
+ * dump variables disregarding their depth:
+ * + Kint::dump()
+ * *****
+ * return output instead of displaying it:
+ * @ Kint::dump()
+ * *****
+ * force output as plain text
+ * ~ Kint::dump()
+ *
+ * Modifiers are supported by all dump wrapper functions, including Kint::trace(). Space is optional.
+ *
+ *
+ * You can also use the following shorthand to display debug_backtrace():
+ * Kint::dump( 1 );
+ *
+ * Passing the result from debug_backtrace() to kint::dump() as a single parameter will display it as trace too:
+ * $trace = debug_backtrace( true );
+ * Kint::dump( $trace );
+ * Or simply:
+ * Kint::dump( debug_backtrace() );
+ *
+ *
+ * @param mixed $data
+ *
+ * @return void|string
+ */
+ public static function dump( $data = null )
+ {
+ if ( !self::enabled() ) return '';
+
+ list( $names, $modifiers, $callee, $previousCaller, $miniTrace ) = self::_getCalleeInfo(
+ defined( 'DEBUG_BACKTRACE_IGNORE_ARGS' )
+ ? debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS )
+ : debug_backtrace()
+ );
+ $modeOldValue = self::enabled();
+ $firstRunOldValue = self::$_firstRun;
+
+ # process modifiers: @, +, !, ~ and -
+ if ( strpos( $modifiers, '-' ) !== false ) {
+ self::$_firstRun = true;
+ while ( ob_get_level() ) {
+ ob_end_clean();
+ }
+ }
+ if ( strpos( $modifiers, '!' ) !== false ) {
+ $expandedByDefaultOldValue = self::$expandedByDefault;
+ self::$expandedByDefault = true;
+ }
+ if ( strpos( $modifiers, '+' ) !== false ) {
+ $maxLevelsOldValue = self::$maxLevels;
+ self::$maxLevels = false;
+ }
+ if ( strpos( $modifiers, '@' ) !== false ) {
+ $returnOldValue = self::$returnOutput;
+ self::$returnOutput = true;
+ self::$_firstRun = true;
+ }
+ if ( strpos( $modifiers, '~' ) !== false ) {
+ self::enabled( self::MODE_WHITESPACE );
+ }
+
+ # set mode for current run
+ $mode = self::enabled();
+ if ( $mode === true ) {
+ $mode = PHP_SAPI === 'cli'
+ ? self::MODE_CLI
+ : self::MODE_RICH;
+ }
+ self::enabled( $mode );
+
+ $decorator = self::enabled() === self::MODE_RICH
+ ? 'Kint_Decorators_Rich'
+ : 'Kint_Decorators_Plain';
+
+ $output = '';
+ if ( self::$_firstRun ) {
+ $output .= call_user_func( array( $decorator, 'init' ) );
+ }
+
+
+ $trace = false;
+ if ( $names === array( null ) && func_num_args() === 1 && $data === 1 ) { # Kint::dump(1) shorthand
+ $trace = KINT_PHP53 ? debug_backtrace( true ) : debug_backtrace();
+ } elseif ( func_num_args() === 1 && is_array( $data ) ) {
+ $trace = $data; # test if the single parameter is result of debug_backtrace()
+ }
+ $trace and $trace = self::_parseTrace( $trace );
+
+
+ $output .= call_user_func( array( $decorator, 'wrapStart' ) );
+ if ( $trace ) {
+ $output .= call_user_func( array( $decorator, 'decorateTrace' ), $trace );
+ } else {
+ $data = func_num_args() === 0
+ ? array( "[[no arguments passed]]" )
+ : func_get_args();
+
+ foreach ( $data as $k => $argument ) {
+ kintParser::reset();
+ # when the dump arguments take long to generate output, user might have changed the file and
+ # Kint might not parse the arguments correctly, so check if names are set and while the
+ # displayed names might be wrong, at least don't throw an error
+ $output .= call_user_func(
+ array( $decorator, 'decorate' ),
+ kintParser::factory( $argument, isset( $names[ $k ] ) ? $names[ $k ] : '' )
+ );
+ }
+ }
+
+ $output .= call_user_func( array( $decorator, 'wrapEnd' ), $callee, $miniTrace, $previousCaller );
+
+ self::enabled( $modeOldValue );
+
+ self::$_firstRun = false;
+ if ( strpos( $modifiers, '~' ) !== false ) {
+ self::$_firstRun = $firstRunOldValue;
+ } else {
+ self::enabled( $modeOldValue );
+ }
+ if ( strpos( $modifiers, '!' ) !== false ) {
+ self::$expandedByDefault = $expandedByDefaultOldValue;
+ }
+ if ( strpos( $modifiers, '+' ) !== false ) {
+ self::$maxLevels = $maxLevelsOldValue;
+ }
+ if ( strpos( $modifiers, '@' ) !== false ) {
+ self::$returnOutput = $returnOldValue;
+ self::$_firstRun = $firstRunOldValue;
+ return $output;
+ }
+
+ if ( self::$returnOutput ) return $output;
+
+ echo $output;
+ return '';
+ }
+
+
+ /**
+ * generic path display callback, can be configured in the settings; 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 = str_replace( '\\', '/', $file );
+ $shortenedName = $file;
+ $replaced = false;
+ if ( is_array( self::$appRootDirs ) ) foreach ( self::$appRootDirs as $path => $replaceString ) {
+ if ( empty( $path ) ) continue;
+
+ $path = str_replace( '\\', '/', $path );
+
+ if ( strpos( $file, $path ) === 0 ) {
+ $shortenedName = $replaceString . substr( $file, strlen( $path ) );
+ $replaced = true;
+ break;
+ }
+ }
+
+ # fallback to find common path with Kint dir
+ if ( !$replaced ) {
+ $pathParts = explode( '/', str_replace( '\\', '/', KINT_DIR ) );
+ $fileParts = explode( '/', $file );
+ $i = 0;
+ foreach ( $fileParts as $i => $filePart ) {
+ if ( !isset( $pathParts[ $i ] ) || $pathParts[ $i ] !== $filePart ) break;
+ }
+
+ $shortenedName = ( $i ? '.../' : '' ) . implode( '/', array_slice( $fileParts, $i ) );
+ }
+
+ return $shortenedName;
+ }
+
+ public static function getIdeLink( $file, $line )
+ {
+ return str_replace( array( '%f', '%l' ), array( $file, $line ), self::$fileLinkFormat );
+ }
+
+ /**
+ * trace helper, shows the place in code inline
+ *
+ * @param string $file full path to file
+ * @param int $lineNumber the line to display
+ * @param int $padding surrounding lines to show besides the main one
+ *
+ * @return bool|string
+ */
+ private static function _showSource( $file, $lineNumber, $padding = 7 )
+ {
+ if ( !$file OR !is_readable( $file ) ) {
+ # continuing will cause errors
+ return false;
+ }
+
+ # open the file and set the line position
+ $file = fopen( $file, 'r' );
+ $line = 0;
+
+ # Set the reading range
+ $range = array(
+ 'start' => $lineNumber - $padding,
+ 'end' => $lineNumber + $padding
+ );
+
+ # set the zero-padding amount for line numbers
+ $format = '% ' . strlen( $range['end'] ) . 'd';
+
+ $source = '';
+ while ( ( $row = fgets( $file ) ) !== false ) {
+ # increment the line number
+ if ( ++$line > $range['end'] ) {
+ break;
+ }
+
+ if ( $line >= $range['start'] ) {
+ # make the row safe for output
+ $row = htmlspecialchars( $row, ENT_NOQUOTES, 'UTF-8' );
+
+ # trim whitespace and sanitize the row
+ $row = '<span>' . sprintf( $format, $line ) . '</span> ' . $row;
+
+ if ( $line === $lineNumber ) {
+ # apply highlighting to this row
+ $row = '<div class="kint-highlight">' . $row . '</div>';
+ } else {
+ $row = '<div>' . $row . '</div>';
+ }
+
+ # add to the captured source
+ $source .= $row;
+ }
+ }
+
+ # close the file
+ fclose( $file );
+
+ return $source;
+ }
+
+
+ /**
+ * returns parameter names that the function was passed, as well as any predefined symbols before function
+ * call (modifiers)
+ *
+ * @param array $trace
+ *
+ * @return array( $parameters, $modifier, $callee, $previousCaller )
+ */
+ private static function _getCalleeInfo( $trace )
+ {
+ $previousCaller = array();
+ $miniTrace = array();
+ $prevStep = array();
+
+ # go from back of trace to find first occurrence of call to Kint or its wrappers
+ while ( $step = array_pop( $trace ) ) {
+
+ if ( self::_stepIsInternal( $step ) ) {
+ $previousCaller = $prevStep;
+ break;
+ } elseif ( isset( $step['file'], $step['line'] ) ) {
+ unset( $step['object'], $step['args'] );
+ array_unshift( $miniTrace, $step );
+ }
+
+ $prevStep = $step;
+ }
+ $callee = $step;
+
+ if ( !isset( $callee['file'] ) || !is_readable( $callee['file'] ) ) return false;
+
+
+ # open the file and read it up to the position where the function call expression ended
+ $file = fopen( $callee['file'], 'r' );
+ $line = 0;
+ $source = '';
+ while ( ( $row = fgets( $file ) ) !== false ) {
+ if ( ++$line > $callee['line'] ) break;
+ $source .= $row;
+ }
+ fclose( $file );
+ $source = self::_removeAllButCode( $source );
+
+
+ if ( empty( $callee['class'] ) ) {
+ $codePattern = $callee['function'];
+ } else {
+ if ( $callee['type'] === '::' ) {
+ $codePattern = $callee['class'] . "\x07*" . $callee['type'] . "\x07*" . $callee['function'];;
+ } else /*if ( $callee['type'] === '->' )*/ {
+ $codePattern = ".*\x07*" . $callee['type'] . "\x07*" . $callee['function'];;
+ }
+ }
+
+ // todo if more than one call in one line - not possible to determine variable names
+ // todo does not recognize string concat
+ # get the position of the last call to the function
+ preg_match_all( "
+ [
+ # beginning of statement
+ [\x07{(]
+
+ # search for modifiers (group 1)
+ ([-+!@~]*)?
+
+ # spaces
+ \x07*
+
+ # check if output is assigned to a variable (group 2) todo: does not detect concat
+ (
+ \\$[a-z0-9_]+ # variable
+ \x07*\\.?=\x07* # assignment
+ )?
+
+ # possibly a namespace symbol
+ \\\\?
+
+ # spaces again
+ \x07*
+
+ # main call to Kint
+ {$codePattern}
+
+ # spaces everywhere
+ \x07*
+
+ # find the character where kint's opening bracket resides (group 3)
+ (\\()
+
+ ]ix",
+ $source,
+ $matches,
+ PREG_OFFSET_CAPTURE
+ );
+
+ $modifiers = end( $matches[1] );
+ $assignment = end( $matches[2] );
+ $bracket = end( $matches[3] );
+
+ $modifiers = $modifiers[0];
+ if ( $assignment[1] !== -1 ) {
+ $modifiers .= '@';
+ }
+
+ $paramsString = preg_replace( "[\x07+]", ' ', substr( $source, $bracket[1] + 1 ) );
+ # we now have a string like this:
+ # <parameters passed>); <the rest of the last read line>
+
+ # remove everything in brackets and quotes, we don't need nested statements nor literal strings which would
+ # only complicate separating individual arguments
+ $c = strlen( $paramsString );
+ $inString = $escaped = $openedBracket = $closingBracket = false;
+ $i = 0;
+ $inBrackets = 0;
+ $openedBrackets = array();
+
+ while ( $i < $c ) {
+ $letter = $paramsString[ $i ];
+
+ if ( !$inString ) {
+ if ( $letter === '\'' || $letter === '"' ) {
+ $inString = $letter;
+ } elseif ( $letter === '(' || $letter === '[' ) {
+ $inBrackets++;
+ $openedBrackets[] = $openedBracket = $letter;
+ $closingBracket = $openedBracket === '(' ? ')' : ']';
+ } elseif ( $inBrackets && $letter === $closingBracket ) {
+ $inBrackets--;
+ array_pop( $openedBrackets );
+ $openedBracket = end( $openedBrackets );
+ $closingBracket = $openedBracket === '(' ? ')' : ']';
+ } elseif ( !$inBrackets && $letter === ')' ) {
+ $paramsString = substr( $paramsString, 0, $i );
+ break;
+ }
+ } elseif ( $letter === $inString && !$escaped ) {
+ $inString = false;
+ }
+
+ # replace whatever was inside quotes or brackets with untypeable characters, we don't
+ # need that info. We'll later replace the whole string with '...'
+ if ( $inBrackets > 0 ) {
+ if ( $inBrackets > 1 || $letter !== $openedBracket ) {
+ $paramsString[ $i ] = "\x07";
+ }
+ }
+ if ( $inString ) {
+ if ( $letter !== $inString || $escaped ) {
+ $paramsString[ $i ] = "\x07";
+ }
+ }
+
+ $escaped = !$escaped && ( $letter === '\\' );
+ $i++;
+ }
+
+ # by now we have an un-nested arguments list, lets make it to an array for processing further
+ $arguments = explode( ',', preg_replace( "[\x07+]", '...', $paramsString ) );
+
+ # test each argument whether it was passed literary or was it an expression or a variable name
+ $parameters = array();
+ $blacklist = array( 'null', 'true', 'false', 'array(...)', 'array()', '"..."', '[...]', 'b"..."', );
+ foreach ( $arguments as $argument ) {
+ $argument = trim( $argument );
+
+ if ( is_numeric( $argument )
+ || in_array( str_replace( "'", '"', strtolower( $argument ) ), $blacklist, true )
+ ) {
+ $parameters[] = null;
+ } else {
+ $parameters[] = $argument;
+ }
+ }
+
+ return array( $parameters, $modifiers, $callee, $previousCaller, $miniTrace );
+ }
+
+ /**
+ * removes comments and zaps whitespace & <?php tags from php code, makes for easier further parsing
+ *
+ * @param string $source
+ *
+ * @return string
+ */
+ private static function _removeAllButCode( $source )
+ {
+ $commentTokens = array(
+ T_COMMENT => true, T_INLINE_HTML => true, T_DOC_COMMENT => true
+ );
+ $whiteSpaceTokens = array(
+ T_WHITESPACE => true, T_CLOSE_TAG => true,
+ T_OPEN_TAG => true, T_OPEN_TAG_WITH_ECHO => true,
+ );
+
+ $cleanedSource = '';
+ foreach ( token_get_all( $source ) as $token ) {
+ if ( is_array( $token ) ) {
+ if ( isset( $commentTokens[ $token[0] ] ) ) continue;
+
+ if ( isset( $whiteSpaceTokens[ $token[0] ] ) ) {
+ $token = "\x07";
+ } else {
+ $token = $token[1];
+ }
+ } elseif ( $token === ';' ) {
+ $token = "\x07";
+ }
+
+ $cleanedSource .= $token;
+ }
+ return $cleanedSource;
+ }
+
+ /**
+ * returns whether current trace step belongs to Kint or its wrappers
+ *
+ * @param $step
+ *
+ * @return array
+ */
+ private static function _stepIsInternal( $step )
+ {
+ if ( isset( $step['class'] ) ) {
+ foreach ( self::$aliases['methods'] as $alias ) {
+ if ( $alias[0] === strtolower( $step['class'] ) && $alias[1] === strtolower( $step['function'] ) ) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return in_array( strtolower( $step['function'] ), self::$aliases['functions'], true );
+ }
+ }
+
+ private static function _parseTrace( array $data )
+ {
+ $trace = array();
+ $traceFields = array( 'file', 'line', 'args', 'class' );
+ $fileFound = false; # file element must exist in one of the steps
+
+ # validate whether a trace was indeed passed
+ while ( $step = array_pop( $data ) ) {
+ if ( !is_array( $step ) || !isset( $step['function'] ) ) return false;
+ if ( !$fileFound && isset( $step['file'] ) && file_exists( $step['file'] ) ) {
+ $fileFound = true;
+ }
+
+ $valid = false;
+ foreach ( $traceFields as $element ) {
+ if ( isset( $step[ $element ] ) ) {
+ $valid = true;
+ break;
+ }
+ }
+ if ( !$valid ) return false;
+
+ if ( self::_stepIsInternal( $step ) ) {
+ $step = array(
+ 'file' => $step['file'],
+ 'line' => $step['line'],
+ 'function' => '',
+ );
+ array_unshift( $trace, $step );
+ break;
+ }
+ if ( $step['function'] !== 'spl_autoload_call' ) { # meaningless
+ array_unshift( $trace, $step );
+ }
+ }
+ if ( !$fileFound ) return false;
+
+ $output = array();
+ foreach ( $trace as $step ) {
+ if ( isset( $step['file'] ) ) {
+ $file = $step['file'];
+
+ if ( isset( $step['line'] ) ) {
+ $line = $step['line'];
+ # include the source of this step
+ if ( self::enabled() === self::MODE_RICH ) {
+ $source = self::_showSource( $file, $line );
+ }
+ }
+ }
+
+ $function = $step['function'];
+
+ if ( in_array( $function, array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
+ if ( empty( $step['args'] ) ) {
+ # no arguments
+ $args = array();
+ } else {
+ # sanitize the included file path
+ $args = array( 'file' => self::shortenPath( $step['args'][0] ) );
+ }
+ } elseif ( isset( $step['args'] ) ) {
+ if ( empty( $step['class'] ) && !function_exists( $function ) ) {
+ # introspection on closures or language constructs in a stack trace is impossible before PHP 5.3
+ $params = null;
+ } else {
+ try {
+ if ( isset( $step['class'] ) ) {
+ if ( method_exists( $step['class'], $function ) ) {
+ $reflection = new ReflectionMethod( $step['class'], $function );
+ } else if ( isset( $step['type'] ) && $step['type'] == '::' ) {
+ $reflection = new ReflectionMethod( $step['class'], '__callStatic' );
+ } else {
+ $reflection = new ReflectionMethod( $step['class'], '__call' );
+ }
+ } else {
+ $reflection = new ReflectionFunction( $function );
+ }
+
+ # get the function parameters
+ $params = $reflection->getParameters();
+ } catch ( Exception $e ) { # avoid various PHP version incompatibilities
+ $params = null;
+ }
+ }
+
+ $args = array();
+ foreach ( $step['args'] as $i => $arg ) {
+ if ( isset( $params[ $i ] ) ) {
+ # assign the argument by the parameter name
+ $args[ $params[ $i ]->name ] = $arg;
+ } else {
+ # assign the argument by number
+ $args[ '#' . ( $i + 1 ) ] = $arg;
+ }
+ }
+ }
+
+ if ( isset( $step['class'] ) ) {
+ # Class->method() or Class::method()
+ $function = $step['class'] . $step['type'] . $function;
+ }
+
+ // todo it's possible to parse the object name out from the source!
+ $output[] = array(
+ 'function' => $function,
+ 'args' => isset( $args ) ? $args : null,
+ 'file' => isset( $file ) ? $file : null,
+ 'line' => isset( $line ) ? $line : null,
+ 'source' => isset( $source ) ? $source : null,
+ 'object' => isset( $step['object'] ) ? $step['object'] : null,
+ );
+
+ unset( $function, $args, $file, $line, $source );
+ }
+
+ return $output;
+ }
+}
+
+
+if ( !function_exists( 'd' ) ) {
+ /**
+ * Alias of Kint::dump()
+ *
+ * @return string
+ */
+ function d()
+ {
+ if ( !Kint::enabled() ) return '';
+ $_ = func_get_args();
+ return call_user_func_array( array( 'Kint', 'dump' ), $_ );
+ }
+}
+
+if ( !function_exists( 'dd' ) ) {
+ /**
+ * Alias of Kint::dump()
+ * [!!!] IMPORTANT: execution will halt after call to this function
+ *
+ * @return string
+ * @deprecated
+ */
+ function dd()
+ {
+ if ( !Kint::enabled() ) return '';
+
+ echo "<pre>Kint: dd() is being deprecated, please use ddd() instead</pre>\n";
+ $_ = func_get_args();
+ call_user_func_array( array( 'Kint', 'dump' ), $_ );
+ die;
+ }
+}
+
+if ( !function_exists( 'ddd' ) ) {
+ /**
+ * Alias of Kint::dump()
+ * [!!!] IMPORTANT: execution will halt after call to this function
+ *
+ * @return string
+ */
+ function ddd()
+ {
+ if ( !Kint::enabled() ) return '';
+ $_ = func_get_args();
+ call_user_func_array( array( 'Kint', 'dump' ), $_ );
+ die;
+ }
+}
+
+if ( !function_exists( 's' ) ) {
+ /**
+ * Alias of Kint::dump(), however the output is in plain htmlescaped text and some minor visibility enhancements
+ * added. If run in CLI mode, output is pure whitespace.
+ *
+ * To force rendering mode without autodetecting anything:
+ *
+ * Kint::enabled( Kint::MODE_PLAIN );
+ * Kint::dump( $variable );
+ *
+ * [!!!] IMPORTANT: execution will halt after call to this function
+ *
+ * @return string
+ */
+ function s()
+ {
+ $enabled = Kint::enabled();
+ if ( !$enabled ) return '';
+
+ if ( $enabled === Kint::MODE_WHITESPACE ) { # if already in whitespace, don't elevate to plain
+ $restoreMode = Kint::MODE_WHITESPACE;
+ } else {
+ $restoreMode = Kint::enabled( # remove cli colors in cli mode; remove rich interface in HTML mode
+ PHP_SAPI === 'cli' ? Kint::MODE_WHITESPACE : Kint::MODE_PLAIN
+ );
+ }
+
+ $params = func_get_args();
+ $dump = call_user_func_array( array( 'Kint', 'dump' ), $params );
+ Kint::enabled( $restoreMode );
+ return $dump;
+ }
+}
+
+if ( !function_exists( 'sd' ) ) {
+ /**
+ * @see s()
+ *
+ * [!!!] IMPORTANT: execution will halt after call to this function
+ *
+ * @return string
+ */
+ function sd()
+ {
+ $enabled = Kint::enabled();
+ if ( !$enabled ) return '';
+
+ if ( $enabled !== Kint::MODE_WHITESPACE ) {
+ Kint::enabled(
+ PHP_SAPI === 'cli' ? Kint::MODE_WHITESPACE : Kint::MODE_PLAIN
+ );
+ }
+
+ $params = func_get_args();
+ call_user_func_array( array( 'Kint', 'dump' ), $params );
+ die;
+ }
+}