Compare commits

...

20 Commits

Author SHA1 Message Date
Clemens Schwaighofer
3ae3b1b761 Simplify language calls
There are no more lang vars passed on to any class calls
The new order is the following
$OVERRIDE_LANG > _SESSION > SITE_LANG > DEFAULT_LANG

Todo: make the setLang better so we do not have the same method in
Backend/Generic/SmartyExtended
2019-11-15 17:07:35 +09:00
Clemens Schwaighofer
3c9ca025f5 Smarty Extended split out cms var merge & content render
The down merge of outside class smarty vars is now an extra function
that can be called stand alone.

The smarty render function call is also a stand alone function that can
be called from outside
2019-11-15 15:20:12 +09:00
Clemens Schwaighofer
96afa463e0 Smarty Extended add method documentation 2019-11-15 14:47:40 +09:00
Clemens Schwaighofer
5195212fae Smarty Extended move set paths method on top 2019-11-15 14:43:22 +09:00
Clemens Schwaighofer
e990d6b410 Smarty Extended class update
Move all smarty and path settings into the Smarty Extended class

the include files <admin|frontend>_set_paths.php and <admin|frontend>_smarty.php

are deprecated.

For special frontend smarty (which will be not used in future anyway) a
dedicated sub class to Smarty Extended with its own methods should be
created
2019-11-15 14:15:12 +09:00
Clemens Schwaighofer
b5dd85bc75 add test images 2019-11-05 18:09:26 +09:00
Clemens Schwaighofer
b2945a8fa0 Update Create Thumbnail calls in Basic class
ImageMagick direct convert call uses pre-set vars
GD Thumbnail creator can create dummy thumbnails if they are not in the
normal convertable type
2019-11-05 14:01:21 +09:00
Clemens Schwaighofer
c77562b595 config master update
- use config.other.php to include other none core settings
- fix tab intends for not used defines
- remove old ACL defines that are not needed
- move BASE_NAME out to new area

TODO: think about removing G_TITLE
TODO: think about BASE_NAME external setting
2019-10-29 12:00:55 +09:00
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
51 changed files with 1981 additions and 1172 deletions

View File

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

View File

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

View File

@@ -64,3 +64,14 @@ msgstr "日"
msgid "INPUT TEST" msgid "INPUT TEST"
msgstr "OUTPUT TEST JA" msgstr "OUTPUT TEST JA"
# login string
msgid "Hello %s"
msgstr "こにちは %s"
msgid "I should be translated"
msgstr "「スマーティー」これは正しいです"
msgid "Are we translated?"
msgstr "「クラス」これは翻訳です?"

View File

@@ -24,12 +24,10 @@ if (!defined('SET_SESSION_NAME')) {
} }
// define log file id // define log file id
$LOG_FILE_ID = 'classTest'; $LOG_FILE_ID = 'classTest';
// set language for l10n
$lang = 'en_utf8';
// init login & backend class // init login & backend class
$login = new CoreLibs\ACL\Login(DB_CONFIG, $lang); $login = new CoreLibs\ACL\Login(DB_CONFIG);
$basic = new CoreLibs\Admin\Backend(DB_CONFIG, $lang); $basic = new CoreLibs\Admin\Backend(DB_CONFIG);
$basic->dbInfo(true); $basic->dbInfo(true);
ob_end_flush(); ob_end_flush();
@@ -131,20 +129,20 @@ print "UPDATE STATUS: $status | RETURNING EXT: ".print_r($basic->insert_id_ext,
$table = 'foo'; $table = 'foo';
print "TABLE META DATA: ".$basic->printAr($basic->dbShowTableMetaData($table))."<br>"; print "TABLE META DATA: ".$basic->printAr($basic->dbShowTableMetaData($table))."<br>";
$primary_key = ''; # unset $primary_key = ''; # unset
$db_write_table = array ('test', 'string_a', 'number_a', 'some_bool'); $db_write_table = array('test', 'string_a', 'number_a', 'some_bool');
// $db_write_table = array ('test'); // $db_write_table = array('test');
$object_fields_not_touch = array (); $object_fields_not_touch = array();
$object_fields_not_update = array (); $object_fields_not_update = array();
$data = array ('test' => 'BOOL TEST SOMETHING '.time(), 'string_a' => 'SOME TEXT', 'number_a' => 5); $data = array('test' => 'BOOL TEST SOMETHING '.time(), 'string_a' => 'SOME TEXT', 'number_a' => 5);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST ON '.time(), 'string_a' => '', 'number_a' => 0, 'some_bool' => 1); $data = array('test' => 'BOOL TEST ON '.time(), 'string_a' => '', 'number_a' => 0, 'some_bool' => 1);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST OFF '.time(), 'string_a' => null, 'number_a' => null, 'some_bool' => 0); $data = array('test' => 'BOOL TEST OFF '.time(), 'string_a' => null, 'number_a' => null, 'some_bool' => 0);
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
$data = array ('test' => 'BOOL TEST UNSET '.time()); $data = array('test' => 'BOOL TEST UNSET '.time());
$primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data); $primary_key = $basic->dbWriteDataExt($db_write_table, $primary_key, $table, $object_fields_not_touch, $object_fields_not_update, $data);
print "Wrote to DB tabel $table and got primary key $primary_key<br>"; print "Wrote to DB tabel $table and got primary key $primary_key<br>";
@@ -236,8 +234,63 @@ $date_1 = '2017/1/5';
$date_2 = '2017-01-05'; $date_2 = '2017-01-05';
print "COMPARE DATE: ".$basic->compareDate($date_1, $date_2)."<br>"; print "COMPARE DATE: ".$basic->compareDate($date_1, $date_2)."<br>";
// recursive array search
$test_array = array(
'foo' => 'bar',
'input' => array(
'element_a' => array(
'type' => 'text'
),
'element_b' => array(
'type' => 'email'
),
'element_c' => array(
'type' => 'email'
)
)
);
// array re echo "SOURCE ARRAY: ".$basic->printAr($test_array)."<br>";
echo "FOUND ELEMENTS [base]: ".$basic->printAr($basic->arraySearchRecursive('email', $test_array, 'type'))."<br>";
echo "FOUND ELEMENTS [input]: ".$basic->printAr($basic->arraySearchRecursive('email', $test_array['input'], 'type'))."<br>";
// image thumbnail
$images = array(
// height bigger
// 'no_picture.jpg',
// 'no_picture.png',
// width bigger
// 'no_picture_width_bigger.jpg',
// 'no_picture_width_bigger.png',
// square
// 'no_picture_square.jpg',
// 'no_picture_square.png',
// other sample images
// '5c501af48da6c.jpg',
// Apple HEIC files
// 'img_2145.heic',
// Photoshop
'photoshop_test.psd',
);
echo "<hr>";
$thumb_width = 250;
$thumb_height = 300;
// return mime type ala mimetype
$finfo = new finfo(FILEINFO_MIME_TYPE);
foreach ($images as $image) {
$image = BASE.LAYOUT.CONTENT_PATH.IMAGES.$image;
list ($height, $width, $img_type) = getimagesize($image);
echo "<div>IMAGE INFO: ".$height."x".$width.", TYPE: ".$img_type." [".$finfo->file($image)."]</div>";
// 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>";
// test with dummy
echo "<div>".basename($image).": WIDTH/HEIGHT: $thumb_width x $thumb_height (+DUMMY)<br><img src=".$basic->createThumbnailSimple($image, $thumb_width, $thumb_height, null, true, false)."></div>";
echo "<hr>";
}
// print error messages // print error messages
// print $login->printErrorMsg(); // print $login->printErrorMsg();

View File

