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 @@
- = $class !== null ? $handler->addTypeLinks("$class::$method()") : $method . '()' ?>
+ = $class !== null ? $handler->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{
- = $handler->renderCallStackItem($exception->getFile(), $exception->getLine(), null, null, 1) ?>
+ = $handler->renderCallStackItem($exception->getFile(), $exception->getLine(), null, null, [], 1) ?>
getTrace(), $length = count($trace); $i < $length; ++$i): ?>
= $handler->renderCallStackItem(@$trace[$i]['file'] ?: null, @$trace[$i]['line'] ?: null,
- @$trace[$i]['class'] ?: null, @$trace[$i]['function'] ?: null, $i + 2) ?>
+ @$trace[$i]['class'] ?: null, @$trace[$i]['function'] ?: null, $trace[$i]['args'], $i + 2) ?>
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;
+ }
}