3.4.0
This commit is contained in:
@@ -119,7 +119,11 @@ class Frame implements Serializable
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->fileContentsCache = file_get_contents($filePath);
|
||||
try {
|
||||
$this->fileContentsCache = file_get_contents($filePath);
|
||||
} catch (ErrorException $exception) {
|
||||
// Internal file paths of PHP extensions cannot be opened
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fileContentsCache;
|
||||
@@ -187,7 +191,7 @@ class Frame implements Serializable
|
||||
* $frame->getFileLines(); // => array( 0 => '<?php', 1 => '...', ...)
|
||||
* @example
|
||||
* Get one line for this file, starting at line 10 (zero-indexed, remember!)
|
||||
* $frame->getFileLines(9, 1); // array( 10 => '...', 11 => '...')
|
||||
* $frame->getFileLines(9, 1); // array( 9 => '...' )
|
||||
*
|
||||
* @throws InvalidArgumentException if $length is less than or equal to 0
|
||||
* @param int $start
|
||||
|
@@ -61,7 +61,7 @@ class FrameCollection implements ArrayAccess, IteratorAggregate, Serializable, C
|
||||
|
||||
if (!$frame instanceof Frame) {
|
||||
throw new UnexpectedValueException(
|
||||
"Callable to " . __METHOD__ . " must return a Frame object"
|
||||
"Callable to " . __CLASS__ . "::map must return a Frame object"
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -252,7 +252,7 @@ class Inspector
|
||||
}
|
||||
|
||||
if (!extension_loaded('xdebug') || !xdebug_is_enabled()) {
|
||||
return [];
|
||||
return $traces;
|
||||
}
|
||||
|
||||
// Use xdebug to get the full stack trace and remove the shutdown handler stack trace
|
||||
|
@@ -46,6 +46,11 @@ class PlainTextHandler extends Handler
|
||||
*/
|
||||
private $traceFunctionArgsOutputLimit = 1024;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $addPreviousToOutput = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -114,6 +119,21 @@ class PlainTextHandler extends Handler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add previous exceptions to output.
|
||||
* @param bool|null $addPreviousToOutput
|
||||
* @return bool|$this
|
||||
*/
|
||||
public function addPreviousToOutput($addPreviousToOutput = null)
|
||||
{
|
||||
if (func_num_args() == 0) {
|
||||
return $this->addPreviousToOutput;
|
||||
}
|
||||
|
||||
$this->addPreviousToOutput = (bool) $addPreviousToOutput;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add error trace function arguments to output.
|
||||
* Set to True for all frame args, or integer for the n first frame args.
|
||||
@@ -151,14 +171,18 @@ class PlainTextHandler extends Handler
|
||||
public function generateResponse()
|
||||
{
|
||||
$exception = $this->getException();
|
||||
return sprintf(
|
||||
"%s: %s in file %s on line %d%s\n",
|
||||
get_class($exception),
|
||||
$exception->getMessage(),
|
||||
$exception->getFile(),
|
||||
$exception->getLine(),
|
||||
$this->getTraceOutput()
|
||||
);
|
||||
$message = $this->getExceptionOutput($exception);
|
||||
|
||||
if ($this->addPreviousToOutput) {
|
||||
$previous = $exception->getPrevious();
|
||||
while ($previous) {
|
||||
$message .= "\n\nCaused by\n" . $this->getExceptionOutput($previous);
|
||||
$previous = $previous->getPrevious();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $message . $this->getTraceOutput() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,6 +308,22 @@ class PlainTextHandler extends Handler
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception as plain text.
|
||||
* @param \Throwable $exception
|
||||
* @return string
|
||||
*/
|
||||
private function getExceptionOutput($exception)
|
||||
{
|
||||
return sprintf(
|
||||
"%s: %s in file %s on line %d",
|
||||
get_class($exception),
|
||||
$exception->getMessage(),
|
||||
$exception->getFile(),
|
||||
$exception->getLine()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
@@ -17,9 +17,21 @@ use Whoops\Util\TemplateHelper;
|
||||
|
||||
class PrettyPageHandler extends Handler
|
||||
{
|
||||
const EDITOR_SUBLIME = "sublime";
|
||||
const EDITOR_TEXTMATE = "textmate";
|
||||
const EDITOR_EMACS = "emacs";
|
||||
const EDITOR_MACVIM = "macvim";
|
||||
const EDITOR_PHPSTORM = "phpstorm";
|
||||
const EDITOR_IDEA = "idea";
|
||||
const EDITOR_VSCODE = "vscode";
|
||||
const EDITOR_ATOM = "atom";
|
||||
const EDITOR_ESPRESSO = "espresso";
|
||||
const EDITOR_XDEBUG = "xdebug";
|
||||
|
||||
/**
|
||||
* Search paths to be scanned for resources, in the reverse
|
||||
* order they're declared.
|
||||
* Search paths to be scanned for resources.
|
||||
*
|
||||
* Stored in the reverse order they're declared.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -39,6 +51,13 @@ class PrettyPageHandler extends Handler
|
||||
*/
|
||||
private $customCss = null;
|
||||
|
||||
/**
|
||||
* The name of the custom js file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $customJs = null;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
*/
|
||||
@@ -73,19 +92,22 @@ class PrettyPageHandler extends Handler
|
||||
];
|
||||
|
||||
/**
|
||||
* A string identifier for a known IDE/text editor, or a closure
|
||||
* that resolves a string that can be used to open a given file
|
||||
* in an editor. If the string contains the special substrings
|
||||
* %file or %line, they will be replaced with the correct data.
|
||||
* An identifier for a known IDE/text editor.
|
||||
*
|
||||
* Either a string, or a calalble that resolves a string, that can be used
|
||||
* to open a given file in an editor. If the string contains the special
|
||||
* substrings %file or %line, they will be replaced with the correct data.
|
||||
*
|
||||
* @example
|
||||
* "txmt://open?url=%file&line=%line"
|
||||
* @var mixed $editor
|
||||
* "txmt://open?url=%file&line=%line"
|
||||
*
|
||||
* @var callable|string $editor
|
||||
*/
|
||||
protected $editor;
|
||||
|
||||
/**
|
||||
* A list of known editor strings
|
||||
* A list of known editor strings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $editors = [
|
||||
@@ -97,15 +119,18 @@ class PrettyPageHandler extends Handler
|
||||
"idea" => "idea://open?file=%file&line=%line",
|
||||
"vscode" => "vscode://file/%file:%line",
|
||||
"atom" => "atom://core/open/file?filename=%file&line=%line",
|
||||
"espresso" => "x-espresso://open?filepath=%file&lines=%line",
|
||||
];
|
||||
|
||||
/**
|
||||
* @var TemplateHelper
|
||||
*/
|
||||
private $templateHelper;
|
||||
protected $templateHelper;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -114,6 +139,9 @@ class PrettyPageHandler extends Handler
|
||||
$this->editors['xdebug'] = function ($file, $line) {
|
||||
return str_replace(['%f', '%l'], [$file, $line], ini_get('xdebug.file_link_format'));
|
||||
};
|
||||
|
||||
// If xdebug is available, use it as default editor.
|
||||
$this->setEditor('xdebug');
|
||||
}
|
||||
|
||||
// Add the default, local resource search path:
|
||||
@@ -126,10 +154,11 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
if (class_exists('Symfony\Component\VarDumper\Cloner\VarCloner')) {
|
||||
$cloner = new VarCloner();
|
||||
// Only dump object internals if a custom caster exists.
|
||||
// Only dump object internals if a custom caster exists for performance reasons
|
||||
// https://github.com/filp/whoops/pull/404
|
||||
$cloner->addCasters(['*' => function ($obj, $a, $stub, $isNested, $filter = 0) {
|
||||
$class = $stub->class;
|
||||
$classes = [$class => $class] + class_parents($class) + class_implements($class);
|
||||
$classes = [$class => $class] + class_parents($obj) + class_implements($obj);
|
||||
|
||||
foreach ($classes as $class) {
|
||||
if (isset(AbstractCloner::$defaultCasters[$class])) {
|
||||
@@ -177,6 +206,10 @@ class PrettyPageHandler extends Handler
|
||||
$customCssFile = $this->getResource($this->customCss);
|
||||
}
|
||||
|
||||
if ($this->customJs) {
|
||||
$customJsFile = $this->getResource($this->customJs);
|
||||
}
|
||||
|
||||
$inspector = $this->getInspector();
|
||||
$frames = $this->getExceptionFrames();
|
||||
$code = $this->getExceptionCode();
|
||||
@@ -236,6 +269,10 @@ class PrettyPageHandler extends Handler
|
||||
$vars["stylesheet"] .= file_get_contents($customCssFile);
|
||||
}
|
||||
|
||||
if (isset($customJsFile)) {
|
||||
$vars["javascript"] .= file_get_contents($customJsFile);
|
||||
}
|
||||
|
||||
// Add extra entries list of data tables:
|
||||
// @todo: Consolidate addDataTable and addDataTableCallback
|
||||
$extraTables = array_map(function ($table) use ($inspector) {
|
||||
@@ -255,9 +292,9 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stack trace frames of the exception that is currently being handled.
|
||||
* Get the stack trace frames of the exception currently being handled.
|
||||
*
|
||||
* @return \Whoops\Exception\FrameCollection;
|
||||
* @return \Whoops\Exception\FrameCollection
|
||||
*/
|
||||
protected function getExceptionFrames()
|
||||
{
|
||||
@@ -278,7 +315,7 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the code of the exception that is currently being handled.
|
||||
* Get the code of the exception currently being handled.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -305,10 +342,14 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
/**
|
||||
* Adds an entry to the list of tables displayed in the template.
|
||||
*
|
||||
* The expected data is a simple associative array. Any nested arrays
|
||||
* will be flattened with print_r
|
||||
* will be flattened with `print_r`.
|
||||
*
|
||||
* @param string $label
|
||||
* @param array $data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addDataTable($label, array $data)
|
||||
{
|
||||
@@ -317,13 +358,17 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
/**
|
||||
* Lazily adds an entry to the list of tables displayed in the table.
|
||||
* The supplied callback argument will be called when the error is rendered,
|
||||
* it should produce a simple associative array. Any nested arrays will
|
||||
* be flattened with print_r.
|
||||
*
|
||||
* The supplied callback argument will be called when the error is
|
||||
* rendered, it should produce a simple associative array. Any nested
|
||||
* arrays will be flattened with `print_r`.
|
||||
*
|
||||
* @param string $label
|
||||
* @param callable $callback Callable returning an associative array
|
||||
*
|
||||
* @throws InvalidArgumentException If $callback is not callable
|
||||
* @param string $label
|
||||
* @param callable $callback Callable returning an associative array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addDataTableCallback($label, /* callable */ $callback)
|
||||
{
|
||||
@@ -346,9 +391,12 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
/**
|
||||
* Returns all the extra data tables registered with this handler.
|
||||
* Optionally accepts a 'label' parameter, to only return the data
|
||||
* table under that label.
|
||||
* @param string|null $label
|
||||
*
|
||||
* Optionally accepts a 'label' parameter, to only return the data table
|
||||
* under that label.
|
||||
*
|
||||
* @param string|null $label
|
||||
*
|
||||
* @return array[]|callable
|
||||
*/
|
||||
public function getDataTables($label = null)
|
||||
@@ -362,10 +410,14 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to disable all attempts to dynamically decide whether to
|
||||
* handle or return prematurely.
|
||||
* Set this to ensure that the handler will perform no matter what.
|
||||
* @param bool|null $value
|
||||
* Set whether to handle unconditionally.
|
||||
*
|
||||
* Allows to disable all attempts to dynamically decide whether to handle
|
||||
* or return prematurely. Set this to ensure that the handler will perform,
|
||||
* no matter what.
|
||||
*
|
||||
* @param bool|null $value
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function handleUnconditionally($value = null)
|
||||
@@ -378,10 +430,11 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an editor resolver, identified by a string
|
||||
* name, and that may be a string path, or a callable
|
||||
* resolver. If the callable returns a string, it will
|
||||
* be set as the file reference's href attribute.
|
||||
* Adds an editor resolver.
|
||||
*
|
||||
* Either a string, or a closure that resolves a string, that can be used
|
||||
* to open a given file in an editor. If the string contains the special
|
||||
* substrings %file or %line, they will be replaced with the correct data.
|
||||
*
|
||||
* @example
|
||||
* $run->addEditor('macvim', "mvim://open?url=file://%file&line=%line")
|
||||
@@ -390,8 +443,11 @@ class PrettyPageHandler extends Handler
|
||||
* unlink($file);
|
||||
* return "http://stackoverflow.com";
|
||||
* });
|
||||
* @param string $identifier
|
||||
* @param string $resolver
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param string|callable $resolver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addEditor($identifier, $resolver)
|
||||
{
|
||||
@@ -399,18 +455,21 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the editor to use to open referenced files, by a string
|
||||
* identifier, or a callable that will be executed for every
|
||||
* file reference, with a $file and $line argument, and should
|
||||
* return a string.
|
||||
* Set the editor to use to open referenced files.
|
||||
*
|
||||
* Pass either the name of a configured editor, or a closure that directly
|
||||
* resolves an editor string.
|
||||
*
|
||||
* @example
|
||||
* $run->setEditor(function($file, $line) { return "file:///{$file}"; });
|
||||
* @example
|
||||
* $run->setEditor('sublime');
|
||||
*
|
||||
* @param string|callable $editor
|
||||
*
|
||||
* @throws InvalidArgumentException If invalid argument identifier provided
|
||||
* @param string|callable $editor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEditor($editor)
|
||||
{
|
||||
@@ -425,14 +484,13 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string file path, and an integer file line,
|
||||
* executes the editor resolver and returns, if available,
|
||||
* a string that may be used as the href property for that
|
||||
* file reference.
|
||||
* Get the editor href for a given file and line, if available.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
*
|
||||
* @throws InvalidArgumentException If editor resolver does not return a string
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getEditorHref($filePath, $line)
|
||||
@@ -458,13 +516,13 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a boolean if the editor link should
|
||||
* act as an Ajax request. The editor must be a
|
||||
* valid callable function/closure
|
||||
* Determine if the editor link should act as an Ajax request.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
*
|
||||
* @throws UnexpectedValueException If editor resolver does not return a boolean
|
||||
*
|
||||
* @throws UnexpectedValueException If editor resolver does not return a boolean
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
* @return bool
|
||||
*/
|
||||
public function getEditorAjax($filePath, $line)
|
||||
@@ -481,12 +539,11 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a boolean if the editor link should
|
||||
* act as an Ajax request. The editor must be a
|
||||
* valid callable function/closure
|
||||
* Determines both the editor and if ajax should be used.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $line
|
||||
* @return array
|
||||
*/
|
||||
protected function getEditor($filePath, $line)
|
||||
@@ -530,7 +587,10 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
* Set the page title.
|
||||
*
|
||||
* @param string $title
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPageTitle($title)
|
||||
@@ -539,6 +599,8 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the page title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPageTitle()
|
||||
@@ -547,12 +609,12 @@ class PrettyPageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a path to the list of paths to be searched for
|
||||
* resources.
|
||||
* Adds a path to the list of paths to be searched for resources.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws InvalidArgumentException If $path is not a valid directory
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function addResourcePath($path)
|
||||
@@ -569,7 +631,8 @@ class PrettyPageHandler extends Handler
|
||||
/**
|
||||
* Adds a custom css file to be loaded.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addCustomCss($name)
|
||||
@@ -577,6 +640,17 @@ class PrettyPageHandler extends Handler
|
||||
$this->customCss = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom js file to be loaded.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function addCustomJs($name)
|
||||
{
|
||||
$this->customJs = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -587,13 +661,15 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
/**
|
||||
* Finds a resource, by its relative path, in all available search paths.
|
||||
*
|
||||
* The search is performed starting at the last search path, and all the
|
||||
* way back to the first, enabling a cascading-type system of overrides
|
||||
* for all resources.
|
||||
* way back to the first, enabling a cascading-type system of overrides for
|
||||
* all resources.
|
||||
*
|
||||
* @param string $resource
|
||||
*
|
||||
* @throws RuntimeException If resource cannot be found in any of the available paths
|
||||
*
|
||||
* @param string $resource
|
||||
* @return string
|
||||
*/
|
||||
protected function getResource($resource)
|
||||
@@ -639,7 +715,8 @@ class PrettyPageHandler extends Handler
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $resourcesPath
|
||||
* @param string $resourcesPath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setResourcesPath($resourcesPath)
|
||||
@@ -661,6 +738,8 @@ class PrettyPageHandler extends Handler
|
||||
* Set the application paths.
|
||||
*
|
||||
* @param array $applicationPaths
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApplicationPaths($applicationPaths)
|
||||
{
|
||||
@@ -671,6 +750,8 @@ class PrettyPageHandler extends Handler
|
||||
* Set the application root path.
|
||||
*
|
||||
* @param string $applicationRootPath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApplicationRootPath($applicationRootPath)
|
||||
{
|
||||
@@ -680,8 +761,10 @@ class PrettyPageHandler extends Handler
|
||||
/**
|
||||
* blacklist a sensitive value within one of the superglobal arrays.
|
||||
*
|
||||
* @param $superGlobalName string the name of the superglobal array, e.g. '_GET'
|
||||
* @param $key string the key within the superglobal
|
||||
* @param string $superGlobalName The name of the superglobal array, e.g. '_GET'
|
||||
* @param string $key The key within the superglobal
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function blacklist($superGlobalName, $key)
|
||||
{
|
||||
@@ -690,12 +773,14 @@ class PrettyPageHandler extends Handler
|
||||
|
||||
/**
|
||||
* Checks all values within the given superGlobal array.
|
||||
* Blacklisted values will be replaced by a equal length string cointaining only '*' characters.
|
||||
*
|
||||
* We intentionally dont rely on $GLOBALS as it depends on 'auto_globals_jit' php.ini setting.
|
||||
* Blacklisted values will be replaced by a equal length string cointaining
|
||||
* only '*' characters. We intentionally dont rely on $GLOBALS as it
|
||||
* depends on the 'auto_globals_jit' php.ini setting.
|
||||
*
|
||||
* @param array $superGlobal One of the superglobal arrays
|
||||
* @param string $superGlobalName The name of the superglobal array, e.g. '_GET'
|
||||
*
|
||||
* @param $superGlobal array One of the superglobal arrays
|
||||
* @param $superGlobalName string the name of the superglobal array, e.g. '_GET'
|
||||
* @return array $values without sensitive data
|
||||
*/
|
||||
private function masked(array $superGlobal, $superGlobalName)
|
||||
@@ -703,11 +788,13 @@ class PrettyPageHandler extends Handler
|
||||
$blacklisted = $this->blacklist[$superGlobalName];
|
||||
|
||||
$values = $superGlobal;
|
||||
|
||||
foreach ($blacklisted as $key) {
|
||||
if (isset($superGlobal[$key])) {
|
||||
if (isset($superGlobal[$key]) && is_string($superGlobal[$key])) {
|
||||
$values[$key] = str_repeat('*', strlen($superGlobal[$key]));
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ class XmlResponseHandler extends Handler
|
||||
),
|
||||
];
|
||||
|
||||
echo $this->toXml($response);
|
||||
echo self::toXml($response);
|
||||
|
||||
return Handler::QUIT;
|
||||
}
|
||||
|
@@ -12,6 +12,11 @@ body {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.Whoops.container {
|
||||
position: relative;
|
||||
z-index: 9999999999;
|
||||
}
|
||||
|
||||
.panel {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
@@ -414,12 +419,9 @@ pre:not(.prettyprinted) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#copy-button {
|
||||
.rightButton {
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clipboard {
|
||||
opacity: .8;
|
||||
background: none;
|
||||
|
||||
@@ -431,7 +433,7 @@ pre:not(.prettyprinted) {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.clipboard:hover {
|
||||
.rightButton:hover {
|
||||
box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.3);
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
@@ -32,9 +32,9 @@
|
||||
<?php /* List registered handlers, in order of first to last registered */ ?>
|
||||
<div class="data-table-container" id="handlers">
|
||||
<label>Registered Handlers</label>
|
||||
<?php foreach ($handlers as $i => $handler): ?>
|
||||
<div class="handler <?php echo ($handler === $handler) ? 'active' : ''?>">
|
||||
<?php echo $i ?>. <?php echo $tpl->escape(get_class($handler)) ?>
|
||||
<?php foreach ($handlers as $i => $h): ?>
|
||||
<div class="handler <?php echo ($h === $handler) ? 'active' : ''?>">
|
||||
<?php echo $i ?>. <?php echo $tpl->escape(get_class($h)) ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
@@ -1,14 +1,8 @@
|
||||
<div class="frames-description <?php echo $has_frames_tabs ? 'frames-description-application' : '' ?>">
|
||||
<?php if ($has_frames_tabs): ?>
|
||||
<?php if ($active_frames_tab == 'application'): ?>
|
||||
<span href="#" id="application-frames-tab" class="frames-tab frames-tab-active">
|
||||
<a href="#" id="application-frames-tab" class="frames-tab <?php echo $active_frames_tab == 'application' ? 'frames-tab-active' : '' ?>">
|
||||
Application frames (<?php echo $frames->countIsApplication() ?>)
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<a href="#" id="application-frames-tab" class="frames-tab">
|
||||
Application frames (<?php echo $frames->countIsApplication() ?>)
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<a href="#" id="all-frames-tab" class="frames-tab <?php echo $active_frames_tab == 'all' ? 'frames-tab-active' : '' ?>">
|
||||
All frames (<?php echo count($frames) ?>)
|
||||
</a>
|
||||
|
@@ -86,8 +86,11 @@
|
||||
</ul>
|
||||
|
||||
<span id="plain-exception"><?php echo $tpl->escape($plain_exception) ?></span>
|
||||
<button id="copy-button" class="clipboard" data-clipboard-text="<?php echo $tpl->escape($plain_exception) ?>" title="Copy exception details to clipboard">
|
||||
<button id="copy-button" class="rightButton clipboard" data-clipboard-text="<?php echo $tpl->escape($plain_exception) ?>" title="Copy exception details to clipboard">
|
||||
COPY
|
||||
</button>
|
||||
<button id="hide-error" class="rightButton" title="Hide error message" onclick="document.getElementsByClassName('Whoops')[0].style.display = 'none';">
|
||||
HIDE
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
114
kirby/vendor/filp/whoops/src/Whoops/Run.php
vendored
114
kirby/vendor/filp/whoops/src/Whoops/Run.php
vendored
@@ -41,7 +41,25 @@ final class Run implements RunInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a handler to the end of the stack
|
||||
* Explicitly request your handler runs as the last of all currently registered handlers
|
||||
*/
|
||||
public function appendHandler($handler)
|
||||
{
|
||||
array_unshift($this->handlerStack, $this->resolveHandler($handler));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly request your handler runs as the first of all currently registered handlers
|
||||
*/
|
||||
public function prependHandler($handler)
|
||||
{
|
||||
return $this->pushHandler($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register your handler as the last of all currently registered handlers.
|
||||
* Prefer using appendHandler and prependHandler for clarity.
|
||||
*
|
||||
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
|
||||
* @param Callable|HandlerInterface $handler
|
||||
@@ -49,24 +67,12 @@ final class Run implements RunInterface
|
||||
*/
|
||||
public function pushHandler($handler)
|
||||
{
|
||||
if (is_callable($handler)) {
|
||||
$handler = new CallbackHandler($handler);
|
||||
}
|
||||
|
||||
if (!$handler instanceof HandlerInterface) {
|
||||
throw new InvalidArgumentException(
|
||||
"Argument to " . __METHOD__ . " must be a callable, or instance of "
|
||||
. "Whoops\\Handler\\HandlerInterface"
|
||||
);
|
||||
}
|
||||
|
||||
$this->handlerStack[] = $handler;
|
||||
$this->handlerStack[] = $this->resolveHandler($handler);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last handler in the stack and returns it.
|
||||
* Returns null if there"s nothing else to pop.
|
||||
* See removeFirstHandler and removeLastHandler
|
||||
* @return null|HandlerInterface
|
||||
*/
|
||||
public function popHandler()
|
||||
@@ -74,6 +80,23 @@ final class Run implements RunInterface
|
||||
return array_pop($this->handlerStack);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the first handler
|
||||
*/
|
||||
public function removeFirstHandler()
|
||||
{
|
||||
array_pop($this->handlerStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last handler
|
||||
*/
|
||||
public function removeLastHandler()
|
||||
{
|
||||
array_shift($this->handlerStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all handlers, in the
|
||||
* order they were added to the stack.
|
||||
@@ -260,33 +283,35 @@ final class Run implements RunInterface
|
||||
$handlerResponse = null;
|
||||
$handlerContentType = null;
|
||||
|
||||
foreach (array_reverse($this->handlerStack) as $handler) {
|
||||
$handler->setRun($this);
|
||||
$handler->setInspector($inspector);
|
||||
$handler->setException($exception);
|
||||
try {
|
||||
foreach (array_reverse($this->handlerStack) as $handler) {
|
||||
$handler->setRun($this);
|
||||
$handler->setInspector($inspector);
|
||||
$handler->setException($exception);
|
||||
|
||||
// The HandlerInterface does not require an Exception passed to handle()
|
||||
// and neither of our bundled handlers use it.
|
||||
// However, 3rd party handlers may have already relied on this parameter,
|
||||
// and removing it would be possibly breaking for users.
|
||||
$handlerResponse = $handler->handle($exception);
|
||||
// The HandlerInterface does not require an Exception passed to handle()
|
||||
// and neither of our bundled handlers use it.
|
||||
// However, 3rd party handlers may have already relied on this parameter,
|
||||
// and removing it would be possibly breaking for users.
|
||||
$handlerResponse = $handler->handle($exception);
|
||||
|
||||
// Collect the content type for possible sending in the headers.
|
||||
$handlerContentType = method_exists($handler, 'contentType') ? $handler->contentType() : null;
|
||||
// Collect the content type for possible sending in the headers.
|
||||
$handlerContentType = method_exists($handler, 'contentType') ? $handler->contentType() : null;
|
||||
|
||||
if (in_array($handlerResponse, [Handler::LAST_HANDLER, Handler::QUIT])) {
|
||||
// The Handler has handled the exception in some way, and
|
||||
// wishes to quit execution (Handler::QUIT), or skip any
|
||||
// other handlers (Handler::LAST_HANDLER). If $this->allowQuit
|
||||
// is false, Handler::QUIT behaves like Handler::LAST_HANDLER
|
||||
break;
|
||||
if (in_array($handlerResponse, [Handler::LAST_HANDLER, Handler::QUIT])) {
|
||||
// The Handler has handled the exception in some way, and
|
||||
// wishes to quit execution (Handler::QUIT), or skip any
|
||||
// other handlers (Handler::LAST_HANDLER). If $this->allowQuit
|
||||
// is false, Handler::QUIT behaves like Handler::LAST_HANDLER
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$willQuit = $handlerResponse == Handler::QUIT && $this->allowQuit();
|
||||
} finally {
|
||||
$output = $this->system->cleanOutputBuffer();
|
||||
}
|
||||
|
||||
$willQuit = $handlerResponse == Handler::QUIT && $this->allowQuit();
|
||||
|
||||
$output = $this->system->cleanOutputBuffer();
|
||||
|
||||
// If we're allowed to, send output generated by handlers directly
|
||||
// to the output, otherwise, and if the script doesn't quit, return
|
||||
// it so that it may be used by the caller
|
||||
@@ -375,6 +400,7 @@ final class Run implements RunInterface
|
||||
if ($error && Misc::isLevelFatal($error['type'])) {
|
||||
// If there was a fatal error,
|
||||
// it was not handled in handleError yet.
|
||||
$this->allowQuit = false;
|
||||
$this->handleError(
|
||||
$error['type'],
|
||||
$error['message'],
|
||||
@@ -390,6 +416,22 @@ final class Run implements RunInterface
|
||||
*/
|
||||
private $canThrowExceptions = true;
|
||||
|
||||
private function resolveHandler($handler)
|
||||
{
|
||||
if (is_callable($handler)) {
|
||||
$handler = new CallbackHandler($handler);
|
||||
}
|
||||
|
||||
if (!$handler instanceof HandlerInterface) {
|
||||
throw new InvalidArgumentException(
|
||||
"Handler must be a callable, or instance of "
|
||||
. "Whoops\\Handler\\HandlerInterface"
|
||||
);
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo something to the browser
|
||||
* @param string $output
|
||||
|
@@ -26,9 +26,9 @@ class SystemFacade
|
||||
*/
|
||||
public function setErrorHandler(callable $handler, $types = 'use-php-defaults')
|
||||
{
|
||||
// Workaround for PHP 5.5
|
||||
// Since PHP 5.4 the constant E_ALL contains all errors (even E_STRICT)
|
||||
if ($types === 'use-php-defaults') {
|
||||
$types = E_ALL | E_STRICT;
|
||||
$types = E_ALL;
|
||||
}
|
||||
return set_error_handler($handler, $types);
|
||||
}
|
||||
|
@@ -104,7 +104,7 @@ class TemplateHelper
|
||||
{
|
||||
$parts = explode($delimiter, $s);
|
||||
foreach ($parts as &$part) {
|
||||
$part = '<div class="delimiter">' . $part . '</div>';
|
||||
$part = '<span class="delimiter">' . $part . '</span>';
|
||||
}
|
||||
|
||||
return implode($delimiter, $parts);
|
||||
|
Reference in New Issue
Block a user