Compare commits

...

14 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
Clemens Schwaighofer
b6a35d15cf Basic: resurcive array search, IO unset fix
Basic: recusrive array search has correct parameter declarations &
checks for null/empty/not string

IO: all unset are removed and null or init to array is used to reset

Update for other include pages with some missing default data
2019-09-30 15:52:14 +09:00
Clemens Schwaighofer
20c44694e8 Default config fix for HOST_NAME and example db host array update 2019-09-26 15:03:00 +09:00
34 changed files with 1178 additions and 555 deletions

View File

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

View File

@@ -82,17 +82,17 @@ return [
// A list of directories holding code that we want
// to parse, but not analyze
"exclude_analysis_directory_list" => [
'www/vendor',
'www/lib/FileUpload',
'www/lib/pChart',
'www/lib/pChart2.1.4',
'www/lib/Smarty',
'www/lib/smarty-3.1.30',
'www/templates_c',
'www/log',
'www/tmp',
'www/cache',
'www/media',
'www/vendor',
'www/lib/FileUpload',
'www/lib/pChart',
'www/lib/pChart2.1.4',
'www/lib/Smarty',
'www/lib/smarty-3.1.30',
'www/templates_c',
'www/log',
'www/tmp',
'www/cache',
'www/media',
],
'exclude_file_list' => [
// ignore all symlink files to edit

View File

@@ -16,6 +16,7 @@ table/edit_scheme.sql
table/edit_language.sql
table/edit_group.sql
table/edit_page_access.sql
table/edit_page_content.sql
table/edit_user.sql
table/edit_log.sql
table/edit_access.sql
@@ -31,6 +32,7 @@ trigger/trg_edit_group.sql
trigger/trg_edit_language.sql
trigger/trg_edit_log.sql
trigger/trg_edit_page_access.sql
trigger/trg_edit_page_content.sql
trigger/trg_edit_page.sql
trigger/trg_edit_query_string.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';
print "TABLE META DATA: ".$basic->printAr($basic->dbShowTableMetaData($table))."<br>";
$primary_key = ''; # unset
$db_write_table = array ('test', 'string_a', 'number_a', 'some_bool');
// $db_write_table = array ('test');
$object_fields_not_touch = array ();
$object_fields_not_update = array ();
$data = array ('test' => 'BOOL TEST SOMETHING '.time(), 'string_a' => 'SOME TEXT', 'number_a' => 5);
$db_write_table = array('test', 'string_a', 'number_a', 'some_bool');
// $db_write_table = array('test');
$object_fields_not_touch = array();
$object_fields_not_update = array();
$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);
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);
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);
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);
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';
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 $login->printErrorMsg();

View File

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

View File

@@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2018/10/11
@@ -7,19 +7,18 @@
* - DB access name (array group from config.db)
* - location (test/stage/live)
* - debug flag (true/false)
* - DB path (eg PUBLIC_SCHEMA)
* - stie lang
* - site lang
* HISTORY:
*********************************************************************/
// other master config to attach
// $LOCAL_CONFIG = array(
// $__LOCAL_CONFIG = array(
// 'db_host' => '',
// 'location' => '',
// 'debug_flag' => true,
// 'site_lang' => 'en_utf8',
// 'login_enabled' => true
// )
// );
// each host has a different db_host
$SITE_CONFIG = array(
@@ -39,7 +38,7 @@ $SITE_CONFIG = array(
// enable/disable login override
'login_enabled' => true
),
// 'other.host.com' => $LOCAL_CONFIG
// 'other.host.com' => $__LOCAL_CONFIG
);
// __END__

View File

