Compare commits

...

12 Commits

Author SHA1 Message Date
Clemens Schwaighofer
2210f62441 Simple Thumbnail with GD only, base config master update, test images add 2019-10-28 16:39:46 +09:00
Clemens Schwaighofer
dfb2a93fbd Basic class add two new methods
correctImageOrientation: fixes the orientation of a JPEG image with
the exif Orientation header set

uuidv4: creates a uuid v4 string
2019-10-16 18:58:19 +09:00
Clemens Schwaighofer
ca073c1b56 Fix JS key in object check function
instead of using "in" which could return true for other entries in the
object use the proper hasOwnProperty call
2019-10-16 15:08:08 +09:00
Clemens Schwaighofer
f316dde8b7 CoreLibs Fix mandator check & sub group checks for unique input 2019-10-09 10:55:54 +09:00
Clemens Schwaighofer
13b18c3a62 Add ajax page flag to basic class and updated login class to reflect this 2019-10-08 18:34:29 +09:00
Clemens Schwaighofer
18bf829c6b Fix JS comments 2019-10-04 18:56:23 +09:00
Clemens Schwaighofer
723b6345bb Info text about target base library for edit.js 2019-10-04 11:38:41 +09:00
Clemens Schwaighofer
e235721c8b Update JQUERY to jdocs3 comment style 2019-10-04 11:33:54 +09:00
Clemens Schwaighofer
fd0af5a294 Update Login class to return login screen with reset _POST
Login class checks if AJAX_PAGE is set to true and then does not print
the login html to the screen directly, but returns it in the _POST array
login_html, _POST action is set to login
It also resets _POST & _GET arrays before hand to avoid any misuese.
All _SESSION array access needs to be checked in any following class as
the _SESSION is unset in this moment

html element should be overwritten with this JS:
document.getElementsByTagName('html')[0].innerHTML  =
data.content.login_html;
2019-10-03 15:37:06 +09:00
Clemens Schwaighofer
fd8caaf5de htaccess update for short open tag 2019-10-02 11:54:19 +09:00
Clemens Schwaighofer
3d842d4107 Missing strict declares, Progress bar init, missing site config bail
In master config if there is no site config for this page, bail out.
In the other config pages the strict declare header was missing.

Progress bar inits the progress array with all set to null to avoid
calls on not set index
2019-10-01 15:43:50 +09:00
Clemens Schwaighofer
c895beb35f IO: reset field names update
instead of set to array, set to null as we fully reset this entry
2019-09-30 15:57:23 +09:00
32 changed files with 1112 additions and 511 deletions

View File

@@ -9,6 +9,7 @@ php_value xdebug.show_local_vars 0
# allowed COOKIE, FILES, GET, POST, REQUEST, SERVER, SESSION # allowed COOKIE, FILES, GET, POST, REQUEST, SERVER, SESSION
#php_value xdebug.dump.GET * #php_value xdebug.dump.GET *
# PHP ERROR SETTINGS # PHP ERROR SETTINGS
php_flag short_open_tag off
php_flag display_startup_errors on php_flag display_startup_errors on
php_flag display_errors on php_flag display_errors on
php_flag html_errors on php_flag html_errors on

View File

@@ -16,6 +16,7 @@ table/edit_scheme.sql
table/edit_language.sql table/edit_language.sql
table/edit_group.sql table/edit_group.sql
table/edit_page_access.sql table/edit_page_access.sql
table/edit_page_content.sql
table/edit_user.sql table/edit_user.sql
table/edit_log.sql table/edit_log.sql
table/edit_access.sql table/edit_access.sql
@@ -31,6 +32,7 @@ trigger/trg_edit_group.sql
trigger/trg_edit_language.sql trigger/trg_edit_language.sql
trigger/trg_edit_log.sql trigger/trg_edit_log.sql
trigger/trg_edit_page_access.sql trigger/trg_edit_page_access.sql
trigger/trg_edit_page_content.sql
trigger/trg_edit_page.sql trigger/trg_edit_page.sql
trigger/trg_edit_query_string.sql trigger/trg_edit_query_string.sql
trigger/trg_edit_scheme.sql trigger/trg_edit_scheme.sql

View File

@@ -131,20 +131,20 @@ print "UPDATE STATUS: $status | RETURNING EXT: ".print_r($basic->insert_id_ext,
$table = 'foo'; $table = 'foo';
print "TABLE META DATA: ".$basic->printAr($basic->dbShowTableMetaData($table))."<br>"; print "TABLE META DATA: ".$basic->printAr($basic->dbShowTableMetaData($table))."<br>";
$primary_key = ''; # unset $primary_key = ''; # unset
$db_write_table = array ('test', 'string_a', 'number_a', 'some_bool'); $db_write_table = array('test', 'string_a', 'number_a', 'some_bool');
// $db_write_table = array ('test'); // $db_write_table = array('test');
$object_fields_not_touch = array (); $object_fields_not_touch = array();
$object_fields_not_update = array (); $object_fields_not_update = array();
$data = array ('test' => 'BOOL TEST SOMETHING '.time(), 'string_a' => 'SOME TEXT', 'number_a' => 5); $data = array('test' => 'BOOL TEST SOMETHING '.time(), 'string_a' => 'SOME TEXT', 'number_a' => 5);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST ON '.time(), 'string_a' => '', 'number_a' => 0, 'some_bool' => 1); $data = array('test' => 'BOOL TEST ON '.time(), 'string_a' => '', 'number_a' => 0, 'some_bool' => 1);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST OFF '.time(), 'string_a' => null, 'number_a' => null, 'some_bool' => 0); $data = array('test' => 'BOOL TEST OFF '.time(), 'string_a' => null, 'number_a' => null, 'some_bool' => 0);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST UNSET '.time()); $data = array('test' => 'BOOL TEST UNSET '.time());
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
@@ -236,8 +236,52 @@ $date_1 = '2017/1/5';
$date_2 = '2017-01-05'; $date_2 = '2017-01-05';
print "COMPARE DATE: ".$basic->compareDate($date_1, $date_2)."<br>"; print "COMPARE DATE: ".$basic->compareDate($date_1, $date_2)."<br>";
// recursive array search
$test_array = array(
'foo' => 'bar',
'input' => array(
'element_a' => array(
'type' => 'text'
),
'element_b' => array(
'type' => 'email'
),
'element_c' => array(
'type' => 'email'
)
)
);
// array re echo "SOURCE ARRAY: ".$basic->printAr($test_array)."<br>";
echo "FOUND ELEMENTS [base]: ".$basic->printAr($basic->arraySearchRecursive('email', $test_array, 'type'))."<br>";
echo "FOUND ELEMENTS [input]: ".$basic->printAr($basic->arraySearchRecursive('email', $test_array['input'], 'type'))."<br>";
// image thumbnail
$images = array(
// height bigger
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture.jpg',
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture.png',
// width bigger
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture_width_bigger.jpg',
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture_width_bigger.png',
// square
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture_square.jpg',
// BASE.LAYOUT.CONTENT_PATH.IMAGES.'no_picture_square.png',
// other sample images
BASE.LAYOUT.CONTENT_PATH.IMAGES.'5c501af48da6c.jpg'
);
echo "<hr>";
$thumb_width = 250;
$thumb_height = 250;
foreach ($images as $image) {
// rotate image first
$basic->correctImageOrientation($image);
// thumbnail tests
echo "<div>".basename($image).": WIDTH: $thumb_width<br><img src=".$basic->createThumbnailSimple($image, $thumb_width)."></div>";
echo "<div>".basename($image).": HEIGHT: $thumb_height<br><img src=".$basic->createThumbnailSimple($image, 0, $thumb_height)."></div>";
echo "<div>".basename($image).": WIDTH/HEIGHT: $thumb_width x $thumb_height<br><img src=".$basic->createThumbnailSimple($image, $thumb_width, $thumb_height)."></div>";
echo "<hr>";
}
// print error messages // print error messages
// print $login->printErrorMsg(); // print $login->printErrorMsg();

View File

