GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 2ab419...940f7c )
by Robert
32:50
created

ErrorHandler::isCoreFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
cc 2
eloc 2
nc 2
nop 1
crap 6
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\web;
9
10
use Yii;
11
use yii\base\Exception;
12
use yii\base\ErrorException;
13
use yii\base\UserException;
14
use yii\helpers\VarDumper;
15
16
/**
17
 * ErrorHandler handles uncaught PHP errors and exceptions.
18
 *
19
 * ErrorHandler displays these errors using appropriate views based on the
20
 * nature of the errors and the mode the application runs at.
21
 *
22
 * ErrorHandler is configured as an application component in [[\yii\base\Application]] by default.
23
 * You can access that instance via `Yii::$app->errorHandler`.
24
 *
25
 * For more details and usage information on ErrorHandler, see the [guide article on handling errors](guide:runtime-handling-errors).
26
 *
27
 * @author Qiang Xue <[email protected]>
28
 * @author Timur Ruziev <[email protected]>
29
 * @since 2.0
30
 */
31
class ErrorHandler extends \yii\base\ErrorHandler
32
{
33
    /**
34
     * @var integer maximum number of source code lines to be displayed. Defaults to 19.
35
     */
36
    public $maxSourceLines = 19;
37
    /**
38
     * @var integer maximum number of trace source code lines to be displayed. Defaults to 13.
39
     */
40
    public $maxTraceSourceLines = 13;
41
    /**
42
     * @var string the route (e.g. `site/error`) to the controller action that will be used
43
     * to display external errors. Inside the action, it can retrieve the error information
44
     * using `Yii::$app->errorHandler->exception`. This property defaults to null, meaning ErrorHandler
45
     * will handle the error display.
46
     */
47
    public $errorAction;
48
    /**
49
     * @var string the path of the view file for rendering exceptions without call stack information.
50
     */
51
    public $errorView = '@yii/views/errorHandler/error.php';
52
    /**
53
     * @var string the path of the view file for rendering exceptions.
54
     */
55
    public $exceptionView = '@yii/views/errorHandler/exception.php';
56
    /**
57
     * @var string the path of the view file for rendering exceptions and errors call stack element.
58
     */
59
    public $callStackItemView = '@yii/views/errorHandler/callStackItem.php';
60
    /**
61
     * @var string the path of the view file for rendering previous exceptions.
62
     */
63
    public $previousExceptionView = '@yii/views/errorHandler/previousException.php';
64
    /**
65
     * @var array list of the PHP predefined variables that should be displayed on the error page.
66
     * Note that a variable must be accessible via `$GLOBALS`. Otherwise it won't be displayed.
67
     * Defaults to `['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION']`.
68
     * @see renderRequest()
69
     * @since 2.0.7
70
     */
71
    public $displayVars = ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION'];
72
73
74
    /**
75
     * Renders the exception.
76
     * @param \Exception $exception the exception to be rendered.
77
     */
78
    protected function renderException($exception)
79
    {
80
        if (Yii::$app->has('response')) {
81
            $response = Yii::$app->getResponse();
82
            // reset parameters of response to avoid interference with partially created response data
83
            // in case the error occurred while sending the response.
84
            $response->isSent = false;
85
            $response->stream = null;
86
            $response->data = null;
87
            $response->content = null;
88
        } else {
89
            $response = new Response();
90
        }
91
92
        $useErrorView = $response->format === Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException);
93
94
        if ($useErrorView && $this->errorAction !== null) {
95
            $result = Yii::$app->runAction($this->errorAction);
96
            if ($result instanceof Response) {
97
                $response = $result;
98
            } else {
99
                $response->data = $result;
100
            }
101
        } elseif ($response->format === Response::FORMAT_HTML) {
102
            if (YII_ENV_TEST || isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
103
                // AJAX request
104
                $response->data = '<pre>' . $this->htmlEncode(static::convertExceptionToString($exception)) . '</pre>';
105
            } else {
106
                // if there is an error during error rendering it's useful to
107
                // display PHP error in debug mode instead of a blank screen
108
                if (YII_DEBUG) {
109
                    ini_set('display_errors', 1);
110
                }
111
                $file = $useErrorView ? $this->errorView : $this->exceptionView;
112
                $response->data = $this->renderFile($file, [
113
                    'exception' => $exception,
114
                ]);
115
            }
116
        } elseif ($response->format === Response::FORMAT_RAW) {
117
            $response->data = static::convertExceptionToString($exception);
118
        } else {
119
            $response->data = $this->convertExceptionToArray($exception);
120
        }
121
122
        if ($exception instanceof HttpException) {
123
            $response->setStatusCode($exception->statusCode);
124
        } else {
125
            $response->setStatusCode(500);
126
        }
127
128
        $response->send();
129
    }
