From 3945c2ad5249996e7ae1dc8c824e6d14ca2d2e6c Mon Sep 17 00:00:00 2001 From: tobi132 Date: Tue, 16 Jul 2019 20:07:32 +0200 Subject: [PATCH] New, beautiful exception handler --- common.php | 3 +- images/error.ico | Bin 0 -> 4286 bytes system/exception.php | 47 ++++ system/libs/SensitiveException.php | 3 + system/templates/exception.html.twig | 77 +++++++ tools/js/html5shiv.js | 326 +++++++++++++++++++++++++++ 6 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 images/error.ico create mode 100644 system/exception.php create mode 100644 system/libs/SensitiveException.php create mode 100644 system/templates/exception.html.twig create mode 100644 tools/js/html5shiv.js diff --git a/common.php b/common.php index 37a85ec1..fdc6dd2e 100644 --- a/common.php +++ b/common.php @@ -105,4 +105,5 @@ if(isset($_SERVER['HTTP_HOST'])) { //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); } -?> + +require SYSTEM . 'exception.php'; \ No newline at end of file diff --git a/images/error.ico b/images/error.ico new file mode 100644 index 0000000000000000000000000000000000000000..c31ef7f03ceff46d8e2e65d95d3ca44bcb8ead2a GIT binary patch literal 4286 zcmeI0F-`+95Je}rpbQlyq@>^gbmSa}yRf3*6jTVI6o`rgxJHx_6^bGbfKnoaF#j(x z8?0pGu^l9&b@bz1Z)V`A9g$rTIe@SvLx}6?!y(u`L9a?NCI<}5 zHG6{DC5o|$9;w-g_6zox@|?CgVjrT}?_i!ntP$!2;#wP@*IGP8vzccE zXfWJO1b>AG6`MIO0ys|Hc_csZpk_1v5!z}z@Yp>l_zNED-okUO?htb{*KI;PdA_e{ z*`getMessage(); + if($exception instanceof SensitiveException) { + $message = 'This error is sensitive and will be logged into system/logs/error.log.
View this file for further informations.'; + + // log error to file + $f = fopen(LOGS . 'error.log', 'ab'); + if(!$f) { + $message = 'We wanted to save detailed informations about this error, but file: ' . LOGS . "error.log couldn't be opened for writing.. so the detailed information couldn't be saved.. are you sure directory system/logs is writable by web server? Correct this, and then refresh this site."; + } + else { + fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $exception->getMessage() . PHP_EOL); + fclose($f); + } + } + + $backtrace_formatted = nl2br($exception->getTraceAsString()); + + // display basic error message without template + // template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right + $template_file = SYSTEM . 'templates/exception.html.twig'; + if(!file_exists($template_file)) { + echo 'Something went terribly wrong..

'; + echo "$message

"; + echo 'Backtrace:
'; + echo $backtrace_formatted; + return; + } + + // display beautiful error message + // the file is .twig.html, but its not really parsed by Twig + // we just replace some values manually + // cause in case Twig throws exception, we can show it too + $content = file_get_contents($template_file); + $content = str_replace(array('{{ BASE_URL }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); + + echo $content; +} + +set_exception_handler('exception_handler'); diff --git a/system/libs/SensitiveException.php b/system/libs/SensitiveException.php new file mode 100644 index 00000000..58978198 --- /dev/null +++ b/system/libs/SensitiveException.php @@ -0,0 +1,3 @@ + + + + + + + Something went wrong... + + + + + + + + + + + +
+

Whoops something went wrong...

+
+ {{ message }} +


+ Backtrace:

+ {{ backtrace }} +
+
+ + + \ No newline at end of file diff --git a/tools/js/html5shiv.js b/tools/js/html5shiv.js new file mode 100644 index 00000000..45ea723d --- /dev/null +++ b/tools/js/html5shiv.js @@ -0,0 +1,326 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +;(function(window, document) { +/*jshint evil:true */ + /** version */ + var version = '3.7.3'; + + /** Preset options */ + var options = window.html5 || {}; + + /** Used to skip problem elements */ + var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; + + /** Not all elements can be cloned in IE **/ + var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; + + /** Detect whether the browser supports default html5 styles */ + var supportsHtml5Styles; + + /** Name of the expando, to work with multiple documents or to re-shiv one document */ + var expando = '_html5shiv'; + + /** The id for the the documents expando */ + var expanID = 0; + + /** Cached data for each document */ + var expandoData = {}; + + /** Detect whether the browser supports unknown elements */ + var supportsUnknownElements; + + (function() { + try { + var a = document.createElement('a'); + a.innerHTML = ''; + //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles + supportsHtml5Styles = ('hidden' in a); + + supportsUnknownElements = a.childNodes.length == 1 || (function() { + // assign a false positive if unable to shiv + (document.createElement)('a'); + var frag = document.createDocumentFragment(); + return ( + typeof frag.cloneNode == 'undefined' || + typeof frag.createDocumentFragment == 'undefined' || + typeof frag.createElement == 'undefined' + ); + }()); + } catch(e) { + // assign a false positive if detection fails => unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Extends the built-in list of html5 elements + * @memberOf html5 + * @param {String|Array} newElements whitespace separated list or array of new element names to shiv + * @param {Document} ownerDocument The context document. + */ + function addElements(newElements, ownerDocument) { + var elements = html5.elements; + if(typeof elements != 'string'){ + elements = elements.join(' '); + } + if(typeof newElements != 'string'){ + newElements = newElements.join(' '); + } + html5.elements = elements +' '+ newElements; + shivDocument(ownerDocument); + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document|DocumentFragment} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i