diff --git a/apps/bootstrap/controllers/SiteController.php b/apps/bootstrap/controllers/SiteController.php index 4c00cea..4652430 100644 --- a/apps/bootstrap/controllers/SiteController.php +++ b/apps/bootstrap/controllers/SiteController.php @@ -21,6 +21,7 @@ class SiteController extends Controller public function actionIndex() { throw new \yii\base\HttpException(500, 'Test exception'); + $x = 1; echo $this->render('index'); } diff --git a/apps/bootstrap/www/tmp/main.css b/apps/bootstrap/www/tmp/main.css index 334bc82..69ca6f7 100644 --- a/apps/bootstrap/www/tmp/main.css +++ b/apps/bootstrap/www/tmp/main.css @@ -50,9 +50,6 @@ h1,h2,p,img,ul li{ font-family: Arial,sans-serif; color: #505050; } -body,html{ - /*overflow-x: hidden;*/ -} /* header */ .header{ @@ -85,70 +82,70 @@ body,html{ text-shadow: 0 1px 0 #cacaca; } -/* traceback */ -.traceback{ +/* call stack */ +.call-stack{ margin-top: 30px; margin-bottom: 40px; } -.traceback ul li{ +.call-stack ul li{ margin: 1px 0; } -.traceback ul li .li-wrap{ +.call-stack ul li .element-wrap{ cursor: pointer; padding: 15px 0; } -.traceback ul li.application .li-wrap{ +.call-stack ul li.application .element-wrap{ background-color: #fafafa; } -.traceback ul li .li-wrap:hover{ +.call-stack ul li .element-wrap:hover{ background-color: #edf9ff; } -.traceback ul li .li{ +.call-stack ul li .element{ min-width: 860px; /* 960px - 50px * 2 */ max-width: 1100px; /* 1200px - 50px * 2 */ margin: 0 auto; padding: 0 50px; position: relative; } -.traceback ul li a{ +.call-stack ul li a{ color: #505050; } -.traceback ul li a:hover{ +.call-stack ul li a:hover{ color: #000000; text-shadow: 0 1px 0 #cacaca; } -.traceback ul li .number{ +.call-stack ul li .number{ width: 45px; display: inline-block; } -.traceback ul li .text{ +.call-stack ul li .text{ color: #bbbbbb; } -.traceback ul li.application .text{ +.call-stack ul li.application .text{ color: #505050; } -.traceback ul li .at{ +.call-stack ul li .at{ position: absolute; right: 110px; /* 50px + 60px */ color: #bbbbbb; } -.traceback ul li.application .at{ +.call-stack ul li.application .at{ color: #505050; } -.traceback ul li .line{ +.call-stack ul li .line{ position: absolute; right: 50px; width: 60px; text-align: right; } -.traceback ul li .code-wrap{ +.call-stack ul li .code-wrap{ display: none; position: relative; } -.traceback ul li.application .code-wrap{ +.call-stack ul li.application .code-wrap{ display: block; } -.traceback ul li .error-line{ +.call-stack ul li .error-line,.call-stack ul li .hover-line{ background-color: #ffebeb; position: absolute; width: 100%; @@ -156,29 +153,36 @@ body,html{ z-index: 100; margin-top: 15px; } -.traceback ul li .code{ +.call-stack ul li .hover-line{ + background: none; +} +.call-stack ul li .hover-line.hover,.call-stack ul li .hover-line:hover{ + background: #edf9ff !important; +} +.call-stack ul li .code{ min-width: 860px; /* 960px - 50px * 2 */ max-width: 1100px; /* 1200px - 50px * 2 */ margin: 0 auto; padding: 15px 50px; position: relative; } -.traceback ul li .code .lines{ +.call-stack ul li .code .lines{ position: absolute; z-index: 200; left: 50px; line-height: 18px; font-size: 14px; - font-family: Consolas, Courier New, monospaced; + font-family: Consolas, Courier New, monospace; color: #bbbbbb; } -.traceback ul li .code pre{ +.call-stack ul li .code pre{ position: relative; z-index: 200; left: 50px; line-height: 18px; font-size: 14px; - font-family: Consolas, Courier New, monospaced; + font-family: Consolas, Courier New, monospace; + display: inline; } /* request */ @@ -190,15 +194,15 @@ body,html{ margin-bottom: 1px; } .request pre{ - font-family: Consolas, Courier New, monospaced; + font-family: Consolas, Courier New, monospace; } /* footer */ .footer{ position: relative; height: 222px; - min-width: 860px; /* padding compensation: 960px - 50px * 2 */ - max-width: 1100px; /* padding compensation: 1200px - 50px * 2 */ + min-width: 860px; /* 960px - 50px * 2 */ + max-width: 1100px; /* 1200px - 50px * 2 */ padding: 0 50px; margin: 1px auto 0 auto; } @@ -223,30 +227,7 @@ body,html{ right: -50px; } -/* code */ -#code-wrap{ - overflow: hidden; - position: relative; -} -#code-highlighter{ - background-color: #ffffff; - position: fixed; - width: 100%; - z-index: 100; -} -#code-inner-wrap{ - min-width: 860px; /* padding compensation: 960px - 50px * 2 */ - max-width: 1100px; /* padding compensation: 1200px - 50px * 2 */ - margin: 0 auto; -} -pre{ - display: inline; - color: #505050; - font-size: 14px; - line-height: 18px; - z-index: 200; - position: relative; -} +/* highlight.js */ pre .subst,pre .title{ font-weight: normal; color: #505050; @@ -255,16 +236,16 @@ pre .comment,pre .template_comment,pre .javadoc,pre .diff .header{ 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{ +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{ +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{ color: #000080; } pre .attribute,pre .rules .keyword,pre .number,pre .date,pre .regexp,pre .tex .special{ @@ -273,7 +254,7 @@ pre .attribute,pre .rules .keyword,pre .number,pre .date,pre .regexp,pre .tex .s pre .number,pre .regexp{ font-weight: normal; } -pre .string,pre .value,pre .filter .argument,pre .css .function .params,pre .apache .tag { +pre .string,pre .value,pre .filter .argument,pre .css .function .params,pre .apache .tag{ color: #00aa00; } pre .symbol,pre .ruby .symbol .string,pre .char,pre .tex .formula{ diff --git a/apps/bootstrap/www/tmp/main.js b/apps/bootstrap/www/tmp/main.js index 2bd4980..020ce41 100644 --- a/apps/bootstrap/www/tmp/main.js +++ b/apps/bootstrap/www/tmp/main.js @@ -1,58 +1,43 @@ -/*; - -var lines = null; -var line = document.getElementById('code-highlighter') - -var updateLines = function() { - lines = document.getElementById('code').getClientRects(); -}; -updateLines(); -window.onresize = updateLines; -window.onscroll = updateLines; - -document.onmousemove = function(e) { - var event = e || window.event; - var x = event.clientX, y = event.clientY; - for (var i = 0, max = lines.length; i < max; i++) { - if (y > lines[i].top && y < lines[i].bottom) { - line.style.height = parseInt(lines[i].bottom - lines[i].top + 1) + 'px'; - line.style.top = parseInt(lines[i].top) + 'px'; - break; - } - } -} -*/ - window.onload = function() { - var i, j, max, max2, + var i, imax, codeBlocks = Sizzle('pre'), - traceBackItems = Sizzle('.trace-back-item'); + callStackItems = Sizzle('.call-stack-item'); - // highlight code - for (i = 0, max = codeBlocks.length; i < max; i++) { + // highlight code blocks + for (i = 0, imax = codeBlocks.length; i < imax; ++i) { hljs.highlightBlock(codeBlocks[i], ' '); } - // error lines -// var updateErrorLines = function() { -// for (i = 0, max = codeBlocks.length; i < max; i++) { -// var lines = codeBlocks[i].getClientRects(), -// errorLine = codeBlocks[i].getAttribute('data-error-line'), -// top = 0; -// if (errorLine > lines.length - 1) { -// errorLine = lines.length - 1; -// } -// for (j = 0; j < errorLine; j++) { -// top += lines[j].height; -// } -// Sizzle('.error-line', codeBlocks[i].parentNode.parentNode)[0].style.marginTop = top + 'px'; -// } -// }; -// updateErrorLines(); + // + document.onmousemove = function(e) { + var lines, i, imax, j, jmax, k, kmax, + event = e || window.event, + y = event.clientY, + lineFound = false; + for (i = 0, imax = codeBlocks.length; i < imax; ++i) { + lines = codeBlocks[i].getClientRects(); + for (j = 0, jmax = lines.length; j < jmax; ++j) { + if (y > lines[j].top && y < lines[j].bottom) { + lineFound = true; + break; + } + } + if (lineFound) { + break; + } + } + var hoverLines = Sizzle('.hover-line'); + for (k = 0, kmax = hoverLines.length; k < kmax; ++k) { + hoverLines[k].className = 'hover-line'; + } + if (lineFound) { + Sizzle('.call-stack-item:eq(' + i + ') .hover-line:eq(' + j + ')')[0].className = 'hover-line hover'; + } + } - // toggle code block visibility of each trace back item - for (i = 0, max = traceBackItems.length; i < max; i++) { - Sizzle('.li-wrap', traceBackItems[i])[0].addEventListener('click', function() { + // toggle code block visibility + for (i = 0, imax = callStackItems.length; i < imax; i++) { + Sizzle('.element-wrap', callStackItems[i])[0].addEventListener('click', function() { var code = Sizzle('.code-wrap', this.parentNode)[0]; code.style.display = window.getComputedStyle(code).display == 'block' ? 'none' : 'block'; }); diff --git a/framework/yii/base/ErrorHandler.php b/framework/yii/base/ErrorHandler.php index 09e4a59..4c6e8eb 100644 --- a/framework/yii/base/ErrorHandler.php +++ b/framework/yii/base/ErrorHandler.php @@ -16,6 +16,7 @@ use Yii; * nature of the errors and the mode the application runs at. * * @author Qiang Xue + * @author Timur Ruziev * @since 2.0 */ class ErrorHandler extends Component @@ -42,7 +43,11 @@ class ErrorHandler extends Component /** * @var string the path of the view file for rendering exceptions and errors. */ - public $view = '@yii/views/errorHandler.php'; + public $mainView = '@yii/views/errorHandler/main.php'; + /** + * @var string the path of the view file for rendering exceptions and errors call stack element. + */ + public $callStackItemView = '@yii/views/errorHandler/callStackItem.php'; /** * @var \Exception the exception that is being handled currently. */ @@ -56,11 +61,9 @@ class ErrorHandler extends Component public function handle($exception) { $this->exception = $exception; - if ($this->discardExistingOutput) { $this->clearOutput(); } - $this->renderException($exception); } @@ -90,9 +93,8 @@ class ErrorHandler extends Component if (YII_DEBUG) { ini_set('display_errors', 1); } - $view = new View(); - echo $view->renderFile($this->view, array('e' => $exception), $this); + echo $view->renderFile($this->mainView, array('e' => $exception), $this); } } } @@ -100,7 +102,7 @@ class ErrorHandler extends Component /** * Converts special characters to HTML entities. * @param string $text to encode. - * @return string encoded text. + * @return string encoded original text. */ public function htmlEncode($text) { @@ -117,4 +119,109 @@ class ErrorHandler extends Component @ob_end_clean(); } } + + /** + * Adds informational links to the given PHP type/class. + * @param string $code type/class name to be linkified. + * @return string linkified with HTML type/class name. + */ + public function addTypeLinks($code) + { + $html = ''; + if (strpos($code, '\\') !== false) { + // namespaced class + foreach (explode('\\', $code) as $part) { + $html .= '' . $this->htmlEncode($part) . '\\'; + } + $html = rtrim($html, '\\'); + } + return $html; + } + + /** + * Creates HTML containing link to the page with the information on given HTTP status code. + * @param integer $statusCode to be used to generate information link. + * @return string generated HTML with HTTP status code information. + */ + public function createHttpStatusLink($statusCode) + { + return '' . (int)$statusCode . ''; + } + + /** + * Renders a single call stack element. + * @param string $file name where call has happened. + * @param integer $line number on which call has happened. + * @param integer $index number of the call stack element. + * @return string HTML content of the rendered call stack element. + */ + public function renderCallStackItem($file, $line, $index) + { + $line--; // adjust line number from one-based to zero-based + $lines = @file($file); + if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line + 1) { + return ''; + } + + $half = (int)(($index == 0 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2); + $begin = $line - $half > 0 ? $line - $half : 0; + $end = $line + $half < $lineCount ? $line + $half : $lineCount - 1; + + $view = new View(); + return $view->renderFile($this->callStackItemView, array( + 'file' => $file, + 'line' => $line, + 'index' => $index, + 'lines' => $lines, + 'begin' => $begin, + 'end' => $end, + ), $this); + } + + /** + * Determines whether given name of the file belongs to the framework. + * @param string $file name to be checked. + * @return boolean whether given name of the file belongs to the framework. + */ + public function isCoreFile($file) + { + return $file === 'unknown' || strpos(realpath($file), YII_PATH . DIRECTORY_SEPARATOR) === 0; + } + + /** + * Creates string containing HTML link which refers to the home page of determined web-server software + * and its full name. + * @return string server software information hyperlink. + */ + public function createServerInformationLink() + { + static $serverUrls = array( + 'http://httpd.apache.org/' => array('apache'), + 'http://nginx.org/' => array('nginx'), + 'http://lighttpd.net/' => array('lighttpd'), + 'http://gwan.com/' => array('g-wan', 'gwan'), + 'http://iis.net/' => array('iis', 'services'), + 'http://php.net/manual/en/features.commandline.webserver.php' => array('development'), + ); + if (isset($_SERVER['SERVER_SOFTWARE'])) { + foreach ($serverUrls as $url => $keywords) { + foreach ($keywords as $keyword) { + if (stripos($_SERVER['SERVER_SOFTWARE'], $keyword) !== false ) { + return '' . $this->htmlEncode($_SERVER['SERVER_SOFTWARE']) . ''; + } + } + } + } + return ''; + } + + /** + * Creates string containing HTML link which refers to the page with the current version + * of the framework and version number text. + * @return string framework version information hyperlink. + */ + public function createFrameworkVersionLink() + { + return '' . $this->htmlEncode(Yii::getVersion()) . ''; + } } diff --git a/framework/yii/views/errorHandler.php b/framework/yii/views/errorHandler.php deleted file mode 100644 index 7589a96..0000000 --- a/framework/yii/views/errorHandler.php +++ /dev/null @@ -1,209 +0,0 @@ -context; -?> - - - - - - - - - - - - - - - - -
-
-
-
- - 10
11
12
13
14
15
16
17
18
19
20
21
22
- 23
24
25
26
27
28
29
30
31
32
33
34 -
-
	{
-		return array(
-			'captcha' => array(
-				'class' => 'yii\web\CaptchaAction',
-			),
-		);
-	}
-
-	public function actionIndex()
-	{
-//		throw new \yii\base\HttpException(500);
-		$x = null;
-		$x->y = 1;
-
-		echo $this->render('index');
-	}
-
-	public function actionLogin()
-	{
-		$model = new LoginForm();
-		if ($this->populate($_POST, $model) && $model->login()) {
-			Yii::$app->response->redirect(array('site/index'));
-		} else {
-			echo $this->render('login', array(
-				'model' => $model,
-
-
- - - -
- Attention -

Exceptionyii\base\HttpException – 404

-

Requested user cannot be found!

-
- -
-
    -
  • -
    -
    - 1. - in C:\_work\jetbrains\yii2\apps\bootstrap\protected\controllers\SiteController.php - at line - 22 -
    -
    - -
  • -
  • -
    -
    - 2. - at C:\_work\jetbrains\yii2\yii\base\InlineAction.php – - call_user_func_array() - at line - 47 -
    -
    - -
  • -
  • -
    -
    - 3. - at C:\_work\jetbrains\yii2\yii\base\Controller.php – - yii\base\InlineActionrunWithParams() - at line - 117 -
    -
    - -
  • -
  • -
    -
    - 4. - at C:\_work\jetbrains\yii2\yii\web\Application.php – - yii\base\ModulerunAction() - at line - 35 -
    -
    - -
  • -
  • -
    -
    - 5. - at C:\_work\jetbrains\yii2\yii\web\Application.php – - yii\base\ModulerunAction() - at line - 35 -
    -
    - -
  • -
  • -
    -
    - 6. - at C:\_work\jetbrains\yii2\yii\base\Application.php – - yii\web\ApplicationprocessRequest() - at line - 146 -
    -
    - -
  • -
  • -
    -
    - 7. - at C:\_work\jetbrains\yii2\apps\bootstrap\index.php – - yii\base\Applicationrun() - at line - 14 -
    -
    - -
  • -
-
- - -
-
-
-
$_GET = [
-	'show-post' => 100,
-	'refresh-page' => 'yes',
-	'ascending-sort' => 1,
-];
-
-$_POST = [
-	'blog-post-form' => [
-		'title' => 'hello',
-		'author_id' => '12',
-	],
-];
-
-$_SERVER = [
-	'DOCUMENT_ROOT' => '/home/resurtm/work/data',
-	'REMOTE_ADDR' => '::1',
-	'REMOTE_PORT' => '52694',
-	'SERVER_SOFTWARE' => 'PHP 5.4.3 Development Server',
-	'SERVER_PROTOCOL' => 'HTTP/1.1',
-	'SERVER_NAME' => 'localhost',
-	'SERVER_PORT' => '8000',
-	'REQUEST_URI' => '/index.php?post-form[title]=hello&post-form[author_id]=12',
-	'REQUEST_METHOD' => 'GET',
-	'SCRIPT_NAME' => '/index.php',
-	'SCRIPT_FILENAME' => '/home/resurtm/work/data/index.php',
-	'PHP_SELF' => '/index.php',
-	'QUERY_STRING' => 'post-form[title]=hello&post-form[author_id]=12',
-	'HTTP_HOST' => 'localhost:8000',
-	'HTTP_USER_AGENT' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0',
-	'HTTP_ACCEPT_LANGUAGE' => 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
-	'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
-	'HTTP_CONNECTION' => 'keep-alive',
-	'REQUEST_TIME_FLOAT' => 1369146454.0856,
-	'REQUEST_TIME' => 1369146454,
-];
-
- - */ ?> - - - - - diff --git a/framework/yii/views/errorHandler/callStackItem.php b/framework/yii/views/errorHandler/callStackItem.php new file mode 100644 index 0000000..e4ac1bf --- /dev/null +++ b/framework/yii/views/errorHandler/callStackItem.php @@ -0,0 +1,34 @@ +context; +?> + +
  • +
    +
    + . + in htmlEncode($file); ?> + at line + +
    +
    +
    +
    + +
    + +
    + '; ?> +
    htmlEncode($lines[$i]); ?>
    +
    +
    +
  • diff --git a/framework/yii/views/errorHandler/main.php b/framework/yii/views/errorHandler/main.php new file mode 100644 index 0000000..4ff8c8d --- /dev/null +++ b/framework/yii/views/errorHandler/main.php @@ -0,0 +1,101 @@ +context; +?> + + + + + + + + <?php echo $c->htmlEncode($e->getName() . ' – ' . get_class($e)); ?> + + <?php echo $c->htmlEncode(get_class($e)); ?> + + + + + + + + + + +
    + Attention +

    + ExceptionaddTypeLinks(get_class($e)); ?> + + – createHttpStatusLink($e->statusCode); ?> + +

    +

    htmlEncode($e->getName()); ?>

    +
    + +
    +
      + renderCallStackItem($e->getFile(), $e->getLine(), 1); ?> + getTrace(), $length = count($trace); $i < $length; ++$i): ?> + renderCallStackItem($trace[$i]['file'], $trace[$i]['line'], $i + 1); ?> + +
    +
    + + +
    +
    +
    +
    $_GET = [
    +	'show-post' => 100,
    +	'refresh-page' => 'yes',
    +	'ascending-sort' => 1,
    +];
    +
    +$_POST = [
    +	'blog-post-form' => [
    +		'title' => 'hello',
    +		'author_id' => '12',
    +	],
    +];
    +
    +$_SERVER = [
    +	'DOCUMENT_ROOT' => '/home/resurtm/work/data',
    +	'REMOTE_ADDR' => '::1',
    +	'REMOTE_PORT' => '52694',
    +	'SERVER_SOFTWARE' => 'PHP 5.4.3 Development Server',
    +	'SERVER_PROTOCOL' => 'HTTP/1.1',
    +	'SERVER_NAME' => 'localhost',
    +	'SERVER_PORT' => '8000',
    +	'REQUEST_URI' => '/index.php?post-form[title]=hello&post-form[author_id]=12',
    +	'REQUEST_METHOD' => 'GET',
    +	'SCRIPT_NAME' => '/index.php',
    +	'SCRIPT_FILENAME' => '/home/resurtm/work/data/index.php',
    +	'PHP_SELF' => '/index.php',
    +	'QUERY_STRING' => 'post-form[title]=hello&post-form[author_id]=12',
    +	'HTTP_HOST' => 'localhost:8000',
    +	'HTTP_USER_AGENT' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0',
    +	'HTTP_ACCEPT_LANGUAGE' => 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
    +	'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
    +	'HTTP_CONNECTION' => 'keep-alive',
    +	'REQUEST_TIME_FLOAT' => 1369146454.0856,
    +	'REQUEST_TIME' => 1369146454,
    +];
    +
    + + */ ?> + + + + +