@@ -14,8 +14,7 @@ $SET_SESSION_NAME = EDIT_SESSION_NAME;
echo "DIR: ".DIR."<br>ROOT: ".ROOT."<br>BASE: ".BASE."<br>"; echo "DIR: ".DIR."<br>ROOT: ".ROOT."<br>BASE: ".BASE."<br>";
$lang = 'ja_utf8'; $base = new CoreLibs\Admin\Backend(DB_CONFIG);
$base = new CoreLibs\Admin\Backend(DB_CONFIG, $lang);
ob_end_flush(); ob_end_flush();
if ($base->getConnectionStatus()) { if ($base->getConnectionStatus()) {
die("Cannot connect to database"); die("Cannot connect to database");

View File

@@ -10,24 +10,26 @@ define('USE_DATABASE', true);
define('USE_HEADER', true); define('USE_HEADER', true);
require 'config.php'; require 'config.php';
require BASE.INCLUDES.'admin_header.php'; require BASE.INCLUDES.'admin_header.php';
$MASTER_TEMPLATE_NAME = 'main_body.tpl'; $smarty->MASTER_TEMPLATE_NAME = 'main_body.tpl';
$TEMPLATE_NAME = 'smarty_test.tpl'; $smarty->TEMPLATE_NAME = 'smarty_test.tpl';
$CSS_NAME = 'smart_test.css'; $smarty->CSS_SPECIAL_TEMPLATE_NAME = 'smart_test.css';
$USE_PROTOTYPE = false; $smarty->USE_PROTOTYPE = false;
$USE_JQUERY = true; $smarty->USE_JQUERY = true;
$JS_DATEPICKR = false; $smarty->JS_DATEPICKR = false;
if ($USE_PROTOTYPE) { if ($smarty->USE_PROTOTYPE) {
$ADMIN_JAVASCRIPT = 'edit.pt.js'; $smarty->ADMIN_JAVASCRIPT = 'edit.pt.js';
$JS_NAME = 'prototype.test.js'; $smarty->JS_SPECIAL_TEMPLATE_NAME = 'prototype.test.js';
} elseif ($USE_JQUERY) { } elseif ($smarty->USE_JQUERY) {
$ADMIN_JAVASCRIPT = 'edit.jq.js'; $smarty->ADMIN_JAVASCRIPT = 'edit.jq.js';
$JS_NAME = 'jquery.test.js'; $smarty->JS_SPECIAL_TEMPLATE_NAME = 'jquery.test.js';
} }
$PAGE_WIDTH = "100%"; $smarty->PAGE_WIDTH = "100%";
require BASE.INCLUDES.'admin_set_paths.php'; // require BASE.INCLUDES.'admin_set_paths.php';
$smarty->setSmartyPaths();
// smarty test // smarty test
$cms->DATA['SMARTY_TEST'] = 'Test Data'; $smarty->DATA['SMARTY_TEST'] = 'Test Data';
$smarty->DATA['TRANSLATE_TEST'] = $cms->l->__('Are we translated?');
// drop down test with optgroups // drop down test with optgroups
$options = array ( $options = array (
@@ -46,7 +48,8 @@ $options = array (
) )
); );
$cms->DATA['drop_down_test'] = $options; $smarty->DATA['drop_down_test'] = $options;
require BASE.INCLUDES.'admin_smarty.php'; // require BASE.INCLUDES.'admin_smarty.php';
$smarty->setSmartyVarsAdmin();
require BASE.INCLUDES.'admin_footer.php'; require BASE.INCLUDES.'admin_footer.php';

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/******************************************************************** /********************************************************************
* AUTHOR: Clemens Schwaighofer * AUTHOR: Clemens Schwaighofer
* CREATED: 2003/06/10 * CREATED: 2003/06/10
@@ -78,27 +78,19 @@ DEFINE('TEMPLATES', 'templates'.DS);
DEFINE('DEFAULT_HASH', 'sha256'); DEFINE('DEFAULT_HASH', 'sha256');
// default acl level // default acl level
DEFINE('DEFAULT_ACL_LEVEL', 80); DEFINE('DEFAULT_ACL_LEVEL', 80);
// default levels for certain actions
/* DEFINE('DEFAULT_ACL_READ', 20);
DEFINE('DEFAULT_ACL_CONFIRM', 35);
DEFINE('DEFAULT_ACL_MOD', 40);
DEFINE('DEFAULT_ACL_WRITE', 60);
DEFINE('DEFAULT_ACL_SEND', 70);
DEFINE('DEFAULT_ACL_DEL', 80);
DEFINE('DEFAULT_ACL_ADMIN', 100); */
// SSL host name // SSL host name
// DEFINE('SSL_HOST', 'ssl.host.name'); // DEFINE('SSL_HOST', 'ssl.host.name');
// error page strictness, Default is 3 // error page strictness, Default is 3
// 1: only show error page as the last mesure if really no mid & aid can be loaded and found at all // 1: only show error page as the last mesure if really no mid & aid can be loaded and found at all
// 2: if template not found, do not search, show error template // 2: if template not found, do not search, show error template
// 3: if default template is not found, show error template, do not fall back to default tree // 3: if default template is not found, show error template, do not fall back to default tree
// 4: very strict, even on normal fixable errors through error // 4: very strict, even on normal fixable errors through error
// DEFINE('ERROR_STRICT', 3); // DEFINE('ERROR_STRICT', 3);
// allow page caching in general, set to 'FALSE' if you do debugging or development! // allow page caching in general, set to 'FALSE' if you do debugging or development!
// DEFINE('ALLOW_SMARTY_CACHE', FALSE); // DEFINE('ALLOW_SMARTY_CACHE', FALSE);
// cache life time, in second', default here is 2 days (172800s) // cache life time, in second', default here is 2 days (172800s)
// -1 is never expire cache // -1 is never expire cache
// DEFINE('SMARTY_CACHE_LIFETIME', -1); // DEFINE('SMARTY_CACHE_LIFETIME', -1);
/************* LOGOUT ********************/ /************* LOGOUT ********************/
// logout target // logout target
@@ -123,29 +115,37 @@ DEFINE('PAGE_WIDTH', 800);
// the default template name // the default template name
DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl'); DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl');
/************* OVERALL CONTROL NAMES *************/
// BELOW has HAS to be changed
// base name for all session and log names
DEFINE('BASE_NAME', 'CoreLibs');
/************* SESSION NAMES *************/ /************* SESSION NAMES *************/
// server name HASH // server name HASH
DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST'])); DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST']));
DEFINE('SERVER_PATH_HASH', hash('crc32b', BASE));
// backend // backend
DEFINE('EDIT_SESSION_NAME', 'ADMIN_SESSION_NAME'.SERVER_NAME_HASH); DEFINE('EDIT_SESSION_NAME', BASE_NAME.'Admin'.SERVER_NAME_HASH.SERVER_PATH_HASH);
// frontend // frontend
DEFINE('SESSION_NAME', 'SESSION_NAME'.SERVER_NAME_HASH); DEFINE('SESSION_NAME', BASE_NAME.SERVER_NAME_HASH.SERVER_PATH_HASH);
// SET_SESSION_NAME should be set in the header if a special session name is needed // SET_SESSION_NAME should be set in the header if a special session name is needed
DEFINE('SET_SESSION_NAME', SESSION_NAME); DEFINE('SET_SESSION_NAME', SESSION_NAME);
/************* CACHE/COMPILE IDS *************/ /************* CACHE/COMPILE IDS *************/
DEFINE('CACHE_ID', 'CACHE_'.SERVER_NAME_HASH); DEFINE('CACHE_ID', 'CACHE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
DEFINE('COMPILE_ID', 'COMPILE_'.SERVER_NAME_HASH); DEFINE('COMPILE_ID', 'COMPILE_'.BASE_NAME.'_'.SERVER_NAME_HASH);
/************* LANGUAGE / ENCODING *******/ /************* LANGUAGE / ENCODING *******/
DEFINE('DEFAULT_LANG', 'en_utf8'); DEFINE('DEFAULT_LANG', 'en_utf8');
// default web page encoding setting // default web page encoding setting
DEFINE('DEFAULT_ENCODING', 'UTF-8'); DEFINE('DEFAULT_ENCODING', 'UTF-8');
/************* LOGGING *******************/
// below two can be defined here, but they should be // below two can be defined here, but they should be
// defined in either the header file or the file itself // defined in either the header file or the file itself
/************* LOGGING *******************/ // as $LOG_FILE_ID which takes presence over LOG_FILE_ID
DEFINE('LOG_FILE_ID', ''); // see Basic class constructor
DEFINE('LOG_FILE_ID', BASE_NAME);
/************* CLASS ERRORS *******************/ /************* CLASS ERRORS *******************/
// 0 = default all OFF // 0 = default all OFF
@@ -158,7 +158,7 @@ define('CLASS_VARIABLE_ERROR_MODE', 3);
// if we have a dev/live system // if we have a dev/live system
// set_live is a per page/per item // set_live is a per page/per item
// live_queue is a global queue system // live_queue is a global queue system
// DEFINE('QUEUE', 'live_queue'); // DEFINE('QUEUE', 'live_queue');
/************* DB PATHS (PostgreSQL) *****************/ /************* DB PATHS (PostgreSQL) *****************/
// schema names, can also be defined per <DB INFO> // schema names, can also be defined per <DB INFO>
@@ -186,13 +186,19 @@ if (file_exists(BASE.CONFIGS.'config.path.php')) {
require BASE.CONFIGS.'config.path.php'; require BASE.CONFIGS.'config.path.php';
} }
/************* MASTER INIT *****************/
// live frontend pages // live frontend pages
// ** missing live domains ** // ** missing live domains **
// get the name without the port // get the name without the port
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null); list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// set HOST name // set HOST name
DEFINE('HOST_NAME', $HOST_NAME); DEFINE('HOST_NAME', $HOST_NAME);
// BAIL ON: // BAIL ON MISSING MASTER SITE CONFIG
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
echo 'Missing SITE_CONFIG entry for: "'.HOST_NAME.'". Contact Administrator';
exit;
}
// BAIL ON MISSING DB CONFIG:
// we have either no db selction for this host but have db config entries // we have either no db selction for this host but have db config entries
// or we have a db selection but no db config as array or empty // or we have a db selection but no db config as array or empty
// or we have a selection but no matching db config entry // or we have a selection but no matching db config entry
@@ -249,10 +255,13 @@ DEFINE('JAVASCRIPT', 'frontend.js');
// anything optional // anything optional
/************* INTERNAL ******************/ /************* INTERNAL ******************/
// any other global definitons here // any other global definitons in the config.other.php
// DEFINE('SOME_ID', <SOME VALUE>); if (file_exists(BASE.CONFIGS.'config.other.php')) {
require BASE.CONFIGS.'config.other.php';
}
/************* CONVERT *******************/ /************* CONVERT *******************/
// this only needed if the external thumbnail create is used
$paths = array( $paths = array(
'/bin', '/bin',
'/usr/bin', '/usr/bin',
@@ -265,7 +274,9 @@ foreach ($paths as $path) {
DEFINE('CONVERT', $path.DS.'convert'); DEFINE('CONVERT', $path.DS.'convert');
} }
} }
unset($paths);
/************* DEBUG *******************/
// turn off debug if debug flag is OFF // turn off debug if debug flag is OFF
if (defined('DEBUG') && DEBUG == false) { if (defined('DEBUG') && DEBUG == false) {
$ECHO_ALL = false; $ECHO_ALL = false;
@@ -283,6 +294,7 @@ if (defined('DEBUG') && DEBUG == false) {
$DEBUG_ALL_OVERRIDE = false; $DEBUG_ALL_OVERRIDE = false;
} }
/************* AUTO LOADER *******************/
// read auto loader // read auto loader
require BASE.LIB.'autoloader.php'; require BASE.LIB.'autoloader.php';

12
www/configs/config.other.php Executable file
View File

@@ -0,0 +1,12 @@
<?php declare(strict_types=1);
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2019/10/28
* SHORT DESCRIPTION:
* other global constant variables
* HISTORY:
*********************************************************************/
// DEFINE('SOME_ID', <SOME VALUE>);
// __END__

View File

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

View File

@@ -13,10 +13,10 @@ if ($DEBUG_ALL && $ENABLE_ERROR_HANDLING) {
include BASE.LIBS."Error.Handling.php"; include BASE.LIBS."Error.Handling.php";
} }
// predefine vars // predefine vars
$lang = ''; $LANG = '';
$messages = array(); $messages = array();
// import all POST vars // import all POST vars
extract($_POST, EXTR_SKIP); // extract($_POST, EXTR_SKIP);
//------------------------------ variable init end //------------------------------ variable init end
//------------------------------ library include start //------------------------------ library include start
@@ -24,6 +24,7 @@ extract($_POST, EXTR_SKIP);
ob_start(); ob_start();
// set the session name // set the session name
$SET_SESSION_NAME = EDIT_SESSION_NAME; $SET_SESSION_NAME = EDIT_SESSION_NAME;
$LOG_FILE_ID = BASE_NAME.'Admin';
//------------------------------ library include end //------------------------------ library include end
//------------------------------ basic variable settings start //------------------------------ basic variable settings start
@@ -34,18 +35,12 @@ if (!isset($ZIP_STREAM)) {
$ZIP_STREAM = false; $ZIP_STREAM = false;
} }
// set encoding // set encoding
if (!isset($encoding)) { if (!isset($ENCODING) || !$ENCODING) {
$encoding = DEFAULT_ENCODING; $ENCODING = DEFAULT_ENCODING;
}
// set the default lang, if not given
if (session_id() && $_SESSION['DEFAULT_LANG']) {
$lang = $_SESSION['DEFAULT_LANG'];
} elseif (!$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 // end the stop of the output flow, but only if we didn't request a csv file download
if (isset($_POST['action']) && $_POST['action'] != 'download_csv' && !$AJAX_PAGE) { if (isset($_POST['action']) && $_POST['action'] != 'download_csv' && !$AJAX_PAGE) {
header("Content-type: text/html; charset=".$encoding); header("Content-type: text/html; charset=".$ENCODING);
} }
if ($AJAX_PAGE && !$ZIP_STREAM) { if ($AJAX_PAGE && !$ZIP_STREAM) {
header("Content-Type: application/json; charset=UTF-8"); header("Content-Type: application/json; charset=UTF-8");
@@ -54,21 +49,21 @@ if ($AJAX_PAGE && !$ZIP_STREAM) {
//------------------------------ class init start //------------------------------ class init start
// login & page access check // login & page access check
$login = new CoreLibs\ACL\Login(DB_CONFIG, $lang); $login = new CoreLibs\ACL\Login(DB_CONFIG);
// post login lang check // post login lang check
if ($_SESSION['DEFAULT_LANG']) { if (isset($_SESSION['DEFAULT_LANG'])) {
$lang = $_SESSION['DEFAULT_LANG']; $LANG = $_SESSION['DEFAULT_LANG'];
} }
// create smarty object // create smarty object
$smarty = new CoreLibs\Template\SmartyExtend($lang); $smarty = new CoreLibs\Template\SmartyExtend();
// create new DB class // create new DB class
$cms = new CoreLibs\Admin\Backend(DB_CONFIG, $lang); $cms = new CoreLibs\Admin\Backend(DB_CONFIG);
// the menu show flag (what menu to show) // the menu show flag (what menu to show)
$cms->menu_show_flag = 'main'; $cms->menu_show_flag = 'main';
// db nfo // db nfo
$cms->dbInfo(); $cms->dbInfo();
// set acl // set acl
$cms->acl = $login->acl; $cms->setACL($login->acl);
// flush // flush
ob_end_flush(); ob_end_flush();
//------------------------------ class init end //------------------------------ class init end
@@ -89,12 +84,6 @@ if (!$login->login) {
} }
//------------------------------ logging end //------------------------------ logging end
//------------------------------ 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'];
//------------------------------ page rights ned
// automatic hide for DEBUG messages on live server // automatic hide for DEBUG messages on live server
// can be overridden when setting DEBUG_ALL_OVERRIDE on top of the script (for emergency debugging of one page only) // can be overridden when setting DEBUG_ALL_OVERRIDE on top of the script (for emergency debugging of one page only)
if ((TARGET == 'live' || TARGET == 'remote') && !$DEBUG_ALL_OVERRIDE) { if ((TARGET == 'live' || TARGET == 'remote') && !$DEBUG_ALL_OVERRIDE) {
@@ -105,6 +94,6 @@ if ((TARGET == 'live' || TARGET == 'remote') && !$DEBUG_ALL_OVERRIDE) {
$cms->echo_output_all = false; $cms->echo_output_all = false;
$cms->print_output_all = false; $cms->print_output_all = false;
} }
$cms->DATA['JS_DEBUG'] = DEBUG; $smarty->DATA['JS_DEBUG'] = DEBUG;
// __END__ // __END__

View File

@@ -7,161 +7,13 @@
* HISTORY: * HISTORY:
*********************************************************************/ *********************************************************************/
// master template /******
if (!isset($MASTER_TEMPLATE_NAME)) { NOTE THAT THIS INCLUDE IS OBSOLETE
$MASTER_TEMPLATE_NAME = MASTER_TEMPLATE_NAME; USE THE BELOW FUNCTION CALL IN THE SCRIPT ITSELF
} *******/
trigger_error('admin_set_paths.php is deprecated. Use SmartyExtended->setSmartyPaths();', E_USER_DEPRECATED);
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$encoding = $_SESSION['DEFAULT_CHARSET'];
} elseif (!isset($encoding)) {
$encoding = DEFAULT_ENCODING;
}
// just emergency fallback for language
if (isset($_SESSION['DEFAULT_LANG'])) {
$lang = $_SESSION['DEFAULT_LANG'];
} elseif (!isset($lang)) {
$lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$lang_short = substr($lang, 0, 2);
// set include & template names
$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;
// 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);
// javascript include per page
$cms->JS_TEMPLATE_NAME = str_replace('.tpl', '.js', $CONTENT_INCLUDE);
// css per page
$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
$cms->JS_SPECIAL_TEMPLATE_NAME = isset($JS_NAME) ? $JS_NAME : '';
// compile & cache id
$cms->CACHE_ID = isset($CACHE_ID) ? $CACHE_ID : CACHE_ID;
$cms->COMPILE_ID = isset($COMPILE_ID) ? $COMPILE_ID : CACHE_ID;
// set basic template path (tmp)
$cms->includes = BASE.INCLUDES; // no longer in templates, only global
$cms->template_path = BASE.INCLUDES.TEMPLATES.CONTENT_PATH;
if ($smarty) { if ($smarty) {
$smarty->setTemplateDir($cms->template_path); $smarty->setSmartyPaths();
}
if (isset($LANGUAGE_FOLDER)) {
$cms->lang_dir = $LANGUAGE_FOLDER;
} else {
$cms->lang_dir = BASE.INCLUDES.LANG.CONTENT_PATH; // no outside
}
$cms->javascript = LAYOUT.JS;
$cms->css = LAYOUT.CSS;
$cms->pictures = LAYOUT.IMAGES;
$cms->cache_pictures = LAYOUT.CACHE;
$cms->cache_pictures_root = ROOT.$cms->cache_pictures;
if (!is_dir($cms->cache_pictures_root)) {
mkdir($cms->cache_pictures_root);
}
// check if we have an external file with the template name
if (file_exists($cms->includes.$cms->INC_TEMPLATE_NAME) &&
is_file($cms->includes.$cms->INC_TEMPLATE_NAME)
) {
include($cms->includes.$cms->INC_TEMPLATE_NAME);
}
// only CSS/JS/etc include stuff if we have non AJAX page
if (isset($AJAX_PAGE) && !$AJAX_PAGE) {
// check for template include
if (isset($USE_INCLUDE_TEMPLATE) && $USE_INCLUDE_TEMPLATE === true && !isset($TEMPLATE_NAME)) {
$TEMPLATE_NAME = $CONTENT_INCLUDE;
// add to cache & compile id
$cms->COMPILE_ID .= '_'.$TEMPLATE_NAME;
$cms->CACHE_ID .= '_'.$TEMPLATE_NAME;
}
// additional per page Javascript include
$cms->JS_INCLUDE = '';
if (file_exists($cms->javascript.$cms->JS_TEMPLATE_NAME) && is_file($cms->javascript.$cms->JS_TEMPLATE_NAME)) {
$cms->JS_INCLUDE = $cms->javascript.$cms->JS_TEMPLATE_NAME;
}
// per page css file
$cms->CSS_INCLUDE = '';
if (file_exists($cms->css.$cms->CSS_TEMPLATE_NAME) && is_file($cms->css.$cms->CSS_TEMPLATE_NAME)) {
$cms->CSS_INCLUDE = $cms->css.$cms->CSS_TEMPLATE_NAME;
}
// optional CSS file
$cms->CSS_SPECIAL_INCLUDE = '';
if (file_exists($cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME) && is_file($cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME)) {
$cms->CSS_SPECIAL_INCLUDE = $cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME;
}
// optional JS file
$cms->JS_SPECIAL_INCLUDE = '';
if (file_exists($cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME) && is_file($cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME)) {
$cms->JS_SPECIAL_INCLUDE = $cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME;
}
if ($smarty) {
// check if template names exist
if (!file_exists($smarty->getTemplateDir()[0].DS.$MASTER_TEMPLATE_NAME)) {
// abort if master template could not be found
exit('MASTER TEMPLATE: '.$MASTER_TEMPLATE_NAME.' could not be found');
}
if (isset($TEMPLATE_NAME) && !file_exists($smarty->getTemplateDir()[0].DS.$TEMPLATE_NAME)) {
exit('INCLUDE TEMPLATE: '.$TEMPLATE_NAME.' could not be found');
}
}
}
// if the lang folder is different to the default one
// if the default lang is not like the lang given, switch lang
/** @phan-suppress-next-line PhanParamSuspiciousOrder */
if (false === strstr(BASE.INCLUDES.LANG.CONTENT_PATH, $cms->lang_dir) ||
strcasecmp(defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG, $lang)
) {
$cms->debug('LANG', 'Orig: '.BASE.INCLUDES.LANG.CONTENT_PATH.', New: '.$cms->lang_dir.' | Orig Lang: '.(defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG).', New Lang: '.$lang);
$cms->l->l10nReloadMOfile($lang, $cms->lang_dir);
// if we have login class
if ($login) {
$login->l->l10nReloadMOfile($lang, $cms->lang_dir);
}
// if we have smarty template class
if ($smarty) {
$smarty->l10n->l10nReloadMOfile($lang, $cms->lang_dir);
}
}
if (isset($AJAX_PAGE) && !$AJAX_PAGE) {
// javascript translate data as template for auto translate
if (empty($TEMPLATE_TRANSLATE)) {
$TEMPLATE_TRANSLATE = 'jsTranslate_'.$lang.'.tpl';
$cms->debug('LANG', 'Load lang: '.$lang.', for page file '.$TEMPLATE_TRANSLATE);
} else {
// we assume we have some fixed set
// we must add _<$lang>
// if .tpl, put before .tpl
// if not .tpl, add _<$lang>.tpl
if (strpos($TEMPLATE_TRANSLATE, '.tpl')) {
$TEMPLATE_TRANSLATE = str_replace('.tpl', '_'.$lang.'.tpl', $TEMPLATE_TRANSLATE);
} else {
$TEMPLATE_TRANSLATE .= '_'.$lang.'.tpl';
}
}
// if we can't find it, dump it
if ($smarty && !file_exists($smarty->getTemplateDir()[0].DS.$TEMPLATE_TRANSLATE)) {
unset($TEMPLATE_TRANSLATE);
}
}
// $cms->debug("LANGUAGE", "L: $lang | ".$cms->lang_dir." | MO File: ".$cms->l->mofile);
$cms->debug("LANGUAGE", "SL: ".$_SESSION['DEFAULT_CHARSET']." | ".$_SESSION['LANG']." | ".$_SESSION['DEFAULT_LANG']);
if ($smarty) {
$cms->debug("TEMPLATE", "P: ".$smarty->getTemplateDir()[0]);
} }
// __END__ // __END__

View File

@@ -7,109 +7,11 @@
* HISTORY: * HISTORY:
*********************************************************************/ *********************************************************************/
// trigger flags /******
$cms->HEADER['USE_PROTOTYPE'] = isset($USE_PROTOTYPE) ? $USE_PROTOTYPE : USE_PROTOTYPE; NOTE THAT THIS INCLUDE IS OBSOLETE
// scriptacolous, can only be used with prototype USE THE BELOW FUNCTION CALL IN THE SCRIPT ITSELF
if ($cms->HEADER['USE_PROTOTYPE']) { *******/
$cms->HEADER['USE_SCRIPTACULOUS'] = isset($USE_SCRIPTACULOUS) ? $USE_SCRIPTACULOUS : USE_SCRIPTACULOUS; trigger_error('admin_smarty.php is deprecated. Use SmartyExtended->setSmartyVarsAdmin(); or setSmartyVarsFrontend();', E_USER_DEPRECATED);
} $smarty->setSmartyVarsAdmin();
// jquery and prototype should not be used together
$cms->HEADER['USE_JQUERY'] = isset($USE_JQUERY) ? $USE_JQUERY : USE_JQUERY; // don't use either of those two together
// check if we have an external file with the template name
if (file_exists($cms->includes.$cms->INC_TEMPLATE_NAME) && is_file($cms->includes.$cms->INC_TEMPLATE_NAME)) {
include($cms->includes.$cms->INC_TEMPLATE_NAME);
}
// additional per page Javascript include
$cms->JS_INCLUDE = '';
if (file_exists($cms->javascript.$cms->JS_TEMPLATE_NAME) && is_file($cms->javascript.$cms->JS_TEMPLATE_NAME)) {
$cms->JS_INCLUDE = $cms->javascript.$cms->JS_TEMPLATE_NAME;
}
// per page css file
$cms->CSS_INCLUDE = '';
if (file_exists($cms->css.$cms->CSS_TEMPLATE_NAME) && is_file($cms->css.$cms->CSS_TEMPLATE_NAME)) {
$cms->CSS_INCLUDE = $cms->css.$cms->CSS_TEMPLATE_NAME;
}
// optional CSS file
$cms->CSS_SPECIAL_INCLUDE = '';
if (file_exists($cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME) && is_file($cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME)) {
$cms->CSS_SPECIAL_INCLUDE = $cms->css.$cms->CSS_SPECIAL_TEMPLATE_NAME;
}
// optional JS file
$cms->JS_SPECIAL_INCLUDE = '';
if (file_exists($cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME) && is_file($cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME)) {
$cms->JS_SPECIAL_INCLUDE = $cms->javascript.$cms->JS_SPECIAL_TEMPLATE_NAME;
}
// the actual include files for javascript (per page)
$cms->HEADER['JS_INCLUDE'] = $cms->JS_INCLUDE;
$cms->HEADER['CSS_INCLUDE'] = $cms->CSS_INCLUDE;
$cms->HEADER['CSS_SPECIAL_INCLUDE'] = $cms->CSS_SPECIAL_INCLUDE;
$cms->HEADER['JS_SPECIAL_INCLUDE'] = $cms->JS_SPECIAL_INCLUDE;
// paths to the files
$cms->DATA['includes'] = $cms->includes;
$cms->DATA['js'] = $cms->javascript;
$cms->DATA['css'] = $cms->css;
$cms->DATA['pictures'] = $cms->pictures;
// default CMS settings
// define all needed smarty stuff for the general HTML/page building
$cms->HEADER['CSS'] = CSS;
$cms->HEADER['JS'] = JS;
$cms->HEADER['ENCODING'] = $encoding;
$cms->HEADER['DEFAULT_ENCODING'] = DEFAULT_ENCODING;
$cms->HEADER['STYLESHEET'] = isset($ADMIN_STYLESHEET) ? $ADMIN_STYLESHEET : ADMIN_STYLESHEET;
$cms->HEADER['JAVASCRIPT'] = isset($ADMIN_JAVASCRIPT) ? $ADMIN_JAVASCRIPT : ADMIN_JAVASCRIPT;
// html title
$cms->HEADER['HTML_TITLE'] = isset($L_TITLE) ? $cms->l->__($L_TITLE) : $cms->l->__(G_TITLE);
$cms->DATA['table_width'] = isset($PAGE_WIDTH) ? $PAGE_WIDTH : PAGE_WIDTH;
// messages = array('msg' =>, 'class' => 'error/warning/...')
$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'] = $TEMPLATE_TRANSLATE;
$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;
// debug data, if DEBUG flag is on, this data is print out
$cms->DEBUG_DATA['debug_error_msg'] = $cms->runningTime();
$cms->DEBUG_DATA['DEBUG'] = @$DEBUG_TMPL;
// create main data array
$cms->CONTENT_DATA = array_merge($cms->HEADER, $cms->DATA, $cms->DEBUG_DATA);
// data is 1:1 mapping (all vars, values, etc)
foreach ($cms->CONTENT_DATA as $key => $value) {
$smarty->assign($key, $value);
}
if (is_dir(BASE.TEMPLATES_C)) {
$smarty->setCompileDir(BASE.TEMPLATES_C);
}
if (is_dir(BASE.CACHE)) {
$smarty->setCacheDir(BASE.CACHE);
}
$smarty->display(
$MASTER_TEMPLATE_NAME,
$cms->CACHE_ID.($cms->CACHE_ID ? '_' : '').$lang,
$cms->COMPILE_ID.($cms->COMPILE_ID ? '_' : '').$lang
);
// __END__ // __END__

View File

@@ -36,23 +36,19 @@ if (!DEBUG) {
$ECHO_ALL = 0; $ECHO_ALL = 0;
} }
// set default lang if not set otherwise
if (!isset($lang)) {
$lang = DEFAULT_LANG;
}
// should be utf8 // should be utf8
header("Content-type: text/html; charset=".DEFAULT_ENCODING); header("Content-type: text/html; charset=".DEFAULT_ENCODING);
ob_end_flush(); ob_end_flush();
$login = new CoreLibs\ACL\Login(DB_CONFIG, $lang); $login = new CoreLibs\ACL\Login(DB_CONFIG);
// create form class // create form class
$form = new CoreLibs\Output\Form\Generate(DB_CONFIG, $lang); $form = new CoreLibs\Output\Form\Generate(DB_CONFIG);
if ($form->mobile_phone) { if ($form->mobile_phone) {
echo "I am sorry, but this page cannot be viewed by a mobile phone"; echo "I am sorry, but this page cannot be viewed by a mobile phone";
exit; exit;
} }
// smarty template engine (extended Translation version) // smarty template engine (extended Translation version)
$smarty = new CoreLibs\Template\SmartyExtend($lang); $smarty = new CoreLibs\Template\SmartyExtend();
// $form->debug('POST', $form->printAr($_POST)); // $form->debug('POST', $form->printAr($_POST));
@@ -453,7 +449,7 @@ if (is_dir(BASE.TEMPLATES_C)) {
if (is_dir(BASE.CACHE)) { if (is_dir(BASE.CACHE)) {
$smarty->setCacheDir(BASE.CACHE); $smarty->setCacheDir(BASE.CACHE);
} }
$smarty->display($EDIT_TEMPLATE, 'editAdmin_'.$lang, 'editAdmin_'.$lang); $smarty->display($EDIT_TEMPLATE, 'editAdmin_'.$smarty->lang, 'editAdmin_'.$smarty->lang);
// debug output // debug output
echo $login->printErrorMsg(); echo $login->printErrorMsg();

Binary file not shown.

View File

@@ -1,113 +0,0 @@
{*
********************************************************************
* AUTHOR: Clemens Schwaighofer
* DATE: 2007/10/18
* DESCRIPTION:
* content main part (buttons, load, etc)
* HISTORY:
********************************************************************
*}
<script language="JavaScript">
<!--
var form_name = '{$form_name}';
var load_id = '{if $primary_key}{$primary_key}{else}0{/if}';
var show_sort = {$show_sort};
//-->
</script>
<div style="position:relative; width: {$table_width}px; margin-top: 5px; margin-bottom: 5px; top: 0px; left: 0px;">
<div id="main_menu" style="position: absolute; top: 0px; left: 0px; width: 750px; height: 550px; z-index: 5; overflow: auto; padding: 2px; visibility: hidden;" class="sidemenu">
<div style="position: absolute; top: 2px; left: 2px;">
<input type="button" id="show_menu" name="show_menu" value="{t}Close Menu{/t}" OnClick="ShowHideMenu('hide', 'main_menu');"> {if $primary_key}<a href="#{$primary_key}">&darr;</a>{/if}&nbsp;<input type="text" id="search" name="search" value="{$search}" OnKeyup="QuickSearch(); return false;" {popup text="Search" width="150"}> <span id="search_status">{t}Enter Value{/t}</span>
<div id="search_found">{t 1=$menu_elements}Found: %1{/t}</div>
</div>
<div id="search_results" style="position: relative; top: 32px; left: 2px; padding: 2px; margin: 2px; width: 95%; height: 90%; overflow: auto; visibility: hidden; display: none; z-index: 3;">
</div>
<div id="element_list" style="position: relative; top: 32px; left: 2px; padding: 2px; margin: 2px; width: 95%; height: 90%; overflow: auto; z-index: 3;">
{foreach from=$table_menu key=key item=item}
{if $s_title != $item.title && $item.title}
{assign var='s_title' value=$item.title}
<div style="font-weight: bold;">{$item.title}</div>
{/if}
{if $show_sort}
{strip}
<span style="font-family: monospace;">[
{if $item.order_move == '-' || !$item.order_move}
&nbsp;
{/if}
{if $item.order_move == '+' || $item.order_move == '*'}
<a href="javascript:me({$item.id}, '+');" {popup text="Up" width="20"}>&uarr;</a>
{/if}
{if $item.order_move == '-' || $item.order_move == '*'}
<a href="javascript:me({$item.id}, '-');" {popup text="Down" width="20"}>&darr;</a>
{/if}
{if $item.order_move == '+' || !$item.order_move}
&nbsp;
{/if}
]</span>
{/strip}
{/if}
<a name="{$item.id}"></a>
{if $item.key}[{$item.key}] {/if}{if $item.status}[{$item.status}] {/if}<a href="javascript:le('{$item.id}');" class="{if $item.deleted == 't' && $primary_key == $item.id}item_loaded_deleted{elseif $item.deleted == 't'}item_deleted{elseif $primary_key == $item.id}item_loaded{/if}" {popup text="`$item.desc`" caption="Info" width="350"}>{$item.name}</a><br>
{/foreach}
</div>
<div style="position: absolute; bottom: 2px; left: 2px; z-index: 5;">
<input type="button" id="show_menu" name="show_menu" value="{t}Close Menu{/t}" OnClick="ShowHideMenu('hide', 'main_menu');">
</div>
</div>
<div style="position: relative; top: 0px; left: 0px; width: 790px; z-index: 0; margin: 2px; padding: 2px;">
<form method="post" name="{$form_name}" enctype="multipart/form-data">
{* menu button *}
{if !$hide_menu}
<div style="margin-bottom: 2px; padding: 2px; position: relative;">
<input type="button" id="show_menu" name="show_menu" value="{t}Show Menu{/t}" OnClick="ShowHideMenu('show', 'main_menu');" {if $page_acl < 20}disabled{/if}>
</div>
{/if}
{* save, delete commands *}
<div style="margin-bottom: 2px; padding: 2px; position: relative;" class="buttongroup">
<div style="margin-bottom: 2px; padding: 2px; position: relative; height: 20px;">
<input type="button" name="new" value="{t}New{/t}" OnClick="document.{$form_name}.action.value='new';document.{$form_name}.action_yes.value=confirm('{t}Do you want to create a new entry entry?{/t}');if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
<input type="button" name="save" value="{t}Save{/t}" OnClick="document.{$form_name}.action.value='save';document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
{if $show_delete_button && !$show_undelete_button}
<input type="button" name="delete" value="{t}Delete{/t}" OnClick="document.{$form_name}.action.value='delete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to delete this entry?{/t}');document.{$form_name}.action_id.value='{$primary_key}';if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
{if $show_delete_button && $show_undelete_button}
<input type="button" name="un_delete" value="{t}Un-Delete{/t}" OnClick="document.{$form_name}.action.value='undelete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to undelete this entry?{/t}');document.{$form_name}.action_id.value='{$primary_key}';if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
</div>
</div>
{* status messages *}
<div id="status_message" style="margin-bottom: 2px; padding: 2px; text-align: center; position: relative; visibility: hidden;">
</div>
{* main grouping *}
<div style="margin-bottom: 5px; padding: 2px; position: relative; min-height: 400px;" class="{$status_color}">
{include file=$CONTENT_INCLUDE}
</div>
{* save, delete commands *}
<div style="margin-bottom: 2px; padding: 2px; position: relative;" class="buttongroup">
<div style="margin-bottom: 2px; padding: 2px; position: relative; height: 20px;">
<input type="button" name="new" value="{t}New{/t}" OnClick="document.{$form_name}.action.value='new';document.{$form_name}.action_yes.value=confirm('{t}Do you want to create a new entry entry?{/t}');if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
<input type="button" name="save" value="{t}Save{/t}" OnClick="document.{$form_name}.action.value='save';document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
{if $show_delete_button && !$show_undelete_button}
<input type="button" name="delete" value="{t}Delete{/t}" OnClick="document.{$form_name}.action.value='delete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to delete this entry?{/t}');document.{$form_name}.action_id.value='{$primary_key}';if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
{if $show_delete_button && $show_undelete_button}
<input type="button" name="un_delete" value="{t}Un-Delete{/t}" OnClick="document.{$form_name}.action.value='undelete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to undelete this entry?{/t}');document.{$form_name}.action_id.value='{$primary_key}';if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
</div>
</div>
{* hidden group *}
<input type="hidden" id="primary_key" name="primary_key" value="{$primary_key}">
{* action var set *}
<input type="hidden" id="action" name="action" value="">
<input type="hidden" id="action_flag" name="action_flag" value="">
<input type="hidden" id="action_yes" name="action_yes" value="">
<input type="hidden" id="action_id" name="action_id" value="">
<input type="hidden" id="action_value" name="action_value" value="">
<input type="hidden" id="action_menu" name="action_menu" value="">
<input type="hidden" id="action_error" name="action_error" value="">
<input type="hidden" name="action_loaded" value="true">
</form>
</div>
</div>

View File

@@ -1,42 +0,0 @@
{*
********************************************************************
* AUTHOR: Clemens Schwaighofer
* DATE: 2007/10/18
* DESCRIPTION:
* content main part (buttons, load, etc)
* HISTORY:
********************************************************************
*}
<script language="JavaScript">
<!--
var form_name = '{$form_name}';
var load_id = '{if $primary_key}{$primary_key}{/if}';
var show_sort = {if $show_sort}{$show_sort}{else}0{/if};
//-->
</script>
<div style="width: {$table_width}px; margin-top: 5px; margin-bottom: 5px;">
<form method="post" name="{$form_name}" enctype="multipart/form-data">
{* save, delete commands *}
<div style="margin-bottom: 2px; padding: 2px;" class="buttongroup">
{include file=cms_buttons.tpl}
</div>
{include file=$CONTENT_INCLUDE}
{* save, delete commands *}
<div style="margin-bottom: 2px; padding: 2px;" class="buttongroup">
{include file=cms_buttons.tpl}
</div> <!-- button close //-->
{* hidden group *}
<input type="hidden" id="primary_key" name="primary_key" value="{$primary_key}">
{* action var set *}
<input type="hidden" id="action" name="action" value="">
<input type="hidden" id="action_flag" name="action_flag" value="">
<input type="hidden" id="action_yes" name="action_yes" value="">
<input type="hidden" id="action_id" name="action_id" value="">
<input type="hidden" id="action_value" name="action_value" value="">
<input type="hidden" id="action_menu" name="action_menu" value="">
<input type="hidden" id="action_error" name="action_error" value="">
<input type="hidden" name="action_loaded" value="true">
</form>
</div>

View File

@@ -1,19 +0,0 @@
{*
********************************************************************
* AUTHOR: Clemens Schwaighofer
* DATE: 2007/10/18
* DESCRIPTION:
* content main part (buttons, load, etc)
* HISTORY:
********************************************************************
*}
<script language="JavaScript">
<!--
var form_name = '{$form_name}';
var load_id = {if $primary_key}{$primary_key}{else}0{/if};
var show_sort = {if $show_sort}{$show_sort}{else}0{/if};
//-->
</script>
{include file=$CONTENT_INCLUDE}

View File

@@ -1,91 +0,0 @@
{*
********************************************************************
* AUTHOR: Clemens Schwaighofer
* DATE: 2008/04/11
* DESCRIPTION:
* special content main part (buttons, load, etc)
* HISTORY:
********************************************************************
*}
<script language="JavaScript">
<!--
var form_name = '{$form_name}';
var load_id = {if $primary_key}{$primary_key}{else}0{/if};
//-->
</script>
<div style="position:relative; width: {$table_width}px; margin-top: 5px; margin-bottom: 5px; top: 0px; left: 0px;">
<div style="position: relative; top: 0px; left: 0px; width: 790px; z-index: 0; margin: 2px; padding: 2px;">
<form method="post" name="{$form_name}">
{* save, delete commands *}
<div style="margin: 2px; padding: 2px; position: relative;" class="buttongroup">
<div style="padding: 2px; position: relative; height: 20px;">
<input type="button" name="new" value="{t}New{/t}" OnClick="document.{$form_name}.action.value='new';document.{$form_name}.action_yes.value=confirm('{t}Do you want to create a new entry entry?{/t}');if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
<input type="button" name="save" value="{t}Save{/t}" OnClick="document.{$form_name}.action.value='save';document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
{if $show_delete_button && !$show_undelete_button}
<input type="button" name="delete" value="{t}Delete{/t}" OnClick="document.{$form_name}.action.value='delete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to delete this entry?{/t}');document.{$form_name}.action_id.value={$primary_key};if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
{if $show_delete_button && $show_undelete_button}
<input type="button" name="un_delete" value="{t}Un-Delete{/t}" OnClick="document.{$form_name}.action.value='undelete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to undelete this entry?{/t}');document.{$form_name}.action_id.value={$primary_key};if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
</div>
</div>
{* status messages *}
<div id="status_message" style="margin-bottom: 2px; padding: 2px; text-align: center; position: relative; visibility: hidden; display: none;">
</div>
{* main grouping *}
<div>
<div class="spacer"></div>
<div id="main_menu" style="float: left; position: relative; width: 200px; height: 450px; z-index: 5; overflow: auto; padding: 2px; margin: 2px;" class="sidemenu">
<div style="position: absolute; top: 2px; left: 2px;">
{if $primary_key}<a href="#{$primary_key}">&darr;</a>{/if}&nbsp;<input type="text" id="search" name="search" size="15" value="{$search}" OnKeyup="QuickSearch(); return false;" {popup text="Search" width="150"}> <span id="search_status">{t}Search{/t}</span>
<div id="search_found">{t}Found:{/t} {$menu_elements}</div>
</div>
<div id="search_results" style="position: relative; top: 32px; left: 2px; padding: 2px; margin: 2px; width: 95%; height: 90%; overflow: auto; visibility: hidden; display: none;">
</div>
<div id="element_list" style="position: relative; top: 32px; left: 2px; padding: 2px; margin: 2px; width: 95%; height: 90%; overflow: auto;">
{foreach from=$table_menu key=key item=item}
<a name="{$item.id}"></a>
{if $item.key}[{$item.key}] {/if}{if $item.status}[{$item.status}] {/if}<a href="javascript:le({$item.id});" class="{if $item.deleted == 't' && $primary_key == $item.id}item_loaded_deleted{elseif $item.deleted == 't'}item_deleted{elseif $primary_key == $item.id}item_loaded{/if}">{$item.name}</a><br>
{/foreach}
</div>
</div>
<div style="float: left; margin: 2px; padding: 2px; position: relative; width: 570px; min-height: 450px;" class="{$status_color}">
{* START CONTENT *}
{include file="$CONTENT_INCLUDE"}
{* END CONTENT *}
</div>
<div class="spacer"></div>
{* END MENU / CONTENT BLOCK *}
</div>
{* save, delete commands *}
<div style="margin: 2px; padding: 2px; position: relative;" class="buttongroup">
<div style="padding: 2px; position: relative; height: 20px;">
<input type="button" name="new" value="{t}New{/t}" OnClick="document.{$form_name}.action.value='new';document.{$form_name}.action_yes.value=confirm('{t}Do you want to create a new entry entry?{/t}');if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
<input type="button" name="save" value="{t}Save{/t}" OnClick="document.{$form_name}.action.value='save';document.{$form_name}.submit();" {if $page_acl < 60}disabled{/if}>
{if $show_delete_button && !$show_undelete_button}
<input type="button" name="delete" value="{t}Delete{/t}" OnClick="document.{$form_name}.action.value='delete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to delete this entry?{/t}');document.{$form_name}.action_id.value={$primary_key};if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
{if $show_delete_button && $show_undelete_button}
<input type="button" name="un_delete" value="{t}Un-Delete{/t}" OnClick="document.{$form_name}.action.value='undelete';document.{$form_name}.action_yes.value=confirm('{t}Do you want to undelete this entry?{/t}');document.{$form_name}.action_id.value={$primary_key};if (document.{$form_name}.action_yes.value == 'true') document.{$form_name}.submit();" {if $page_acl < 80}disabled{/if}>
{/if}
</div>
</div>
{* hidden group *}
<input type="hidden" id="primary_key" name="primary_key" value="{$primary_key}">
{* action var set *}
<input type="hidden" id="action" name="action" value="">
<input type="hidden" id="action_flag" name="action_flag" value="">
<input type="hidden" id="action_yes" name="action_yes" value="">
<input type="hidden" id="action_id" name="action_id" value="">
<input type="hidden" id="action_value" name="action_value" value="">
<input type="hidden" id="action_menu" name="action_menu" value="">
<input type="hidden" id="action_error" name="action_error" value="">
<input type="hidden" name="action_loaded" value="true">
</form>
</div>
</div>

View File

@@ -1,6 +1,9 @@
<div> <div>
{$SMARTY_TEST} {$SMARTY_TEST}
</div> </div>
<div>
TRANSLATION CLASS: {$TRANSLATE_TEST}
</div>
<div> <div>
<select id="drop_down_test" name="drop_down_test"> <select id="drop_down_test" name="drop_down_test">
{html_options options=$drop_down_test selected=$drop_down_test_selected} {html_options options=$drop_down_test selected=$drop_down_test_selected}
@@ -11,6 +14,9 @@
<div id="test-div" class="test-div"> <div id="test-div" class="test-div">
Some content ehre or asdfasdfasf Some content ehre or asdfasdfasf
</div> </div>
<div id="translate-div">
TRANSLATION SMARTY: {t}I should be translated{/t}
</div>
</div> </div>
</div> </div>
{* progresss indicator *} {* progresss indicator *}

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.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -52,45 +52,30 @@ class Backend extends \CoreLibs\DB\IO
public $error = 0; public $error = 0;
public $warning = 0; public $warning = 0;
public $info = 0; public $info = 0;
// smarty publics // internal lang & encoding vars
public $lang_dir = '';
public $lang;
public $lang_short;
public $encoding;
// language
public $l;
// smarty publics [end processing in smarty class]
public $DATA; public $DATA;
public $HEADER; public $HEADER;
public $DEBUG_DATA; public $DEBUG_DATA;
public $CONTENT_DATA; public $CONTENT_DATA;
// smarty include/set var
public $INC_TEMPLATE_NAME;
public $JS_TEMPLATE_NAME;
public $CSS_TEMPLATE_NAME;
public $CSS_SPECIAL_TEMPLATE_NAME;
public $JS_SPECIAL_TEMPLATE_NAME;
public $CACHE_ID;
public $COMPILE_ID;
public $includes;
public $template_path;
public $lang_dir = '';
public $javascript;
public $css;
public $pictures;
public $cache_pictures;
public $cache_pictures_root;
public $JS_INCLUDE;
public $JS_SPECIAL_INCLUDE;
public $CSS_INCLUDE;
public $CSS_SPECIAL_INCLUDE;
// language
public $l;
// CONSTRUCTOR / DECONSTRUCTOR |====================================> // CONSTRUCTOR / DECONSTRUCTOR |====================================>
/** /**
* main class constructor * main class constructor
* @param array $db_config db config array * @param array $db_config db config array
* @param string $lang language string
* @param int|integer $set_control_flag class variable check flag * @param int|integer $set_control_flag class variable check flag
*/ */
public function __construct(array $db_config, string $lang, int $set_control_flag = 0) public function __construct(array $db_config, int $set_control_flag = 0)
{ {
$this->setLangEncoding();
// get the language sub class & init it // get the language sub class & init it
$this->l = new \CoreLibs\Language\L10n($lang); $this->l = new \CoreLibs\Language\L10n($this->lang);
// init the database class // init the database class
parent::__construct($db_config, $set_control_flag); parent::__construct($db_config, $set_control_flag);
@@ -118,9 +103,51 @@ class Backend extends \CoreLibs\DB\IO
// INTERNAL METHODS |===============================================> // INTERNAL METHODS |===============================================>
/**
* set the language encoding and language settings
* the default charset from _SESSION login or from
* config DEFAULT ENCODING
* the lang full name for mo loading from _SESSION login
* or SITE LANG or DEFAULT LANG from config
* creates short lang (only first two chars) from the lang
* @return void
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE.INCLUDES.LANG.CONTENT_PATH;
}
// PUBLIC METHODS |=================================================> // PUBLIC METHODS |=================================================>
/**
* set internal ACL from login ACL
* @param array $acl login acl array
*/
public function setACL(array $acl): void
{
$this->acl = $acl;
}
/** /**
* writes all action vars plus other info into edit_log tabl * writes all action vars plus other info into edit_log tabl
* @param string $event any kind of event description, * @param string $event any kind of event description,
@@ -157,7 +184,7 @@ class Backend extends \CoreLibs\DB\IO
$q .= "ip, user_agent, referer, script_name, query_string, server_name, http_host, http_accept, http_accept_charset, http_accept_encoding, session_id, "; $q .= "ip, user_agent, referer, script_name, query_string, server_name, http_host, http_accept, http_accept_charset, http_accept_encoding, session_id, ";
$q .= "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) "; $q .= "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) ";
$q .= "VALUES "; $q .= "VALUES ";
$q .= "(".$this->dbEscapeString(isset($_SESSION['EUID']) ? $_SESSION['EUID'] : '').", "; $q .= "(".$this->dbEscapeString(isset($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? $_SESSION['EUID'] : 'NULL').", ";
$q .= "NOW(), "; $q .= "NOW(), ";
$q .= "'".$this->dbEscapeString((string)$event)."', '".$data."', '".$data_binary."', '".$this->dbEscapeString($this->page_name)."', "; $q .= "'".$this->dbEscapeString((string)$event)."', '".$data."', '".$data_binary."', '".$this->dbEscapeString($this->page_name)."', ";
$q .= "'".@$_SERVER["REMOTE_ADDR"]."', '".$this->dbEscapeString(@$_SERVER['HTTP_USER_AGENT'])."', "; $q .= "'".@$_SERVER["REMOTE_ADDR"]."', '".$this->dbEscapeString(@$_SERVER['HTTP_USER_AGENT'])."', ";
@@ -181,6 +208,42 @@ class Backend extends \CoreLibs\DB\IO
$this->dbExec($q, 'NULL'); $this->dbExec($q, 'NULL');
} }
/**
* helper function for PHP file upload error messgaes to messge string
* @param int $error_code integer _FILE upload error code
* @return string message string, translated
*/
public function fileUploadErrorMessage(int $error_code): string
{
switch ($error_code) {
case UPLOAD_ERR_INI_SIZE:
$message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
break;
case UPLOAD_ERR_FORM_SIZE:
$message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
break;
case UPLOAD_ERR_PARTIAL:
$message = 'The uploaded file was only partially uploaded';
break;
case UPLOAD_ERR_NO_FILE:
$message = 'No file was uploaded';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$message = 'Missing a temporary folder';
break;
case UPLOAD_ERR_CANT_WRITE:
$message = 'Failed to write file to disk';
break;
case UPLOAD_ERR_EXTENSION:
$message = 'File upload stopped by extension';
break;
default:
$message = 'Unknown upload error';
break;
}
return $this->l->__($message);
}
/** /**
* menu creater (from login menu session pages) * menu creater (from login menu session pages)
* @param int $flag visible flag trigger * @param int $flag visible flag trigger
@@ -193,7 +256,7 @@ class Backend extends \CoreLibs\DB\IO
} }
// get the session pages array // get the session pages array
$PAGES = $_SESSION['PAGES']; $PAGES = isset($_SESSION['PAGES']) ? $_SESSION['PAGES'] : null;
if (!isset($PAGES) || !is_array($PAGES)) { if (!isset($PAGES) || !is_array($PAGES)) {
$PAGES = array(); $PAGES = array();
} }

View File

@@ -181,6 +181,8 @@ class Basic
// form token (used for form validation) // form token (used for form validation)
private $form_token = ''; private $form_token = '';
// ajax flag
protected $ajax_page_flag = false;
// METHOD: __construct // METHOD: __construct
// PARAMS: set_control_flag [current sets set/get var errors] // PARAMS: set_control_flag [current sets set/get var errors]
@@ -218,6 +220,11 @@ class Basic
die('Core Constant missing. Check config file.'); die('Core Constant missing. Check config file.');
} }
// set ajax page flag based on the AJAX_PAGE varaibles
// convert to true/false so if AJAX_PAGE is 0 or false it is
// always boolean false
$this->ajax_page_flag = isset($GLOBALS['AJAX_PAGE']) && $GLOBALS['AJAX_PAGE'] ? true : false;
// set the page name // set the page name
$this->page_name = $this->getPageName(); $this->page_name = $this->getPageName();
$this->host_name = $this->getHostName(); $this->host_name = $this->getHostName();
@@ -1521,7 +1528,7 @@ class Basic
// labels in order of size // labels in order of size
$labels = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'); $labels = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB');
// calc file size, round down too two digits, add label based max change // calc file size, round down too two digits, add label based max change
return round($number / pow(1024, ($i = floor(log((float)$number, 1024)))), 2).($space ? ' ' : '').(isset($labels[(int)$i]) ? $labels[(int)$i] : '>EB'); return round((float)$number / pow(1024, ($i = floor(log((float)$number, 1024)))), 2).($space ? ' ' : '').(isset($labels[(int)$i]) ? $labels[(int)$i] : '>EB');
} }
return (string)$number; return (string)$number;
} }
@@ -1843,8 +1850,15 @@ class Basic
* @param bool $clear_cache if set to true, will create thumb all the tame * @param bool $clear_cache if set to true, will create thumb all the tame
* @return string|bool thumbnail name, or false for error * @return string|bool thumbnail name, or false for error
*/ */
public static function createThumbnail(string $pic, int $size_x, int $size_y, string $dummy = '', string $path = '', string $cache_source = '', bool $clear_cache = false) public static function createThumbnail(
{ string $pic,
int $size_x,
int $size_y,
string $dummy = '',
string $path = '',
string $cache_source = '',
bool $clear_cache = false
) {
// get image type flags // get image type flags
$image_types = array( $image_types = array(
1 => 'gif', 1 => 'gif',
@@ -1852,6 +1866,15 @@ class Basic
3 => 'png' 3 => 'png'
); );
$return_data = false; $return_data = false;
$CONVERT = '';
// if CONVERT is not defined, abort
/** @phan-suppress-next-line PhanUndeclaredConstant */
if (defined('CONVERT') && is_executable(CONVERT)) {
/** @phan-suppress-next-line PhanUndeclaredConstant */
$CONVERT = CONVERT;
} else {
return $return_data;
}
if (!empty($cache_source)) { if (!empty($cache_source)) {
$tmp_src = $cache_source; $tmp_src = $cache_source;
} else { } else {
@@ -1889,7 +1912,7 @@ class Basic
// is this a PDF, if no, return from here with nothing // is this a PDF, if no, return from here with nothing
$convert_prefix = 'png:'; $convert_prefix = 'png:';
# TEMP convert to PNG, we then override the file name # TEMP convert to PNG, we then override the file name
$convert_string = CONVERT.' '.$filename.' '.$convert_prefix.$filename.'_TEMP'; $convert_string = $CONVERT.' '.$filename.' '.$convert_prefix.$filename.'_TEMP';
$status = exec($convert_string, $output, $return); $status = exec($convert_string, $output, $return);
$filename .= '_TEMP'; $filename .= '_TEMP';
// for delete, in case we need to glob // for delete, in case we need to glob
@@ -1913,7 +1936,7 @@ class Basic
if (!is_file($thumbnail) || $clear_cache == true) { if (!is_file($thumbnail) || $clear_cache == true) {
// convert the picture // convert the picture
if ($width > $size_x) { if ($width > $size_x) {
$convert_string = CONVERT.' -geometry '.$size_x.'x '.$filename.' '.$thumbnail; $convert_string = $CONVERT.' -geometry '.$size_x.'x '.$filename.' '.$thumbnail;
$status = exec($convert_string, $output, $return); $status = exec($convert_string, $output, $return);
// get the size of the converted data, if converted // get the size of the converted data, if converted
if (is_file($thumbnail)) { if (is_file($thumbnail)) {
@@ -1921,7 +1944,7 @@ class Basic
} }
} }
if ($height > $size_y) { if ($height > $size_y) {
$convert_string = CONVERT.' -geometry x'.$size_y.' '.$filename.' '.$thumbnail; $convert_string = $CONVERT.' -geometry x'.$size_y.' '.$filename.' '.$thumbnail;
$status = exec($convert_string, $output, $return); $status = exec($convert_string, $output, $return);
} }
} }
@@ -1949,6 +1972,282 @@ class Basic
return $return_data; return $return_data;
} }
/**
* simple thumbnail creation for jpeg, png only
* TODO: add other types like gif, etc
* - bails with false on failed create
* - if either size_x or size_y are empty (0)
* the resize is to max of one size
* if both are set, those are the max sizes (aspect ration is always ekpt)
* - if path is not given will cache folder for current path set
* @param string $filename source file name with full path
* @param int $thumb_width thumbnail width
* @param int $thumb_height thumbnail height
* @param string|null $thumbnail_path altnerative path for thumbnails
* @param bool $create_dummy if we encounter an invalid file
* create a dummy image file and return it
* @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 $create_dummy = true,
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);
$thumbnail_write_path = null;
$thumbnail_web_path = null;
// path set first
if ($img_type == IMG_JPG ||
$img_type == IMG_PNG ||
$create_dummy === true
) {
// $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;
}
}
}
// do resize or fall back on dummy run
if ($img_type == IMG_JPG ||
$img_type == IMG_PNG
) {
// 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;
}
} elseif ($create_dummy === true) {
// create dummy image in the thumbnail size
// if one side is missing, use the other side to create a square
if (!$thumb_width) {
$thumb_width = $thumb_height;
}
if (!$thumb_height) {
$thumb_height = $thumb_width;
}
// do we have an image already?
$thumbnail = 'thumb-'.pathinfo($filename)['filename'].'-'.$thumb_width.'x'.$thumb_height;
if ($use_cache === false ||
!file_exists($thumbnail_write_path.$thumbnail)
) {
// if both are unset, set to 250
if ($thumb_height == 0) {
$thumb_height = 250;
}
if ($thumb_width == 0) {
$thumb_width = 250;
}
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
// add outside border px = 5% (rounded up)
// eg 50px -> 2.5px
$gray = imagecolorallocate($thumb, 200, 200, 200);
$white = imagecolorallocate($thumb, 255, 255, 255);
// fill gray background
imagefill($thumb, 0, 0, $gray);
// now create rectangle
if (imagesx($thumb) < imagesy($thumb)) {
$width = (int)round(imagesx($thumb) / 100 * 5);
} else {
$width = (int)round(imagesy($thumb) / 100 * 5);
}
imagefilledrectangle($thumb, 0 + $width, 0 + $width, imagesx($thumb) - $width, imagesy($thumb) - $width, $white);
// add "No valid images source"
// OR add circle
// * find center
// * width/height is 75% of size - border
// smaller size is taken
$base_width = imagesx($thumb) > imagesy($thumb) ? imagesy($thumb) : imagesx($thumb);
// get 75% width
$cross_width = (int)round((($base_width - ($width * 2)) / 100 * 75) / 2);
$center_x = (int)round(imagesx($thumb) / 2);
$center_y = (int)round(imagesy($thumb) / 2);
imagefilledellipse($thumb, $center_x, $center_y, $cross_width, $cross_width, $gray);
// find top left and bottom left for first line
imagepng($thumb, $thumbnail_write_path.$thumbnail);
}
// add web path
$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);
// add @ to avoid "file not supported error"
$exif = @exif_read_data($filename);
$orientation = null;
$img = null;
if ($exif && isset($exif['Orientation'])) {
$orientation = $exif['Orientation'];
}
if ($orientation != 1) {
$this->debug('IMAGE FILE ROTATE', 'Need to rotate image ['.$filename.'] from: '.$orientation);
switch ($img_type) {
case IMG_JPG:
$img = imagecreatefromjpeg($filename);
break;
case IMG_PNG:
$img = imagecreatefrompng($filename);
break;
}
$deg = 0;
// 1 top, 6: left, 8: right, 3: bottom
switch ($orientation) {
case 3:
$deg = 180;
break;
case 6:
$deg = -90;
break;
case 8:
$deg = 90;
break;
}
if ($img !== null) {
if ($deg) {
$img = imagerotate($img, $deg, 0);
}
// then rewrite the rotated image back to the disk as $filename
switch ($img_type) {
case IMG_JPG:
imagejpeg($img, $filename);
break;
case IMG_PNG:
imagepng($img, $filename);
break;
}
// clean up image if we have an image
imagedestroy($img);
}
} // only if we need to rotate
} // function exists & file is writeable, else do nothing
}
/** /**
* test if a string can be safely convert between encodings. mostly utf8 to shift jis * test if a string can be safely convert between encodings. mostly utf8 to shift jis
* the default compare has a possibility of failure, especially with windows * the default compare has a possibility of failure, especially with windows
@@ -2110,6 +2409,35 @@ class Basic
return false; return false;
} }
/**
* creates psuedo random uuid v4
* Code take from class here:
* https://www.php.net/manual/en/function.uniqid.php#94959
* @return string pseudo random uuid v4
*/
public static function uuidv4(): string
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
// 16 bits for "time_mid"
mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
}
// [!!! DEPRECATED !!!] // [!!! DEPRECATED !!!]
// ALL crypt* methids are DEPRECATED and SHALL NOT BE USED // ALL crypt* methids are DEPRECATED and SHALL NOT BE USED
// use the new password* instead // use the new password* instead

View File

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

View File

@@ -448,10 +448,10 @@ class PgSQL
} }
if ('{}' != $text) { if ('{}' != $text) {
do { do {
if ('{' != $text{$offset}) { if ('{' != $text[$offset]) {
preg_match("/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", $text, $match, 0, $offset); preg_match("/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", $text, $match, 0, $offset);
$offset += strlen($match[0]); $offset += strlen($match[0]);
$output[] = ('"' != $match[1]{0} ? $match[1] : stripcslashes(substr($match[1], 1, -1))); $output[] = ('"' != $match[1][0] ? $match[1] : stripcslashes(substr($match[1], 1, -1)));
if ('},' == $match[3]) { if ('},' == $match[3]) {
return $offset; return $offset;
} }

View File

@@ -242,6 +242,11 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
public $security_level; public $security_level;
// layout publics // layout publics
public $table_width; public $table_width;
// internal lang & encoding vars
public $lang_dir = '';
public $lang;
public $lang_short;
public $encoding;
// language // language
public $l; public $l;
@@ -251,15 +256,15 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
/** /**
* construct form generator * construct form generator
* @param array $db_config db config array * @param array $db_config db config array
* @param string $lang interface language
* @param int|integer $table_width table/div width (default 750) * @param int|integer $table_width table/div width (default 750)
* @param int|integer $set_control_flag basic class set/get variable error flags * @param int|integer $set_control_flag basic class set/get variable error flags
*/ */
public function __construct(array $db_config, string $lang, int $table_width = 750, int $set_control_flag = 0) public function __construct(array $db_config, int $table_width = 750, int $set_control_flag = 0)
{ {
$this->my_page_name = $this->getPageName(1); $this->my_page_name = $this->getPageName(1);
$this->setLangEncoding();
// init the language class // init the language class
$this->l = new \CoreLibs\Language\L10n($lang); $this->l = new \CoreLibs\Language\L10n($this->lang);
// load config array // load config array
// get table array definitions for current page name // get table array definitions for current page name
// WARNING: auto spl load does not work with this as it is an array and not a function/object // WARNING: auto spl load does not work with this as it is an array and not a function/object
@@ -348,6 +353,45 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
parent::__destruct(); parent::__destruct();
} }
// INTERNAL METHODS |===============================================>
/**
* ORIGINAL in \CoreLibs\Admin\Backend
* set the language encoding and language settings
* the default charset from _SESSION login or from
* config DEFAULT ENCODING
* the lang full name for mo loading from _SESSION login
* or SITE LANG or DEFAULT LANG from config
* creates short lang (only first two chars) from the lang
* @return void
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE.INCLUDES.LANG.CONTENT_PATH;
}
// PUBLIC METHODS |=================================================>
/** /**
* dumps all values into output (for error msg) * dumps all values into output (for error msg)
* @return string full table array data output as string html formatted * @return string full table array data output as string html formatted
@@ -727,7 +771,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$EDIT_FGCOLOR_T = 'edit_fgcolor'; $EDIT_FGCOLOR_T = 'edit_fgcolor';
} }
$output_name = $this->table_array[$element_name]['output_name']; $output_name = $this->table_array[$element_name]['output_name'];
if (isset($this->table_array[$element_name]['mandatory'])) { if (isset($this->table_array[$element_name]['mandatory']) &&
$this->table_array[$element_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
// create right side depending on 'definiton' in table_array // create right side depending on 'definiton' in table_array
@@ -1022,6 +1068,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
} // switch } // switch
} // for each error to check } // for each error to check
} elseif (isset($value['mandatory']) && } elseif (isset($value['mandatory']) &&
$value['mandatory'] &&
( (
// for all 'normal' fields // for all 'normal' fields
($this->table_array[$key]['type'] != 'password' && $this->table_array[$key]['type'] != 'drop_down_db_input' && !$this->table_array[$key]['value']) || ($this->table_array[$key]['type'] != 'password' && $this->table_array[$key]['type'] != 'drop_down_db_input' && !$this->table_array[$key]['value']) ||
@@ -1065,7 +1112,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if (is_array($this->reference_array)) { if (is_array($this->reference_array)) {
reset($this->reference_array); reset($this->reference_array);
foreach ($this->reference_array as $key => $value) { foreach ($this->reference_array as $key => $value) {
if ($this->reference_array[$key]['mandatory'] && !$this->reference_array[$key]['selected'][0]) { if (isset($this->reference_array[$key]['mandatory']) &&
$this->reference_array[$key]['mandatory'] &&
!$this->reference_array[$key]['selected'][0]) {
$this->msg .= sprintf($this->l->__('Please select at least one Element from field <b>%s</b>!<br>'), $this->reference_array[$key]['output_name']); $this->msg .= sprintf($this->l->__('Please select at least one Element from field <b>%s</b>!<br>'), $this->reference_array[$key]['output_name']);
} }
} }
@@ -1119,20 +1168,25 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
for ($i = 0; $i < $max; $i ++) { for ($i = 0; $i < $max; $i ++) {
// either one of the post pks is set, or the mandatory // either one of the post pks is set, or the mandatory
foreach ($reference_array['elements'] as $el_name => $data_array) { foreach ($reference_array['elements'] as $el_name => $data_array) {
if (isset($data_array['mandatory'])) { if (isset($data_array['mandatory']) && $data_array['mandatory']) {
$mand_name = $data_array['output_name']; $mand_name = $data_array['output_name'];
} }
// check if there is a primary ket inside, so it is okay // check if there is a primary ket inside, so it is okay
if (isset($data_array['pk_id']) && if (isset($data_array['pk_id']) &&
count($_POST[$prfx.$el_name]) && count($_POST[$prfx.$el_name]) &&
isset($reference_array['mandatory']) isset($reference_array['mandatory']) &&
$reference_array['mandatory']
) { ) {
$mand_okay = 1; $mand_okay = 1;
} }
// we found a mandatory field. check now if one is set to satisfy the main mandatory // we found a mandatory field. check now if one is set to satisfy the main mandatory
// also check, if this field is mandatory and its not set, but any other, throw an error // also check, if this field is mandatory and its not set, but any other, throw an error
// $this->debug('edit_error_chk', 'RG error - Data['.$prfx.$el_name.': '.$_POST[$prfx.$el_name][$i].' | '.$_POST[$prfx.$el_name].' - '.$reference_array['enable_name'].' - '.$_POST[$reference_array['enable_name']][$_POST[$prfx.$el_name][$i]]); // $this->debug('edit_error_chk', 'RG error - Data['.$prfx.$el_name.': '.$_POST[$prfx.$el_name][$i].' | '.$_POST[$prfx.$el_name].' - '.$reference_array['enable_name'].' - '.$_POST[$reference_array['enable_name']][$_POST[$prfx.$el_name][$i]]);
if (isset($data_array['mandatory']) && $_POST[$prfx.$el_name][$i]) { if (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
isset($_POST[$prfx.$el_name][$i]) &&
$_POST[$prfx.$el_name][$i]
) {
$mand_okay = 1; $mand_okay = 1;
$row_okay[$i] = 1; $row_okay[$i] = 1;
} elseif ($data_array['type'] == 'radio_group' && !isset($_POST[$prfx.$el_name])) { } elseif ($data_array['type'] == 'radio_group' && !isset($_POST[$prfx.$el_name])) {
@@ -1145,7 +1199,10 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// $this->debug('edit_error_chk', '[$i]'); // $this->debug('edit_error_chk', '[$i]');
$element_set[$i] = 1; $element_set[$i] = 1;
$row_okay[$i] = 1; $row_okay[$i] = 1;
} elseif (isset($data_array['mandatory']) && !$_POST[$prfx.$el_name][$i]) { } elseif (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
!$_POST[$prfx.$el_name][$i]
) {
$row_okay[$i] = 0; $row_okay[$i] = 0;
} }
// do optional error checks like for normal fields // do optional error checks like for normal fields
@@ -1153,19 +1210,20 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if (isset($data_array['error_check'])) { if (isset($data_array['error_check'])) {
foreach (explode('|', $data_array['error_check']) as $error_check) { foreach (explode('|', $data_array['error_check']) as $error_check) {
switch ($error_check) { switch ($error_check) {
// check unique, check if field in table is not yet exist // check unique, check if field is filled and not same in _POST set
case 'unique': case 'unique':
$q = 'SELECT '.$_pk_name.' FROM '.$table_name.' WHERE '.$el_name.' = '."'".$this->dbEscapeString($_POST[$prfx.$el_name][$i])."'"; // must be set for double check
if ($this->table_array[$this->int_pk_name]['value']) { if ($_POST[$prfx.$el_name][$i] &&
$q .= ' AND '.$this->int_pk_name.' <> '.$this->table_array[$this->int_pk_name]['value']; count(array_keys($_POST[$prfx.$el_name], $_POST[$prfx.$el_name][$i])) >= 2
} ) {
list($key) = $this->dbReturnRow($q);
if ($key) {
$this->msg .= sprintf($this->l->__('The field <b>%s</b> in row <b>%s</b> can be used only once!<br>'), $reference_array['output_name'], $i); $this->msg .= sprintf($this->l->__('The field <b>%s</b> in row <b>%s</b> can be used only once!<br>'), $reference_array['output_name'], $i);
} }
break; break;
case 'alphanumericspace': case 'alphanumericspace':
if (!preg_match("/^[0-9A-Za-z\ ]+$/", $_POST[$prfx.$el_name][$i])) { // only check if set
if ($_POST[$prfx.$el_name][$i] &&
!preg_match("/^[0-9A-Za-z\ ]+$/", $_POST[$prfx.$el_name][$i])
) {
$this->msg .= sprintf($this->l->__('Please enter a valid alphanumeric (Numbers and Letters, spaces allowed) value for the <b>%s</b> Field and row <b>%s</b>!<br>'), $reference_array['output_name'], $i); $this->msg .= sprintf($this->l->__('Please enter a valid alphanumeric (Numbers and Letters, spaces allowed) value for the <b>%s</b> Field and row <b>%s</b>!<br>'), $reference_array['output_name'], $i);
} }
break; break;
@@ -1176,7 +1234,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
} }
// main mandatory is met -> error msg // main mandatory is met -> error msg
if (!$mand_okay && isset($reference_array['mandatory'])) { if (!$mand_okay &&
isset($reference_array['mandatory']) &&
$reference_array['mandatory']) {
$this->msg .= sprintf($this->l->__('You need to enter at least one data set for field <b>%s</b>!<Br>'), $reference_array['output_name']); $this->msg .= sprintf($this->l->__('You need to enter at least one data set for field <b>%s</b>!<Br>'), $reference_array['output_name']);
} }
for ($i = 0; $i < $max; $i ++) { for ($i = 0; $i < $max; $i ++) {
@@ -1472,6 +1532,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// if we have enable name & delete set, then only insert/update those which are flagged as active // if we have enable name & delete set, then only insert/update those which are flagged as active
// check if mandatory field is set, if not set 'do not write flag' // check if mandatory field is set, if not set 'do not write flag'
if (isset($data_array['mandatory']) && if (isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
(!isset($_POST[$prfx.$el_name][$i]) || (isset($_POST[$prfx.$el_name][$i]) && empty($_POST[$prfx.$el_name][$i]))) (!isset($_POST[$prfx.$el_name][$i]) || (isset($_POST[$prfx.$el_name][$i]) && empty($_POST[$prfx.$el_name][$i])))
) { ) {
$no_write[$i] = 1; $no_write[$i] = 1;
@@ -1678,7 +1739,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
{ {
$data = array(); $data = array();
$output_name = $this->reference_array[$table_name]['output_name']; $output_name = $this->reference_array[$table_name]['output_name'];
if ($this->reference_array[$table_name]['mandatory']) { if (isset($this->reference_array[$table_name]['mandatory']) &&
$this->reference_array[$table_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
$data['name'] = $this->reference_array[$table_name]['other_table_pk']; $data['name'] = $this->reference_array[$table_name]['other_table_pk'];
@@ -1708,7 +1771,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$data = array(); $data = array();
// output name for the viewable left table td box, prefixed with * if mandatory // output name for the viewable left table td box, prefixed with * if mandatory
$output_name = $this->element_list[$table_name]['output_name']; $output_name = $this->element_list[$table_name]['output_name'];
if (isset($this->element_list[$table_name]['mandatory'])) { if (isset($this->element_list[$table_name]['mandatory']) &&
$this->element_list[$table_name]['mandatory']
) {
$output_name .= ' *'; $output_name .= ' *';
} }
// delete button name, if there is one set // delete button name, if there is one set
@@ -1789,7 +1854,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if ($this->error) { if ($this->error) {
if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) { if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) {
// this is for the new line // this is for the new line
$proto[$el_name] = $_POST[$el_name][(count($_POST[$el_name]) - 1)]; $proto[$el_name] = isset($_POST[$el_name][(count($_POST[$el_name]) - 1)]) ? $_POST[$el_name][(count($_POST[$el_name]) - 1)] : 0;
} else { } else {
$proto[$el_name] = 0; $proto[$el_name] = 0;
} }

View File

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

View File

@@ -22,22 +22,413 @@ use SmartyBC;
class SmartyExtend extends SmartyBC class SmartyExtend extends SmartyBC
{ {
// internal translation engine
public $l10n; public $l10n;
// lang & encoding
public $lang_dir = '';
public $lang;
public $lang_short;
public $encoding;
// page name
public $page_name;
// array for data parsing
public $HEADER = array();
public $DATA = array();
public $DEBUG_DATA = array();
private $CONTENT_DATA = array();
// control vars
public $USE_PROTOTYPE = USE_PROTOTYPE;
public $USE_JQUERY = USE_JQUERY;
public $USE_SCRIPTACULOUS = USE_SCRIPTACULOUS;
// sub content input vars
public $USE_TINY_MCE = false;
public $JS_DATEPICKR = false;
public $JS_FLATPICKR = false;
public $DEBUG_TMPL = false;
public $USE_INCLUDE_TEMPLATE = false;
// cache & compile
public $CACHE_ID = '';
public $COMPILE_ID = '';
// template vars
public $MASTER_TEMPLATE_NAME;
public $PAGE_FILE_NAME;
public $CONTENT_INCLUDE;
public $FORM_NAME;
public $FORM_ACTION;
public $L_TITLE;
public $PAGE_WIDTH;
// smarty include/set var
public $TEMPLATE_PATH;
public $TEMPLATE_NAME;
public $INC_TEMPLATE_NAME;
public $JS_TEMPLATE_NAME;
public $CSS_TEMPLATE_NAME;
public $TEMPLATE_TRANSLATE;
// local names
public $JS_SPECIAL_TEMPLATE_NAME = '';
public $CSS_SPECIAL_TEMPLATE_NAME = '';
public $JS_INCLUDE;
public $CSS_INCLUDE;
public $JS_SPECIAL_INCLUDE;
public $CSS_SPECIAL_INCLUDE;
public $ADMIN_JAVASCRIPT;
public $ADMIN_STYLESHEET;
public $FRONTEND_JAVASCRIPT;
public $FRONTEND_STYLESHEET;
// other smarty folder vars
public $INCLUDES;
public $JAVASCRIPT;
public $CSS;
public $PICTURES;
public $CACHE_PICTURES;
public $CACHE_PICTURES_ROOT;
// constructor class, just sets the language stuff // constructor class, just sets the language stuff
/** /**
* constructor class, just sets the language stuff * constructor class, just sets the language stuff
* calls L10 for pass on internaly in smarty * calls L10 for pass on internaly in smarty
* also registers the getvar caller pliugin * also registers the getvar caller plugin
* @param string $lang language string to set
*/ */
public function __construct(string $lang) public function __construct()
{ {
// call basic smarty
parent::__construct(); parent::__construct();
$this->l10n = new \CoreLibs\Language\L10n($lang); // set lang vars
$this->setLangEncoding();
// iinit lang
$this->l10n = new \CoreLibs\Language\L10n($this->lang);
// variable variable register // variable variable register
// $this->register_modifier('getvar', array(&$this, 'get_template_vars')); // $this->register_modifier('getvar', array(&$this, 'get_template_vars'));
$this->registerPlugin('modifier', 'getvar', array(&$this, 'get_template_vars')); $this->registerPlugin('modifier', 'getvar', array(&$this, 'get_template_vars'));
$this->page_name = pathinfo($_SERVER["PHP_SELF"])['basename'];
// set internal settings
$this->CACHE_ID = defined('CACHE_ID') ? CACHE_ID : '';
$this->COMPILE_ID = defined('COMPILE_ID') ? COMPILE_ID : '';
}
/**
* ORIGINAL in \CoreLibs\Admin\Backend
* set the language encoding and language settings
* the default charset from _SESSION login or from
* config DEFAULT ENCODING
* the lang full name for mo loading from _SESSION login
* or SITE LANG or DEFAULT LANG from config
* creates short lang (only first two chars) from the lang
* @return void
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE.INCLUDES.LANG.CONTENT_PATH;
}
/**
* sets all internal paths and names that need to be passed on to the smarty template
* @return void
*/
public function setSmartyPaths(): void
{
// master template
if (!isset($this->MASTER_TEMPLATE_NAME)) {
$this->MASTER_TEMPLATE_NAME = MASTER_TEMPLATE_NAME;
}
// set include & template names
if (!isset($this->CONTENT_INCLUDE)) {
$this->CONTENT_INCLUDE = str_replace('.php', '', $this->page_name).'.tpl';
}
// strip tpl and replace it with php
// php include file per page
$this->INC_TEMPLATE_NAME = str_replace('.tpl', '.php', $this->CONTENT_INCLUDE);
// javascript include per page
$this->JS_TEMPLATE_NAME = str_replace('.tpl', '.js', $this->CONTENT_INCLUDE);
// css per page
$this->CSS_TEMPLATE_NAME = str_replace('.tpl', '.css', $this->CONTENT_INCLUDE);
// set basic template path (tmp)
$this->INCLUDES = BASE.INCLUDES; // no longer in templates, only global
$this->TEMPLATE_PATH = BASE.INCLUDES.TEMPLATES.CONTENT_PATH;
$this->setTemplateDir($this->TEMPLATE_PATH);
$this->JAVASCRIPT = LAYOUT.JS;
$this->CSS = LAYOUT.CSS;
$this->PICTURES = LAYOUT.IMAGES;
$this->CACHE_PICTURES = LAYOUT.CACHE;
$this->CACHE_PICTURES_ROOT = ROOT.$this->CACHE_PICTURES;
// check if we have an external file with the template name
if (file_exists($this->INCLUDES.$this->INC_TEMPLATE_NAME) &&
is_file($this->INCLUDES.$this->INC_TEMPLATE_NAME)
) {
include($this->INCLUDES.$this->INC_TEMPLATE_NAME);
}
// check for template include
if ($this->USE_INCLUDE_TEMPLATE === true &&
!$this->TEMPLATE_NAME
) {
$this->TEMPLATE_NAME = $this->CONTENT_INCLUDE;
// add to cache & compile id
$this->COMPILE_ID .= '_'.$this->TEMPLATE_NAME;
$this->CACHE_ID .= '_'.$this->TEMPLATE_NAME;
}
// additional per page Javascript include
$this->JS_INCLUDE = '';
if (file_exists($this->JAVASCRIPT.$this->JS_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT.$this->JS_TEMPLATE_NAME)
) {
$this->JS_INCLUDE = $this->JAVASCRIPT.$this->JS_TEMPLATE_NAME;
}
// per page css file
$this->CSS_INCLUDE = '';
if (file_exists($this->CSS.$this->CSS_TEMPLATE_NAME) &&
is_file($this->CSS.$this->CSS_TEMPLATE_NAME)
) {
$this->CSS_INCLUDE = $this->CSS.$this->CSS_TEMPLATE_NAME;
}
// optional CSS file
$this->CSS_SPECIAL_INCLUDE = '';
if (file_exists($this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME)
) {
$this->CSS_SPECIAL_INCLUDE = $this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME;
}
// optional JS file
$this->JS_SPECIAL_INCLUDE = '';
if (file_exists($this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME)
) {
$this->JS_SPECIAL_INCLUDE = $this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME;
}
// check if template names exist
if (!$this->MASTER_TEMPLATE_NAME) {
exit('MASTER TEMPLATE is not set');
} elseif (!file_exists($this->getTemplateDir()[0].DS.$this->MASTER_TEMPLATE_NAME)) {
// abort if master template could not be found
exit('MASTER TEMPLATE: '.$this->MASTER_TEMPLATE_NAME.' could not be found');
}
if ($this->TEMPLATE_NAME &&
!file_exists($this->getTemplateDir()[0].DS.$this->TEMPLATE_NAME)
) {
exit('INCLUDE TEMPLATE: '.$this->TEMPLATE_NAME.' could not be found');
}
// javascript translate data as template for auto translate
if (empty($this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = 'jsTranslate_'.$this->lang.'.tpl';
} else {
// we assume we have some fixed set
// we must add _<$this->lang>
// if .tpl, put before .tpl
// if not .tpl, add _<$this->lang>.tpl
if (strpos($this->TEMPLATE_TRANSLATE, '.tpl')) {
$this->TEMPLATE_TRANSLATE = str_replace('.tpl', '_'.$this->lang.'.tpl', $this->TEMPLATE_TRANSLATE);
} else {
$this->TEMPLATE_TRANSLATE .= '_'.$this->lang.'.tpl';
}
}
// if we can't find it, dump it
if (!file_exists($this->getTemplateDir()[0].DS.$this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = null;
}
}
/**
* wrapper call for setSmartyVars
* this is for frontend type and will not set any only admin needed variables
* @return void
*/
public function setSmartyVarsFrontend(): void
{
$this->setSmartyVars();
}
/**
* wrapper call for setSmartyVars
* this is only for admin interface and will set additional variables
*/
public function setSmartyVarsAdmin(): void
{
$this->setSmartyVars(true);
}
/**
* set smarty pass on variables, sub template names and finally calls the smarty parser
* @param boolean $admin_call default false, will set admin only variables
* @return void
*/
private function setSmartyVars($admin_call = false): void
{
global $cms;
$this->mergeCmsSmartyVars($cms);
// trigger flags
$this->HEADER['USE_PROTOTYPE'] = $this->USE_PROTOTYPE;
// scriptacolous, can only be used with prototype
if ($this->HEADER['USE_PROTOTYPE']) {
$this->HEADER['USE_SCRIPTACULOUS'] = $this->USE_SCRIPTACULOUS;
}
// jquery and prototype should not be used together
$this->HEADER['USE_JQUERY'] = $this->USE_JQUERY;
// additional per page Javascript include
$this->JS_INCLUDE = '';
if (file_exists($this->JAVASCRIPT.$this->JS_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT.$this->JS_TEMPLATE_NAME)
) {
$this->JS_INCLUDE = $this->JAVASCRIPT.$this->JS_TEMPLATE_NAME;
}
// per page css file
$this->CSS_INCLUDE = '';
if (file_exists($this->CSS.$this->CSS_TEMPLATE_NAME) &&
is_file($this->CSS.$this->CSS_TEMPLATE_NAME)
) {
$this->CSS_INCLUDE = $this->CSS.$this->CSS_TEMPLATE_NAME;
}
// optional CSS file
$this->CSS_SPECIAL_INCLUDE = '';
if (file_exists($this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME)
) {
$this->CSS_SPECIAL_INCLUDE = $this->CSS.$this->CSS_SPECIAL_TEMPLATE_NAME;
}
// optional JS file
$this->JS_SPECIAL_INCLUDE = '';
if (file_exists($this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME)
) {
$this->JS_SPECIAL_INCLUDE = $this->JAVASCRIPT.$this->JS_SPECIAL_TEMPLATE_NAME;
}
// the actual include files for javascript (per page)
$this->HEADER['JS_INCLUDE'] = $this->JS_INCLUDE;
$this->HEADER['CSS_INCLUDE'] = $this->CSS_INCLUDE;
$this->HEADER['CSS_SPECIAL_INCLUDE'] = $this->CSS_SPECIAL_INCLUDE;
$this->HEADER['JS_SPECIAL_INCLUDE'] = $this->JS_SPECIAL_INCLUDE;
// paths to the files
$this->DATA['includes'] = $this->INCLUDES;
$this->DATA['js'] = $this->JAVASCRIPT;
$this->DATA['css'] = $this->CSS;
$this->DATA['pictures'] = $this->PICTURES;
// default CMS settings
// define all needed smarty stuff for the general HTML/page building
$this->HEADER['CSS'] = CSS;
$this->HEADER['JS'] = JS;
$this->HEADER['ENCODING'] = $this->encoding;
$this->HEADER['DEFAULT_ENCODING'] = DEFAULT_ENCODING;
// special for admin
if ($admin_call === true) {
// set ACL extra show
$this->DATA['show_ea_extra'] = isset($cms->acl['show_ea_extra']) ? $cms->acl['show_ea_extra'] : false;
$this->DATA['ADMIN'] = !empty($cms->acl['admin']) ? $cms->acl['admin'] : 0;
// set style sheets
$this->HEADER['STYLESHEET'] = $this->ADMIN_STYLESHEET ? $this->ADMIN_STYLESHEET : ADMIN_STYLESHEET;
$this->HEADER['JAVASCRIPT'] = $this->ADMIN_JAVASCRIPT ? $this->ADMIN_JAVASCRIPT : ADMIN_JAVASCRIPT;
// top menu
$this->DATA['nav_menu'] = $cms->adbTopMenu();
$this->DATA['nav_menu_count'] = is_array($this->DATA['nav_menu']) ? count($this->DATA['nav_menu']) : 0;
// messages = array('msg' =>, 'class' => 'error/warning/...')
$this->DATA['messages'] = isset($cms->messages) ? $cms->messages : $cms->messages;
// the page name
$this->DATA['page_name'] = $this->page_name;
$this->DATA['table_width'] = isset($this->PAGE_WIDTH) ? $this->PAGE_WIDTH : PAGE_WIDTH;
// for tinymce special
$this->DATA['TINYMCE_LANG'] = $this->lang_short;
// include flags
$this->DATA['USE_TINY_MCE'] = $this->USE_TINY_MCE;
// debug data, if DEBUG flag is on, this data is print out
$this->DEBUG_DATA['DEBUG'] = $this->DEBUG_TMPL;
} else {
$this->HEADER['STYLESHEET'] = $this->FRONTEND_STYLESHEET ? $this->FRONTEND_STYLESHEET : STYLESHEET;
$this->HEADER['JAVASCRIPT'] = $this->FRONTEND_JAVASCRIPT ? $this->FRONTEND_JAVASCRIPT : JAVASCRIPT;
}
// html title
// set local page title
$this->HEADER['HTML_TITLE'] = !$this->L_TITLE ?
ucfirst(str_replace('_', ' ', $cms->getPageName(1))).(defined(G_TITLE) ? ' - '.$this->l10n->__(G_TITLE) : '') :
$this->l10n->__($this->L_TITLE);
// LANG
$this->DATA['LANG'] = $this->lang;
// form name
$this->DATA['FORM_NAME'] = !$this->FORM_NAME ?
str_replace('.php', '', $this->page_name) :
$this->FORM_NAME;
$this->DATA['FORM_ACTION'] = $this->FORM_ACTION;
// include flags
$this->DATA['JS_DATEPICKR'] = $this->JS_DATEPICKR;
$this->DATA['JS_FLATPICKR'] = $this->JS_FLATPICKR;
// user name
$this->DATA['USER_NAME'] = !empty($_SESSION['USER_NAME']) ? $_SESSION['USER_NAME'] : '';
// the template part to include into the body
$this->DATA['TEMPLATE_NAME'] = $this->TEMPLATE_NAME;
$this->DATA['CONTENT_INCLUDE'] = $this->CONTENT_INCLUDE;
$this->DATA['TEMPLATE_TRANSLATE'] = isset($this->TEMPLATE_TRANSLATE) ? $this->TEMPLATE_TRANSLATE : null;
$this->DATA['PAGE_FILE_NAME'] = str_replace('.php', '', $this->page_name).'.tpl';
// render page
$this->renderSmarty();
}
/**
* merge outside object HEADER/DATA/DEBUG_DATA vars into the smarty class
* @param object $cms object that has header/data/debug_data
* @return void
*/
public function mergeCmsSmartyVars(object $cms): void
{
// array merge HEADER, DATA, DEBUG DATA
foreach (array('HEADER', 'DATA', 'DEBUG_DATA') as $ext_smarty) {
if (is_array($cms->{$ext_smarty})) {
$this->{$ext_smarty} = array_merge($this->{$ext_smarty}, $cms->{$ext_smarty});
}
}
}
/**
* render smarty data (can be called sepparate)
* @return void
*/
public function renderSmarty(): void
{
// create main data array
$this->CONTENT_DATA = array_merge($this->HEADER, $this->DATA, $this->DEBUG_DATA);
// data is 1:1 mapping (all vars, values, etc)
foreach ($this->CONTENT_DATA as $key => $value) {
$this->assign($key, $value);
}
if (is_dir(BASE.TEMPLATES_C)) {
$this->setCompileDir(BASE.TEMPLATES_C);
}
if (is_dir(BASE.CACHE)) {
$this->setCacheDir(BASE.CACHE);
}
$this->display(
$this->MASTER_TEMPLATE_NAME,
$this->CACHE_ID.($this->CACHE_ID ? '_' : '').$this->lang,
$this->COMPILE_ID.($this->COMPILE_ID ? '_' : '').$this->lang
);
} }
} }