130
131
    /**
132
     * Converts an exception into an array.
133
     * @param \Exception $exception the exception being converted
134
     * @return array the array representation of the exception.
135
     */
136
    protected function convertExceptionToArray($exception)
137
    {
138
        if (!YII_DEBUG && !$exception instanceof UserException && !$exception instanceof HttpException) {
139
            $exception = new HttpException(500, Yii::t('yii', 'An internal server error occurred.'));
140
        }
141
142
        $array = [
143
            'name' => ($exception instanceof Exception || $exception instanceof ErrorException) ? $exception->getName() : 'Exception',
144
            'message' => $exception->getMessage(),
145
            'code' => $exception->getCode(),
146
        ];
147
        if ($exception instanceof HttpException) {
148
            $array['status'] = $exception->statusCode;
149
        }
150
        if (YII_DEBUG) {
151
            $array['type'] = get_class($exception);
152
            if (!$exception instanceof UserException) {
153
                $array['file'] = $exception->getFile();
154
                $array['line'] = $exception->getLine();
155
                $array['stack-trace'] = explode("\n", $exception->getTraceAsString());
156
                if ($exception instanceof \yii\db\Exception) {
157
                    $array['error-info'] = $exception->errorInfo;
158
                }
159
            }
160
        }
161
        if (($prev = $exception->getPrevious()) !== null) {
162
            $array['previous'] = $this->convertExceptionToArray($prev);
163
        }
164
165
        return $array;
166
    }
167
168
    /**
169
     * Converts special characters to HTML entities.
170
     * @param string $text to encode.
171
     * @return string encoded original text.
172
     */
173
    public function htmlEncode($text)
174
    {
175
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
176
    }
177
178
    /**
179
     * Adds informational links to the given PHP type/class.
180
     * @param string $code type/class name to be linkified.
181
     * @return string linkified with HTML type/class name.
182
     */
183
    public function addTypeLinks($code)
184
    {
185
        if (preg_match('/(.*?)::([^(]+)/', $code, $matches)) {
186
            $class = $matches[1];
187
            $method = $matches[2];
188
            $text = $this->htmlEncode($class) . '::' . $this->htmlEncode($method);
189
        } else {
190
            $class = $code;
191
            $method = null;
192
            $text = $this->htmlEncode($class);
193
        }
194
195
        $url = null;
196
197
        $shouldGenerateLink = true;
198
        if ($method !== null) {
199
            $reflection = new \ReflectionMethod($class, $method);
200
            $shouldGenerateLink = $reflection->isPublic() || $reflection->isProtected();
201
        }
202
203
        if ($shouldGenerateLink) {
204
            $url = $this->getTypeUrl($class, $method);
205
        }
206
207
        if ($url === null) {
208
            return $text;
209
        }
210
211
        return '<a href="' . $url . '" target="_blank">' . $text . '</a>';
212
    }
213
214
    /**
215
     * Returns the informational link URL for a given PHP type/class.
216
     * @param string $class the type or class name.
217
     * @param string|null $method the method name.
218
     * @return string|null the informational link URL.
219
     * @see addTypeLinks()
220
     */
221
    protected function getTypeUrl($class, $method)
222
    {
223
        if (strpos($class, 'yii\\') !== 0) {
224
            return null;
225
        }
226
227
        $page = $this->htmlEncode(strtolower(str_replace('\\', '-', $class)));
228
        $url = "http://www.yiiframework.com/doc-2.0/$page.html";
229
        if ($method) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $method of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
230
            $url .= "#$method()-detail";
231
        }
232
233
        return $url;
234
    }
