diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 02893aac04..43a0075f43 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -11,6 +11,7 @@ Yii Framework 2 Change Log - Bug #3125: `yii\console\controllers\AssetController` now respects data URL resources (klimov-paul) - Bug #3128: Fixed the bug that `defaultRoles` set in RBAC manager was not working as specified (qiangxue) - Bug #3153: Fixed the bug that using "between" operator to build a SQL query will cause a PHP notice (gonimar) +- Enh #2837: Error page now shows arguments in stack trace method calls (samdark) - Enh #3103: debugger panel is now not displayed when printing a page (githubjeka) - Enh #3108: Added `yii\debug\Module::enableDebugLogs` to disable logging debug logs by default (qiangxue) - Enh #3132: `yii\rbac\PhpManager` now supports more compact data file format (qiangxue) diff --git a/framework/views/errorHandler/callStackItem.php b/framework/views/errorHandler/callStackItem.php index 7b28858153..e98506d712 100644 --- a/framework/views/errorHandler/callStackItem.php +++ b/framework/views/errorHandler/callStackItem.php @@ -20,7 +20,7 @@ - addTypeLinks("$class::$method()") : $method . '()' ?> + addTypeLinks("$class::$method(" . $handler->argumentsToString($args) . ")") : $handler->htmlEncode($method) . '(' . $handler->argumentsToString($args) . ')' ?> diff --git a/framework/views/errorHandler/exception.php b/framework/views/errorHandler/exception.php index 7cefc29d77..1b7629bcd9 100644 --- a/framework/views/errorHandler/exception.php +++ b/framework/views/errorHandler/exception.php @@ -150,6 +150,7 @@ html,body{ margin: 0 auto; padding: 0 50px; position: relative; + white-space: nowrap; } .call-stack ul li a{ color: #505050; @@ -286,54 +287,32 @@ html,body{ } /* highlight.js */ -pre .subst,pre .title{ - font-weight: normal; - color: #505050; -} -pre .comment,pre .template_comment,pre .javadoc,pre .diff .header{ +.comment{ color: #808080; font-style: italic; } -pre .annotation,pre .decorator,pre .preprocessor,pre .doctype,pre .pi,pre .chunk,pre .shebang,pre .apache .cbracket, -pre .prompt,pre .http .title{ - color: #808000; -} -pre .tag,pre .pi{ - background: #efefef; -} -pre .tag .title,pre .id,pre .attr_selector,pre .pseudo,pre .literal,pre .keyword,pre .hexcolor,pre .css .function, -pre .ini .title,pre .css .class,pre .list .title,pre .clojure .title,pre .nginx .title,pre .tex .command, -pre .request,pre .status{ +.keyword{ color: #000080; } -pre .attribute,pre .rules .keyword,pre .number,pre .date,pre .regexp,pre .tex .special{ +.number{ color: #00a; } -pre .number,pre .regexp{ +.number{ font-weight: normal; } -pre .string,pre .value,pre .filter .argument,pre .css .function .params,pre .apache .tag{ +.string, .value{ color: #0a0; } -pre .symbol,pre .ruby .symbol .string,pre .char,pre .tex .formula{ +.symbol, .char { color: #505050; background: #d0eded; font-style: italic; } -pre .phpdoc,pre .yardoctag,pre .javadoctag{ +.phpdoc{ text-decoration: underline; } -pre .variable,pre .envvar,pre .apache .sqbracket,pre .nginx .built_in{ +.variable{ color: #a00; -} -pre .addition{ - background: #baeeba; -} -pre .deletion{ - background: #ffc8bd; -} -pre .diff .change{ - background: #bccff9; } @@ -367,10 +346,10 @@ pre .diff .change{
diff --git a/framework/web/ErrorHandler.php b/framework/web/ErrorHandler.php index fb65aed8fa..985011a8ab 100644 --- a/framework/web/ErrorHandler.php +++ b/framework/web/ErrorHandler.php @@ -152,15 +152,18 @@ class ErrorHandler extends \yii\base\ErrorHandler */ public function addTypeLinks($code) { - if (strpos($code, 'yii\\') !== 0) { - return $this->htmlEncode($code); - } - - if (($pos = strpos($code, '::')) !== false) { - $class = substr($code, 0, $pos); - $method = substr($code, $pos + 2); + if (preg_match('/(.*?)::([^(]+)\((.*)\)/', $code, $matches)) { + $class = $matches[1]; + $method = $matches[2]; + $args = $matches[3]; + $text = $this->htmlEncode($class) . '::' . $this->htmlEncode($method) . '(' . $args . ')'; } else { $class = $code; + $text = $this->htmlEncode($class); + } + + if (strpos($code, 'yii\\') !== 0) { + return $text; } $page = $this->htmlEncode(strtolower(str_replace('\\', '-', $class))); @@ -169,7 +172,7 @@ class ErrorHandler extends \yii\base\ErrorHandler $url .= "#$method-detail"; } - return '' . $this->htmlEncode($code) . ''; + return '' . $text . ''; } /** @@ -215,9 +218,10 @@ class ErrorHandler extends \yii\base\ErrorHandler * @param string|null $class called class name. * @param string|null $method called function/method name. * @param integer $index number of the call stack element. + * @param array $args array of method arguments. * @return string HTML content of the rendered call stack element. */ - public function renderCallStackItem($file, $line, $class, $method, $index) + public function renderCallStackItem($file, $line, $class, $method, $args, $index) { $lines = []; $begin = $end = 0; @@ -242,6 +246,7 @@ class ErrorHandler extends \yii\base\ErrorHandler 'lines' => $lines, 'begin' => $begin, 'end' => $end, + 'args' => $args, ]); } @@ -319,4 +324,57 @@ class ErrorHandler extends \yii\base\ErrorHandler { return '' . $this->htmlEncode(Yii::getVersion()) . ''; } + + /** + * Converts arguments array to its string representation + * + * @param array $args arguments array to be converted + * @return string string representation of the arguments array + */ + public function argumentsToString($args) + { + $count = 0; + $isAssoc = $args !== array_values($args); + + foreach ($args as $key => $value) { + $count++; + if($count>=5) { + if($count>5) { + unset($args[$key]); + } else { + $args[$key] = '...'; + } + continue; + } + + if (is_object($value)) { + $args[$key] = '' . $this->htmlEncode(get_class($value)) . ''; + } elseif (is_bool($value)) { + $args[$key] = '' . ($value ? 'true' : 'false') . ''; + } elseif (is_string($value)) { + if (strlen($value) > 64) { + $value = substr($value, 0, 64) . '...'; + } + $value = $this->htmlEncode($value); + $args[$key] = "'$value'"; + } elseif (is_array($value)) { + $args[$key] = '[' . $this->argumentsToString($value) . ']'; + } elseif ($value === null) { + $args[$key] = 'null'; + } elseif(is_resource($value)) { + $args[$key] = 'resource'; + } else { + $args[$key] = '' . $value . ''; + } + + if (is_string($key)) { + $args[$key] = '\'' . $this->htmlEncode($key) . "' => $args[$key]"; + } elseif ($isAssoc) { + $args[$key] = "$key => $args[$key]"; + } + } + $out = implode(", ", $args); + + return $out; + } }