9use InvalidArgumentException;
 
   11use Symfony\Component\VarDumper\Cloner\AbstractCloner;
 
   12use Symfony\Component\VarDumper\Cloner\VarCloner;
 
   13use UnexpectedValueException;
 
   92        "sublime"  => 
"subl://open?url=file://%file&line=%line",
 
   93        "textmate" => 
"txmt://open?url=file://%file&line=%line",
 
   94        "emacs"    => 
"emacs://open?url=file://%file&line=%line",
 
   95        "macvim"   => 
"mvim://open/?url=file://%file&line=%line",
 
   96        "phpstorm" => 
"phpstorm://open?file=%file&line=%line",
 
   97        "idea"     => 
"idea://open?file=%file&line=%line",
 
   98        "vscode"   => 
"vscode://file/%file:%line",
 
  111        if (ini_get(
'xdebug.file_link_format') || extension_loaded(
'xdebug')) {
 
  113            $this->editors[
'xdebug'] = 
function (
$file, $line) {
 
  114                return str_replace([
'%f', 
'%l'], [
$file, $line], ini_get(
'xdebug.file_link_format'));
 
  119        $this->searchPaths[] = __DIR__ . 
"/../Resources";
 
  122        $this->
blacklist(
'_SERVER', 
'PHP_AUTH_PW');
 
  126        if (class_exists(
'Symfony\Component\VarDumper\Cloner\VarCloner')) {
 
  127            $cloner = 
new VarCloner();
 
  129            $cloner->addCasters([
'*' => 
function ($obj, $a, $stub, $isNested, $filter = 0) {
 
  130                $class = $stub->class;
 
  131                $classes = [$class => $class] + class_parents($class) + class_implements($class);
 
  133                foreach ($classes as $class) {
 
  134                    if (isset(AbstractCloner::$defaultCasters[$class])) {
 
  142            $this->templateHelper->setCloner($cloner);
 
  154            if (PHP_SAPI === 
'cli') {
 
  157                if (isset($_ENV[
'whoops-test'])) {
 
  158                    throw new \Exception(
 
  159                        'Use handleUnconditionally instead of whoops-test' 
  160                        .
' environment variable' 
  168        $templateFile = $this->
getResource(
"views/layout.html.php");
 
  169        $cssFile      = $this->
getResource(
"css/whoops.base.css");
 
  170        $zeptoFile    = $this->
getResource(
"js/zepto.min.js");
 
  171        $prettifyFile = $this->
getResource(
"js/prettify.min.js");
 
  172        $clipboard    = $this->
getResource(
"js/clipboard.min.js");
 
  175        if ($this->customCss) {
 
  176            $customCssFile = $this->
getResource($this->customCss);
 
  188            "stylesheet" => file_get_contents($cssFile),
 
  189            "zepto"      => file_get_contents($zeptoFile),
 
  190            "prettify"   => file_get_contents($prettifyFile),
 
  191            "clipboard"  => file_get_contents($clipboard),
 
  192            "javascript" => file_get_contents($jsFile),
 
  195            "header"                     => $this->
getResource(
"views/header.html.php"),
 
  196            "header_outer"               => $this->
getResource(
"views/header_outer.html.php"),
 
  197            "frame_list"                 => $this->
getResource(
"views/frame_list.html.php"),
 
  198            "frames_description"         => $this->
getResource(
"views/frames_description.html.php"),
 
  199            "frames_container"           => $this->
getResource(
"views/frames_container.html.php"),
 
  200            "panel_details"              => $this->
getResource(
"views/panel_details.html.php"),
 
  201            "panel_details_outer"        => $this->
getResource(
"views/panel_details_outer.html.php"),
 
  202            "panel_left"                 => $this->
getResource(
"views/panel_left.html.php"),
 
  203            "panel_left_outer"           => $this->
getResource(
"views/panel_left_outer.html.php"),
 
  204            "frame_code"                 => $this->
getResource(
"views/frame_code.html.php"),
 
  205            "env_details"                => $this->
getResource(
"views/env_details.html.php"),
 
  208            "name"           => explode(
"\\", 
$inspector->getExceptionName()),
 
  209            "message"        => 
$inspector->getExceptionMessage(),
 
  210            "docref_url"     => 
$inspector->getExceptionDocrefUrl(),
 
  214            "has_frames"     => !!count($frames),
 
  216            "handlers"       => $this->
getRun()->getHandlers(),
 
  218            "active_frames_tab" => count($frames) && $frames->offsetGet(0)->isApplication() ?  
'application' : 
'all',
 
  224                "Files"                 => isset($_FILES) ? $this->
masked($_FILES, 
'_FILES') : [],
 
  228                "Environment Variables" => $this->
masked($_ENV, 
'_ENV'),
 
  232        if (isset($customCssFile)) {
 
  233            $vars[
"stylesheet"] .= file_get_contents($customCssFile);
 
  241        $vars[
"tables"] = array_merge(
$extraTables, $vars[
"tables"]);
 
  246        $vars[
"preface"] = 
"<!--\n\n\n" .  $this->templateHelper->escape($plainTextHandler->generateResponse()) . 
"\n\n\n\n\n\n\n\n\n\n\n-->";
 
  248        $this->templateHelper->setVariables($vars);
 
  249        $this->templateHelper->render($templateFile);
 
  264            foreach ($frames as $frame) {
 
  266                    if (strpos($frame->getFile(), 
$path) === 0) {
 
  267                        $frame->setApplication(
true);
 
  292        return (
string) 
$code;
 
  312        $this->extraTables[$label] = 
$data;
 
  327        if (!is_callable($callback)) {
 
  328            throw new InvalidArgumentException(
'Expecting callback argument to be callable');
 
  337            } 
catch (\Exception $e) {
 
  353        if ($label !== 
null) {
 
  354            return isset($this->extraTables[$label]) ?
 
  355                   $this->extraTables[$label] : [];
 
  370        if (func_num_args() == 0) {
 
  395        $this->editors[$identifier] = $resolver;
 
  415            throw new InvalidArgumentException(
 
  416                "Unknown editor identifier: $editor. Known editors:" .
 
  417                implode(
",", array_keys($this->editors))
 
  446            throw new UnexpectedValueException(
 
  447                __METHOD__ . 
" should always resolve to a string or a valid editor array; got something else instead." 
  451        $editor[
'url'] = str_replace(
"%line", rawurlencode($line), 
$editor[
'url']);
 
  452        $editor[
'url'] = str_replace(
"%file", rawurlencode($filePath), 
$editor[
'url']);
 
  473            throw new UnexpectedValueException(
 
  474                __METHOD__ . 
" should always resolve to a bool; got something else instead." 
  491        if (!$this->editor || (!is_string($this->editor) && !is_callable($this->editor))) {
 
  495        if (is_string($this->editor) && isset($this->editors[$this->editor]) && !is_callable($this->editors[$this->editor])) {
 
  502        if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) {
 
  503            if (is_callable($this->editor)) {
 
  504                $callback = call_user_func($this->editor, $filePath, $line);
 
  506                $callback = call_user_func($this->editors[$this->editor], $filePath, $line);
 
  509            if (is_string($callback)) {
 
  517                'ajax' => isset($callback[
'ajax']) ? $callback[
'ajax'] : 
false,
 
  518                'url' => isset($callback[
'url']) ? $callback[
'url'] : $callback,
 
  531        $this->pageTitle = (string) 
$title;
 
  553        if (!is_dir(
$path)) {
 
  554            throw new InvalidArgumentException(
 
  555                "'$path' is not a valid directory" 
  559        array_unshift($this->searchPaths, 
$path);
 
  570        $this->customCss = 
$name;
 
  596        if (isset($this->resourceCache[$resource])) {
 
  597            return $this->resourceCache[$resource];
 
  602        foreach ($this->searchPaths as 
$path) {
 
  603            $fullPath = 
$path . 
"/$resource";
 
  605            if (is_file($fullPath)) {
 
  607                $this->resourceCache[$resource] = $fullPath;
 
  613        throw new RuntimeException(
 
  614            "Could not find resource '$resource' in any resource paths." 
  615            . 
"(searched: " . join(
", ", $this->searchPaths). 
")" 
  629        return end($allPaths) ?: 
null;
 
  670        $this->templateHelper->setApplicationRootPath($applicationRootPath);
 
  694    private function masked(array $superGlobal, $superGlobalName)
 
  696        $blacklisted = $this->
blacklist[$superGlobalName];
 
  698        $values = $superGlobal;
 
  699        foreach ($blacklisted as 
$key) {
 
  700            if (isset($superGlobal[
$key])) {
 
  701                $values[
$key] = str_repeat(
'*', strlen($superGlobal[
$key]));
 
An exception for terminatinating execution or to throw for unit testing.
Wraps ErrorException; mostly used for typing (at least now) to easily cleanup the stack trace of redu...
Abstract implementation of a Handler.
const QUIT
The Handler has handled the Throwable in some way, and wishes to quit/stop execution.
Handler outputing plaintext error messages.
getEditorHref($filePath, $line)
Given a string file path, and an integer file line, executes the editor resolver and returns,...
addEditor($identifier, $resolver)
blacklist($superGlobalName, $key)
blacklist a sensitive value within one of the superglobal arrays.
setApplicationPaths($applicationPaths)
Set the application paths.
getEditor($filePath, $line)
Given a boolean if the editor link should act as an Ajax request.
addDataTableCallback($label, $callback)
Lazily adds an entry to the list of tables displayed in the table.
handleUnconditionally($value=null)
Allows to disable all attempts to dynamically decide whether to handle or return prematurely.
addResourcePath($path)
Adds a path to the list of paths to be searched for resources.
setApplicationRootPath($applicationRootPath)
Set the application root path.
masked(array $superGlobal, $superGlobalName)
Checks all values within the given superGlobal array.
addCustomCss($name)
Adds a custom css file to be loaded.
getEditorAjax($filePath, $line)
Given a boolean if the editor link should act as an Ajax request.
addDataTable($label, array $data)
Adds an entry to the list of tables displayed in the template.
getExceptionCode()
Get the code of the exception that is currently being handled.
__construct()
Constructor.
getDataTables($label=null)
Returns all the extra data tables registered with this handler.
getExceptionFrames()
Get the stack trace frames of the exception that is currently being handled.
setResourcesPath($resourcesPath)
getApplicationPaths()
Return the application paths.
getResource($resource)
Finds a resource, by its relative path, in all available search paths.
static translateErrorCode($error_code)
Translate ErrorException code into the represented constant.
Exposes useful tools for working with/in templates.
Whoops - php errors for cool kids.
if(empty($password)) $table
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']