/** * @param $variable * * @return array|bool */ public function parse(&$variable) { if (!$variable instanceof \Closure) { return false; } $this->name = 'Closure'; $reflection = new \ReflectionFunction($variable); $ret = array('Parameters' => array()); $val = $reflection->getParameters(); if ($val) { foreach ($val as $parameter) { // todo http://php.net/manual/en/class.reflectionparameter.php $ret['Parameters'][] = $parameter->name; } } $val = $reflection->getStaticVariables(); if ($val) { $ret['Uses'] = $val; } if (method_exists($reflection, 'getClousureThis') && ($val = $reflection->getClosureThis())) { $ret['Uses']['$this'] = $val; } $val = $reflection->getFileName(); if ($val) { $this->value = Kint::shortenPath($val) . ':' . $reflection->getStartLine(); } return $ret; }
/** * @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 */ private static function _parse_resource(&$variable, KintVariableData $variableData) { $resourceType = get_resource_type($variable); $variableData->type = "resource ({$resourceType})"; if ($resourceType === 'stream' && ($meta = stream_get_meta_data($variable))) { /** @noinspection NestedPositiveIfStatementsInspection */ if (isset($meta['uri'])) { $file = $meta['uri']; if (function_exists('stream_is_local')) { // Only exists on PHP >= 5.2.4 if (stream_is_local($file)) { $file = Kint::shortenPath($file); } } $variableData->value = $file; } } }
/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { if (!is_object($variable)) { return false; } $className = get_class($variable); # assuming class definition will not change inside one request if (!isset(self::$cache[$className])) { $reflection = new \ReflectionClass($variable); $public = $private = $protected = array(); // Class methods foreach ($reflection->getMethods() as $method) { $params = array(); // Access type $access = implode(' ', \Reflection::getModifierNames($method->getModifiers())); // Method parameters foreach ($method->getParameters() as $param) { $paramString = ''; if ($param->isArray()) { $paramString .= 'array '; } else { try { $paramClassName = $param->getClass(); if ($paramClassName) { $paramString .= $paramClassName->name . ' '; } } catch (\ReflectionException $e) { preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/', (string) $param, $matches); $paramClassName = isset($matches[1]) ? $matches[1] : ''; $paramString .= ' UNDEFINED CLASS (' . $paramClassName . ') '; } } $paramString .= ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName(); if ($param->isDefaultValueAvailable()) { if (is_array($param->getDefaultValue())) { $arrayValues = array(); foreach ($param->getDefaultValue() as $key => $value) { $arrayValues[] = $key . ' => ' . $value; } $defaultValue = 'array(' . implode(', ', $arrayValues) . ')'; } elseif ($param->getDefaultValue() === null) { $defaultValue = 'NULL'; } elseif ($param->getDefaultValue() === false) { $defaultValue = 'false'; } elseif ($param->getDefaultValue() === true) { $defaultValue = 'true'; } elseif ($param->getDefaultValue() === '') { $defaultValue = '""'; } else { $defaultValue = $param->getDefaultValue(); } $paramString .= ' = ' . $defaultValue; } $params[] = $paramString; } $output = new KintVariableData(); // Simple DocBlock parser, look for @return $docBlock = $method->getDocComment(); if ($docBlock) { $matches = array(); if (preg_match_all('/@(\\w+)\\s+(.*)\\r?\\n/m', $docBlock, $matches)) { $lines = array_combine($matches[1], $matches[2]); if (isset($lines['return'])) { $output->operator = '->'; # since we're outputting code, assumption that the string is utf8 is most likely correct # and saves resources $output->type = self::escape($lines['return'], 'UTF-8'); } } } $output->name = ($method->returnsReference() ? '&' : '') . $method->getName() . '(' . implode(', ', $params) . ')'; $output->access = $access; if (is_string($docBlock)) { $lines = array(); foreach (explode("\n", $docBlock) as $line) { $line = trim($line); if (in_array($line, array('/**', '/*', '*/'), true)) { continue; } elseif (strpos($line, '*') === 0) { $line = trim(substr($line, 1)); } $lines[] = self::escape($line, 'UTF-8'); } $output->extendedValue = implode("\n", $lines) . "\n\n"; } $declaringClass = $method->getDeclaringClass(); $declaringClassName = $declaringClass->getName(); if ($declaringClassName !== $className) { /** @noinspection PhpToStringImplementationInspection */ $output->extendedValue .= "<small>Inherited from <i>{$declaringClassName}</i></small>\n"; } $fileName = Kint::shortenPath($method->getFileName()) . ':' . $method->getStartLine(); /** @noinspection PhpToStringImplementationInspection */ $output->extendedValue .= "<small>Defined in {$fileName}</small>"; $sortName = $access . $method->getName(); if ($method->isPrivate()) { $private[$sortName] = $output; } elseif ($method->isProtected()) { $protected[$sortName] = $output; } else { $public[$sortName] = $output; } } if (!$private && !$protected && !$public) { self::$cache[$className] = false; } ksort($public); ksort($protected); ksort($private); /** @noinspection AdditionOperationOnArraysInspection */ self::$cache[$className] = $public + $protected + $private; } if (count(self::$cache[$className]) === 0) { return false; } $this->value = self::$cache[$className]; $this->type = 'Available methods'; $this->size = count(self::$cache[$className]); return true; }