@@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2003/06/10
@@ -124,18 +124,21 @@ DEFINE('PAGE_WIDTH', 800);
DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl');
/************* SESSION NAMES *************/
// base name
DEFINE('BASE_NAME', 'CoreLibs');
// server name HASH
DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST']));
DEFINE('SERVER_PATH_HASH', hash('crc32b', BASE));
// 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
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
DEFINE('SET_SESSION_NAME', SESSION_NAME);
/************* CACHE/COMPILE IDS *************/
DEFINE('CACHE_ID', 'CACHE_'.SERVER_NAME_HASH);
DEFINE('COMPILE_ID', 'COMPILE_'.SERVER_NAME_HASH);
DEFINE('CACHE_ID', 'CACHE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
DEFINE('COMPILE_ID', 'COMPILE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
/************* LANGUAGE / ENCODING *******/
DEFINE('DEFAULT_LANG', 'en_utf8');
@@ -190,24 +193,29 @@ if (file_exists(BASE.CONFIGS.'config.path.php')) {
// ** missing live domains **
// get the name without the port
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// BAIL ON:
// set HOST name
DEFINE('HOST_NAME', $HOST_NAME);
// 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
// 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
if ((!isset($SITE_CONFIG[$HOST_NAME]['db_host']) && count($DB_CONFIG)) ||
(isset($SITE_CONFIG[$HOST_NAME]['db_host']) &&
if ((!isset($SITE_CONFIG[HOST_NAME]['db_host']) && count($DB_CONFIG)) ||
(isset($SITE_CONFIG[HOST_NAME]['db_host']) &&
// missing DB CONFIG
((is_array($DB_CONFIG) && !count($DB_CONFIG)) ||
!is_array($DB_CONFIG) ||
// has DB CONFIG but no match
(is_array($DB_CONFIG) && count($DB_CONFIG) && !isset($DB_CONFIG[$SITE_CONFIG[$HOST_NAME]['db_host']])))
(is_array($DB_CONFIG) && count($DB_CONFIG) && !isset($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']])))
)
) {
echo 'No matching DB config found for: "'.$HOST_NAME.'". Contact Administrator';
echo 'No matching DB config found for: "'.HOST_NAME.'". Contact Administrator';
exit;
}
// set HOST name
DEFINE('HOST_NAME', $HOST_NAME);
// set SSL on
if ((array_key_exists('HTTPS', $_SERVER) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
$_SERVER['SERVER_PORT'] == 443) {
@@ -218,7 +226,7 @@ if ((array_key_exists('HTTPS', $_SERVER) && !empty($_SERVER['HTTPS']) && $_SERVE
DEFINE('HOST_PROTOCOL', 'http://');
}
// define the db config set name, the db config and the db schema
DEFINE('DB_CONFIG_NAME', $SITE_CONFIG[$HOST_NAME]['db_host']);
DEFINE('DB_CONFIG_NAME', $SITE_CONFIG[HOST_NAME]['db_host']);
DEFINE('DB_CONFIG', isset($DB_CONFIG[DB_CONFIG_NAME]) ? $DB_CONFIG[DB_CONFIG_NAME] : array());
// DEFINE('DB_CONFIG_TARGET', SITE_CONFIG[$HOST_NAME]['db_host_target']);
// DEFINE('DB_CONFIG_OTHER', SITE_CONFIG[$HOST_NAME]['db_host_other']);
@@ -226,10 +234,10 @@ DEFINE('DB_CONFIG', isset($DB_CONFIG[DB_CONFIG_NAME]) ? $DB_CONFIG[DB_CONFIG_NAM
// DEFINE('LOGIN_DB_SCHEMA', PUBLIC_SCHEMA); // where the edit* tables are
// DEFINE('GLOBAL_DB_SCHEMA', PUBLIC_SCHEMA); // where global tables are that are used by all schemas (eg queue tables for online, etc)
// debug settings, site lang, etc
DEFINE('TARGET', $SITE_CONFIG[$HOST_NAME]['location']);
DEFINE('DEBUG', $SITE_CONFIG[$HOST_NAME]['debug_flag']);
DEFINE('SITE_LANG', $SITE_CONFIG[$HOST_NAME]['site_lang']);
DEFINE('LOGIN_ENABLED', $SITE_CONFIG[$HOST_NAME]['login_enabled']);
DEFINE('TARGET', $SITE_CONFIG[HOST_NAME]['location']);
DEFINE('DEBUG', $SITE_CONFIG[HOST_NAME]['debug_flag']);
DEFINE('SITE_LANG', $SITE_CONFIG[HOST_NAME]['site_lang']);
DEFINE('LOGIN_ENABLED', $SITE_CONFIG[HOST_NAME]['login_enabled']);
// paths
// DEFINE('CSV_PATH', $PATHS[TARGET]['csv_path']);
// DEFINE('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin']);

View File

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

View File

@@ -27,6 +27,12 @@ $SET_SESSION_NAME = EDIT_SESSION_NAME;
//------------------------------ library include end
//------------------------------ basic variable settings start
if (!isset($AJAX_PAGE)) {
$AJAX_PAGE = false;
}
if (!isset($ZIP_STREAM)) {
$ZIP_STREAM = false;
}
// set encoding
if (!isset($encoding)) {
$encoding = DEFAULT_ENCODING;
@@ -38,10 +44,10 @@ if (session_id() && $_SESSION['DEFAULT_LANG']) {
$lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// end the stop of the output flow, but only if we didn't request a csv file download
if (array_key_exists('action', $_POST) && $_POST['action'] != 'download_csv') {
if (isset($_POST['action']) && $_POST['action'] != 'download_csv' && !$AJAX_PAGE) {
header("Content-type: text/html; charset=".$encoding);
}
if (isset($AJAX_PAGE) && isset($ZIP_STREAM) && $AJAX_PAGE && !$ZIP_STREAM) {
if ($AJAX_PAGE && !$ZIP_STREAM) {
header("Content-Type: application/json; charset=UTF-8");
}
//------------------------------ basic variable settings start
@@ -86,7 +92,7 @@ if (!$login->login) {
//------------------------------ page rights start
// flag if to show the edit access id drop down list
// 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
// automatic hide for DEBUG messages on live server

View File

@@ -29,21 +29,21 @@ if (isset($_SESSION['DEFAULT_LANG'])) {
$lang_short = substr($lang, 0, 2);
// set include & template names
$PAGE_FILE_NAME = str_replace(".php", "", $cms->page_name);
$PAGE_FILE_NAME = str_replace('.php', '', $cms->page_name);
// set include & template names
if (!isset($CONTENT_INCLUDE)) {
$CONTENT_INCLUDE = $PAGE_FILE_NAME.'.tpl';
}
$FORM_NAME = !isset($FORM_NAME) || !$FORM_NAME ? str_replace(".php", "", $cms->page_name) : $FORM_NAME;
$FORM_NAME = !isset($FORM_NAME) || !$FORM_NAME ? str_replace('.php', '', $cms->page_name) : $FORM_NAME;
// set local page title
$L_TITLE = ucfirst(str_replace('_', ' ', $cms->getPageName(1))).(defined(G_TITLE) ? ' - '.G_TITLE : '');
// strip tpl and replace it with php
// php include file per page
$cms->INC_TEMPLATE_NAME = str_replace(".tpl", ".php", $CONTENT_INCLUDE);
$cms->INC_TEMPLATE_NAME = str_replace('.tpl', '.php', $CONTENT_INCLUDE);
// javascript include per page
$cms->JS_TEMPLATE_NAME = str_replace(".tpl", ".js", $CONTENT_INCLUDE);
$cms->JS_TEMPLATE_NAME = str_replace('.tpl', '.js', $CONTENT_INCLUDE);
// css per page
$cms->CSS_TEMPLATE_NAME = str_replace(".tpl", ".css", $CONTENT_INCLUDE);
$cms->CSS_TEMPLATE_NAME = str_replace('.tpl', '.css', $CONTENT_INCLUDE);
// special CSS file
$cms->CSS_SPECIAL_TEMPLATE_NAME = isset($CSS_NAME) ? $CSS_NAME : '';
// special JS file

View File

@@ -69,16 +69,23 @@ $cms->DATA['messages'] = $cms->messages;
// top menu
$cms->DATA['nav_menu'] = $cms->adbTopMenu();
$cms->DATA['nav_menu_count'] = is_array($cms->DATA['nav_menu']) ? count($cms->DATA['nav_menu']) : 0;
// the page name
$cms->DATA['page_name'] = $cms->page_name;
// user name
$cms->DATA['USER_NAME'] = $_SESSION['USER_NAME'];
$cms->DATA['ADMIN'] = $login->acl['admin'];
// the template part to include into the body
$cms->DATA['TEMPLATE_NAME'] = $TEMPLATE_NAME;
$cms->DATA['CONTENT_INCLUDE'] = $CONTENT_INCLUDE;
$cms->DATA['TEMPLATE_TRANSLATE'] = isset($TEMPLATE_TRANSLATE) ? $TEMPLATE_TRANSLATE : null;
$cms->DATA['PAGE_FILE_NAME'] = $PAGE_FILE_NAME;
// LANG
$cms->DATA['LANG'] = $lang;
$cms->DATA['TINYMCE_LANG'] = $lang_short;
// form name
$cms->DATA['FORM_NAME'] = $FORM_NAME;
// include flags
$cms->DATA['USE_TINY_MCE'] = isset($USE_TINY_MCE) ? $USE_TINY_MCE : false;
$cms->DATA['JS_DATEPICKR'] = isset($JS_DATEPICKR) ? $JS_DATEPICKR : false;
$cms->DATA['JS_FLATPICKR'] = isset($JS_FLATPICKR) ? $JS_FLATPICKR : false;

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

View File

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

View File

@@ -181,6 +181,8 @@ class Basic
// form token (used for form validation)
private $form_token = '';
// ajax flag
protected $ajax_page_flag = false;
// METHOD: __construct
// PARAMS: set_control_flag [current sets set/get var errors]
@@ -218,6 +220,11 @@ class Basic
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
$this->page_name = $this->getPageName();
$this->host_name = $this->getHostName();
@@ -471,13 +478,22 @@ class Basic
* if strict mode is set, throws an error if the class variable is not set
* default is strict mode false
* @param mixed $name class variable name
* @return void
* @return mixed return set variable content
*/
public function __get($name): void
public function &__get($name)
{
if ($this->set_strict_mode === true && !property_exists($this, $name)) {
trigger_error('Undefined property via __get(): '.$name, E_USER_NOTICE);
}
// on set return
if (property_exists($this, $name)) {
return $this->$name;
} elseif ($this->set_compatible === true && !property_exists($this, $name)) {
// if it is not set, and we are in compatible mode we need to init.
// This is so that $class->array['key'] = 'bar'; works
$this->{$name} = null;
return $this->$name;
}
}
// *************************************************************
@@ -1164,18 +1180,19 @@ class Basic
/**
* searches key = value in an array / array
* only returns the first one found
* @param string|int $needle needle (search for)
* @param array $haystack haystack (search in)
* @param string $key_lookin the key to look out for, default empty
* @return ?array array with the elements where the needle can be found in the haystack array
* @param string|int $needle needle (search for)
* @param array $haystack haystack (search in)
* @param string|null $key_lookin the key to look out for, default empty
* @return array array with the elements where the needle can be
* found in the haystack array
*/
public static function arraySearchRecursive($needle, array $haystack, $key_lookin = ''): ?array
public static function arraySearchRecursive($needle, array $haystack, ?string $key_lookin = null): array
{
$path = array();
if (!is_array($haystack)) {
$haystack = array();
}
if (!is_array($key_lookin) &&
if ($key_lookin != null &&
!empty($key_lookin) &&
array_key_exists($key_lookin, $haystack) &&
$needle === $haystack[$key_lookin]
@@ -1511,7 +1528,7 @@ class Basic
// labels in order of size
$labels = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB');
// 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;
}
@@ -1939,6 +1956,218 @@ class Basic
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
* the default compare has a possibility of failure, especially with windows
@@ -2100,6 +2329,35 @@ class Basic
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 !!!]
// ALL crypt* methids are DEPRECATED and SHALL NOT BE USED
// use the new password* instead

View File

@@ -305,8 +305,8 @@ class IO extends \CoreLibs\Basic
/**
* main DB concstructor with auto connection to DB and failure set on failed connection
* @param array $db_config DB configuration array
* @param int|integer $set_control_flag Class set control flag
* @param array $db_config DB configuration array
* @param int $set_control_flag 0/1/2/3 to set internal class parameter check
*/
public function __construct(array $db_config, int $set_control_flag = 0)
{
@@ -1056,7 +1056,7 @@ class IO extends \CoreLibs\Basic
// if it is a call with reset in it we reset the cursor, so we get an uncached return
// but only for the FIRST call (pos == 0)
if ($reset && !$this->cursor_ext[$md5]['pos']) {
unset($this->cursor_ext[$md5]['cursor']);
$this->cursor_ext[$md5]['cursor'] = null;
}
// $this->debug('MENU', 'Reset: '.$reset.', Cursor: '.$this->cursor_ext[$md5]['cursor'].', Pos: '.$this->cursor_ext[$md5]['pos'].', Query: '.$query);
@@ -1156,7 +1156,7 @@ class IO extends \CoreLibs\Basic
// return row, if last && reset, then unset the hole md5 array
if (!$return && ($reset == 1 || $reset == 3) && $this->cursor_ext[$md5]['pos']) {
// unset only the field names here of course
unset($this->cursor_ext[$md5]['field_names']);
$this->cursor_ext[$md5]['field_names'] = null;
$this->cursor_ext[$md5]['pos'] = 0;
} 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)

View File

@@ -727,7 +727,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$EDIT_FGCOLOR_T = 'edit_fgcolor';
}
$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 .= ' *';
}
// create right side depending on 'definiton' in table_array
@@ -1022,6 +1024,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
} // switch
} // for each error to check
} elseif (isset($value['mandatory']) &&
$value['mandatory'] &&
(
// for all 'normal' fields
($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)) {
reset($this->reference_array);
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']);
}
}
@@ -1119,20 +1124,25 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
for ($i = 0; $i < $max; $i ++) {
// either one of the post pks is set, or the mandatory
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'];
}
// check if there is a primary ket inside, so it is okay
if (isset($data_array['pk_id']) &&
count($_POST[$prfx.$el_name]) &&
isset($reference_array['mandatory'])
isset($reference_array['mandatory']) &&
$reference_array['mandatory']
) {
$mand_okay = 1;
}
// 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
// $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;
$row_okay[$i] = 1;
} 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]');
$element_set[$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;
}
// 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'])) {
foreach (explode('|', $data_array['error_check']) as $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':
$q = 'SELECT '.$_pk_name.' FROM '.$table_name.' WHERE '.$el_name.' = '."'".$this->dbEscapeString($_POST[$prfx.$el_name][$i])."'";
if ($this->table_array[$this->int_pk_name]['value']) {
$q .= ' AND '.$this->int_pk_name.' <> '.$this->table_array[$this->int_pk_name]['value'];
}
list($key) = $this->dbReturnRow($q);
if ($key) {
// must be set for double check
if ($_POST[$prfx.$el_name][$i] &&
count(array_keys($_POST[$prfx.$el_name], $_POST[$prfx.$el_name][$i])) >= 2
) {
$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;
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);
}
break;
@@ -1176,7 +1190,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
}
// 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']);
}
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
// check if mandatory field is set, if not set 'do not write flag'
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])))
) {
$no_write[$i] = 1;
@@ -1678,7 +1695,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
{
$data = array();
$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 .= ' *';
}
$data['name'] = $this->reference_array[$table_name]['other_table_pk'];
@@ -1708,7 +1727,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$data = array();
// output name for the viewable left table td box, prefixed with * if mandatory
$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 .= ' *';
}
// delete button name, if there is one set
@@ -1789,7 +1810,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if ($this->error) {
if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) {
// 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 {
$proto[$el_name] = 0;
}

View File

@@ -22,7 +22,12 @@ class ProgressBar
public $code; // unique code
public $status = 'new'; // current status (new,show,hide)
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_init = 1024*1024; // if I don't send that junk, it won't send anything