From 9d918f3b435e58865e73b0e795300148b6c66c6b Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Wed, 7 Nov 2018 13:32:58 +0900 Subject: [PATCH] Fix admin edit_access wrong enabled type, other fixes General notice fixes as much as possible --- 4dev/database/data/edit_tables.sql | 2 +- 4dev/database/table/edit_access.sql | 5 +- www/admin/edit_order.php | 21 +- www/includes/edit_base.inc | 2 +- .../table_arrays/array_edit_access.inc | 2 +- www/layout/admin/default/javascript/edit.js | 519 +++++++++++++++--- .../admin/default/templates/edit_body.tpl | 2 +- www/lib/CoreLibs/Basic.inc | 6 +- www/lib/CoreLibs/DB/Extended/ArrayIO.inc | 2 + www/lib/CoreLibs/Output/Form/Generate.inc | 4 +- 10 files changed, 457 insertions(+), 108 deletions(-) diff --git a/4dev/database/data/edit_tables.sql b/4dev/database/data/edit_tables.sql index 483d7617..838dc517 100755 --- a/4dev/database/data/edit_tables.sql +++ b/4dev/database/data/edit_tables.sql @@ -136,7 +136,7 @@ INSERT INTO edit_user (username, password, enabled, debug, db_debug, email, prot -- edit access DELETE FROM edit_access; -INSERT INTO edit_access (name, enabled, protected) VALUES ('Admin Access', 't', 1); +INSERT INTO edit_access (name, enabled, protected) VALUES ('Admin Access', 1, 1); -- edit access user DELETE FROM edit_access_user; diff --git a/4dev/database/table/edit_access.sql b/4dev/database/table/edit_access.sql index 8fd0246b..bf0fe3fa 100644 --- a/4dev/database/table/edit_access.sql +++ b/4dev/database/table/edit_access.sql @@ -12,6 +12,7 @@ CREATE TABLE edit_access ( description VARCHAR, color VARCHAR, uid VARCHAR, - enabled BOOLEAN DEFAULT 'true', - protected INT + enabled SMALLINT NOT NULL DEFAULT 0, + protected INT, + deleted SMALLINT DEFAULT 0 ) INHERITS (edit_generic) WITHOUT OIDS; diff --git a/www/admin/edit_order.php b/www/admin/edit_order.php index 2238fea1..6cd4d472 100644 --- a/www/admin/edit_order.php +++ b/www/admin/edit_order.php @@ -71,6 +71,9 @@ if (defined('LAYOUT')) { // there are the POSITION stored, that should CHANGE there order (up/down) // $row_data_id ... has ALL ids from the sorting part // $row_data_order ... has ALL order positions from the soirting part +if (!is_array($position)) { + $position = array (); +} if (count($position)) { $original_id = $row_data_id; @@ -146,9 +149,12 @@ if ($error) { $DATA['form_error_msg'] = $messages; // all the row data -$options_id = array(); -$options_name = array(); -$options_selected = array(); +$options_id = array (); +$options_name = array (); +$options_selected = array (); +if (!is_array($row_data)) { + $row_data = array (); +} for ($i = 0; $i < count($row_data); $i ++) { $options_id[] = $i; $options_name[] = $row_data[$i]["name"]; @@ -165,8 +171,8 @@ $DATA['options_name'] = $options_name; $DATA['options_selected'] = $options_selected; // hidden list for the data (id, order number) -$row_data_id = array(); -$row_data_order = array(); +$row_data_id = array (); +$row_data_order = array (); for ($i = 0; $i < count($row_data); $i++) { $row_data_id[] = $row_data[$i]["id"]; $row_data_order[] = $row_data[$i]["order"]; @@ -184,7 +190,7 @@ $DEBUG_DATA['DEBUG'] = $DEBUG_TMPL; // create main data array $CONTENT_DATA = array_merge($HEADER, $DATA, $DEBUG_DATA); // data is 1:1 mapping (all vars, values, etc) -while (list($key, $value) = each($CONTENT_DATA)) { +foreach ($CONTENT_DATA as $key => $value) { $smarty->assign($key, $value); } $smarty->display('edit_order.tpl'); @@ -192,5 +198,4 @@ $smarty->display('edit_order.tpl'); echo $login->printErrorMsg(); echo $db->printErrorMsg(); -# __END__ - +// __END__ diff --git a/www/includes/edit_base.inc b/www/includes/edit_base.inc index 4f7a7cc6..646e4ef7 100644 --- a/www/includes/edit_base.inc +++ b/www/includes/edit_base.inc @@ -22,7 +22,7 @@ $DB_DEBUG = 1; extract($_POST, EXTR_SKIP); -$table_width = 750; +$table_width = '100%'; // this is for certain CMS modules that set a relative path define('REL_PATH', ''); diff --git a/www/includes/table_arrays/array_edit_access.inc b/www/includes/table_arrays/array_edit_access.inc index a10266b5..07269764 100644 --- a/www/includes/table_arrays/array_edit_access.inc +++ b/www/includes/table_arrays/array_edit_access.inc @@ -33,7 +33,7 @@ $edit_access = array ( "value" => $GLOBALS["enabled"], "output_name" => "Enabled", "type" => "binary", - "int" => 1, + "int" => 1, // OR "bool" => 1 "element_list" => array ( "1" => "Yes", "0" => "No" diff --git a/www/layout/admin/default/javascript/edit.js b/www/layout/admin/default/javascript/edit.js index f34cdbf6..8e1917ac 100644 --- a/www/layout/admin/default/javascript/edit.js +++ b/www/layout/admin/default/javascript/edit.js @@ -17,20 +17,28 @@ if (clientPC.indexOf('opera') != -1) { var is_opera_preseven = (window.opera && !document.childNodes); var is_opera_seven = (window.opera && document.childNodes); } +// debug set +var FRONTEND_DEBUG = false; +var DEBUG = true; +if (!DEBUG) { + $($H(window.console)).each(function(w) { + window.console[w.key] = function() {}; + }); +} +// METHOD: pop +// PARAMS: url, window name, features +// RETURN: none +// DESC : opens a popup window with winNAme and given features (string) function pop(theURL, winName, features) { winName = window.open(theURL, winName, features); winName.focus(); } -function emd_check_checkbox() { - for (i = 0; i < document.manage_emails.length; i ++) { - if (document.manage_emails.elements[i].checked == false && document.manage_emails.elements[i].type == 'checkbox') { - document.manage_emails.elements[i].checked = true; - } - } -} - +// METHOD: expandTA +// PARAMS: id +// RETURN: none +// DESC : automatically resize a text area based on the amount of lines in it function expandTA(ta_id) { var ta; // if a string comes, its a get by id, else use it as an element pass on @@ -50,11 +58,13 @@ function expandTA(ta_id) { } ta.rows = numNewRows + theRows.length; } + // METHOD: ShowHideMenu // PARAMS: status -> show or hide // id -> id to work on // RETURN: none // DESC: shows or hides the menu +// this is used in some old menu templates function ShowHideMenu(status, id) { if (status == 'show') { @@ -70,18 +80,7 @@ function ShowHideMenu(status, id) } } -function ShowHideDiv(id) -{ - element = document.getElementById(id); - if (element.className == 'visible' || !element.className) { - element.className = 'hidden'; - } else { - element.className = 'visible'; - } - -// alert('E: ' + element.className + ' -- ' + element.style.visibility); -} - +// used in old templates // move element action function mv(id, direction) { @@ -107,10 +106,39 @@ function le(id) } } +// METHOD: sh +// PARAMS: id -> element to hide +// showText -> text for the element if shown +// hideText -> text for the element if hidden +// RETURN: returns true if hidden, or false if not +// DESC : hides an element, additional writes 1 (show) or 0 (hide) into Flag field +// this needs scriptacolous installed for BlindUp/BlindDown +function sh(id, showText, hideText) +{ + flag = id + 'Flag'; + btn = id + 'Btn'; + // get status from element (hidden or visible) + divStatus = $(id).visible(); + //console.log('Set flag %s for element %s', divStatus, id); + if (divStatus) { + // hide the element + Effect.BlindUp(id, {duration:0.3}); + $(flag).value = 0; + $(btn).innerHTML = showText; + } else if (!divStatus) { + // show the element + Effect.BlindDown(id, {duration:0.3}); + $(flag).value = 1; + $(btn).innerHTML = hideText; + } + // return current button status + return divStatus; +} + // METHOD: getWindowSize // PARAMS: none // RETURN: array with width/height -// DESC: wrapper to get the real window size for the current browser window +// DESC : wrapper to get the real window size for the current browser window function getWindowSize() { var width, height; @@ -125,7 +153,7 @@ function getWindowSize() // METHOD: getScrollOffset // PARAMS: none // RETURN: array with x/y px -// DESC: wrapper to get the correct scroll offset +// DESC : wrapper to get the correct scroll offset function getScrollOffset() { var left, top; @@ -140,7 +168,7 @@ function getScrollOffset() // METHOD: setCenter // PARAMS: id to set center // RETURN: none -// DESC: centers div to current window size middle +// DESC : centers div to current window size middle function setCenter(id, left, top) { // get size of id @@ -166,38 +194,146 @@ function setCenter(id, left, top) } } -// METHOD sh -// PARAMS: id -> element to hide -// showText -> text for the element if shown -// hideText -> text for the element if hidden -// RETURN: returns true if hidden, or false if not -// DESC: hides an element, additional writes 1 (show) or 0 (hide) into Flag field -function sh(id, showText, hideText) +// METHOD: goToPos() +// PARAMS: element, offset (default 0) +// RETURN: none +// DESC: goes to an element id position +function goToPos(element, offset = 0) { - flag = id + 'Flag'; - btn = id + 'Btn'; - // get status from element (hidden or visible) - divStatus = $(id).visible(); - //console.log('Set flag %s for element %s', divStatus, id); - if (divStatus) { - // hide the element - Effect.BlindUp(id, {duration:0.3}); - $(flag).value = 0; - $(btn).innerHTML = showText; - } else if (!divStatus) { - // show the element - Effect.BlindDown(id, {duration:0.3}); - $(flag).value = 1; - $(btn).innerHTML = hideText; + try { + if ($(element)) + { + // get the element pos + var pos = $(element).cumulativeOffset(); + // if not top element and no offset given, set auto offset for top element + // also compensate by -40 for some offset calc issue and not have it too much to the header + if (pos.top != 0 && offset == 0) { + offset = ($(GL_main_content_div).style.paddingTop.replace('px', '') * -1) - 40; + } + //console.log('Scroll to: %s, Offset: %s [%s], PT: %s', element, offset, $('pbsMainContent').style.paddingTop.replace('px', ''), pos.top); + window.scrollTo(pos.left, pos.top + offset); + } + } catch (err) { + errorCatch(err); } - // return current button status - return divStatus; } +// METHOD: __ +// PARAMS: text +// RETURN: translated text (based on PHP selected language) +// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty) +function __(string) +{ + if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) { + return i18n[string]; + } else { + return string; + } +} + +// METHOD: string.format +// PARAMS: any, for string format +// RETURN: formatted string +// DESC : simple sprintf formater for replace +// "{0} is cool, {1} is not".format("Alpha", "Beta"); +// First, checks if it isn't implemented yet. +if (!String.prototype.format) { + String.prototype.format = function() + { + var args = arguments; + return this.replace(/{(\d+)}/g, function(match, number) + { + return typeof args[number] != 'undefined' ? + args[number] : + match + ; + }); + }; +} + +// METHOD: numberWithCommas +// PARAMS: number +// RETURN: formatted with , in thousands +// DESC : formats flat number 123456 to 123,456 +const numberWithCommas = (x) => { + var parts = x.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return parts.join("."); +}; + +// METHOD: +// PARAMS: string +// RETURN: string with
+// DESC : converts line breaks to br +function convertLBtoBR(string) +{ + return string.replace(/(?:\r\n|\r|\n)/g, '
'); +} + +if (!String.prototype.escapeHTML) { + String.prototype.escapeHTML = function() { + return this.replace(/[&<>"'\/]/g, function (s) { + var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''', + "/": '/' + }; + + return entityMap[s]; + }); + }; +} + +if (!String.prototype.unescapeHTML) { + String.prototype.unescapeHTML = function() { + return this.replace(/&[#\w]+;/g, function (s) { + var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + ''': "'", + '/': "/" + }; + + return entityMap[s]; + }); + }; +} + +// METHOD: getTimestamp +// PARAMS: none +// RETURN: timestamp (in milliseconds) +// DESC : returns current timestamp (unix timestamp) +function getTimestamp() +{ + let date = new Date(); + return date.getTime(); +} + +// METHOD: isObject +// PARAMS: possible object +// RETURN: true/false if it is an object or not +function isObject(val) { + if (val === null) { + return false; + } + return ((typeof val === 'function') || (typeof val === 'object')); +} + +// METHOD: exists +// PARAMS: uid +// RETURN: true/false +// DESC : checks if a DOM element actually exists +const exists = (id) => $(id) ? true : false; + // METHOD: formatBytes // PARAMS: bytes in int // RETURN: string in GB/MB/KB -// DESC: converts a int number into bytes with prefix in two decimals precision +// DESC : converts a int number into bytes with prefix in two decimals precision // currently precision is fixed, if dynamic needs check for max/min precision function formatBytes(bytes) { @@ -210,6 +346,142 @@ function formatBytes(bytes) return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i]; } +// METHOD: goToPos() +// PARAMS: element, offset (default 0) +// RETURN: none +// DESC : goes to an element id position +function goToPos(element, offset = 0) +{ + try { + if ($(element)) + { + // get the element pos + var pos = $(element).cumulativeOffset(); + // if not top element and no offset given, set auto offset for top element + // also compensate by -40 for some offset calc issue and not have it too much to the header + if (pos.top != 0 && offset == 0) { + offset = ($(GL_main_content_div).style.paddingTop.replace('px', '') * -1) - 40; + } + //console.log('Scroll to: %s, Offset: %s [%s], PT: %s', element, offset, $('pbsMainContent').style.paddingTop.replace('px', ''), pos.top); + window.scrollTo(pos.left, pos.top + offset); + } + } catch (err) { + errorCatch(err); + } +} + +// METHOD: errorCatch +// PARAMS: err (error from try/catch +// RETURN: none +// DESC : prints out error messages based on data available from the browser +function errorCatch(err) +{ + // for FF & Chrome + if (err.stack) { + // only FF + if (err.lineNumber) { + console.log('ERROR[%s:%s] %s', err.name, err.lineNumber, err.message); + } else if (err.line) { + // only Safari + console.log('ERROR[%s:%s] %s', err.name, err.line, err.message); + } else { + console.log('ERROR[%s] %s', err.name, err.message); + } + // stack trace + console.log('ERROR[stack] %s', err.stack); + } else if (err.number) { + // IE + console.log('ERROR[%s:%s] %s', err.name, err.number, err.message); + console.log('ERROR[description] %s', err.description); + } else { + // the rest + console.log('ERROR[%s] %s', err.name, err.message); + } +} + +// METHOD: actionIndicator +// PARAMS: none +// RETURN: none +// DESC : show or hide the "do" overlay +function actionIndicator(loc = '') +{ + if ($('overlayBox').visible()) { + actionIndicatorHide(loc); + } else { + actionIndicatorShow(loc); + } +} + +// METHOD: actionIndicatorShow/actionIndicatorHide +// PARAMS: loc for console log info +// RETURN: none +// DESC : explicit show/hide for action Indicator +// instead of automatically show or hide, do +// on command +function actionIndicatorShow(loc = '') +{ + console.log('Indicator: SHOW [%s]', loc); + $('indicator').addClassName('progress'); + setCenter('indicator', true, true); + $('indicator').show(); + overlayBoxShow(); +} +function actionIndicatorHide(loc = '') +{ + console.log('Indicator: HIDE [%s]', loc); + $('indicator').hide(); + $('indicator').removeClassName('progress'); + overlayBoxHide(); +} + +// METHOD: overlayBoxView +// PARAMS: none +// RETURN: none +// DESC : shows or hides the overlay box +function overlayBoxShow() +{ + // check if overlay box exists and if yes set the z-index to 100 + if ($('overlayBox').visible()) { + $('overlayBox').style.zIndex = "100"; + } else { + $('overlayBox').show(); + } +} +function overlayBoxHide() +{ + // if the overlay box z-index is 100, do no hide, but set to 98 + if ($('overlayBox').style.zIndex == 100) { + $('overlayBox').style.zIndex = "98"; + } else { + $('overlayBox').hide(); + } +} + +// METHOD: setOverlayBox +// PARAMS: none +// RETURN: none +// DESC : position the overlay block box and shows it +function setOverlayBox() +{ + var viewport = document.viewport.getDimensions(); + $('overlayBox').setStyle ({ + width: '100%', + height: '100%' + }); + $('overlayBox').show(); +} + +// METHOD: ClearCall +// PARAMS: none +// RETURN: none +// DESC : the abort call, clears the action box and hides it and the overlay box +function ClearCall() +{ + $('actionBox').innerHTML = ''; + $('actionBox').hide(); + $('overlayBox').hide(); +} + // *** DOM MANAGEMENT FUNCTIONS // METHOD: cel [create element] // PARAMS: tag: must set tag (div, span, etc) @@ -220,7 +492,7 @@ function formatBytes(bytes) // RETURN: object // DESC : creates object for DOM element creation flow const cel = (tag, id = '', content = '', css = [], options = {}) => - element = { + _element = { tag: tag, id: id, name: options.name, // override name if set [name gets ignored in tree build anyway] @@ -241,7 +513,7 @@ function ael(base, attach, id = '') if (id) { // base id match already if (base.id == id) { - base.sub.push(attach); + base.sub.push(Object.assign({}, attach)); } else { // sub check if (base.sub.length > 0) { @@ -252,7 +524,7 @@ function ael(base, attach, id = '') } } } else { - base.sub.push(attach); + base.sub.push(Object.assign({}, attach)); } return base; } @@ -271,7 +543,7 @@ function aelx(base, ...attach) return base; } -// METHOD: rel [rese element] +// METHOD: rel [reset element] // PARAMS: cel created element // RETURN: "none", is self change, but returns base.sub // DESC : resets the sub elements of the base element given @@ -281,23 +553,23 @@ const rel = (base) => base.sub = []; // PARAMS: element, style sheet to remove // RETURN: "none", in place because of reference // DESC : searches and removes style from css array -function rcssel(element, css) +function rcssel(_element, css) { - let css_index = element.css.indexOf(css); + let css_index = _element.css.indexOf(css); if (css_index > -1) { - element.css.splice(css_index, 1); + _element.css.splice(css_index, 1); } } -// METHOD acssel [add css element] +// METHOD: acssel [add css element] // PARAMS: element, style sheet to add // RETURN: "none", in place add because of reference // DESC : adds a new style sheet to the element given -function acssel(element, css) +function acssel(_element, css) { - let css_index = element.css.indexOf(css); + let css_index = _element.css.indexOf(css); if (css_index == -1) { - element.css.push(css); + _element.css.push(css); } } @@ -306,10 +578,10 @@ function acssel(element, css) // RETURN: "none", in place add because of reference // DESC : removes one css and adds another // is a wrapper around rcssel/acssel -function scssel(element, rcss, acss) +function scssel(_element, rcss, acss) { - rcssel(element, rcss); - acssel(element, acss); + rcssel(_element, rcss); + acssel(_element, acss); } // METHOD: phfo [produce html from object] @@ -375,6 +647,7 @@ function phfo(tree) // combine to string return content.join(''); } +// *** DOM MANAGEMENT FUNCTIONS // BLOCK: html wrappers for quickly creating html data blocks // METHOD: html_options @@ -393,36 +666,33 @@ function html_options(name, data, selected = '', options_only = false, return_st let data_list = []; // for sorted output // set outside select, gets stripped on return if options only is true element_select = cel('select', name); - if (isObject(data)) { - // console.log('Call for %s, options: %s', name, options_only); - // console.log('Call for %s, options: %s', name, options_only); - if (sort == 'keys') { - data_list = Object.keys(data).sort(); - } else if (sort == 'values') { - data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b])); - } else { - data_list = Object.keys(data); - } - // console.log('ORDER: %s', data_list); - // use the previously sorted list - // for (const [key, value] of Object.entries(data)) { - for (const key of data_list) { - let value = data[key]; - console.log('options: key: %s, value: %s', key, value); - // basic options init - let options = { - 'label': value, - 'value': key - }; - // add selected if matching - if (selected == key) { - options.selected = ''; - } - // create the element option - element_option = cel('option', '', value, '', options); - // attach it to the select element - ael(element_select, element_option); + // console.log('Call for %s, options: %s', name, options_only); + if (sort == 'keys') { + data_list = Object.keys(data).sort(); + } else if (sort == 'values') { + data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b])); + } else { + data_list = Object.keys(data); + } + // console.log('ORDER: %s', data_list); + // use the previously sorted list + // for (const [key, value] of Object.entries(data)) { + for (const key of data_list) { + let value = data[key]; + console.log('create [%s] options: key: %s, value: %s', name, key, value); + // basic options init + let options = { + 'label': value, + 'value': key + }; + // add selected if matching + if (selected == key) { + options.selected = ''; } + // create the element option + element_option = cel('option', '', value, '', options); + // attach it to the select element + ael(element_select, element_option); } // if with select part, convert to text if (!options_only) { @@ -445,4 +715,71 @@ function html_options(name, data, selected = '', options_only = false, return_st } } +// METHOD: html_options_refill +// PARAMS: name/id, array of options, sort = '' +// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored +// RETURN: none +// DESC : refills a select box with options and keeps the selected +function html_options_refill(name, data, sort = '') +{ + let element_option; + let option_selected; + let data_list = []; // for sorted output + // skip if not exists + if ($(name)) { + // console.log('Call for %s, options: %s', name, options_only); + if (sort == 'keys') { + data_list = Object.keys(data).sort(); + } else if (sort == 'values') { + data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b])); + } else { + data_list = Object.keys(data); + } + // first read in existing ones from the options and get the selected one + [].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) { + option_selected = elm.value; + }); + $(name).innerHTML = ''; + for (const key of data_list) { + let value = data[key]; + // console.log('add [%s] options: key: %s, value: %s', name, key, value); + element_option = document.createElement('option'); + element_option.label = value; + element_option.value = key; + element_option.innerHTML = value; + $(name).appendChild(element_option); + } + } +} + +// METHOD: initDatepickr +// PARAMS: initial date ID (#) +// RETURN: true on ok, false on failure +// DESC : inits date pickr which translations for dates (week/month) +function initDatepickr(init_date) +{ + if ($(init_date)) { + datepickr('#' + init_date); // we need to add this so we have it initialized before we can actually change the definitions + // dates in japanese + datepickr.prototype.l10n.months.shorthand = [__('Jan'), __('Feb'), __('Mar'), __('Apr'), __('May'), __('Jun'), __('Jul'), __('Aug'), __('Sep'), __('Oct'), __('Nov'), __('Dec')]; + datepickr.prototype.l10n.months.longhand = [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December')]; + datepickr.prototype.l10n.weekdays.shorthand = [__('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat'), __('Sun')]; + datepickr.prototype.l10n.weekdays.longhand = [__('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday'), __('Sunday')]; + return true; + } else { + return false; + } +} + +// *** MASTER logout call +// METHOD: loginLogout +// PARAMS: none +// RETURN: none +// DESC : submits basic data for form logout +function loginLogout() +{ + $('login_logout').value = 'Logout'; + $(form_name).submit(); +} + /* END */ diff --git a/www/layout/admin/default/templates/edit_body.tpl b/www/layout/admin/default/templates/edit_body.tpl index 9d2f2bd5..e50e369a 100644 --- a/www/layout/admin/default/templates/edit_body.tpl +++ b/www/layout/admin/default/templates/edit_body.tpl @@ -79,7 +79,7 @@ -
+ {include file="edit_load.tpl"} diff --git a/www/lib/CoreLibs/Basic.inc b/www/lib/CoreLibs/Basic.inc index 27c97c34..cf281eef 100644 --- a/www/lib/CoreLibs/Basic.inc +++ b/www/lib/CoreLibs/Basic.inc @@ -2259,7 +2259,11 @@ class Basic // DESC : full wrapper for html entities public function htmlent($string) { - return htmlentities($string, ENT_COMPAT|ENT_HTML401, 'UTF-8', false); + if (is_string($string)) { + return htmlentities($string, ENT_COMPAT|ENT_HTML401, 'UTF-8', false); + } else { + return $string; + } } // METHOD: setFormToken diff --git a/www/lib/CoreLibs/DB/Extended/ArrayIO.inc b/www/lib/CoreLibs/DB/Extended/ArrayIO.inc index 0b0252d2..1d2e2fcf 100644 --- a/www/lib/CoreLibs/DB/Extended/ArrayIO.inc +++ b/www/lib/CoreLibs/DB/Extended/ArrayIO.inc @@ -409,6 +409,8 @@ class ArrayIO extends \CoreLibs\DB\IO $_value = $this->table_array[$column]["value"]; } $q_data .= $_value; + } elseif ($this->table_array[$column]['bool']) { + $q_data .= "'".$this->dbBoolean($this->table_array[$column]["value"], true)."'"; } elseif ($this->table_array[$column]["interval"]) { // for interval we check if no value, then we set null if (!$this->table_array[$column]["value"]) { diff --git a/www/lib/CoreLibs/Output/Form/Generate.inc b/www/lib/CoreLibs/Output/Form/Generate.inc index 8c7d97a3..2d0f342c 100644 --- a/www/lib/CoreLibs/Output/Form/Generate.inc +++ b/www/lib/CoreLibs/Output/Form/Generate.inc @@ -879,8 +879,8 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO break; case "alphanumericspace": // $this->debug('edit', 'IN Alphanumericspace'); - if (!preg_match("/^[0-9A-Za-z\ ]+$/", $this->table_array[$key]["value"])) { - $this->msg .= sprintf($this->l->__("Please enter a valid alphanumeric (Numbers and Letters, spaces allowed) value for the %s Field!
"), $this->table_array[$key]["output_name"]); + if (!preg_match("/^[0-9A-Za-z_\-\ ]+$/", $this->table_array[$key]["value"])) { + $this->msg .= sprintf($this->l->__("Please enter a valid alphanumeric (Numbers and Letters, -, _ and spaces allowed) value for the %s Field!
"), $this->table_array[$key]["output_name"]); } break; case "alphanumeric":