235
236
    /**
237
     * Renders a view file as a PHP script.
238
     * @param string $_file_ the view file.
239
     * @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file.
240
     * @return string the rendering result
241
     */
242
    public function renderFile($_file_, $_params_)
243
    {
244
        $_params_['handler'] = $this;
245
        if ($this->exception instanceof ErrorException || !Yii::$app->has('view')) {
246
            ob_start();
247
            ob_implicit_flush(false);
248
            extract($_params_, EXTR_OVERWRITE);
249
            require(Yii::getAlias($_file_));
250
251
            return ob_get_clean();
252
        } else {
253
            return Yii::$app->getView()->renderFile($_file_, $_params_, $this);
254
        }
255
    }
256
257
    /**
258
     * Renders the previous exception stack for a given Exception.
259
     * @param \Exception $exception the exception whose precursors should be rendered.
260
     * @return string HTML content of the rendered previous exceptions.
261
     * Empty string if there are none.
262
     */
263
    public function renderPreviousExceptions($exception)
264
    {
265
        if (($previous = $exception->getPrevious()) !== null) {
266
            return $this->renderFile($this->previousExceptionView, ['exception' => $previous]);
267
        } else {
268
            return '';
269
        }
270
    }
271
272
    /**
273
     * Renders a single call stack element.
274
     * @param string|null $file name where call has happened.
275
     * @param integer|null $line number on which call has happened.
276
     * @param string|null $class called class name.
277
     * @param string|null $method called function/method name.
278
     * @param array $args array of method arguments.
279
     * @param integer $index number of the call stack element.
280
     * @return string HTML content of the rendered call stack element.
281
     */
282
    public function renderCallStackItem($file, $line, $class, $method, $args, $index)
283
    {
284
        $lines = [];
285
        $begin = $end = 0;
286
        if ($file !== null && $line !== null) {
287
            $line--; // adjust line number from one-based to zero-based
288
            $lines = @file($file);
289
            if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line) {
290
                return '';
291
            }
292
293
            $half = (int) (($index === 1 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2);
294
            $begin = $line - $half > 0 ? $line - $half : 0;
295
            $end = $line + $half < $lineCount ? $line + $half : $lineCount - 1;
296
        }
297
298
        return $this->renderFile($this->callStackItemView, [
299
            'file' => $file,
300
            'line' => $line,
301
            'class' => $class,
302
            'method' => $method,
303
            'index' => $index,
304
            'lines' => $lines,
305
            'begin' => $begin,
306
            'end' => $end,
307
            'args' => $args,
308
        ]);
309
    }
310
311
    /**
312
     * Renders the global variables of the request.
313
     * List of global variables is defined in [[displayVars]].
314
     * @return string the rendering result
315
     * @see displayVars
316
     */
317
    public function renderRequest()
318
    {
319
        $request = '';
320
        foreach ($this->displayVars as $name) {
321
            if (!empty($GLOBALS[$name])) {
322
                $request .= '$' . $name . ' = ' . VarDumper::export($GLOBALS[$name]) . ";\n\n";
323
            }
324
        }
325
326
        return '<pre>' . rtrim($request, "\n") . '</pre>';
327
    }
328
329
    /**
330
     * Determines whether given name of the file belongs to the framework.
331
     * @param string $file name to be checked.
332
     * @return boolean whether given name of the file belongs to the framework.
333
     */
334
    public function isCoreFile($file)
335
    {
336
        return $file === null || strpos(realpath($file), YII2_PATH . DIRECTORY_SEPARATOR) === 0;
337
    }
338
339
    /**
340
     * Creates HTML containing link to the page with the information on given HTTP status code.
341
     * @param integer $statusCode to be used to generate information link.
342
     * @param string $statusDescription Description to display after the the status code.
343
     * @return string generated HTML with HTTP status code information.
344
     */
345
    public function createHttpStatusLink($statusCode, $statusDescription)
346
    {
347
        return '<a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#' . (int) $statusCode . '" target="_blank">HTTP ' . (int) $statusCode . ' &ndash; ' . $statusDescription . '</a>';
348
    }
349
350
    /**
351
     * Creates string containing HTML link which refers to the home page of determined web-server software
352
     * and its full name.
353
     * @return string server software information hyperlink.
354
     */
