예제 #1
0
 /**
  * Parses the stack trace, and makes it look pretty.
  * 
  * This includes adding in the syntax highlighting,
  * highlighting the colours for the files,
  * and padding with whitespace.
  *
  * If stackTrace is null, then null is returned.
  */
 private function parseStackTrace($code, $message, $errLine, $errFile, &$stackTrace, $root, $altInfo = null)
 {
     if ($stackTrace !== null) {
         /*
          * For whitespace padding.
          */
         $lineLen = 0;
         $fileLen = 0;
         // parse the stack trace, and remove the long urls
         foreach ($stackTrace as $i => $trace) {
             if ($trace) {
                 if (isset($trace['line'])) {
                     $lineLen = max($lineLen, strlen($trace['line']));
                 } else {
                     $trace['line'] = '';
                 }
                 $info = '';
                 if ($i === 0 && $altInfo !== null) {
                     $info = $altInfo;
                     /*
                      * Skip for the first iteration,
                      * as it's usually magical PHP calls.
                      */
                 } else {
                     if ($i > 0 && (isset($trace['class']) || isset($trace['type']) || isset($trace['function']))) {
                         $args = array();
                         if (isset($trace['args'])) {
                             foreach ($trace['args'] as $arg) {
                                 $args[] = ErrorHandler::identifyTypeHTML($arg, 1);
                             }
                         }
                         $info = ErrorHandler::syntaxHighlightFunction(isset($trace['class']) ? $trace['class'] : null, isset($trace['type']) ? $trace['type'] : null, isset($trace['function']) ? $trace['function'] : null, $args);
                     } else {
                         if (isset($trace['info']) && $trace['info'] !== '') {
                             $info = ErrorHandler::syntaxHighlight($trace['info']);
                         } else {
                             if (isset($trace['file']) && !isset($trace['info'])) {
                                 $contents = $this->getFileContents($trace['file']);
                                 if ($contents) {
                                     $info = ErrorHandler::syntaxHighlight(trim($contents[$trace['line'] - 1]));
                                 }
                             }
                         }
                     }
                 }
                 $trace['info'] = $info;
                 if (isset($trace['file'])) {
                     list($type, $file) = $this->getFolderType($root, $trace['file']);
                     $trace['file_type'] = $type;
                     $trace['is_native'] = false;
                 } else {
                     $file = '[Internal PHP]';
                     $trace['file_type'] = '';
                     $trace['is_native'] = true;
                 }
                 $trace['file'] = $file;
                 $fileLen = max($fileLen, strlen($file));
                 $stackTrace[$i] = $trace;
             }
         }
         /*
          * We are allowed to highlight just once, that's it.
          */
         $highlightI = -1;
         foreach ($stackTrace as $i => $trace) {
             if ($trace['line'] === $errLine && $trace['file'] === $errFile) {
                 $highlightI = $i;
                 break;
             }
         }
         foreach ($stackTrace as $i => $trace) {
             if ($trace) {
                 // line
                 $line = str_pad($trace['line'], $lineLen, ' ', STR_PAD_LEFT);
                 // file
                 $file = $trace['file'];
                 $fileKlass = '';
                 if ($trace['is_native']) {
                     $fileKlass = 'file-internal-php';
                 } else {
                     $fileKlass = 'filename ' . ErrorHandler::folderTypeToCSS($trace['file_type']);
                 }
                 $file = $file . str_pad('', $fileLen - strlen($file), ' ', STR_PAD_LEFT);
                 // info
                 $info = $trace['info'];
                 if ($info) {
                     $info = str_replace("\n", '\\n', $info);
                     $info = str_replace("\r", '\\r', $info);
                 } else {
                     $info = ' ';
                 }
                 // line + file + info
                 $stackStr = "<td class='linenumber'>{$line}</td>" . "<td class='{$fileKlass}'>{$file}</td>" . "<td class='lineinfo'>{$info}</td>";
                 if ($trace['is_native']) {
                     $cssClass = 'is-native ';
                 } else {
                     $cssClass = '';
                 }
                 if ($highlightI === $i) {
                     $cssClass .= ' highlight';
                 } else {
                     if ($highlightI > $i) {
                         $cssClass .= ' pre-highlight';
                     }
                 }
                 if ($i !== 0 && isset($trace['exception']) && $trace['exception']) {
                     $ex = $trace['exception'];
                     $exHtml = '<tr class="error-stack-trace-exception"><td>' . 'exception &quot;' . htmlspecialchars($ex->getMessage()) . '&quot;' . '</td></tr>';
                 } else {
                     $exHtml = '';
                 }
                 $data = '';
                 if (isset($trace['file-lines-id'])) {
                     $data = 'data-file-lines-id="' . $trace['file-lines-id'] . '"';
                 }
                 $stackTrace[$i] = "{$exHtml}<tr class='error-stack-trace-line {$cssClass}' {$data}>{$stackStr}</tr>";
             }
         }
         return '<table id="error-stack-trace">' . join("", $stackTrace) . '</table>';
     } else {
         return null;
     }
 }