/** * @param string $file * @param int $line * * @return string */ private static function _ideLink($file, $line) { $shortenedPath = Kint::shortenPath($file); if (!Kint::$fileLinkFormat) { return $shortenedPath . ':' . $line; } $ideLink = Kint::getIdeLink($file, $line); $class = strpos($ideLink, 'http://') === 0 ? 'class="kint-ide-link" ' : ''; return "<a {$class}href=\"{$ideLink}\">{$shortenedPath}:{$line}</a>"; }
/** * @param $callee * * @return string */ private static function _buildCalleeString($callee) { if (Kint::enabled() === Kint::MODE_CLI) { // todo win/nix ? return "{$callee['file']}:{$callee['line']}"; } $url = Kint::getIdeLink($callee['file'], $callee['line']); $shortenedName = Kint::shortenPath($callee['file']) . ':' . $callee['line']; if (Kint::enabled() === Kint::MODE_PLAIN) { if (strpos($url, 'http://') === 0) { $calleeInfo = '<a href="#"onclick="' . 'X=new XMLHttpRequest;' . "X.open('GET','{$url}');" . 'X.send();' . "return!1\">{$shortenedName}</a>"; } else { $calleeInfo = "<a href=\"{$url}\">{$shortenedName}</a>"; } } else { $calleeInfo = $shortenedName; } return $calleeInfo; }
/** * @param mixed $variable * @param KintVariableData $variableData * * @return bool */ private static function _parse_object(&$variable, KintVariableData $variableData) { if (function_exists('spl_object_hash')) { $hash = spl_object_hash($variable); } else { ob_start(); /** @noinspection ForgottenDebugOutputInspection */ /** @noinspection ReferenceMismatchInspection */ var_dump($variable); preg_match('[#(\\d+)]', ob_get_clean(), $match); $hash = $match[1]; } $castedArray = (array) $variable; $variableData->type = get_class($variable); $variableData->size = count($castedArray); if (isset(self::$_objects[$hash])) { $variableData->value = '*RECURSION*'; return false; } if (self::_checkDepth()) { $variableData->extendedValue = '*DEPTH TOO GREAT*'; return false; } # ArrayObject (and maybe ArrayIterator, did not try yet) unsurprisingly consist of mainly dark magic. # What bothers me most, var_dump sees no problem with it, and ArrayObject also uses a custom, # undocumented serialize function, so you can see the properties in internal functions, but # can never iterate some of them if the flags are not STD_PROP_LIST. Fun stuff. if ($variableData->type === 'ArrayObject' || is_subclass_of($variable, 'ArrayObject')) { /* @var $variable \ArrayObject */ $arrayObjectFlags = $variable->getFlags(); $variable->setFlags(\ArrayObject::STD_PROP_LIST); } self::$_objects[$hash] = true; // TODO: store reflectorObject here for alternatives cache $reflector = new \ReflectionObject($variable); # add link to definition of user-land objects if (Kint::$fileLinkFormat && Kint::enabled() === Kint::MODE_RICH && $reflector->isUserDefined()) { $url = Kint::getIdeLink($reflector->getFileName(), $reflector->getStartLine()); $class = strpos($url, 'http://') === 0 ? 'class="kint-ide-link" ' : ''; $variableData->type = "<a {$class}href=\"{$url}\">{$variableData->type}</a>"; } $variableData->size = 0; $extendedValue = array(); $encountered = array(); # copy the object as an array as it provides more info than Reflection (depends) foreach ($castedArray as $key => $value) { /* casting object to array: * integer properties are inaccessible; * private variables have the class name prepended to the variable name; * protected variables have a '*' prepended to the variable name. * These prepended values have null bytes on either side. * http://www.php.net/manual/en/language.types.array.php#language.types.array.casting */ if ($key[0] === "") { $access = $key[1] === '*' ? 'protected' : 'private'; // Remove the access level from the variable name. $key = substr($key, strrpos($key, "") + 1); } else { $access = 'public'; } $encountered[$key] = true; $output = self::factory($value, self::escape($key)); $output->access = $access; $output->operator = '->'; $extendedValue[] = $output; $variableData->size++; } foreach ($reflector->getProperties() as $property) { $name = $property->name; if (isset($encountered[$name]) || $property->isStatic()) { continue; } if ($property->isProtected()) { $property->setAccessible(true); $access = 'protected'; } elseif ($property->isPrivate()) { $property->setAccessible(true); $access = 'private'; } else { $access = 'public'; } $value = $property->getValue($variable); $output = self::factory($value, self::escape($name)); $output->access = $access; $output->operator = '->'; $extendedValue[] = $output; $variableData->size++; } if (isset($arrayObjectFlags)) { $variable->setFlags($arrayObjectFlags); } if ($variableData->size) { $variableData->extendedValue = $extendedValue; } return true; }