[ 'title' => 'Emergency', 'class' => 'error' ], 1 => [ 'title' => 'Alert', 'class' => 'error' ], 2 => [ 'title' => 'Critical', 'class' => 'error' ], 3 => [ 'title' => 'Error', 'class' => 'error' ], 4 => [ 'title' => 'Warning', 'class' => 'warning' ], 5 => [ 'title' => 'Notice', 'class' => 'notice' ], 6 => [ 'title' => 'Information', 'class' => 'info' ], 7=> [ 'title' => 'SilverStripe\\Dev\\Debug', 'class' => 'debug' ], E_USER_ERROR => [ 'title' => 'User Error', 'class' => 'error' ], E_CORE_ERROR => [ 'title' => 'Core Error', 'class' => 'error' ], E_NOTICE => [ 'title' => 'Notice', 'class' => 'notice' ], E_USER_NOTICE => [ 'title' => 'User Notice', 'class' => 'notice' ], E_DEPRECATED => [ 'title' => 'Deprecated', 'class' => 'notice' ], E_USER_DEPRECATED => [ 'title' => 'User Deprecated', 'class' => 'notice' ], E_CORE_ERROR => [ 'title' => 'Core Error', 'class' => 'error' ], E_WARNING => [ 'title' => 'Warning', 'class' => 'warning' ], E_CORE_WARNING => [ 'title' => 'Core Warning', 'class' => 'warning' ], E_USER_WARNING => [ 'title' => 'User Warning', 'class' => 'warning' ], E_STRICT => [ 'title' => 'Strict Notice', 'class' => 'notice' ], E_RECOVERABLE_ERROR => [ 'title' => 'Recoverable Error', 'class' => 'warning' ] ]; protected static $unknown_error = [ 'title' => 'Unknown Error', 'class' => 'error' ]; /** * Generate breadcrumb links to the URL path being displayed * * @return string */ public function Breadcrumbs() { $basePath = str_replace(Director::protocolAndHost() ?? '', '', Director::absoluteBaseURL() ?? ''); $relPath = parse_url( substr($_SERVER['REQUEST_URI'] ?? '', strlen($basePath ?? ''), strlen($_SERVER['REQUEST_URI'] ?? '')), PHP_URL_PATH ); $parts = explode('/', $relPath ?? ''); $base = Director::absoluteBaseURL(); $pathPart = ""; $pathLinks = []; foreach ($parts as $part) { if ($part != '') { $pathPart .= "$part/"; $pathLinks[] = "$part"; } } return implode(' → ', $pathLinks); } /** * @deprecated 4.0.1 Use renderHeader() instead */ public function writeHeader() { Deprecation::notice('4.0.1', 'Use renderHeader() instead'); echo $this->renderHeader(); } /** * @deprecated 4.0.1 Use renderInfo() instead */ public function writeInfo($title, $subtitle, $description = false) { Deprecation::notice('4.0.1', 'Use renderInfo() instead'); echo $this->renderInfo($title, $subtitle, $description); } /** * @deprecated 4.0.1 Use renderFooter() instead */ public function writeFooter() { Deprecation::notice('4.0.1', 'Use renderFooter() instead'); echo $this->renderFooter(); } /** * @deprecated 4.0.1 Use renderError() instead */ public function writeError($httpRequest, $errno, $errstr, $errfile, $errline) { Deprecation::notice('4.0.1', 'Use renderError() instead'); echo $this->renderError($httpRequest, $errno, $errstr, $errfile, $errline); } /** * @deprecated 4.0.1 Use renderSourceFragment() instead */ public function writeSourceFragment($lines, $errline) { Deprecation::notice('4.0.1', 'Use renderSourceFragment() instead'); echo $this->renderSourceFragment($lines, $errline); } /** * @deprecated 4.0.1 Use renderTrace() instead */ public function writeTrace($trace) { Deprecation::notice('4.0.1', 'Use renderTrace() instead'); echo $this->renderTrace($trace); } /** * @deprecated 4.0.1 Use renderVariable() instead */ public function writeVariable($val, $caller) { Deprecation::notice('4.0.1', 'Use renderVariable() instead'); echo $this->renderVariable($val, $caller); } /** * Render HTML header for development views * * @param HTTPRequest $httpRequest * @return string */ public function renderHeader($httpRequest = null) { $url = htmlentities( $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'], ENT_COMPAT, 'UTF-8' ); $debugCSS = ModuleResourceLoader::singleton() ->resolveURL('silverstripe/framework:client/styles/debug.css'); $output = '' . $url . ''; $output .= ''; $output .= ''; $output .= ''; $output .= ''; return $output; } /** * Render the information header for the view * * @param string $title The main title * @param string $subtitle The subtitle * @param string|bool $description The description to show * @return string */ public function renderInfo($title, $subtitle, $description = false) { $output = '
'; $output .= "

" . Convert::raw2xml($title) . "

"; if ($subtitle) { $output .= "

" . Convert::raw2xml($subtitle) . "

"; } if ($description) { $output .= "

$description

"; } else { $output .= $this->Breadcrumbs(); } $output .= '
'; return $output; } /** * Render HTML footer for development views * @return string */ public function renderFooter() { return ""; } /** * Render an error. * * @param string $httpRequest the kind of request * @param int $errno Codenumber of the error * @param string $errstr The error message * @param string $errfile The name of the source code file where the error occurred * @param int $errline The line number on which the error occurred * @return string */ public function renderError($httpRequest, $errno, $errstr, $errfile, $errline) { $errorType = isset(self::$error_types[$errno]) ? self::$error_types[$errno] : self::$unknown_error; $httpRequestEnt = htmlentities($httpRequest ?? '', ENT_COMPAT, 'UTF-8'); if (ini_get('html_errors')) { $errstr = strip_tags($errstr ?? ''); } else { $errstr = Convert::raw2xml($errstr); } $output = '
'; $output .= "

[" . $errorType['title'] . '] ' . $errstr . "

"; $output .= "

$httpRequestEnt

"; $output .= "

Line $errline in $errfile

"; $output .= '
'; return $output; } /** * Render a fragment of the a source file * * @param array $lines An array of file lines; the keys should be the original line numbers * @param int $errline The line of the error * @return string */ public function renderSourceFragment($lines, $errline) { $output = '

Source

'; $output .= '
';
        foreach ($lines as $offset => $line) {
            $line = htmlentities($line ?? '', ENT_COMPAT, 'UTF-8');
            if ($offset == $errline) {
                $output .= "$offset $line";
            } else {
                $output .= "$offset $line";
            }
        }
        $output .= '
'; return $output; } /** * Render a call track * * @param array $trace The debug_backtrace() array * @return string */ public function renderTrace($trace) { $output = '
'; $output .= '

Trace

'; $output .= Backtrace::get_rendered_backtrace($trace); $output .= '
'; return $output; } /** * Render an arbitrary paragraph. * * @param string $text The HTML-escaped text to render * @return string */ public function renderParagraph($text) { return '

' . $text . '

'; } /** * Formats the caller of a method * * @param array $caller * @return string */ protected function formatCaller($caller) { $return = basename($caller['file'] ?? '') . ":" . $caller['line']; if (!empty($caller['class']) && !empty($caller['function'])) { $return .= " - {$caller['class']}::{$caller['function']}()"; } return $return; } /** * Outputs a variable in a user presentable way * * @param object $val * @param array $caller Caller information * @return string */ public function renderVariable($val, $caller) { $output = '
';
        $output .= "" . $this->formatCaller($caller) . " - \n";
        if (is_string($val)) {
            $output .= wordwrap($val ?? '', self::config()->columns ?? 0);
        } else {
            $output .= var_export($val, true);
        }
        $output .= '
'; return $output; } public function renderMessage($message, $caller, $showHeader = true) { $header = ''; if ($showHeader) { $file = basename($caller['file'] ?? ''); $line = $caller['line']; $header .= "Debug (line {$line} of {$file}):\n"; } return "

\n" . $header . Convert::raw2xml($message) . "

\n"; } /** * Similar to renderVariable() but respects debug() method on object if available * * @param mixed $val * @param array $caller * @param bool $showHeader * @return string */ public function debugVariable($val, $caller, $showHeader = true) { $text = $this->debugVariableText($val); if ($showHeader) { $callerFormatted = $this->formatCaller($caller); return "
\n
\n" . "

Debug ($callerFormatted)\n

\n" . $text . "
"; } else { return $text; } } /** * Get debug text for this object * * @param mixed $val * @return string */ public function debugVariableText($val) { // Check debug if (is_object($val) && ClassInfo::hasMethod($val, 'debug')) { return $val->debug(); } // Format as array if (is_array($val)) { $result = ''; foreach ($val as $key => $valueItem) { $keyText = Convert::raw2xml($key); $valueText = $this->debugVariableText($valueItem); $result .= "
  • {$keyText} = {$valueText}
  • \n"; } return "\n"; } // Format object if (is_object($val)) { return var_export($val, true); } // Format bool if (is_bool($val)) { return '(bool) ' . ($val ? 'true' : 'false'); } // Format text $html = Convert::raw2xml($val); return "
    {$html}
    \n"; } }