HttpError::report()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation; either version 2 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License along
14
 * with this program; if not, write to the Free Software Foundation, Inc.,
15
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
 * http://www.gnu.org/copyleft/gpl.html
17
 *
18
 * @file
19
 */
20
21
use MediaWiki\Logger\LoggerFactory;
22
23
/**
24
 * Show an error that looks like an HTTP server error.
25
 * Replacement for wfHttpError().
26
 *
27
 * @since 1.19
28
 * @ingroup Exception
29
 */
30
class HttpError extends MWException {
31
	private $httpCode, $header, $content;
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
32
33
	/**
34
	 * Constructor
35
	 *
36
	 * @param int $httpCode HTTP status code to send to the client
37
	 * @param string|Message $content Content of the message
38
	 * @param string|Message|null $header Content of the header (\<title\> and \<h1\>)
39
	 */
40
	public function __construct( $httpCode, $content, $header = null ) {
41
		parent::__construct( $content );
42
		$this->httpCode = (int)$httpCode;
43
		$this->header = $header;
44
		$this->content = $content;
45
	}
46
47
	/**
48
	 * We don't want the default exception logging as we got our own logging set
49
	 * up in self::report.
50
	 *
51
	 * @see MWException::isLoggable
52
	 *
53
	 * @since 1.24
54
	 * @return bool
55
	 */
56
	public function isLoggable() {
57
		return false;
58
	}
59
60
	/**
61
	 * Returns the HTTP status code supplied to the constructor.
62
	 *
63
	 * @return int
64
	 */
65
	public function getStatusCode() {
66
		return $this->httpCode;
67
	}
68
69
	/**
70
	 * Report and log the HTTP error.
71
	 * Sends the appropriate HTTP status code and outputs an
72
	 * HTML page with an error message.
73
	 */
74
	public function report() {
75
		$this->doLog();
76
77
		HttpStatus::header( $this->httpCode );
78
		header( 'Content-type: text/html; charset=utf-8' );
79
80
		print $this->getHTML();
81
	}
82
83
	private function doLog() {
84
		$logger = LoggerFactory::getInstance( 'HttpError' );
85
		$content = $this->content;
86
87
		if ( $content instanceof Message ) {
88
			$content = $content->text();
89
		}
90
91
		$context = [
92
			'file' => $this->getFile(),
93
			'line' => $this->getLine(),
94
			'http_code' => $this->httpCode,
95
		];
96
97
		$logMsg = "$content ({http_code}) from {file}:{line}";
98
99
		if ( $this->getStatusCode() < 500 ) {
100
			$logger->info( $logMsg, $context );
101
		} else {
102
			$logger->error( $logMsg, $context );
103
		}
104
	}
105
106
	/**
107
	 * Returns HTML for reporting the HTTP error.
108
	 * This will be a minimal but complete HTML document.
109
	 *
110
	 * @return string HTML
111
	 */
112
	public function getHTML() {
113
		if ( $this->header === null ) {
114
			$titleHtml = htmlspecialchars( HttpStatus::getMessage( $this->httpCode ) );
115
		} elseif ( $this->header instanceof Message ) {
116
			$titleHtml = $this->header->escaped();
117
		} else {
118
			$titleHtml = htmlspecialchars( $this->header );
119
		}
120
121
		if ( $this->content instanceof Message ) {
122
			$contentHtml = $this->content->escaped();
123
		} else {
124
			$contentHtml = nl2br( htmlspecialchars( $this->content ) );
125
		}
126
127
		return "<!DOCTYPE html>\n" .
128
		"<html><head><title>$titleHtml</title></head>\n" .
129
		"<body><h1>$titleHtml</h1><p>$contentHtml</p></body></html>\n";
130
	}
131
}
132