@@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/******************************************************************** /********************************************************************
* AUTHOR: Clemens Schwaighofer * AUTHOR: Clemens Schwaighofer
* CREATED: 2018/10/11 * CREATED: 2018/10/11

View File

@@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/******************************************************************** /********************************************************************
* AUTHOR: Clemens Schwaighofer * AUTHOR: Clemens Schwaighofer
* CREATED: 2018/10/11 * CREATED: 2018/10/11

View File

@@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/******************************************************************** /********************************************************************
* AUTHOR: Clemens Schwaighofer * AUTHOR: Clemens Schwaighofer
* CREATED: 2003/06/10 * CREATED: 2003/06/10
@@ -124,18 +124,21 @@ DEFINE('PAGE_WIDTH', 800);
DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl'); DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl');
/************* SESSION NAMES *************/ /************* SESSION NAMES *************/
// base name
DEFINE('BASE_NAME', 'CoreLibs');
// server name HASH // server name HASH
DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST'])); DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST']));
DEFINE('SERVER_PATH_HASH', hash('crc32b', BASE));
// backend // backend
DEFINE('EDIT_SESSION_NAME', 'ADMIN_SESSION_NAME'.SERVER_NAME_HASH); DEFINE('EDIT_SESSION_NAME', BASE_NAME.'Admin'.SERVER_NAME_HASH.SERVER_PATH_HASH);
// frontend // frontend
DEFINE('SESSION_NAME', 'SESSION_NAME'.SERVER_NAME_HASH); DEFINE('SESSION_NAME', BASE_NAME.SERVER_NAME_HASH.SERVER_PATH_HASH);
// SET_SESSION_NAME should be set in the header if a special session name is needed // SET_SESSION_NAME should be set in the header if a special session name is needed
DEFINE('SET_SESSION_NAME', SESSION_NAME); DEFINE('SET_SESSION_NAME', SESSION_NAME);
/************* CACHE/COMPILE IDS *************/ /************* CACHE/COMPILE IDS *************/
DEFINE('CACHE_ID', 'CACHE_'.SERVER_NAME_HASH); DEFINE('CACHE_ID', 'CACHE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
DEFINE('COMPILE_ID', 'COMPILE_'.SERVER_NAME_HASH); DEFINE('COMPILE_ID', 'COMPILE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
/************* LANGUAGE / ENCODING *******/ /************* LANGUAGE / ENCODING *******/
DEFINE('DEFAULT_LANG', 'en_utf8'); DEFINE('DEFAULT_LANG', 'en_utf8');
@@ -192,7 +195,12 @@ if (file_exists(BASE.CONFIGS.'config.path.php')) {
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null); list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// set HOST name // set HOST name
DEFINE('HOST_NAME', $HOST_NAME); DEFINE('HOST_NAME', $HOST_NAME);
// BAIL ON: // BAIL ON MISSING MASTER SITE CONFIG
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
echo 'Missing SITE_CONFIG entry for: "'.HOST_NAME.'". Contact Administrator';
exit;
}
// BAIL ON MISSING DB CONFIG:
// we have either no db selction for this host but have db config entries // we have either no db selction for this host but have db config entries
// or we have a db selection but no db config as array or empty // or we have a db selection but no db config as array or empty
// or we have a selection but no matching db config entry // or we have a selection but no matching db config entry

View File

@@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/******************************************************************** /********************************************************************
* AUTHOR: Clemens Schwaighofer * AUTHOR: Clemens Schwaighofer
* CREATED: 2018/10/11 * CREATED: 2018/10/11

View File

@@ -92,7 +92,7 @@ if (!$login->login) {
//------------------------------ page rights start //------------------------------ page rights start
// flag if to show the edit access id drop down list // flag if to show the edit access id drop down list
// check if we have more than one EA ID // check if we have more than one EA ID
$cms->DATA['show_ea_extra'] = $login->acl['show_ea_extra']; $cms->DATA['show_ea_extra'] = isset($login->acl['show_ea_extra']) ? $login->acl['show_ea_extra'] : false;
//------------------------------ page rights ned //------------------------------ page rights ned
// automatic hide for DEBUG messages on live server // automatic hide for DEBUG messages on live server

View File

@@ -78,7 +78,7 @@ $cms->DATA['ADMIN'] = $login->acl['admin'];
// the template part to include into the body // the template part to include into the body
$cms->DATA['TEMPLATE_NAME'] = $TEMPLATE_NAME; $cms->DATA['TEMPLATE_NAME'] = $TEMPLATE_NAME;
$cms->DATA['CONTENT_INCLUDE'] = $CONTENT_INCLUDE; $cms->DATA['CONTENT_INCLUDE'] = $CONTENT_INCLUDE;
$cms->DATA['TEMPLATE_TRANSLATE'] = $TEMPLATE_TRANSLATE; $cms->DATA['TEMPLATE_TRANSLATE'] = isset($TEMPLATE_TRANSLATE) ? $TEMPLATE_TRANSLATE : null;
$cms->DATA['PAGE_FILE_NAME'] = $PAGE_FILE_NAME; $cms->DATA['PAGE_FILE_NAME'] = $PAGE_FILE_NAME;
// LANG // LANG
$cms->DATA['LANG'] = $lang; $cms->DATA['LANG'] = $lang;

2
www/layout/admin/cache/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,4 +1,5 @@
/* general edit javascript */ /* general edit javascript */
/* jquery version */
/* jshint esversion: 6 */ /* jshint esversion: 6 */
@@ -11,19 +12,21 @@ if (!DEBUG) {
}); });
}*/ }*/
// METHOD: pop /**
// PARAMS: url, window name, features * opens a popup window with winName and given features (string)
// RETURN: none * @param {String} theURL the url
// DESC : opens a popup window with winNAme and given features (string) * @param {String} winName window name
* @param {Object} features popup features
*/
function pop(theURL, winName, features) { function pop(theURL, winName, features) {
winName = window.open(theURL, winName, features); winName = window.open(theURL, winName, features);
winName.focus(); winName.focus();
} }
// METHOD: expandTA /**
// PARAMS: id * automatically resize a text area based on the amount of lines in it
// RETURN: none * @param {[string} ta_id element id
// DESC : automatically resize a text area based on the amount of lines in it */
function expandTA(ta_id) { function expandTA(ta_id) {
var ta; var ta;
// if a string comes, its a get by id, else use it as an element pass on // if a string comes, its a get by id, else use it as an element pass on
@@ -44,10 +47,10 @@ function expandTA(ta_id) {
ta.rows = numNewRows + theRows.length; ta.rows = numNewRows + theRows.length;
} }
// METHOD: getWindowSize /**
// PARAMS: none * wrapper to get the real window size for the current browser window
// RETURN: array with width/height * @return {Object} object with width/height
// DESC : wrapper to get the real window size for the current browser window */
function getWindowSize() function getWindowSize()
{ {
var width, height; var width, height;
@@ -59,10 +62,10 @@ function getWindowSize()
}; };
} }
// METHOD: getScrollOffset /**
// PARAMS: none * wrapper to get the correct scroll offset
// RETURN: array with x/y px * @return {Object} object with x/y px
// DESC : wrapper to get the correct scroll offset */
function getScrollOffset() function getScrollOffset()
{ {
var left, top; var left, top;
@@ -74,10 +77,12 @@ function getScrollOffset()
}; };
} }
// METHOD: setCenter /**
// PARAMS: id to set center * centers div to current window size middle
// RETURN: none * @param {String} id element to center
// DESC : centers div to current window size middle * @param {Boolean} left if true centers to the middle from the left
* @param {Boolean} top if true centers to the middle from the top
*/
function setCenter(id, left, top) function setCenter(id, left, top)
{ {
// get size of id // get size of id
@@ -107,10 +112,11 @@ function setCenter(id, left, top)
} }
} }
// METHOD: goToPos() /**
// PARAMS: element, offset (default 0) * goes to an element id position
// RETURN: none * @param {String} element element id to move to
// DESC: goes to an element id position * @param {Number} [offset=0] offset from top, default is 0 (px)
*/
function goToPos(element, offset = 0) function goToPos(element, offset = 0)
{ {
try { try {
@@ -125,10 +131,12 @@ function goToPos(element, offset = 0)
} }
} }
// METHOD: __ /**
// PARAMS: text * uses the i18n object created in the translation template
// RETURN: translated text (based on PHP selected language) * that is filled from gettext in PHP
// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty) * @param {String} string text to translate
* @return {String} translated text (based on PHP selected language)
*/
function __(string) function __(string)
{ {
if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) { if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) {
@@ -138,12 +146,13 @@ function __(string)
} }
} }
// METHOD: string.format /**
// PARAMS: any, for string format * simple sprintf formater for replace
// RETURN: formatted string * usage: "{0} is cool, {1} is not".format("Alpha", "Beta");
// DESC : simple sprintf formater for replace * First, checks if it isn't implemented yet.
// "{0} is cool, {1} is not".format("Alpha", "Beta"); * @param {String} !String.prototype.format string with elements to be replaced
// First, checks if it isn't implemented yet. * @return {String} Formated string
*/
if (!String.prototype.format) { if (!String.prototype.format) {
String.prototype.format = function() String.prototype.format = function()
{ {
@@ -158,25 +167,32 @@ if (!String.prototype.format) {
}; };
} }
// METHOD: numberWithCommas /**
// PARAMS: number * formats flat number 123456 to 123,456
// RETURN: formatted with , in thousands * @param {Number} x number to be formated
// DESC : formats flat number 123456 to 123,456 * @return {String} formatted with , in thousands
*/
const numberWithCommas = (x) => { const numberWithCommas = (x) => {
var parts = x.toString().split("."); var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join("."); return parts.join(".");
}; };
// METHOD: /**
// PARAMS: string * converts line breaks to br
// RETURN: string with <br> * @param {String} string any string
// DESC : converts line breaks to br * @return {String} string with <br>
*/
function convertLBtoBR(string) function convertLBtoBR(string)
{ {
return string.replace(/(?:\r\n|\r|\n)/g, '<br>'); return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
} }
/**
* escape HTML string
* @param {String} !String.prototype.escapeHTML HTML data string to be escaped
* @return {String} escaped string
*/
if (!String.prototype.escapeHTML) { if (!String.prototype.escapeHTML) {
String.prototype.escapeHTML = function() { String.prototype.escapeHTML = function() {
return this.replace(/[&<>"'\/]/g, function (s) { return this.replace(/[&<>"'\/]/g, function (s) {
@@ -194,6 +210,11 @@ if (!String.prototype.escapeHTML) {
}; };
} }
/**
* unescape a HTML encoded string
* @param {String} !String.prototype.unescapeHTML data with escaped entries
* @return {String} HTML formated string
*/
if (!String.prototype.unescapeHTML) { if (!String.prototype.unescapeHTML) {
String.prototype.unescapeHTML = function() { String.prototype.unescapeHTML = function() {
return this.replace(/&[#\w]+;/g, function (s) { return this.replace(/&[#\w]+;/g, function (s) {
@@ -211,31 +232,33 @@ if (!String.prototype.unescapeHTML) {
}; };
} }
// METHOD: getTimestamp /**
// PARAMS: none * returns current timestamp (unix timestamp)
// RETURN: timestamp (in milliseconds) * @return {Number} timestamp (in milliseconds)
// DESC : returns current timestamp (unix timestamp) */
function getTimestamp() function getTimestamp()
{ {
var date = new Date(); var date = new Date();
return date.getTime(); return date.getTime();
} }
// METHOD: dec2hex /**
// PARAMS: decimal string * dec2hex :: Integer -> String
// RETURN: string * i.e. 0-255 -> '00'-'ff'
// DESC : dec2hex :: Integer -> String * @param {Number} dec decimal string
// i.e. 0-255 -> '00'-'ff' * @return {String} hex encdoded number
*/
function dec2hex(dec) function dec2hex(dec)
{ {
return ('0' + dec.toString(16)).substr(-2); return ('0' + dec.toString(16)).substr(-2);
} }
// METHOD: generateId /**
// PARAMS: lenght in int * generateId :: Integer -> String
// RETURN: random string * only works on mondern browsers
// DESC : generateId :: Integer -> String * @param {Number} len length of unique id string
// only works on mondern browsers * @return {String} random string in length of len
*/
function generateId(len) function generateId(len)
{ {
var arr = new Uint8Array((len || 40) / 2); var arr = new Uint8Array((len || 40) / 2);
@@ -243,20 +266,22 @@ function generateId(len)
return Array.from(arr, dec2hex).join(''); return Array.from(arr, dec2hex).join('');
} }
// METHOD: randomIdF() /**
// PARAMS: none * creates a pseudo random string of 10 characters
// RETURN: not true random string * works on all browsers
// DESC : creates a pseudo random string of 10 characters * after many runs it will create duplicates
// after many runs it will create duplicates * @return {String} not true random string
*/
function randomIdF() function randomIdF()
{ {
return Math.random().toString(36).substring(2); return Math.random().toString(36).substring(2);
} }
// METHOD: isObject /**
// PARAMS: possible object * checks if a variable is an object
// RETURN: true/false if it is an object or not * @param {Mixed} val possible object
// DESC : checks if a variable is an object * @return {Boolean} true/false if it is an object or not
*/
function isObject(val) { function isObject(val) {
if (val === null) { if (val === null) {
return false; return false;
@@ -264,47 +289,55 @@ function isObject(val) {
return ((typeof val === 'function') || (typeof val === 'object')); return ((typeof val === 'function') || (typeof val === 'object'));
} }
// METHOD: keyInObject /**
// PARAMS: key name, object * checks if a key exists in a given object
// RETURN: true/false if key exists in object * @param {String} key key name
// DESC : checks if a key exists in a given object * @param {Object} object object to search key in
const keyInObject = (key, object) => (key in object) ? true : false; * @return {Boolean} true/false if key exists in object
*/
const keyInObject = (key, object) => (Object.prototype.hasOwnProperty.call(object, key)) ? true : false;
/*function keyInObject(key, object) /*function keyInObject(key, object)
{ {
return (key in object) ? true : false; return (Object.prototype.hasOwnProperty.call(object, key)) ? true : false;
}*/ }*/
// METHOD: getKeyByValue /**
// PARAMS: object, value * returns matching key of value
// RETURN: key found * @param {Object} obj object to search value in
// DESC : returns matching key of value * @param {Mixed} value any value (String, Number, etc)
* @return {String} the key found for the first matching value
*/
const getKeyByValue = (obj, value) => Object.keys(obj).find(key => obj[key] === value); const getKeyByValue = (obj, value) => Object.keys(obj).find(key => obj[key] === value);
// function getKeyByValue(object, value) // function getKeyByValue(object, value)
// { // {
// return Object.keys(object).find(key => object[key] === value); // return Object.keys(object).find(key => object[key] === value);
// } // }
// METHOD: valueInObject /**
// PARAMS: obj, value * returns true if value is found in object with a key
// RETURN: true/false * @param {Object} obj object to search value in
// DESC : returns true if value is found in object with a key * @param {Mixed} value any value (String, Number, etc)
* @return {Boolean} true on value found, false on not found
*/
const valueInObject = (obj, value) => (Object.keys(obj).find(key => obj[key] === value)) ? true : false; const valueInObject = (obj, value) => (Object.keys(obj).find(key => obj[key] === value)) ? true : false;
// METHOD: exists /**
// PARAMS: uid * checks if a DOM element actually exists
// RETURN: true/false * @param {String} id Element id to check for
// DESC : checks if a DOM element actually exists * @return {Boolean} true if element exists, false on failure
*/
const exists = (id) => $('#' + id).length > 0 ? true : false; const exists = (id) => $('#' + id).length > 0 ? true : false;
/*function exists(id) /*function exists(id)
{ {
return $('#' + id).length > 0 ? true : false; return $('#' + id).length > 0 ? true : false;
}*/ }*/
// METHOD: formatBytes /**
// PARAMS: bytes in int * converts a int number into bytes with prefix in two decimals precision
// RETURN: string in GB/MB/KB * currently precision is fixed, if dynamic needs check for max/min precision
// DESC : converts a int number into bytes with prefix in two decimals precision * @param {Number} bytes bytes in int
// currently precision is fixed, if dynamic needs check for max/min precision * @return {String} string in GB/MB/KB
*/
function formatBytes(bytes) function formatBytes(bytes)
{ {
var i = -1; var i = -1;
@@ -316,10 +349,10 @@ function formatBytes(bytes)
return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i]; return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
} }
// METHOD: errorCatch /**
// PARAMS: err (error from try/catch * prints out error messages based on data available from the browser
// RETURN: none * @param {Object} err error from try/catch block
// DESC : prints out error messages based on data available from the browser */
function errorCatch(err) function errorCatch(err)
{ {
// for FF & Chrome // for FF & Chrome
@@ -345,10 +378,10 @@ function errorCatch(err)
} }
} }
// METHOD: actionIndicator /**
// PARAMS: none * show or hide the "do" overlay
// RETURN: none * @param {String} [loc=''] location name for action indicator, default empty. for console.log
// DESC : show or hide the "do" overlay */
function actionIndicator(loc = '') function actionIndicator(loc = '')
{ {
if ($('#overlayBox').is(':visible')) { if ($('#overlayBox').is(':visible')) {
@@ -358,12 +391,11 @@ function actionIndicator(loc = '')
} }
} }
// METHOD: actionIndicatorShow/actionIndicatorHide /**
// PARAMS: loc for console log info * explicit show for action Indicator
// RETURN: none * instead of automatically show or hide, do on command show
// DESC : explicit show/hide for action Indicator * @param {String} [loc=''] optional location name, empty if not set. for console.log
// instead of automatically show or hide, do */
// on command
function actionIndicatorShow(loc = '') function actionIndicatorShow(loc = '')
{ {
console.log('Indicator: SHOW [%s]', loc); console.log('Indicator: SHOW [%s]', loc);
@@ -372,6 +404,12 @@ function actionIndicatorShow(loc = '')
$('#indicator').show(); $('#indicator').show();
overlayBoxShow(); overlayBoxShow();
} }
/**
* explicit hide for action Indicator
* instead of automatically show or hide, do on command hide
* @param {String} [loc=''] optional location name, empty if not set. for console.log
*/
function actionIndicatorHide(loc = '') function actionIndicatorHide(loc = '')
{ {
console.log('Indicator: HIDE [%s]', loc); console.log('Indicator: HIDE [%s]', loc);
@@ -380,10 +418,9 @@ function actionIndicatorHide(loc = '')
overlayBoxHide(); overlayBoxHide();
} }
// METHOD: overlayBoxView /**
// PARAMS: none * shows the overlay box
// RETURN: none */
// DESC : shows or hides the overlay box
function overlayBoxShow() function overlayBoxShow()
{ {
// check if overlay box exists and if yes set the z-index to 100 // check if overlay box exists and if yes set the z-index to 100
@@ -393,6 +430,10 @@ function overlayBoxShow()
$('#overlayBox').show(); $('#overlayBox').show();
} }
} }
/**
* hides the overlay box
*/
function overlayBoxHide() function overlayBoxHide()
{ {
// if the overlay box z-index is 100, do no hide, but set to 98 // if the overlay box z-index is 100, do no hide, but set to 98
@@ -403,10 +444,9 @@ function overlayBoxHide()
} }
} }
// METHOD: setOverlayBox /**
// PARAMS: none * position the overlay block box and shows it
// RETURN: none */
// DESC : position the overlay block box and shows it
function setOverlayBox() function setOverlayBox()
{ {
var viewport = document.viewport.getDimensions(); var viewport = document.viewport.getDimensions();
@@ -417,10 +457,9 @@ function setOverlayBox()
$('#overlayBox').show(); $('#overlayBox').show();
} }
// METHOD: ClearCall /**
// PARAMS: none * the abort call, clears the action box and hides it and the overlay box
// RETURN: none */
// DESC : the abort call, clears the action box and hides it and the overlay box
function ClearCall() function ClearCall()
{ {
$('#actionBox').innerHTML = ''; $('#actionBox').innerHTML = '';
@@ -429,14 +468,15 @@ function ClearCall()
} }
// *** DOM MANAGEMENT FUNCTIONS // *** DOM MANAGEMENT FUNCTIONS
// METHOD: cel [create element] /**
// PARAMS: tag: must set tag (div, span, etc) * reates object for DOM element creation flow
// id: optional set for id, if input, select will be used for name * @param {String} tag must set tag (div, span, etc)
// content: text content inside, is skipped if sub elements exist * @param {String} [id=''] optional set for id, if input, select will be used for name
// css: array for css tags * @param {String} [content=''] text content inside, is skipped if sub elements exist
// options: anything else (value, placeholder, OnClick, style) * @param {Array} [css=[]] array for css tags
// RETURN: object * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)
// DESC : creates object for DOM element creation flow * @return {Object} created element as an object
*/
const cel = (tag, id = '', content = '', css = [], options = {}) => const cel = (tag, id = '', content = '', css = [], options = {}) =>
_element = { _element = {
tag: tag, tag: tag,
@@ -448,12 +488,13 @@ const cel = (tag, id = '', content = '', css = [], options = {}) =>
sub: [] sub: []
}; };
// METHOD: ael [attach element] /**
// PARAMS: base: object where to attach/search * attach a cel created object to another to create a basic DOM tree
// attach: the object to be attached * @param {Object} base object where to attach/search
// id: optional id, if given search in base for this id and attach there * @param {Object} attach the object to be attached
// RETURN: "none", technically there is no return needed * @param {String} [id=''] optional id, if given search in base for this id and attach there
// DESC : attach a cel created object to another to create a basic DOM tree * @return {Object} "none", technically there is no return needed as it is global attach
*/
function ael(base, attach, id = '') function ael(base, attach, id = '')
{ {
if (id) { if (id) {
@@ -475,12 +516,13 @@ function ael(base, attach, id = '')
return base; return base;
} }
// METHOD: aelx [attach n elements] /**
// PARAMS: base: object to where we attach the elements * directly attach n elements to one master base element
// attach 1..n: attach directly to the base element those attachments * this type does not support attach with optional id
// RETURN: "none", technically there is no return needed * @param {Object} base object to where we attach the elements
// DESC : directly attach n elements to one master base element * @param {...Object} attach attach 1..n: attach directly to the base element those attachments
// this type does not support attach with optional id * @return {Object} "none", technically there is no return needed, global attach
*/
function aelx(base, ...attach) function aelx(base, ...attach)
{ {
for (var i = 0; i < attach.length; i ++) { for (var i = 0; i < attach.length; i ++) {
@@ -489,19 +531,22 @@ function aelx(base, ...attach)
return base; return base;
} }
// METHOD: rel [reset element] /**
// PARAMS: cel created element * resets the sub elements of the base element given
// RETURN: returns sub reset base element * @param {Object} base cel created element
// DESC : resets the sub elements of the base element given * @return {Object} returns reset base element
*/
const rel = (base) => { const rel = (base) => {
base.sub = []; base.sub = [];
return base; return base;
}; };
// METHOD: rcssel [remove a css from the element] /**
// PARAMS: element, style sheet to remove * searches and removes style from css array
// RETURN: "none", in place because of reference * @param {Object} _element element to work one
// DESC : searches and removes style from css array * @param {String css style sheet to remove (name)
* @return {Object} returns full element
*/
function rcssel(_element, css) function rcssel(_element, css)
{ {
var css_index = _element.css.indexOf(css); var css_index = _element.css.indexOf(css);
@@ -511,10 +556,12 @@ function rcssel(_element, css)
return _element; return _element;
} }
// METHOD: acssel [add css element] /**
// PARAMS: element, style sheet to add * adds a new style sheet to the element given
// RETURN: "none", in place add because of reference * @param {Object} _element element to work on
// DESC : adds a new style sheet to the element given * @param {String} css style sheet to add (name)
* @return {Object} returns full element
*/
function acssel(_element, css) function acssel(_element, css)
{ {
var css_index = _element.css.indexOf(css); var css_index = _element.css.indexOf(css);
@@ -524,23 +571,26 @@ function acssel(_element, css)
return _element; return _element;
} }
// METHOD: scssel /**
// PARAMS: element, style to remove, style to add * removes one css and adds another
// RETURN: "none", in place add because of reference * is a wrapper around rcssel/acssel
// DESC : removes one css and adds another * @param {Object} _element element to work on
// is a wrapper around rcssel/acssel * @param {String} rcss style to remove (name)
* @param {String} acss style to add (name)
* @return {Object} returns full element
*/
function scssel(_element, rcss, acss) function scssel(_element, rcss, acss)
{ {
rcssel(_element, rcss); rcssel(_element, rcss);
acssel(_element, acss); acssel(_element, acss);
} }
// METHOD: phfo [produce html from object] /**
// PARAMS: object tree with dom element declarations * parses the object tree created with cel/ael and converts it into an HTML string
// RETURN: HTML string that can be used as innerHTML * that can be inserted into the page
// DESC : parses the object tree created with cel/ael * @param {Object} tree object tree with dom element declarations
// and converts it into an HTML string that can * @return {String} HTML string that can be used as innerHTML
// be inserted into the page */
function phfo(tree) function phfo(tree)
{ {
// holds the elements // holds the elements
@@ -603,33 +653,44 @@ function phfo(tree)
// BLOCK: html wrappers for quickly creating html data blocks // BLOCK: html wrappers for quickly creating html data blocks
// NOTE : OLD FORMAT which misses multiple block set /**
// METHOD: html_options * NOTE: OLD FORMAT which misses multiple block set
// PARAMS: name/id, array for the options, selected item uid * creates an select/options drop down block.
// options_only [def false] if this is true, it will not print the select part * the array needs to be key -> value format.
// return_string [def false]: return as string and not as element * key is for the option id and value is for the data output
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {String} name name/id
// RETURN: html with build options block * @param {Object} data array for the options
// DESC : creates an select/options drop down block. * @param {String} [selected=''] selected item uid
// the array needs to be key -> value format. key is for the option id and value is for the data output * @param {Boolean} [options_only=false] if this is true, it will not print the select part
* @param {Boolean} [return_string=false] return as string and not as element
* @param {String} [sort=''] if empty as is, else allowed 'keys',
* 'values' all others are ignored
* @return {String} html with build options block
*/
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '') function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')
{ {
// wrapper to new call // wrapper to new call
return html_options_block(name, data, selected, false, options_only, return_string, sort); return html_options_block(name, data, selected, false, options_only, return_string, sort);
} }
// NOTE : USE THIS CALL, the above one is deprecated /**
// METHOD: html_options * NOTE: USE THIS CALL, the above one is deprecated
// PARAMS: name/id, array for the options, * creates an select/options drop down block.
// selected item uid [drop down string, multi select array] * the array needs to be key -> value format.
// multiple [def 0] if this is 1 or larger, the drop down will be turned into multiple select * key is for the option id and value is for the data output
// the number sets the size value unless it is 1, then it is default * @param {String} name name/id
// options_only [def false] if this is true, it will not print the select part * @param {Object} data array for the options
// return_string [def false]: return as string and not as element * @param {String} [selected=''] selected item uid
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {Number} [multiple=0] if this is 1 or larger, the drop down
// RETURN: html with build options block * will be turned into multiple select
// DESC : creates an select/options drop down block. * the number sets the size value unless it is 1,
// the array needs to be key -> value format. key is for the option id and value is for the data output * then it is default
* @param {Boolean} [options_only=false] if this is true, it will not print the select part
* @param {Boolean} [return_string=false] return as string and not as element
* @param {String} [sort=''] if empty as is, else allowed 'keys',
* 'values' all others are ignored
* @return {String} html with build options block
*/
function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '') function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '')
{ {
var content = []; var content = [];
@@ -700,11 +761,13 @@ function html_options_block(name, data, selected = '', multiple = 0, options_onl
} }
} }
// METHOD: html_options_refill /**
// PARAMS: name/id, array of options, sort = '' * refills a select box with options and keeps the selected
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {String} name name/id
// RETURN: none * @param {Object} data array of options
// DESC : refills a select box with options and keeps the selected * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'
* all others are ignored
*/
function html_options_refill(name, data, sort = '') function html_options_refill(name, data, sort = '')
{ {
var element_option; var element_option;
@@ -738,11 +801,70 @@ function html_options_refill(name, data, sort = '')
} }
} }
/**
* parses a query string from window.location.search.substring(1)
* ALTERNATIVE CODE
* var url = new URL(window.location.href);
* param_uid = url.searchParams.get('uid');
* @param {String} [query=''] the query string to parse
* if not set will auto fill
* @param {String} [return_key=''] if set only returns this key entry
* or empty for none
* @return {Object|String} parameter entry list
*/
function parseQueryString(query = '', return_key = '') {
if (!query) {
query = window.location.search.substring(1);
}
var vars = query.split("&");
var query_string = {};
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof query_string[key] === "undefined") {
query_string[key] = decodeURIComponent(value);
// If second entry with this name
} else if (typeof query_string[key] === "string") {
var arr = [query_string[key], decodeURIComponent(value)];
query_string[key] = arr;
// If third or later entry with this name
} else {
query_string[key].push(decodeURIComponent(value));
}
}
if (return_key) {
if (keyInObject(return_key, query_string)) {
return query_string[return_key];
} else {
return '';
}
} else {
return query_string;
}
}
/**
* searchs the current url for a parameter
* @param {String} key uid key to get data for
* @return {String} value for the key or '' for not found
*/
function getQueryStringParam(key)
{
var url = new URL(window.location.href);
var param = url.searchParams.get(key);
if (param) {
return param;
} else {
return '';
}
}
// *** MASTER logout call // *** MASTER logout call
// METHOD: loginLogout /**
// PARAMS: none * submits basic data for form logout
// RETURN: none */
// DESC : submits basic data for form logout
function loginLogout() function loginLogout()
{ {
const form = document.createElement('form'); const form = document.createElement('form');

View File

@@ -1,4 +1,5 @@
/* general edit javascript */ /* general edit javascript */
/* prototype version */
/* jshint esversion: 6 */ /* jshint esversion: 6 */
@@ -11,19 +12,21 @@ if (!DEBUG) {
}); });
}*/ }*/
// METHOD: pop /**
// PARAMS: url, window name, features * opens a popup window with winName and given features (string)
// RETURN: none * @param {String} theURL the url
// DESC : opens a popup window with winName and given features (string) * @param {String} winName window name
* @param {Object} features popup features
*/
function pop(theURL, winName, features) { function pop(theURL, winName, features) {
winName = window.open(theURL, winName, features); winName = window.open(theURL, winName, features);
winName.focus(); winName.focus();
} }
// METHOD: expandTA /**
// PARAMS: id * automatically resize a text area based on the amount of lines in it
// RETURN: none * @param {[string} ta_id element id
// DESC : automatically resize a text area based on the amount of lines in it */
function expandTA(ta_id) { function expandTA(ta_id) {
var ta; var ta;
// if a string comes, its a get by id, else use it as an element pass on // if a string comes, its a get by id, else use it as an element pass on
@@ -44,12 +47,12 @@ function expandTA(ta_id) {
ta.rows = numNewRows + theRows.length; ta.rows = numNewRows + theRows.length;
} }
// METHOD: ShowHideMenu /**
// PARAMS: status -> show or hide * shows or hides the menu
// id -> id to work on * this is used in some old menu templates
// RETURN: none * @param {String} status show or hide
// DESC: shows or hides the menu * @param {String} id element id to work on
// this is used in some old menu templates */
function ShowHideMenu(status, id) function ShowHideMenu(status, id)
{ {
if (status == 'show') { if (status == 'show') {
@@ -65,8 +68,12 @@ function ShowHideMenu(status, id)
} }
} }
// used in old templates /**
// move element action * used in old templates
* move element action
* @param {String} id element id to move
* @param {String} direction move direction
*/
function mv(id, direction) function mv(id, direction)
{ {
document.forms[form_name].action.value = 'move'; document.forms[form_name].action.value = 'move';
@@ -75,7 +82,11 @@ function mv(id, direction)
document.forms[form_name].submit(); document.forms[form_name].submit();
} }
// load element action /**
* used in old templates
* load element action
* @param {String} id the element id to load
*/
function le(id) function le(id)
{ {
document.forms[form_name].action.value = 'load'; document.forms[form_name].action.value = 'load';
@@ -91,13 +102,14 @@ function le(id)
} }
} }
// METHOD: sh /**
// PARAMS: id -> element to hide * hides an element, additional writes 1 (show) or 0 (hide) into <id>Flag field
// showText -> text for the element if shown * this needs scriptacolous installed for BlindUp/BlindDown
// hideText -> text for the element if hidden * @param {String} id element id to hide
// RETURN: returns true if hidden, or false if not * @param {String} showText text for the element if shown
// DESC : hides an element, additional writes 1 (show) or 0 (hide) into <id>Flag field * @param {String} hideText text for the element if hidden
// this needs scriptacolous installed for BlindUp/BlindDown * @return {Boolean} returns true if hidden, or false if not
*/
function sh(id, showText, hideText) function sh(id, showText, hideText)
{ {
flag = id + 'Flag'; flag = id + 'Flag';
@@ -120,10 +132,10 @@ function sh(id, showText, hideText)
return divStatus; return divStatus;
} }
// METHOD: getWindowSize /**
// PARAMS: none * wrapper to get the real window size for the current browser window
// RETURN: array with width/height * @return {Object} object with width/height
// DESC : wrapper to get the real window size for the current browser window */
function getWindowSize() function getWindowSize()
{ {
var width, height; var width, height;
@@ -135,10 +147,10 @@ function getWindowSize()
}; };
} }
// METHOD: getScrollOffset /**
// PARAMS: none * wrapper to get the correct scroll offset
// RETURN: array with x/y px * @return {Object} object with x/y px
// DESC : wrapper to get the correct scroll offset */
function getScrollOffset() function getScrollOffset()
{ {
var left, top; var left, top;
@@ -150,10 +162,12 @@ function getScrollOffset()
}; };
} }
// METHOD: setCenter /**
// PARAMS: id to set center * centers div to current window size middle
// RETURN: none * @param {String} id element to center
// DESC : centers div to current window size middle * @param {Boolean} left if true centers to the middle from the left
* @param {Boolean} top if true centers to the middle from the top
*/
function setCenter(id, left, top) function setCenter(id, left, top)
{ {
// get size of id // get size of id
@@ -179,10 +193,11 @@ function setCenter(id, left, top)
} }
} }
// METHOD: goToPos() /**
// PARAMS: element, offset (default 0) * goes to an element id position
// RETURN: none * @param {String} element element id to move to
// DESC: goes to an element id position * @param {Number} [offset=0] offset from top, default is 0 (px)
*/
function goToPos(element, offset = 0) function goToPos(element, offset = 0)
{ {
try { try {
@@ -203,10 +218,12 @@ function goToPos(element, offset = 0)
} }
} }
// METHOD: __ /**
// PARAMS: text * uses the i18n object created in the translation template
// RETURN: translated text (based on PHP selected language) * that is filled from gettext in PHP
// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty) * @param {String} string text to translate
* @return {String} translated text (based on PHP selected language)
*/
function __(string) function __(string)
{ {
if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) { if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) {
@@ -216,12 +233,13 @@ function __(string)
} }
} }
// METHOD: string.format /**
// PARAMS: any, for string format * simple sprintf formater for replace
// RETURN: formatted string * usage: "{0} is cool, {1} is not".format("Alpha", "Beta");
// DESC : simple sprintf formater for replace * First, checks if it isn't implemented yet.
// "{0} is cool, {1} is not".format("Alpha", "Beta"); * @param {String} !String.prototype.format string with elements to be replaced
// First, checks if it isn't implemented yet. * @return {String} Formated string
*/
if (!String.prototype.format) { if (!String.prototype.format) {
String.prototype.format = function() String.prototype.format = function()
{ {
@@ -236,25 +254,32 @@ if (!String.prototype.format) {
}; };
} }
// METHOD: numberWithCommas /**
// PARAMS: number * formats flat number 123456 to 123,456
// RETURN: formatted with , in thousands * @param {Number} x number to be formated
// DESC : formats flat number 123456 to 123,456 * @return {String} formatted with , in thousands
*/
const numberWithCommas = (x) => { const numberWithCommas = (x) => {
var parts = x.toString().split("."); var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join("."); return parts.join(".");
}; };
// METHOD: /**
// PARAMS: string * converts line breaks to br
// RETURN: string with <br> * @param {String} string any string
// DESC : converts line breaks to br * @return {String} string with <br>
*/
function convertLBtoBR(string) function convertLBtoBR(string)
{ {
return string.replace(/(?:\r\n|\r|\n)/g, '<br>'); return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
} }
/**
* escape HTML string
* @param {String} !String.prototype.escapeHTML HTML data string to be escaped
* @return {String} escaped string
*/
if (!String.prototype.escapeHTML) { if (!String.prototype.escapeHTML) {
String.prototype.escapeHTML = function() { String.prototype.escapeHTML = function() {
return this.replace(/[&<>"'\/]/g, function (s) { return this.replace(/[&<>"'\/]/g, function (s) {
@@ -272,6 +297,11 @@ if (!String.prototype.escapeHTML) {
}; };
} }
/**
* unescape a HTML encoded string
* @param {String} !String.prototype.unescapeHTML data with escaped entries
* @return {String} HTML formated string
*/
if (!String.prototype.unescapeHTML) { if (!String.prototype.unescapeHTML) {
String.prototype.unescapeHTML = function() { String.prototype.unescapeHTML = function() {
return this.replace(/&[#\w]+;/g, function (s) { return this.replace(/&[#\w]+;/g, function (s) {
@@ -289,31 +319,33 @@ if (!String.prototype.unescapeHTML) {
}; };
} }
// METHOD: getTimestamp /**
// PARAMS: none * returns current timestamp (unix timestamp)
// RETURN: timestamp (in milliseconds) * @return {Number} timestamp (in milliseconds)
// DESC : returns current timestamp (unix timestamp) */
function getTimestamp() function getTimestamp()
{ {
var date = new Date(); var date = new Date();
return date.getTime(); return date.getTime();
} }
// METHOD: dec2hex /**
// PARAMS: decimal string * dec2hex :: Integer -> String
// RETURN: string * i.e. 0-255 -> '00'-'ff'
// DESC : dec2hex :: Integer -> String * @param {Number} dec decimal string
// i.e. 0-255 -> '00'-'ff' * @return {String} hex encdoded number
*/
function dec2hex(dec) function dec2hex(dec)
{ {
return ('0' + dec.toString(16)).substr(-2); return ('0' + dec.toString(16)).substr(-2);
} }
// METHOD: generateId /**
// PARAMS: lenght in int * generateId :: Integer -> String
// RETURN: random string * only works on mondern browsers
// DESC : generateId :: Integer -> String * @param {Number} len length of unique id string
// only works on mondern browsers * @return {String} random string in length of len
*/
function generateId(len) function generateId(len)
{ {
var arr = new Uint8Array((len || 40) / 2); var arr = new Uint8Array((len || 40) / 2);
@@ -321,20 +353,22 @@ function generateId(len)
return Array.from(arr, dec2hex).join(''); return Array.from(arr, dec2hex).join('');
} }
// METHOD: randomIdF() /**
// PARAMS: none * creates a pseudo random string of 10 characters
// RETURN: not true random string * works on all browsers
// DESC : creates a pseudo random string of 10 characters * after many runs it will create duplicates
// after many runs it will create duplicates * @return {String} not true random string
*/
function randomIdF() function randomIdF()
{ {
return Math.random().toString(36).substring(2); return Math.random().toString(36).substring(2);
} }
// METHOD: isObject /**
// PARAMS: possible object * checks if a variable is an object
// RETURN: true/false if it is an object or not * @param {Mixed} val possible object
// DESC : checks if a variable is an object * @return {Boolean} true/false if it is an object or not
*/
function isObject(val) { function isObject(val) {
if (val === null) { if (val === null) {
return false; return false;
@@ -342,47 +376,55 @@ function isObject(val) {
return ((typeof val === 'function') || (typeof val === 'object')); return ((typeof val === 'function') || (typeof val === 'object'));
} }
// METHOD: keyInObject /**
// PARAMS: key name, object * checks if a key exists in a given object
// RETURN: true/false if key exists in object * @param {String} key key name
// DESC : checks if a key exists in a given object * @param {Object} object object to search key in
const keyInObject = (key, object) => (key in object) ? true : false; * @return {Boolean} true/false if key exists in object
*/
const keyInObject = (key, object) => (Object.prototype.hasOwnProperty.call(object, key)) ? true : false;
/*function keyInObject(key, object) /*function keyInObject(key, object)
{ {
return (key in object) ? true : false; return (Object.prototype.hasOwnProperty.call(object, key)) ? true : false;
}*/ }*/
// METHOD: getKeyByValue /**
// PARAMS: object, value * returns matching key of value
// RETURN: key found * @param {Object} obj object to search value in
// DESC : returns matching key of value * @param {Mixed} value any value (String, Number, etc)
* @return {String} the key found for the first matching value
*/
const getKeyByValue = (obj, value) => Object.keys(obj).find(key => obj[key] === value); const getKeyByValue = (obj, value) => Object.keys(obj).find(key => obj[key] === value);
// function getKeyByValue(object, value) // function getKeyByValue(object, value)
// { // {
// return Object.keys(object).find(key => object[key] === value); // return Object.keys(object).find(key => object[key] === value);
// } // }
// METHOD: valueInObject /**
// PARAMS: obj, value * returns true if value is found in object with a key
// RETURN: true/false * @param {Object} obj object to search value in
// DESC : returns true if value is found in object with a key * @param {Mixed} value any value (String, Number, etc)
* @return {Boolean} true on value found, false on not found
*/
const valueInObject = (obj, value) => (Object.keys(obj).find(key => obj[key] === value)) ? true : false; const valueInObject = (obj, value) => (Object.keys(obj).find(key => obj[key] === value)) ? true : false;
// METHOD: exists /**
// PARAMS: uid * checks if a DOM element actually exists
// RETURN: true/false * @param {String} id Element id to check for
// DESC : checks if a DOM element actually exists * @return {Boolean} true if element exists, false on failure
const exists = (id) => $('#' + id).length > 0 ? true : false; */
const exists = (id) => $(id).length > 0 ? true : false;
/*function exists(id) /*function exists(id)
{ {
return $('#' + id).length > 0 ? true : false; return $(id).length > 0 ? true : false;
}*/ }*/
// METHOD: formatBytes /**
// PARAMS: bytes in int * converts a int number into bytes with prefix in two decimals precision
// RETURN: string in GB/MB/KB * currently precision is fixed, if dynamic needs check for max/min precision
// DESC : converts a int number into bytes with prefix in two decimals precision * @param {Number} bytes bytes in int
// currently precision is fixed, if dynamic needs check for max/min precision * @return {String} string in GB/MB/KB
*/
function formatBytes(bytes) function formatBytes(bytes)
{ {
var i = -1; var i = -1;
@@ -394,10 +436,10 @@ function formatBytes(bytes)
return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i]; return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
} }
// METHOD: errorCatch /**
// PARAMS: err (error from try/catch * prints out error messages based on data available from the browser
// RETURN: none * @param {Object} err error from try/catch block
// DESC : prints out error messages based on data available from the browser */
function errorCatch(err) function errorCatch(err)
{ {
// for FF & Chrome // for FF & Chrome
@@ -423,10 +465,10 @@ function errorCatch(err)
} }
} }
// METHOD: actionIndicator /**
// PARAMS: none * show or hide the "do" overlay
// RETURN: none * @param {String} [loc=''] location name for action indicator, default empty. for console.log
// DESC : show or hide the "do" overlay */
function actionIndicator(loc = '') function actionIndicator(loc = '')
{ {
if ($('overlayBox').visible()) { if ($('overlayBox').visible()) {
@@ -436,12 +478,11 @@ function actionIndicator(loc = '')
} }
} }
// METHOD: actionIndicatorShow/actionIndicatorHide /**
// PARAMS: loc for console log info * explicit show for action Indicator
// RETURN: none * instead of automatically show or hide, do on command show
// DESC : explicit show/hide for action Indicator * @param {String} [loc=''] optional location name, empty if not set. for console.log
// instead of automatically show or hide, do */
// on command
function actionIndicatorShow(loc = '') function actionIndicatorShow(loc = '')
{ {
console.log('Indicator: SHOW [%s]', loc); console.log('Indicator: SHOW [%s]', loc);
@@ -450,6 +491,12 @@ function actionIndicatorShow(loc = '')
$('indicator').show(); $('indicator').show();
overlayBoxShow(); overlayBoxShow();
} }
/**
* explicit hide for action Indicator
* instead of automatically show or hide, do on command hide
* @param {String} [loc=''] optional location name, empty if not set. for console.log
*/
function actionIndicatorHide(loc = '') function actionIndicatorHide(loc = '')
{ {
console.log('Indicator: HIDE [%s]', loc); console.log('Indicator: HIDE [%s]', loc);
@@ -458,10 +505,9 @@ function actionIndicatorHide(loc = '')
overlayBoxHide(); overlayBoxHide();
} }
// METHOD: overlayBoxView /**
// PARAMS: none * shows the overlay box
// RETURN: none */
// DESC : shows or hides the overlay box
function overlayBoxShow() function overlayBoxShow()
{ {
// check if overlay box exists and if yes set the z-index to 100 // check if overlay box exists and if yes set the z-index to 100
@@ -471,6 +517,10 @@ function overlayBoxShow()
$('overlayBox').show(); $('overlayBox').show();
} }
} }
/**
* hides the overlay box
*/
function overlayBoxHide() function overlayBoxHide()
{ {
// if the overlay box z-index is 100, do no hide, but set to 98 // if the overlay box z-index is 100, do no hide, but set to 98
@@ -481,10 +531,9 @@ function overlayBoxHide()
} }
} }
// METHOD: setOverlayBox /**
// PARAMS: none * position the overlay block box and shows it
// RETURN: none */
// DESC : position the overlay block box and shows it
function setOverlayBox() function setOverlayBox()
{ {
var viewport = document.viewport.getDimensions(); var viewport = document.viewport.getDimensions();
@@ -495,10 +544,9 @@ function setOverlayBox()
$('overlayBox').show(); $('overlayBox').show();
} }
// METHOD: ClearCall /**
// PARAMS: none * the abort call, clears the action box and hides it and the overlay box
// RETURN: none */
// DESC : the abort call, clears the action box and hides it and the overlay box
function ClearCall() function ClearCall()
{ {
$('actionBox').innerHTML = ''; $('actionBox').innerHTML = '';
@@ -507,14 +555,15 @@ function ClearCall()
} }
// *** DOM MANAGEMENT FUNCTIONS // *** DOM MANAGEMENT FUNCTIONS
// METHOD: cel [create element] /**
// PARAMS: tag: must set tag (div, span, etc) * reates object for DOM element creation flow
// id: optional set for id, if input, select will be used for name * @param {String} tag must set tag (div, span, etc)
// content: text content inside, is skipped if sub elements exist * @param {String} [id=''] optional set for id, if input, select will be used for name
// css: array for css tags * @param {String} [content=''] text content inside, is skipped if sub elements exist
// options: anything else (value, placeholder, OnClick, style) * @param {Array} [css=[]] array for css tags
// RETURN: object * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)
// DESC : creates object for DOM element creation flow * @return {Object} created element as an object
*/
const cel = (tag, id = '', content = '', css = [], options = {}) => const cel = (tag, id = '', content = '', css = [], options = {}) =>
_element = { _element = {
tag: tag, tag: tag,
@@ -526,12 +575,13 @@ const cel = (tag, id = '', content = '', css = [], options = {}) =>
sub: [] sub: []
}; };
// METHOD: ael [attach element] /**
// PARAMS: base: object where to attach/search * attach a cel created object to another to create a basic DOM tree
// attach: the object to be attached * @param {Object} base object where to attach/search
// id: optional id, if given search in base for this id and attach there * @param {Object} attach the object to be attached
// RETURN: "none", technically there is no return needed * @param {String} [id=''] optional id, if given search in base for this id and attach there
// DESC : attach a cel created object to another to create a basic DOM tree * @return {Object} "none", technically there is no return needed as it is global attach
*/
function ael(base, attach, id = '') function ael(base, attach, id = '')
{ {
if (id) { if (id) {
@@ -553,12 +603,13 @@ function ael(base, attach, id = '')
return base; return base;
} }
// METHOD: aelx [attach n elements] /**
// PARAMS: base: object to where we attach the elements * directly attach n elements to one master base element
// attach 1..n: attach directly to the base element those attachments * this type does not support attach with optional id
// RETURN: "none", technically there is no return needed * @param {Object} base object to where we attach the elements
// DESC : directly attach n elements to one master base element * @param {...Object} attach attach 1..n: attach directly to the base element those attachments
// this type does not support attach with optional id * @return {Object} "none", technically there is no return needed, global attach
*/
function aelx(base, ...attach) function aelx(base, ...attach)
{ {
attach.each(function(t) { attach.each(function(t) {
@@ -567,19 +618,22 @@ function aelx(base, ...attach)
return base; return base;
} }
// METHOD: rel [reset element] /**
// PARAMS: cel created element * resets the sub elements of the base element given
// RETURN: returns reset base element * @param {Object} base cel created element
// DESC : resets the sub elements of the base element given * @return {Object} returns reset base element
*/
const rel = (base) => { const rel = (base) => {
base.sub = []; base.sub = [];
return base; return base;
}; };
// METHOD: rcssel [remove a css from the element] /**
// PARAMS: element, style sheet to remove * searches and removes style from css array
// RETURN: returns full element * @param {Object} _element element to work one
// DESC : searches and removes style from css array * @param {String css style sheet to remove (name)
* @return {Object} returns full element
*/
function rcssel(_element, css) function rcssel(_element, css)
{ {
var css_index = _element.css.indexOf(css); var css_index = _element.css.indexOf(css);
@@ -589,10 +643,12 @@ function rcssel(_element, css)
return _element; return _element;
} }
// METHOD: acssel [add css element] /**
// PARAMS: element, style sheet to add * adds a new style sheet to the element given
// RETURN: returns full element * @param {Object} _element element to work on
// DESC : adds a new style sheet to the element given * @param {String} css style sheet to add (name)
* @return {Object} returns full element
*/
function acssel(_element, css) function acssel(_element, css)
{ {
var css_index = _element.css.indexOf(css); var css_index = _element.css.indexOf(css);
@@ -602,11 +658,14 @@ function acssel(_element, css)
return _element; return _element;
} }
// METHOD: scssel /**
// PARAMS: element, style to remove, style to add * removes one css and adds another
// RETURN: returns full element * is a wrapper around rcssel/acssel
// DESC : removes one css and adds another * @param {Object} _element element to work on
// is a wrapper around rcssel/acssel * @param {String} rcss style to remove (name)
* @param {String} acss style to add (name)
* @return {Object} returns full element
*/
function scssel(_element, rcss, acss) function scssel(_element, rcss, acss)
{ {
rcssel(_element, rcss); rcssel(_element, rcss);
@@ -614,12 +673,12 @@ function scssel(_element, rcss, acss)
return _element; return _element;
} }
// METHOD: phfo [produce html from object] /**
// PARAMS: object tree with dom element declarations * parses the object tree created with cel/ael and converts it into an HTML string
// RETURN: HTML string that can be used as innerHTML * that can be inserted into the page
// DESC : parses the object tree created with cel/ael * @param {Object} tree object tree with dom element declarations
// and converts it into an HTML string that can * @return {String} HTML string that can be used as innerHTML
// be inserted into the page */
function phfo(tree) function phfo(tree)
{ {
// holds the elements // holds the elements
@@ -681,33 +740,44 @@ function phfo(tree)
// BLOCK: html wrappers for quickly creating html data blocks // BLOCK: html wrappers for quickly creating html data blocks
// NOTE : OLD FORMAT which misses multiple block set /**
// METHOD: html_options * NOTE: OLD FORMAT which misses multiple block set
// PARAMS: name/id, array for the options, selected item uid * creates an select/options drop down block.
// options_only [def false] if this is true, it will not print the select part * the array needs to be key -> value format.
// return_string [def false]: return as string and not as element * key is for the option id and value is for the data output
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {String} name name/id
// RETURN: html with build options block * @param {Object} data array for the options
// DESC : creates an select/options drop down block. * @param {String} [selected=''] selected item uid
// the array needs to be key -> value format. key is for the option id and value is for the data output * @param {Boolean} [options_only=false] if this is true, it will not print the select part
* @param {Boolean} [return_string=false] return as string and not as element
* @param {String} [sort=''] if empty as is, else allowed 'keys',
* 'values' all others are ignored
* @return {String} html with build options block
*/
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '') function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')
{ {
// wrapper to new call // wrapper to new call
return html_options_block(name, data, selected, false, options_only, return_string, sort); return html_options_block(name, data, selected, false, options_only, return_string, sort);
} }
// NOTE : USE THIS CALL, the above one is deprecated /**
// METHOD: html_options * NOTE: USE THIS CALL, the above one is deprecated
// PARAMS: name/id, array for the options, * creates an select/options drop down block.
// selected item uid [drop down string, multi select array] * the array needs to be key -> value format.
// multiple [def 0] if this is 1 or larger, the drop down will be turned into multiple select * key is for the option id and value is for the data output
// the number sets the size value unless it is 1, then it is default * @param {String} name name/id
// options_only [def false] if this is true, it will not print the select part * @param {Object} data array for the options
// return_string [def false]: return as string and not as element * @param {String} [selected=''] selected item uid
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {Number} [multiple=0] if this is 1 or larger, the drop down
// RETURN: html with build options block * will be turned into multiple select
// DESC : creates an select/options drop down block. * the number sets the size value unless it is 1,
// the array needs to be key -> value format. key is for the option id and value is for the data output * then it is default
* @param {Boolean} [options_only=false] if this is true, it will not print the select part
* @param {Boolean} [return_string=false] return as string and not as element
* @param {String} [sort=''] if empty as is, else allowed 'keys',
* 'values' all others are ignored
* @return {String} html with build options block
*/
function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '') function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '')
{ {
var content = []; var content = [];
@@ -778,11 +848,13 @@ function html_options_block(name, data, selected = '', multiple = 0, options_onl
} }
} }
// METHOD: html_options_refill /**
// PARAMS: name/id, array of options, sort = '' * refills a select box with options and keeps the selected
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored * @param {String} name name/id
// RETURN: none * @param {Object} data array of options
// DESC : refills a select box with options and keeps the selected * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'
* all others are ignored
*/
function html_options_refill(name, data, sort = '') function html_options_refill(name, data, sort = '')
{ {
var element_option; var element_option;
@@ -816,11 +888,70 @@ function html_options_refill(name, data, sort = '')
} }
} }
/**
* parses a query string from window.location.search.substring(1)
* ALTERNATIVE CODE
* var url = new URL(window.location.href);
* param_uid = url.searchParams.get('uid');
* @param {String} [query=''] the query string to parse
* if not set will auto fill
* @param {String} [return_key=''] if set only returns this key entry
* or empty for none
* @return {Object|String} parameter entry list
*/
function parseQueryString(query = '', return_key = '') {
if (!query) {
query = window.location.search.substring(1);
}
var vars = query.split("&");
var query_string = {};
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof query_string[key] === "undefined") {
query_string[key] = decodeURIComponent(value);
// If second entry with this name
} else if (typeof query_string[key] === "string") {
var arr = [query_string[key], decodeURIComponent(value)];
query_string[key] = arr;
// If third or later entry with this name
} else {
query_string[key].push(decodeURIComponent(value));
}
}
if (return_key) {
if (keyInObject(return_key, query_string)) {
return query_string[return_key];
} else {
return '';
}
} else {
return query_string;
}
}
/**
* searchs the current url for a parameter
* @param {String} key uid key to get data for
* @return {String} value for the key or '' for not found
*/
function getQueryStringParam(key)
{
var url = new URL(window.location.href);
var param = url.searchParams.get(key);
if (param) {
return param;
} else {
return '';
}
}
// *** MASTER logout call // *** MASTER logout call
// METHOD: loginLogout /**
// PARAMS: none * submits basic data for form logout
// RETURN: none */
// DESC : submits basic data for form logout
function loginLogout() function loginLogout()
{ {
const form = document.createElement('form'); const form = document.createElement('form');

2
www/layout/frontend/cache/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -1 +1 @@
../../../admin/default/javascript/debug.js ../../admin/javascript/debug.js

View File

@@ -1 +1 @@
../../../admin/default/javascript/fineuploader/ ../../admin/javascript/fineuploader/

View File

@@ -1 +1 @@
../../../admin/default/javascript/firebug.js ../../admin/javascript/firebug.js

View File

@@ -105,6 +105,9 @@ class Login extends \CoreLibs\DB\IO
// acl vars // acl vars
public $acl = array(); public $acl = array();
public $default_acl_list = array(); public $default_acl_list = array();
// login html, if we are on an ajax page
private $login_html = '';
private $login_is_ajax_page = false;
// language // language
public $l; public $l;
@@ -145,6 +148,10 @@ class Login extends \CoreLibs\DB\IO
exit; exit;
} }
// set global is ajax page for if we show the data directly, or need to pass it back
// to the continue AJAX class for output back to the user
$this->login_is_ajax_page = $this->ajax_page_flag;
$this->l = new \CoreLibs\Language\L10n($lang); $this->l = new \CoreLibs\Language\L10n($lang);
// if we have a search path we need to set it, to use the correct DB to login // if we have a search path we need to set it, to use the correct DB to login
@@ -250,22 +257,41 @@ class Login extends \CoreLibs\DB\IO
$this->loginPasswordForgot(); $this->loginPasswordForgot();
} }
// if !$euid || permission not okay, print login screan // if !$euid || permission not okay, print login screan
echo $this->loginPrintLogin(); $this->login_html = $this->loginPrintLogin();
// closing all connections, depending on error status, exit // closing all connections, depending on error status, exit
if (!$this->loginCloseClass()) { if (!$this->loginCloseClass()) {
// do not go anywhere, quit processing here // if variable AJAX flag is not set, show output, else pass through for ajax work
// do something with possible debug data? if ($this->login_is_ajax_page !== true) {
if (TARGET == 'live' || TARGET == 'remote') { // the login screen if we hav no login permission & login screen html data
// login if ($this->login_html !== null) {
$this->debug_output_all = DEBUG ? 1 : 0; echo $this->login_html;
$this->echo_output_all = 0; }
$this->print_output_all = DEBUG ? 1 : 0; // do not go anywhere, quit processing here
// do something with possible debug data?
if (TARGET == 'live' || TARGET == 'remote') {
// login
$this->debug_output_all = DEBUG ? 1 : 0;
$this->echo_output_all = 0;
$this->print_output_all = DEBUG ? 1 : 0;
}
$status_msg = $this->printErrorMsg();
if ($this->echo_output_all) {
echo $status_msg;
}
// exit so we don't process anything further, at all
exit;
} else {
// if we are on an ajax page reset any POST/GET array data to avoid
// any accidentical processing going on
$_POST = array();
$_GET = array();
// set the action to login so we can trigger special login html return
$_POST['action'] = 'login';
$_POST['login_html'] = $this->login_html;
// NOTE: this part needs to be catched by the frontend AJAX
// and some function needs to then set something like this
// document.getElementsByTagName('html')[0].innerHTML = data.content.login_html;
} }
$status_msg = $this->printErrorMsg();
if ($this->echo_output_all) {
echo $status_msg;
}
exit;
} }
// set acls for this user/group and this page // set acls for this user/group and this page
$this->loginSetAcl(); $this->loginSetAcl();
@@ -737,9 +763,9 @@ class Login extends \CoreLibs\DB\IO
} }
// flag if to show extra edit access drop downs (because user has multiple groups assigned) // flag if to show extra edit access drop downs (because user has multiple groups assigned)
if (count($_SESSION['UNIT']) > 1) { if (count($_SESSION['UNIT']) > 1) {
$this->acl['show_ea_extra'] = 1; $this->acl['show_ea_extra'] = true;
} else { } else {
$this->acl['show_ea_extra'] = 0; $this->acl['show_ea_extra'] = false;
} }
// set the default edit access // set the default edit access
$this->acl['default_edit_access'] = $_SESSION['UNIT_DEFAULT']; $this->acl['default_edit_access'] = $_SESSION['UNIT_DEFAULT'];
@@ -902,76 +928,61 @@ class Login extends \CoreLibs\DB\IO
{ {
$html_string = null; $html_string = null;
if (!$this->permission_okay) { if (!$this->permission_okay) {
// get global AJAX page trigger // set the templates now
// if true, return error ajax $this->loginSetTemplates();
global $AJAX_PAGE; // if there is a global logout target ...
if ($AJAX_PAGE === true) { if (file_exists($this->logout_target) && $this->logout_target) {
$data = array( $LOGOUT_TARGET = $this->logout_target;
'status' => 'error',
'error_code' => $this->login_error,
'msg' => array(
'level' => 'error',
'str' => $this->l->__('Login necessary')
)
);
$html_string = json_encode($data);
} else { } else {
// set the templates now $LOGOUT_TARGET = "";
$this->loginSetTemplates(); }
// if there is a global logout target ...
if (file_exists($this->logout_target) && $this->logout_target) {
$LOGOUT_TARGET = $this->logout_target;
} else {
$LOGOUT_TARGET = "";
}
$html_string = $this->login_template['template']; $html_string = $this->login_template['template'];
// if password change is okay // if password change is okay
if ($this->password_change) { if ($this->password_change) {
$html_string_password_change = $this->login_template['password_change']; $html_string_password_change = $this->login_template['password_change'];
// pre change the data in the PASSWORD_CHANGE_DIV first // pre change the data in the PASSWORD_CHANGE_DIV first
foreach ($this->login_template['strings'] as $string => $data) { foreach ($this->login_template['strings'] as $string => $data) {
if ($data) { if ($data) {
$html_string_password_change = str_replace('{'.$string.'}', $data, $html_string_password_change); $html_string_password_change = str_replace('{'.$string.'}', $data, $html_string_password_change);
}
} }
// print error messagae
if ($this->login_error) {
$html_string_password_change = str_replace('{ERROR_MSG}', $this->login_error_msg[$this->login_error].'<br>', $html_string_password_change);
} else {
$html_string_password_change = str_replace('{ERROR_MSG}', '<br>', $html_string_password_change);
}
// if pw change action, show the float again
if ($this->change_password && !$this->password_change_ok) {
$html_string_password_change = str_replace('{PASSWORD_CHANGE_SHOW}', '<script language="JavaScript">ShowHideDiv(\'pw_change_div\');</script>', $html_string_password_change);
} else {
$html_string_password_change = str_replace('{PASSWORD_CHANGE_SHOW}', '', $html_string_password_change);
}
$this->login_template['strings']['PASSWORD_CHANGE_DIV'] = $html_string_password_change;
} }
// put in the logout redirect string
if ($this->logout && $LOGOUT_TARGET) {
$html_string = str_replace('{LOGOUT_TARGET}', '<meta http-equiv="refresh" content="0; URL='.$LOGOUT_TARGET.'">', $html_string);
} else {
$html_string = str_replace('{LOGOUT_TARGET}', '', $html_string);
}
// print error messagae // print error messagae
if ($this->login_error) { if ($this->login_error) {
$html_string = str_replace('{ERROR_MSG}', $this->login_error_msg[$this->login_error].'<br>', $html_string); $html_string_password_change = str_replace('{ERROR_MSG}', $this->login_error_msg[$this->login_error].'<br>', $html_string_password_change);
} elseif ($this->password_change_ok && $this->password_change) {
$html_string = str_replace('{ERROR_MSG}', $this->login_error_msg[300].'<br>', $html_string);
} else { } else {
$html_string = str_replace('{ERROR_MSG}', '<br>', $html_string); $html_string_password_change = str_replace('{ERROR_MSG}', '<br>', $html_string_password_change);
} }
// if pw change action, show the float again
if ($this->change_password && !$this->password_change_ok) {
$html_string_password_change = str_replace('{PASSWORD_CHANGE_SHOW}', '<script language="JavaScript">ShowHideDiv(\'pw_change_div\');</script>', $html_string_password_change);
} else {
$html_string_password_change = str_replace('{PASSWORD_CHANGE_SHOW}', '', $html_string_password_change);
}
$this->login_template['strings']['PASSWORD_CHANGE_DIV'] = $html_string_password_change;
}
// create the replace array context // put in the logout redirect string
foreach ($this->login_template['strings'] as $string => $data) { if ($this->logout && $LOGOUT_TARGET) {
$html_string = str_replace('{'.$string.'}', $data, $html_string); $html_string = str_replace('{LOGOUT_TARGET}', '<meta http-equiv="refresh" content="0; URL='.$LOGOUT_TARGET.'">', $html_string);
} } else {
$html_string = str_replace('{LOGOUT_TARGET}', '', $html_string);
}
// print error messagae
if ($this->login_error) {
$html_string = str_replace('{ERROR_MSG}', $this->login_error_msg[$this->login_error].'<br>', $html_string);
} elseif ($this->password_change_ok && $this->password_change) {
$html_string = str_replace('{ERROR_MSG}', $this->login_error_msg[300].'<br>', $html_string);
} else {
$html_string = str_replace('{ERROR_MSG}', '<br>', $html_string);
}
// create the replace array context
foreach ($this->login_template['strings'] as $string => $data) {
$html_string = str_replace('{'.$string.'}', $data, $html_string);
} }
} // if permission is 0 then print out login } // if permission is 0 then print out login
// return the created HTML here or null for nothing // return the created HTML here or null for nothing

View File

@@ -193,7 +193,7 @@ class Backend extends \CoreLibs\DB\IO
} }
// get the session pages array // get the session pages array
$PAGES = $_SESSION['PAGES']; $PAGES = isset($_SESSION['PAGES']) ? $_SESSION['PAGES'] : null;
if (!isset($PAGES) || !is_array($PAGES)) { if (!isset($PAGES) || !is_array($PAGES)) {
$PAGES = array(); $PAGES = array();
} }

View File

@@ -181,6 +181,8 @@ class Basic
// form token (used for form validation) // form token (used for form validation)
private $form_token = ''; private $form_token = '';
// ajax flag
protected $ajax_page_flag = false;
// METHOD: __construct // METHOD: __construct
// PARAMS: set_control_flag [current sets set/get var errors] // PARAMS: set_control_flag [current sets set/get var errors]
@@ -218,6 +220,11 @@ class Basic
die('Core Constant missing. Check config file.'); die('Core Constant missing. Check config file.');
} }
// set ajax page flag based on the AJAX_PAGE varaibles
// convert to true/false so if AJAX_PAGE is 0 or false it is
// always boolean false
$this->ajax_page_flag = isset($GLOBALS['AJAX_PAGE']) && $GLOBALS['AJAX_PAGE'] ? true : false;
// set the page name // set the page name
$this->page_name = $this->getPageName(); $this->page_name = $this->getPageName();
$this->host_name = $this->getHostName(); $this->host_name = $this->getHostName();
@@ -1521,7 +1528,7 @@ class Basic
// labels in order of size // labels in order of size
$labels = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'); $labels = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB');
// calc file size, round down too two digits, add label based max change // calc file size, round down too two digits, add label based max change
return round($number / pow(1024, ($i = floor(log((float)$number, 1024)))), 2).($space ? ' ' : '').(isset($labels[(int)$i]) ? $labels[(int)$i] : '>EB'); return round((float)$number / pow(1024, ($i = floor(log((float)$number, 1024)))), 2).($space ? ' ' : '').(isset($labels[(int)$i]) ? $labels[(int)$i] : '>EB');
} }
return (string)$number; return (string)$number;
} }
@@ -1949,6 +1956,218 @@ class Basic
return $return_data; return $return_data;
} }
/**
* simple thumbnail creation for jpeg, png only
* TODO: add other types like gif, etc
* - bails with false on failed create
* - if either size_x or size_y are empty (0)
* the resize is to max of one size
* if both are set, those are the max sizes (aspect ration is always ekpt)
* - if path is not given will cache folder for current path set
* @param string $filename source file name with full path
* @param int $thumb_width thumbnail width
* @param int $thumb_height thumbnail height
* @param string|null $thumbnail_path altnerative path for thumbnails
* @param bool $use_cache default to true, set to false to skip
* creating new image if exists
* @param bool $high_quality default to true, uses sample version, set to false
* to use quick but less nice version
* @param int $jpeg_quality default 80, set image quality for jpeg only
* @return string|bool thumbnail with path
*/
public function createThumbnailSimple(
string $filename,
int $thumb_width = 0,
int $thumb_height = 0,
?string $thumbnail_path = null,
bool $use_cache = true,
bool $high_quality = true,
int $jpeg_quality = 80
) {
$thumbnail = false;
// $this->debug('IMAGE PREPARE', "FILE: $filename (exists ".(string)file_exists($filename)."), WIDTH: $thumb_width, HEIGHT: $thumb_height");
// check that input image exists and is either jpeg or png
// also fail if the basic CACHE folder does not exist at all
if (file_exists($filename) &&
is_dir(BASE.LAYOUT.CONTENT_PATH.CACHE) &&
is_writable(BASE.LAYOUT.CONTENT_PATH.CACHE)
) {
// $this->debug('IMAGE PREPARE', "FILENAME OK, THUMB WIDTH/HEIGHT OK");
list($inc_width, $inc_height, $img_type) = getimagesize($filename);
if ($img_type == IMG_JPG ||
$img_type == IMG_PNG
) {
// $this->debug('IMAGE PREPARE', "IMAGE TYPE OK: ".$inc_width.'x'.$inc_height);
// set thumbnail paths
$thumbnail_write_path = BASE.LAYOUT.CONTENT_PATH.CACHE.IMAGES;
$thumbnail_web_path = LAYOUT.CACHE.IMAGES;
// if images folder in cache does not exist create it, if failed, fall back to base cache folder
if (!is_dir($thumbnail_write_path)) {
if (false === mkdir($thumbnail_write_path)) {
$thumbnail_write_path = BASE.LAYOUT.CONTENT_PATH.CACHE;
$thumbnail_web_path = LAYOUT.CACHE;
}
}
// if missing width or height in thumb, use the set one
if ($thumb_width == 0) {
$thumb_width = $inc_width;
}
if ($thumb_height == 0) {
$thumb_height = $inc_height;
}
// check resize parameters
if ($inc_width > $thumb_width || $inc_height > $thumb_height) {
$thumb_width_r = 0;
$thumb_height_r = 0;
// we need to keep the aspect ration on longest side
if (($inc_height > $inc_width &&
// and the height is bigger than thumb set
$inc_height > $thumb_height) ||
// or the height is smaller or equal width
// but the width for the thumb is equal to the image height
($inc_height <= $inc_width &&
$inc_width == $thumb_width
)
) {
// $this->debug('IMAGE PREPARE', 'HEIGHT > WIDTH');
$ratio = $inc_height / $thumb_height;
$thumb_width_r = (int)ceil($inc_width / $ratio);
$thumb_height_r = $thumb_height;
} else {
// $this->debug('IMAGE PREPARE', 'WIDTH > HEIGHT');
$ratio = $inc_width / $thumb_width;
$thumb_width_r = $thumb_width;
$thumb_height_r = (int)ceil($inc_height / $ratio);
}
// $this->debug('IMAGE PREPARE', "Ratio: $ratio, Target size $thumb_width_r x $thumb_height_r");
// set output thumbnail name
$thumbnail = 'thumb-'.pathinfo($filename)['filename'].'-'.$thumb_width_r.'x'.$thumb_height_r;
if ($use_cache === false ||
!file_exists($thumbnail_write_path.$thumbnail)
) {
// image, copy source image, offset in image, source x/y, new size, source image size
$thumb = imagecreatetruecolor($thumb_width_r, $thumb_height_r);
if ($img_type == IMG_PNG) {
// preservere transaprency
imagecolortransparent(
$thumb,
imagecolorallocatealpha($thumb, 0, 0, 0, 127)
);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
}
$source = null;
switch ($img_type) {
case IMG_JPG:
$source = imagecreatefromjpeg($filename);
break;
case IMG_PNG:
$source = imagecreatefrompng($filename);
break;
}
// check that we have a source image resource
if ($source !== null) {
// resize no shift
if ($high_quality === true) {
imagecopyresized($thumb, $source, 0, 0, 0, 0, $thumb_width_r, $thumb_height_r, $inc_width, $inc_height);
} else {
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $thumb_width_r, $thumb_height_r, $inc_width, $inc_height);
}
// write file
switch ($img_type) {
case IMG_JPG:
imagejpeg($thumb, $thumbnail_write_path.$thumbnail, $jpeg_quality);
break;
case IMG_PNG:
imagepng($thumb, $thumbnail_write_path.$thumbnail);
break;
}
// free up resources (in case we are called in a loop)
imagedestroy($source);
imagedestroy($thumb);
} else {
$thumbnail = false;
}
}
} else {
// we just copy over the image as is, we never upscale
$thumbnail = 'thumb-'.pathinfo($filename)['filename'].'-'.$inc_width.'x'.$inc_height;
if ($use_cache === false ||
!file_exists($thumbnail_write_path.$thumbnail)
) {
copy($filename, $thumbnail_write_path.$thumbnail);
}
}
// add output path
if ($thumbnail !== false) {
$thumbnail = $thumbnail_web_path.$thumbnail;
}
}
}
// either return false or the thumbnail name + output path web
return $thumbnail;
}
/**
* reads the rotation info of an file and rotates it to be correctly upright
* this is done because not all software honers the exit Orientation flag
* only works with jpg or png
* @param string $filename path + filename to rotate. This file must be writeable
* @return void
*/
public function correctImageOrientation($filename): void
{
if (function_exists('exif_read_data') && is_writeable($filename)) {
list($inc_width, $inc_height, $img_type) = getimagesize($filename);
$exif = exif_read_data($filename);
$orientation = null;
$img = null;
if ($exif && isset($exif['Orientation'])) {
$orientation = $exif['Orientation'];
}
if ($orientation != 1) {
$this->debug('IMAGE FILE ROTATE', 'Need to rotate image ['.$filename.'] from: '.$orientation);
switch ($img_type) {
case IMG_JPG:
$img = imagecreatefromjpeg($filename);
break;
case IMG_PNG:
$img = imagecreatefrompng($filename);
break;
}
$deg = 0;
// 1 top, 6: left, 8: right, 3: bottom
switch ($orientation) {
case 3:
$deg = 180;
break;
case 6:
$deg = -90;
break;
case 8:
$deg = 90;
break;
}
if ($img !== null) {
if ($deg) {
$img = imagerotate($img, $deg, 0);
}
// then rewrite the rotated image back to the disk as $filename
switch ($img_type) {
case IMG_JPG:
imagejpeg($img, $filename);
break;
case IMG_PNG:
imagepng($img, $filename);
break;
}
// clean up image if we have an image
imagedestroy($img);
}
} // only if we need to rotate
} // function exists & file is writeable, else do nothing
}
/** /**
* test if a string can be safely convert between encodings. mostly utf8 to shift jis * test if a string can be safely convert between encodings. mostly utf8 to shift jis
* the default compare has a possibility of failure, especially with windows * the default compare has a possibility of failure, especially with windows
@@ -2110,6 +2329,35 @@ class Basic
return false; return false;
} }
/**
* creates psuedo random uuid v4
* Code take from class here:
* https://www.php.net/manual/en/function.uniqid.php#94959
* @return string pseudo random uuid v4
*/
public static function uuidv4(): string
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
// 16 bits for "time_mid"
mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
}
// [!!! DEPRECATED !!!] // [!!! DEPRECATED !!!]
// ALL crypt* methids are DEPRECATED and SHALL NOT BE USED // ALL crypt* methids are DEPRECATED and SHALL NOT BE USED
// use the new password* instead // use the new password* instead