355
    public function createServerInformationLink()
356
    {
357
        $serverUrls = [
358
            'http://httpd.apache.org/' => ['apache'],
359
            'http://nginx.org/' => ['nginx'],
360
            'http://lighttpd.net/' => ['lighttpd'],
361
            'http://gwan.com/' => ['g-wan', 'gwan'],
362
            'http://iis.net/' => ['iis', 'services'],
363
            'http://php.net/manual/en/features.commandline.webserver.php' => ['development'],
364
        ];
365
        if (isset($_SERVER['SERVER_SOFTWARE'])) {
366
            foreach ($serverUrls as $url => $keywords) {
367
                foreach ($keywords as $keyword) {
368
                    if (stripos($_SERVER['SERVER_SOFTWARE'], $keyword) !== false) {
369
                        return '<a href="' . $url . '" target="_blank">' . $this->htmlEncode($_SERVER['SERVER_SOFTWARE']) . '</a>';
370
                    }
371
                }
372
            }
373
        }
374
375
        return '';
376
    }
377
378
    /**
379
     * Creates string containing HTML link which refers to the page with the current version
380
     * of the framework and version number text.
381
     * @return string framework version information hyperlink.
382
     */
383
    public function createFrameworkVersionLink()
384
    {
385
        return '<a href="http://github.com/yiisoft/yii2/" target="_blank">' . $this->htmlEncode(Yii::getVersion()) . '</a>';
386
    }
387
388
    /**
389
     * Converts arguments array to its string representation
390
     *
391
     * @param array $args arguments array to be converted
392
     * @return string string representation of the arguments array
393
     */
394
    public function argumentsToString($args)
395
    {
396
        $count = 0;
397
        $isAssoc = $args !== array_values($args);
398
399
        foreach ($args as $key => $value) {
400
            $count++;
401
            if ($count>=5) {
402
                if ($count>5) {
403
                    unset($args[$key]);
404
                } else {
405
                    $args[$key] = '...';
406
                }
407
                continue;
408
            }
409
410
            if (is_object($value)) {
411
                $args[$key] = '<span class="title">' . $this->htmlEncode(get_class($value)) . '</span>';
412
            } elseif (is_bool($value)) {
413
                $args[$key] = '<span class="keyword">' . ($value ? 'true' : 'false') . '</span>';
414
            } elseif (is_string($value)) {
415
                $fullValue = $this->htmlEncode($value);
416
                if (mb_strlen($value, 'UTF-8') > 32) {
417
                    $displayValue = $this->htmlEncode(mb_substr($value, 0, 32, 'UTF-8')) . '...';
418
                    $args[$key] = "<span class=\"string\" title=\"$fullValue\">'$displayValue'</span>";
419
                } else {
420
                    $args[$key] = "<span class=\"string\">'$fullValue'</span>";
421
                }
422
            } elseif (is_array($value)) {
423
                $args[$key] = '[' . $this->argumentsToString($value) . ']';
424
            } elseif ($value === null) {
425
                $args[$key] = '<span class="keyword">null</span>';
426
            } elseif (is_resource($value)) {
427
                $args[$key] = '<span class="keyword">resource</span>';
428
            } else {
429
                $args[$key] = '<span class="number">' . $value . '</span>';
430
            }
431
432
            if (is_string($key)) {
433
                $args[$key] = '<span class="string">\'' . $this->htmlEncode($key) . "'</span> => $args[$key]";
434
            } elseif ($isAssoc) {
435
                $args[$key] = "<span class=\"number\">$key</span> => $args[$key]";
436
            }
437
        }
438
439
        return implode(', ', $args);
440
    }
441
442
    /**
443
     * Returns human-readable exception name
444
     * @param \Exception $exception
445
     * @return string human-readable exception name or null if it cannot be determined
446
     */
447
    public function getExceptionName($exception)
448
    {
449
        if ($exception instanceof \yii\base\Exception || $exception instanceof \yii\base\InvalidCallException || $exception instanceof \yii\base\InvalidParamException || $exception instanceof \yii\base\UnknownMethodException) {
450
            return $exception->getName();
451
        }
452
        return null;
453
    }
454
}
455