Commit 7ca69f8a authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge remote-tracking branch 'origin/master' into punktetool

parents 975b92c4 dbf51859
......@@ -9,7 +9,7 @@ use qfq;
require_once(__DIR__ . '/../../qfq/qfq/QuickFormQuery.php');
require_once(__DIR__ . '/../../qfq/qfq/exceptions/UserFormException.php');
require_once(__DIR__ . '/../../qfq/qfq/exceptions/UserReportExtension.php');
require_once(__DIR__ . '/../../qfq/qfq/exceptions/UserReportException.php');
require_once(__DIR__ . '/../../qfq/qfq/exceptions/CodeException.php');
require_once(__DIR__ . '/../../qfq/qfq/exceptions/DbException.php');
......@@ -18,6 +18,7 @@ class QfqController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
public function showAction() {
$origErrorReporting = '';
$flagOk = false;
try {
$contentObject = $this->configurationManager->getContentObject();
......@@ -29,6 +30,7 @@ class QfqController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
$qfq = new \qfq\QuickFormQuery($contentObject->data);
$html = $qfq->process();
$flagOk = true;
} catch (qfq\UserFormException $e) {
$html = $e->formatMessage();
......@@ -52,6 +54,10 @@ class QfqController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
$html = "Generic Exception: " . $e->getMessage();
}
if (!$flagOk) {
$html = "<div class='alert alert-warning'>$html</div>";
}
// Restore has to be outside of try/catch - E_NOTICE needs to unset for further T3 handling after an QFQ Exception.
error_reporting($origErrorReporting);
......
......@@ -2448,6 +2448,9 @@ See also at specific *FormElement* definitions.
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| dateFormat | string | yyyy-mm-dd | dd.mm.yyyy |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| decimalFormat | string | [precision,scale] Limits and formats input to a decimal number with the specified precision and scale. |
| | | If no precision and scale are specified, the decimal format is pulled from the table definition. |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| showSeconds | string | 0|1 - Shows the seconds on form load. Default: 0 |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| showZero | string | 0|1 - Empty timestamp: '0'(default) - nothing shown, '1' - the string '0000-00-00 00:00:00' is displayed |
......@@ -2788,6 +2791,8 @@ Type: text
* *hideZero* = 0|1 (optional): `with hideZero=1` a '0' in the value will be replaced by an empty string.
* *emptyMeansNull* = [0|1] (optional): with `emptyMeansNull` or `emptyMeansNull=1` a NULL value will be written if
the value is an empty string
* *inputType* = number (optional). Typically the HTML tag 'type' will be 'text', 'textarea' or 'number' (detected automatically).
If necessary, the HTML tag 'type' might be forced to a specific given value.
.. _`input-typeahead`:
......
......@@ -26,6 +26,7 @@ require_once(__DIR__ . '/helper/Support.php');
require_once(__DIR__ . '/helper/OnArray.php');
require_once(__DIR__ . '/helper/Ldap.php');
require_once(__DIR__ . '/report/Link.php');
require_once(__DIR__ . '/helper/Sanitize.php');
require_once(__DIR__ . '/report/Report.php');
/**
......@@ -41,7 +42,6 @@ abstract class AbstractBuildForm {
protected $wrap = array();
protected $symbol = array();
protected $showDebugInfoFlag = false;
protected $inputCheckPattern = array();
// protected $feDivClass = array(); // Wrap FormElements in <div class="$feDivClass[type]">
......@@ -156,8 +156,6 @@ abstract class AbstractBuildForm {
$this->symbol[SYMBOL_SHOW] = "<span class='glyphicon " . GLYPH_ICON_SHOW . "'></span>";
$this->symbol[SYMBOL_NEW] = "<span class='glyphicon " . GLYPH_ICON_NEW . "'></span>";
$this->symbol[SYMBOL_DELETE] = "<span class='glyphicon " . GLYPH_ICON_DELETE . "'></span>";
$this->inputCheckPattern = Sanitize::inputCheckPatternArray();
}
abstract public function fillWrap();
......@@ -1052,7 +1050,10 @@ abstract class AbstractBuildForm {
$typeAheadUrlParam = $this->typeAheadBuildParam($formElement);
if ($typeAheadUrlParam != '') {
$formElement[FE_TYPE] = FE_TYPE_SEARCH; // typeahead behaves better with 'search' instead of 'text'
if (empty($formElement[FE_INPUT_TYPE])) {
$formElement[FE_INPUT_TYPE] = FE_TYPE_SEARCH; // typeahead behaves better with 'search' instead of 'text'
}
if (empty($formElement[FE_INPUT_AUTOCOMPLETE])) {
$formElement[FE_INPUT_AUTOCOMPLETE] = 'off'; // typeahead behaves better with 'autocomplete'='off'
}
......@@ -1112,6 +1113,18 @@ abstract class AbstractBuildForm {
$value = '';
}
if ($formElement[FE_DECIMAL_FORMAT] !== '') {
$decimalScale = explode(',', $formElement[FE_DECIMAL_FORMAT])[1]; // scale: Nachkommastellen
$value = number_format($value, $decimalScale, '.', '');
}
// In case the user specifies MIN & MAX with numbers, the html tag 'type' has to be 'number', to make the range check work in the browser.
if (empty($formElement[FE_INPUT_TYPE]) && !empty($formElement[FE_MIN]) && !empty($formElement[FE_MAX]) &&
is_numeric($formElement[FE_MIN]) && is_numeric($formElement[FE_MAX])
) {
$formElement[FE_INPUT_TYPE] = 'number';
}
$formElement = HelperFormElement::prepareExtraButton($formElement, !$flagTextarea);
if ($flagTextarea) {
$htmlTag = '<textarea';
......@@ -1121,16 +1134,24 @@ abstract class AbstractBuildForm {
$textarea = htmlentities($value) . '</textarea>';
} else {
$htmlTag = '<input';
$attribute .= $this->getAttributeList($formElement, ['type', 'size']);
if (!empty($formElement[FE_INPUT_TYPE])) {
$formElement[FE_TYPE] = $formElement[FE_INPUT_TYPE];
}
$attribute .= $this->getAttributeList($formElement, [FE_TYPE, 'size']);
$attribute .= Support::doAttribute('value', htmlentities($value), false);
}
$attribute .= $this->getAttributeList($formElement, [FE_INPUT_AUTOCOMPLETE, 'autofocus', 'placeholder']);
$attribute .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
$pattern = Sanitize::getInputCheckPattern($formElement[FE_CHECK_TYPE], $formElement[FE_CHECK_PATTERN], $formElement[FE_DECIMAL_FORMAT], $sanitizeMessage);
$attribute .= ($pattern === '') ? '' : 'pattern="' . $pattern . '" ';
if (empty($formElement[F_FE_DATA_PATTERN_ERROR])) {
$formElement[F_FE_DATA_PATTERN_ERROR] = $sanitizeMessage;
};
$attribute .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR, FE_MIN, FE_MAX]);
$attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
$attribute .= Support::doAttribute('title', $formElement[FE_TOOLTIP]);
$attribute .= $this->getInputCheckPattern($formElement[FE_CHECK_TYPE], $formElement[FE_CHECK_PATTERN]);
$attribute .= $this->getAttributeList($formElement, [FE_MIN, FE_MAX]);
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE], false);
......@@ -1255,7 +1276,7 @@ abstract class AbstractBuildForm {
private function adjustMaxLength(array &$formElement) {
// MIN( $formElement['maxLength'], tabledefinition)
$maxLength = $this->getColumnSize($formElement[FE_NAME]);
$maxLength = $this->getColumnSize($formElement);
$feMaxLength = false;
switch ($formElement[FE_TYPE]) {
......@@ -1295,12 +1316,14 @@ abstract class AbstractBuildForm {
/**
* Get column spec from tabledefinition and parse size of it. If nothing defined, return false.
*
* @param string $column
*
* @return bool|int a) 'false' if there is no length definition, b) length definition, c)
* @param $formElement
* @return bool|int a) 'false' if there is no length definition, b) length definition, c)
* date|time|datetime|timestamp use hardcoded length
*
*/
private function getColumnSize($column) {
private function getColumnSize(array &$formElement) {
$column = $formElement[FE_NAME];
$matches = array();
$typeSpec = $this->store->getVar($column, STORE_TABLE_COLUMN_TYPES);
......@@ -1319,6 +1342,76 @@ abstract class AbstractBuildForm {
break;
}
// $typeSpec = 'tinyint(3) UNSIGNED NOT NULL' | 'int(11) NOT NULL'
$arr = explode(' ', $typeSpec, 2);
if (empty($arr[1])) {
$sign = 'signed';
} else {
$arr = explode(' ', $arr[1], 2);
$sign = $arr[0] == 'unsigned' ? 'unsigned' : 'signed';
}
$arr = explode('(', $typeSpec, 2);
$token = $arr[0];
# s: signed, u: unsigned.
# s-min, s-max, s-checktype, u-min, u-max, u-checktype
$control = [
'tinyint' => [-128, 127, SANITIZE_ALLOW_NUMERICAL, 0, 255, SANITIZE_ALLOW_DIGIT],
'smallint' => [-32768, 32767, SANITIZE_ALLOW_NUMERICAL, 0, 65535, SANITIZE_ALLOW_DIGIT],
'mediumint' => [-8388608, 8388607, SANITIZE_ALLOW_NUMERICAL, 0, 16777215, SANITIZE_ALLOW_DIGIT],
'int' => [0, 4294967295, SANITIZE_ALLOW_NUMERICAL, -2147483648, 2147483647, SANITIZE_ALLOW_DIGIT],
'bigint' => [-9223372036854775808, 9223372036854775807, SANITIZE_ALLOW_NUMERICAL, 0, 18446744073709551615, SANITIZE_ALLOW_DIGIT],
];
$min = false;
$max = false;
$checkType = false;
switch ($token) {
case 'tinyint':
case 'smallint':
case 'mediumint':
case 'int':
case 'bigint':
$arr = $control[$token];
if ($sign == 'signed') {
$min = $arr[0];
$max = $arr[1];
$checkType = $arr[2];
} else {
$min = $arr[3];
$max = $arr[4];
$checkType = $arr[5];
}
break;
case 'decimal':
case 'float':
case 'double':
$checkType = SANITIZE_ALLOW_NUMERICAL;
break;
case 'bit':
$checkType = SANITIZE_ALLOW_DIGIT;
break;
}
if ($min !== false && $formElement[FE_MIN] == '') {
$formElement[FE_MIN] = $min;
}
if ($max !== false && $formElement[FE_MAX] == '') {
$formElement[FE_MAX] = $max;
}
// if given, force Checktype
if ($checkType !== false) {
$formElement[FE_CHECK_TYPE] = $checkType;
if (empty($formElement[FE_INPUT_TYPE])) {
$formElement[FE_INPUT_TYPE] = 'number';
}
}
// e.g.: string(64) >> 64, enum('yes','no') >> false
if (1 === preg_match('/\((.+)\)/', $typeSpec, $matches)) {
if (is_numeric($matches[1]))
......@@ -1374,47 +1467,6 @@ abstract class AbstractBuildForm {
return $attribute;
}
/**
* Construct HTML Input attribute for Client Validation:
*
* type data result
* ------- -----------------------
* ------------------------------------------------------------------------------- min|max <min value>|<max
* value> min="$attrData[0]"|max="$attrData[1]" pattern <regexp> pattern="$data" digit
* - pattern="^[0-9]*$" email -
* pattern="^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$" alnumx -
*
* For 'min/max' and 'pattern' the 'data' will be injected in the attribute string via '%s'.
*
* @param string $type
* @param string $data
*
* @return string
* @throws \qfq\UserFormException
*/
private function getInputCheckPattern($type, $data) {
$attribute = '';
if ($type === '') {
return '';
}
switch ($type) {
case SANITIZE_ALLOW_PATTERN:
$attribute = 'pattern="' . $data . '" ';
break;
case SANITIZE_ALLOW_ALL:
break;
default:
$attribute = 'pattern="' . $this->inputCheckPattern[$type] . '" ';
break;
}
return $attribute;
}
/**
* Set corresponding html attributes readonly/required/disabled, based on $formElement[FE_MODE].
*
......@@ -3147,7 +3199,10 @@ abstract class AbstractBuildForm {
$attribute .= $this->getAttributeList($formElement, [FE_INPUT_AUTOCOMPLETE, 'autofocus', 'placeholder']);
$attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
$attribute .= Support::doAttribute('title', $formElement[FE_TOOLTIP]);
$attribute .= $this->getInputCheckPattern($formElement[FE_CHECK_TYPE], $formElement[FE_CHECK_PATTERN]);
$pattern = Sanitize::getInputCheckPattern($formElement[FE_CHECK_TYPE], $formElement[FE_CHECK_PATTERN], '', $rcSanitizeMessage);
$attribute .= ($pattern === '') ? '' : 'pattern="' . $pattern . '" ';
$attribute .= $this->getAttributeList($formElement, [FE_MIN, FE_MAX]);
$json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
......
......@@ -69,8 +69,6 @@ const SANITIZE_ALLOW_ALNUMX = "alnumx";
const SANITIZE_ALLOW_DIGIT = "digit";
const SANITIZE_ALLOW_NUMERICAL = "numerical";
const SANITIZE_ALLOW_EMAIL = "email";
const SANITIZE_ALLOW_MIN_MAX = "min|max";
const SANITIZE_ALLOW_MIN_MAX_DATE = "min|max date";
const SANITIZE_ALLOW_PATTERN = "pattern";
const SANITIZE_ALLOW_ALLBUT = "allbut";
const SANITIZE_ALLOW_ALL = "all";
......@@ -188,6 +186,7 @@ const ERROR_MISSING_FILE_NAME = 1081;
const ERROR_MAX_FILE_SIZE_TOO_BIG = 1082;
const ERROR_SMALLER_THAN_MIN = 1083;
const ERROR_LARGER_THAN_MAX = 1084;
const ERROR_INVALID_DECIMAL_FORMAT = 1085;
// Subrecord
const ERROR_SUBRECORD_MISSING_COLUMN_ID = 1100;
......@@ -858,6 +857,7 @@ const FE_PLACEHOLDER = 'placeholder';
// FormElement columns: via parameter field
const FE_DATE_FORMAT = 'dateFormat'; // value: FORMAT_DATE_INTERNATIONAL | FORMAT_DATE_GERMAN
const FE_DECIMAL_FORMAT = 'decimalFormat'; // value: 10,2
const FE_SHOW_SECONDS = 'showSeconds'; // value: 0|1
const FE_SHOW_ZERO = 'showZero'; // 0|1 - Used for 'date/datime/time': in case of fe.value='0' shows corresponding '00-00-0000'|'00:00:00'
const FE_HIDE_ZERO = 'hideZero'; // 0|1 - In case of fe.value=0|'0', an empty string is shown.
......@@ -957,6 +957,7 @@ const FE_EMPTY_ITEM_AT_END = 'emptyItemAtEnd';
const FE_SUBRECORD_TABLE_CLASS = 'subrecordTableClass';
const FE_FILE_BUTTON_TEXT = 'fileButtonText';
const FE_FILE_BUTTON_TEXT_DEFAULT = 'Choose File';
const FE_INPUT_TYPE = 'inputType';
const FE_IMAGE_CUT_RESIZE_WIDTH = 'resizeWidth';
const FE_IMAGE_CUT_KEEP_ORIGINAL = 'keepOriginal';
......@@ -1304,3 +1305,30 @@ const AUTOCRON_COUNT = 'count';
// Annotate
const FABRIC_CSS_CLASS = 'fabric';
const EXCEPTION_TYPE = 'Type';
const EXCEPTION_FORM = 'Form';
const EXCEPTION_FORM_ELEMENT = 'Form Element';
const EXCEPTION_FORM_ELEMENT_COLUMN = 'Form Element Column';
const EXCEPTION_SQL_RAW = 'SQL before evaluation';
const EXCEPTION_SQL_FINAL = 'SQL final';
const EXCEPTION_SQL_PARAM_ARRAY = 'SQL Params';
const EXCEPTION_REPORT_COLUMN_INDEX = 'Report column index'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_COLUMN_NAME = 'Report column name'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_COLUMN_VALUE = 'Report column value'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_FULL_LEVEL = 'Report level key';
const EXCEPTION_SIP = 'current sip';
const EXCEPTION_PAGE_ID = 'Page Id';
const EXCEPTION_TT_CONTENT_UID = 'Content Id';
const EXCEPTION_EDIT_FORM = 'Edit form';
const EXCEPTION_TIMESTAMP = 'Timestamp';
const EXCEPTION_CODE = 'Code';
const EXCEPTION_MESSAGE = 'Message';
const EXCEPTION_FILE = 'File';
const EXCEPTION_LINE = 'Line';
const EXCEPTION_STACKTRACE = 'Stacktrace';
const EXCEPTION_TABLE_CLASS = 'table table-hover qfq-table-80';
\ No newline at end of file
......@@ -15,11 +15,13 @@ require_once(__DIR__ . '/../store/Store.php');
require_once(__DIR__ . '/../report/Link.php');
require_once(__DIR__ . '/../database/Database.php');
require_once(__DIR__ . '/UserFormException.php');
require_once(__DIR__ . '/../helper/OnArray.php');
class AbstractException extends \Exception {
public $messageArray = array();
public $messageArrayDebug = array();
public $store = null;
protected $file = '';
......@@ -30,9 +32,9 @@ class AbstractException extends \Exception {
*/
public function formatException() {
$t3Vars = array();
$htmlForm = '';
$arrShow = $this->messageArray;
$htmlDebug = '';
$debug = '';
try {
// In a very early stage, it might be possible that Store can't be initialized: take care not to use it.
$store = Store::getInstance();
......@@ -47,80 +49,70 @@ class AbstractException extends \Exception {
$t3Vars = T3Info::getVars();
}
$html = '';
$arrShow[EXCEPTION_TIMESTAMP] = date('Y.m.d H:i:s O');
$arrShow[EXCEPTION_CODE] = $this->getCode();
$arrShow[EXCEPTION_MESSAGE] = $this->getMessage();
$this->messageArray['File'] = $this->getFile();
$this->messageArray['Line'] = $this->getLine();
$this->messageArray['Message'] = $this->getMessage();
$this->messageArray['Code'] = $this->getCode();
$this->messageArray['Timestamp'] = date('Y.m.d H:i:s O');
//TODO: 'Client' will remove any HTML Tags before displaying. Formatting needs to be solved together with 'Client',
// Respect mode: 'form load' (plain HTML), 'Ajax alert'
$this->messageArray['Stacktrace'] = $this->getTraceAsString();
// $this->messageArray['Stacktrace'] = $this->getTrace();
$html .= "Code: " . htmlspecialchars($this->messageArray['Code']) . "<br>";
$html .= "Message: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray['Message'])) . "<br>";
$html .= 'Page Id: ' . $t3Vars[TYPO3_PAGE_ID] . '<br>';
$html .= 'Content Id: ' . $t3Vars[TYPO3_TT_CONTENT_UID] . '<br>';
// Form
if (isset($this->messageArray['Form']) && $this->messageArray['Form'] != '') {
$htmlForm = "Form: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray['Form'])) . "<br>";
}
if (isset($this->messageArray['Form Element']) && $this->messageArray['Form Element'] != '') {
$html .= "Form Element: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray['Form Element'])) . "<br>";
foreach ([EXCEPTION_FORM, EXCEPTION_FORM_ELEMENT, EXCEPTION_FORM_ELEMENT_COLUMN] as $key) {
if (isset($arrShow[$key])) {
if ($arrShow[$key] == '') {
unset($arrShow[$key]);
}
}
}
// Report
if (isset($this->messageArray[SYSTEM_REPORT_COLUMN_INDEX])) {
$html .= "Column index: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray[SYSTEM_REPORT_COLUMN_INDEX])) . "<br>";
}
// $html .= "Code: " . htmlspecialchars($this->messageArray['Code']) . "<br>";
// $html .= "Message: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray['Message'])) . "<br>";
if (isset($this->messageArray[SYSTEM_REPORT_COLUMN_NAME])) {
$html .= "Column name: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray[SYSTEM_REPORT_COLUMN_NAME])) . "<br>";
}
// Debug Information
if ($store !== null && Support::findInSet(SYSTEM_SHOW_DEBUG_INFO_YES, $store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM))) {
if (isset($this->messageArray[SYSTEM_REPORT_COLUMN_VALUE])) {
$html .= "Column value: " . Support::wrapTag("<strong>", htmlspecialchars($this->messageArray[SYSTEM_REPORT_COLUMN_VALUE])) . "<br>";
}
$arrDebugShow = $this->messageArrayDebug;
if ($store !== null && Support::findInSet(SYSTEM_SHOW_DEBUG_INFO_YES, $store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM))) {
$arrDebugShow[EXCEPTION_SIP] = $store->getStore(STORE_SIP);
$arrDebugShow[EXCEPTION_PAGE_ID] = $t3Vars[TYPO3_PAGE_ID];
$arrDebugShow[EXCEPTION_TT_CONTENT_UID] = $t3Vars[TYPO3_TT_CONTENT_UID];
// In case there is a 'form' name given in SIP, we probably have a problem in a form and a direct link to
// edit the broken form will be helpful.
$storeSystem = $store->getStore(STORE_SYSTEM);
$this->messageArray['current sip'] = $store->getStore(STORE_SIP);
// In case there is a 'form' name given in SIP, we probably have a problem in a form and a direct link to edit the broken form is helpful.
if (!empty($storeSystem[SYSTEM_FORM])) {
$renderedUrl = $this->buildFormLink($storeSystem);
$htmlForm = "Form: " . $renderedUrl . "<br>";
$arrDebugShow[EXCEPTION_EDIT_FORM] = $this->buildFormLink($storeSystem);
}
// Layout
$debug = '<tr bgcolor="#dddddd"><td colspan="2">Exception</td></tr>';
foreach ($this->messageArray as $key => $value) {
// Array to string
if (is_array($value)) {
$value = var_export($value, true);
}
$arrDebugHidden = array();
$arrDebugHidden[EXCEPTION_FILE] = $this->getFile();
$arrDebugHidden[EXCEPTION_LINE] = $this->getLine();
$arrDebugHidden[EXCEPTION_STACKTRACE] = $this->getTraceAsString();
if (!empty($value)) {
$debug .= "<tr>" . "<td>$key</td>" . "<td>" . htmlspecialchars($value) . "</td>" . "</tr>";
}
}
// Optional existing arrays will be flatten.
$arrDebugShow = OnArray::varExportArray($arrDebugShow);
$arrDebugHidden = OnArray::varExportArray($arrDebugHidden);
// Sanitize any HTML content.
$arrDebugShow = OnArray::htmlentitiesOnArray($arrDebugShow);
$arrDebugHidden = OnArray::htmlentitiesOnArray($arrDebugHidden);
$debug = '<table border=1 class="qfq-table-100">' . $debug . "</table>";
$htmlDebug = OnArray::arrayToHtmlTable($arrDebugShow, 'Debug', EXCEPTION_TABLE_CLASS);
$hidden = OnArray::arrayToHtmlTable($arrDebugHidden, 'Details', EXCEPTION_TABLE_CLASS);
// $hidden = 'mein test<br>und mehr content';
// Show / hide with just CSS: http://jsfiddle.net/t5Nf8/1/
$htmlDebug .= "<style>input[type=checkbox]:checked + label + table { display: none; }</style>" .
"<input type='checkbox' checked id='stacktrace'><label for='stacktrace'>&nbsp;Show/hide more details</label>$hidden";
}
$html = "<h2>Error</h2>" . Support::wrapTag('<p>', $html . $htmlForm);
$html = Support::wrapTag("<div class='warning'>", $html);
// Sanitize any HTML content.
$arrShow = OnArray::htmlentitiesOnArray($arrShow);
$html = OnArray::arrayToHtmlTable($arrShow, 'Error', EXCEPTION_TABLE_CLASS);
// foreach ($show as $key => $value) {
// $html .= "$key: " . Support::wrapTag("<strong>", $value) . "<br>";
// }
return $html . $debug;
return $html . $htmlDebug;
}
/**
* Build a FormEditor link to the broken form.
*/
......
......@@ -24,7 +24,7 @@ class CodeException extends AbstractException {
*/
public function formatMessage() {
$this->messageArray['Type'] = 'Code Exception';
$this->messageArrayDebug[EXCEPTION_TYPE] = 'Code Exception';
return parent::formatException();
}
......
......@@ -25,15 +25,17 @@ class DbException extends AbstractException {
*/
public function formatMessage() {
$this->messageArray['Type'] = 'Db Exception';
$this->messageArray['Form'] = Store::getVar(SYSTEM_FORM, STORE_SYSTEM);
$this->messageArray['Form Element'] = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
$this->messageArray['Form Element Column'] = Store::getVar(SYSTEM_FORM_ELEMENT_COLUMN, STORE_SYSTEM);
$this->messageArray['SQL before evaluation'] = Store::getVar(SYSTEM_SQL_RAW, STORE_SYSTEM);
$this->messageArray['SQL final'] = Store::getVar(SYSTEM_SQL_FINAL, STORE_SYSTEM);
$this->messageArray['SQL Params'] = Store::getVar(SYSTEM_SQL_PARAM_ARRAY, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_TYPE] = 'Db Exception';
return parent::formatException();
$this->messageArray[EXCEPTION_FORM] = Store::getVar(SYSTEM_FORM, STORE_SYSTEM);
$this->messageArray[EXCEPTION_FORM_ELEMENT] = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
$this->messageArray[EXCEPTION_FORM_ELEMENT_COLUMN] = Store::getVar(SYSTEM_FORM_ELEMENT_COLUMN, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_SQL_RAW] = Store::getVar(SYSTEM_SQL_RAW, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_SQL_FINAL] = Store::getVar(SYSTEM_SQL_FINAL, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_SQL_PARAM_ARRAY] = Store::getVar(SYSTEM_SQL_PARAM_ARRAY, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_REPORT_FULL_LEVEL] = Store::getVar(SYSTEM_REPORT_FULL_LEVEL, STORE_SYSTEM);
return parent::formatException();
}
}
......@@ -24,7 +24,7 @@ class DownloadException extends AbstractException {
*/
public function formatMessage() {
$this->messageArray['Type'] = 'Download Exception';
$this->messageArrayDebug[EXCEPTION_TYPE] = 'Download Exception';
return parent::formatException();
}
......
......@@ -24,7 +24,7 @@ class ShellException extends AbstractException {
*/
public function formatMessage() {
$this->messageArray['Type'] = 'Shell Exception';
$this->messageArrayDebug[EXCEPTION_TYPE] = 'Shell Exception';
return parent::formatException();
}
......
......@@ -25,10 +25,11 @@ class UserFormException extends AbstractException {
*/
public function formatMessage() {
$this->messageArray['Type'] = 'User Form Exception';
$this->messageArray['Form'] = Store::getVar(SYSTEM_FORM, STORE_SYSTEM);
$this->messageArray['Form Element'] = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
$this->messageArray['Form Element Column'] = Store::getVar(SYSTEM_FORM_ELEMENT_COLUMN, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_TYPE] = 'User Form Exception';
$this->messageArrayDebug[EXCEPTION_FORM] = Store::getVar(SYSTEM_FORM, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_FORM_ELEMENT] = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
$this->messageArrayDebug[EXCEPTION_FORM_ELEMENT_COLUMN] = Store::getVar(SYSTEM_FORM_ELEMENT_COLUMN, STORE_SYSTEM);
return parent::formatException();
}
......
......@@ -24,12 +24,13 @@ class UserReportException extends AbstractException {
*/
public function formatMessage() {