View File

@@ -1156,7 +1156,7 @@ class IO extends \CoreLibs\Basic
// return row, if last && reset, then unset the hole md5 array // return row, if last && reset, then unset the hole md5 array
if (!$return && ($reset == 1 || $reset == 3) && $this->cursor_ext[$md5]['pos']) { if (!$return && ($reset == 1 || $reset == 3) && $this->cursor_ext[$md5]['pos']) {
// unset only the field names here of course // unset only the field names here of course
$this->cursor_ext[$md5]['field_names'] = array(); $this->cursor_ext[$md5]['field_names'] = null;
$this->cursor_ext[$md5]['pos'] = 0; $this->cursor_ext[$md5]['pos'] = 0;
} elseif (!$return && $reset == 2 && $this->cursor_ext[$md5]['pos']) { } elseif (!$return && $reset == 2 && $this->cursor_ext[$md5]['pos']) {
// at end of read reset pos & set cursor to 1 (so it does not get lost in session transfer) // at end of read reset pos & set cursor to 1 (so it does not get lost in session transfer)

View File

@@ -727,7 +727,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$EDIT_FGCOLOR_T = 'edit_fgcolor'; $EDIT_FGCOLOR_T = 'edit_fgcolor';
} }
$output_name = $this->table_array[$element_name]['output_name']; $output_name = $this->table_array[$element_name]['output_name'];
if (isset($this->table_array[$element_name]['mandatory'])) { if (isset($this->table_array[$element_name]['mandatory']) &&
$this->table_array[$element_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
// create right side depending on 'definiton' in table_array // create right side depending on 'definiton' in table_array
@@ -1022,6 +1024,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
} // switch } // switch
} // for each error to check } // for each error to check
} elseif (isset($value['mandatory']) && } elseif (isset($value['mandatory']) &&
$value['mandatory'] &&
( (
// for all 'normal' fields // for all 'normal' fields
($this->table_array[$key]['type'] != 'password' && $this->table_array[$key]['type'] != 'drop_down_db_input' && !$this->table_array[$key]['value']) || ($this->table_array[$key]['type'] != 'password' && $this->table_array[$key]['type'] != 'drop_down_db_input' && !$this->table_array[$key]['value']) ||
@@ -1065,7 +1068,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if (is_array($this->reference_array)) { if (is_array($this->reference_array)) {
reset($this->reference_array); reset($this->reference_array);
foreach ($this->reference_array as $key => $value) { foreach ($this->reference_array as $key => $value) {
if ($this->reference_array[$key]['mandatory'] && !$this->reference_array[$key]['selected'][0]) { if (isset($this->reference_array[$key]['mandatory']) &&
$this->reference_array[$key]['mandatory'] &&
!$this->reference_array[$key]['selected'][0]) {
$this->msg .= sprintf($this->l->__('Please select at least one Element from field <b>%s</b>!<br>'), $this->reference_array[$key]['output_name']); $this->msg .= sprintf($this->l->__('Please select at least one Element from field <b>%s</b>!<br>'), $this->reference_array[$key]['output_name']);
} }
} }
@@ -1119,20 +1124,25 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
for ($i = 0; $i < $max; $i ++) { for ($i = 0; $i < $max; $i ++) {
// either one of the post pks is set, or the mandatory // either one of the post pks is set, or the mandatory
foreach ($reference_array['elements'] as $el_name => $data_array) { foreach ($reference_array['elements'] as $el_name => $data_array) {
if (isset($data_array['mandatory'])) { if (isset($data_array['mandatory']) && $data_array['mandatory']) {
$mand_name = $data_array['output_name']; $mand_name = $data_array['output_name'];
} }
// check if there is a primary ket inside, so it is okay // check if there is a primary ket inside, so it is okay
if (isset($data_array['pk_id']) && if (isset($data_array['pk_id']) &&
count($_POST[$prfx.$el_name]) && count($_POST[$prfx.$el_name]) &&
isset($reference_array['mandatory']) isset($reference_array['mandatory']) &&
$reference_array['mandatory']
) { ) {
$mand_okay = 1; $mand_okay = 1;
} }
// we found a mandatory field. check now if one is set to satisfy the main mandatory // we found a mandatory field. check now if one is set to satisfy the main mandatory
// also check, if this field is mandatory and its not set, but any other, throw an error // also check, if this field is mandatory and its not set, but any other, throw an error
// $this->debug('edit_error_chk', 'RG error - Data['.$prfx.$el_name.': '.$_POST[$prfx.$el_name][$i].' | '.$_POST[$prfx.$el_name].' - '.$reference_array['enable_name'].' - '.$_POST[$reference_array['enable_name']][$_POST[$prfx.$el_name][$i]]); // $this->debug('edit_error_chk', 'RG error - Data['.$prfx.$el_name.': '.$_POST[$prfx.$el_name][$i].' | '.$_POST[$prfx.$el_name].' - '.$reference_array['enable_name'].' - '.$_POST[$reference_array['enable_name']][$_POST[$prfx.$el_name][$i]]);
if (isset($data_array['mandatory']) && $_POST[$prfx.$el_name][$i]) { if (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
isset($_POST[$prfx.$el_name][$i]) &&
$_POST[$prfx.$el_name][$i]
) {
$mand_okay = 1; $mand_okay = 1;
$row_okay[$i] = 1; $row_okay[$i] = 1;
} elseif ($data_array['type'] == 'radio_group' && !isset($_POST[$prfx.$el_name])) { } elseif ($data_array['type'] == 'radio_group' && !isset($_POST[$prfx.$el_name])) {
@@ -1145,7 +1155,10 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// $this->debug('edit_error_chk', '[$i]'); // $this->debug('edit_error_chk', '[$i]');
$element_set[$i] = 1; $element_set[$i] = 1;
$row_okay[$i] = 1; $row_okay[$i] = 1;
} elseif (isset($data_array['mandatory']) && !$_POST[$prfx.$el_name][$i]) { } elseif (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
!$_POST[$prfx.$el_name][$i]
) {
$row_okay[$i] = 0; $row_okay[$i] = 0;
} }
// do optional error checks like for normal fields // do optional error checks like for normal fields
@@ -1153,19 +1166,20 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if (isset($data_array['error_check'])) { if (isset($data_array['error_check'])) {
foreach (explode('|', $data_array['error_check']) as $error_check) { foreach (explode('|', $data_array['error_check']) as $error_check) {
switch ($error_check) { switch ($error_check) {
// check unique, check if field in table is not yet exist // check unique, check if field is filled and not same in _POST set
case 'unique': case 'unique':
$q = 'SELECT '.$_pk_name.' FROM '.$table_name.' WHERE '.$el_name.' = '."'".$this->dbEscapeString($_POST[$prfx.$el_name][$i])."'"; // must be set for double check
if ($this->table_array[$this->int_pk_name]['value']) { if ($_POST[$prfx.$el_name][$i] &&
$q .= ' AND '.$this->int_pk_name.' <> '.$this->table_array[$this->int_pk_name]['value']; count(array_keys($_POST[$prfx.$el_name], $_POST[$prfx.$el_name][$i])) >= 2
} ) {
list($key) = $this->dbReturnRow($q);
if ($key) {
$this->msg .= sprintf($this->l->__('The field <b>%s</b> in row <b>%s</b> can be used only once!<br>'), $reference_array['output_name'], $i); $this->msg .= sprintf($this->l->__('The field <b>%s</b> in row <b>%s</b> can be used only once!<br>'), $reference_array['output_name'], $i);
} }
break; break;
case 'alphanumericspace': case 'alphanumericspace':
if (!preg_match("/^[0-9A-Za-z\ ]+$/", $_POST[$prfx.$el_name][$i])) { // only check if set
if ($_POST[$prfx.$el_name][$i] &&
!preg_match("/^[0-9A-Za-z\ ]+$/", $_POST[$prfx.$el_name][$i])
) {
$this->msg .= sprintf($this->l->__('Please enter a valid alphanumeric (Numbers and Letters, spaces allowed) value for the <b>%s</b> Field and row <b>%s</b>!<br>'), $reference_array['output_name'], $i); $this->msg .= sprintf($this->l->__('Please enter a valid alphanumeric (Numbers and Letters, spaces allowed) value for the <b>%s</b> Field and row <b>%s</b>!<br>'), $reference_array['output_name'], $i);
} }
break; break;
@@ -1176,7 +1190,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
} }
// main mandatory is met -> error msg // main mandatory is met -> error msg
if (!$mand_okay && isset($reference_array['mandatory'])) { if (!$mand_okay &&
isset($reference_array['mandatory']) &&
$reference_array['mandatory']) {
$this->msg .= sprintf($this->l->__('You need to enter at least one data set for field <b>%s</b>!<Br>'), $reference_array['output_name']); $this->msg .= sprintf($this->l->__('You need to enter at least one data set for field <b>%s</b>!<Br>'), $reference_array['output_name']);
} }
for ($i = 0; $i < $max; $i ++) { for ($i = 0; $i < $max; $i ++) {
@@ -1472,6 +1488,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// if we have enable name & delete set, then only insert/update those which are flagged as active // if we have enable name & delete set, then only insert/update those which are flagged as active
// check if mandatory field is set, if not set 'do not write flag' // check if mandatory field is set, if not set 'do not write flag'
if (isset($data_array['mandatory']) && if (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
(!isset($_POST[$prfx.$el_name][$i]) || (isset($_POST[$prfx.$el_name][$i]) && empty($_POST[$prfx.$el_name][$i]))) (!isset($_POST[$prfx.$el_name][$i]) || (isset($_POST[$prfx.$el_name][$i]) && empty($_POST[$prfx.$el_name][$i])))
) { ) {
$no_write[$i] = 1; $no_write[$i] = 1;
@@ -1678,7 +1695,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
{ {
$data = array(); $data = array();
$output_name = $this->reference_array[$table_name]['output_name']; $output_name = $this->reference_array[$table_name]['output_name'];
if ($this->reference_array[$table_name]['mandatory']) { if (isset($this->reference_array[$table_name]['mandatory']) &&
$this->reference_array[$table_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
$data['name'] = $this->reference_array[$table_name]['other_table_pk']; $data['name'] = $this->reference_array[$table_name]['other_table_pk'];
@@ -1708,7 +1727,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$data = array(); $data = array();
// output name for the viewable left table td box, prefixed with * if mandatory // output name for the viewable left table td box, prefixed with * if mandatory
$output_name = $this->element_list[$table_name]['output_name']; $output_name = $this->element_list[$table_name]['output_name'];
if (isset($this->element_list[$table_name]['mandatory'])) { if (isset($this->element_list[$table_name]['mandatory']) &&
$this->element_list[$table_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
// delete button name, if there is one set // delete button name, if there is one set
@@ -1789,7 +1810,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if ($this->error) { if ($this->error) {
if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) { if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) {
// this is for the new line // this is for the new line
$proto[$el_name] = $_POST[$el_name][(count($_POST[$el_name]) - 1)]; $proto[$el_name] = isset($_POST[$el_name][(count($_POST[$el_name]) - 1)]) ? $_POST[$el_name][(count($_POST[$el_name]) - 1)] : 0;
} else { } else {
$proto[$el_name] = 0; $proto[$el_name] = 0;
} }

View File

@@ -22,7 +22,12 @@ class ProgressBar
public $code; // unique code public $code; // unique code
public $status = 'new'; // current status (new,show,hide) public $status = 'new'; // current status (new,show,hide)
public $step = 0; // current step public $step = 0; // current step
public $position = array(); // current bar position public $position = array( // current bar position
'left' => null,
'top' => null,
'width' => null,
'height' => null,
);
public $clear_buffer_size = 1; // we need to send this before the lfush to get browser output public $clear_buffer_size = 1; // we need to send this before the lfush to get browser output
public $clear_buffer_size_init = 1024*1024; // if I don't send that junk, it won't send anything public $clear_buffer_size_init = 1024*1024; // if I don't send that junk, it won't send anything