Compare commits

...

117 Commits

Author SHA1 Message Date
Clemens Schwaighofer
40e6444c2a CoreLibs update 2026-01-06 18:22:17 +09:00
Clemens Schwaighofer
4b015505ff admin libs update 2025-06-05 18:13:10 +09:00
Clemens Schwaighofer
e90387c1fc Composer update 2025-05-15 15:35:13 +09:00
Clemens Schwaighofer
3fb7169531 CoreLibs update 2025-01-16 10:25:19 +09:00
Clemens Schwaighofer
e4dd73d0e9 Composer package update 2024-12-18 10:38:34 +09:00
Clemens Schwaighofer
e71c53b887 Composer package update 2024-12-13 10:48:28 +09:00
Clemens Schwaighofer
16addc4f4b CoreLibs version update 2024-12-05 14:06:44 +09:00
Clemens Schwaighofer
7e845d3954 v9.22.0 update 2024-12-03 13:29:31 +09:00
Clemens Schwaighofer
6fcb7a44e0 Composer corelibs update 2024-11-27 14:36:02 +09:00
Clemens Schwaighofer
e82e4f6079 Admin pages update 2024-11-27 14:35:30 +09:00
Clemens Schwaighofer
231897cf5b phpstan 2.0 update 2024-11-18 18:33:45 +09:00
Clemens Schwaighofer
17da804073 Composer package update 2024-11-18 14:55:46 +09:00
Clemens Schwaighofer
96ad4b0f48 Update admin pages 2024-11-06 13:33:25 +09:00
Clemens Schwaighofer
1386afb552 Composer git pull update 2024-11-06 10:47:54 +09:00
Clemens Schwaighofer
86a9ad8789 Admin pages updates 2024-10-16 14:13:17 +09:00
Clemens Schwaighofer
0c4c018ffa Composer update 2024-09-20 13:39:21 +09:00
Clemens Schwaighofer
8b36807a2e admin files updates 2024-09-20 13:39:00 +09:00
Clemens Schwaighofer
8daef88e5e Composer dev update 2024-09-03 12:09:22 +09:00
Clemens Schwaighofer
a59fa7a2c9 Admin tests update 2024-09-03 12:08:37 +09:00
Clemens Schwaighofer
14c8197a7f Composer update 2024-08-05 13:27:37 +09:00
Clemens Schwaighofer
79bd7fa256 admin class test pages fixes 2024-08-05 13:07:52 +09:00
Clemens Schwaighofer
9ba09b22f5 Class test php udpate 2024-07-29 16:00:19 +09:00
Clemens Schwaighofer
e88ad00d7f Corelibs composer update 2024-05-22 10:54:29 +09:00
Clemens Schwaighofer
9b80fde0d7 Remove composer vendor 2024-05-22 10:54:10 +09:00
Clemens Schwaighofer
f99e8bb70c admin updates 2024-05-22 10:52:28 +09:00
Clemens Schwaighofer
b48894d000 Composer update 2024-03-21 12:41:50 +09:00
Clemens Schwaighofer
5ebe7dc06c Code updates 2024-03-07 15:02:25 +09:00
Clemens Schwaighofer
2e6b7b2f5b Composer basic updates 2024-03-06 18:27:39 +09:00
Clemens Schwaighofer
897406456a admin updates 2023-11-29 10:47:55 +09:00
Clemens Schwaighofer
edb0620308 admin files updates 2023-10-31 10:22:44 +09:00
Clemens Schwaighofer
90edcbf8c8 Admin pages updates 2023-10-16 16:11:34 +09:00
Clemens Schwaighofer
40f267f3dd composer update 2023-10-12 17:15:28 +09:00
Clemens Schwaighofer
c8aee19deb composer local test update 2023-09-15 18:23:25 +09:00
Clemens Schwaighofer
74c8b8d71e CoreLibs update 2023-09-11 13:40:26 +09:00
Clemens Schwaighofer
c0db3be770 Composer libs update 2023-09-01 18:36:22 +09:00
Clemens Schwaighofer
e74bd04d6f Composer updates 2023-08-28 09:54:33 +09:00
Clemens Schwaighofer
3662b1ab1b Composer updates 2023-07-14 15:11:43 +09:00
Clemens Schwaighofer
7abce87653 composer test update 2023-07-04 12:56:10 +09:00
Clemens Schwaighofer
b3e35b5d94 CoreLibs updates 2023-06-16 13:25:07 +09:00
Clemens Schwaighofer
6429b77bda class_test calls 2023-06-16 13:19:16 +09:00
Clemens Schwaighofer
3c8bdab8fa CoreLibs update 2023-06-05 18:33:54 +09:00
Clemens Schwaighofer
3cf6fee548 Bug fixes and updates 2023-06-01 08:48:28 +09:00
Clemens Schwaighofer
f5a9757ae3 composer test update 2023-05-31 16:43:30 +09:00
Clemens Schwaighofer
3d6b461b20 composer update, composer corelibs update, admin pages update 2023-05-31 16:17:14 +09:00
Clemens Schwaighofer
513b115d57 Composer update 2023-05-30 18:31:24 +09:00
Clemens Schwaighofer
eb16f433e8 Composer updates 2023-05-24 15:54:53 +09:00
Clemens Schwaighofer
8f94201478 admin files updates 2023-05-18 15:18:57 +09:00
Clemens Schwaighofer
1b2359a934 Commposer update 2023-05-18 15:18:09 +09:00
Clemens Schwaighofer
d6187005f4 Composer update 2023-04-26 15:41:39 +09:00
Clemens Schwaighofer
f0e6b5b8e9 Composer package update 2023-04-26 14:45:48 +09:00
Clemens Schwaighofer
6b400978ac ComposerLib update 2023-04-11 11:02:26 +09:00
Clemens Schwaighofer
2754a718fa Composer test upgrades 2023-04-10 14:36:37 +09:00
Clemens Schwaighofer
37c3b6afeb Update corelibs for composer test 2023-04-10 09:05:07 +09:00
Clemens Schwaighofer
516b11f2f1 Composer test update 2023-04-03 15:05:22 +09:00
Clemens Schwaighofer
75a42558fd CoreLibs update v8.1.2 2023-03-29 10:02:20 +09:00
Clemens Schwaighofer
48271a8659 Composer update 2023-03-28 16:48:36 +09:00
Clemens Schwaighofer
35d3032df5 CoreLibs DB\IO params methods 2023-03-28 15:39:13 +09:00
Clemens Schwaighofer
7be8bb06c9 CoreLibs update 2023-03-13 09:30:32 +09:00
Clemens Schwaighofer
2aab94a842 CoreLibs composer v8.0.5 update test 2023-03-10 15:29:38 +09:00
Clemens Schwaighofer
1cbe4e5c06 Composer CoreLibs update 2023-03-09 17:00:10 +09:00
Clemens Schwaighofer
137fb9a986 Composer path composer packages update 2023-02-28 18:08:57 +09:00
Clemens Schwaighofer
e1357f5d39 Composer install updates 2023-02-28 12:06:28 +09:00
Clemens Schwaighofer
8766d4db77 Reinstall smarty with fixed autoloader 2023-02-17 13:01:41 +09:00
Clemens Schwaighofer
b696338324 Install Smarty Composer package 2023-02-17 11:23:53 +09:00
Clemens Schwaighofer
43e66edfd1 Composer installed CoreLibs 2023-02-16 17:13:30 +09:00
Clemens Schwaighofer
0e99700bbe Composer vendor name change 2023-02-16 13:04:20 +09:00
Clemens Schwaighofer
2f0b9fb360 Move Fonts folder from lib to includes 2023-02-16 12:32:15 +09:00
Clemens Schwaighofer
c7cc3c2938 Move all dev tools from www composer to outside master composer 2023-02-13 16:36:51 +09:00
Clemens Schwaighofer
f508b607a6 Add new class for auto set vars to certain types or null
Convert\VarSetType for always return type expected (eg string will be string)
or Convert\VarSetTypeNull to return string or null on failure

The return value for failure if not matching type can be set for both, but
only for Convert\VarSetTypeNull the return value can be set to null.
2023-02-08 12:12:46 +09:00
Clemens Schwaighofer
f94b350ba4 Install phan/phpstan local 2023-02-08 12:02:18 +09:00
Clemens Schwaighofer
53eef03387 Fixes in DB\IO query detection regex
- start with allow whitespace in front
- returning allows more white space types between keyword and parameter list
2023-02-02 10:27:07 +09:00
Clemens Schwaighofer
5a81445a28 DB\IO table match regex fix
UPDATE with SET can have spaces with variable length before
2023-01-27 11:31:26 +09:00
Clemens Schwaighofer
4bbbd653cd DB\IO fix for regex query detection
Fix for basic query detection:
Simeple starts with
SELECT/WITH/SHOW
INSERT INTO/UPDATE/DELETE FROM
UPDATE

Above does no complex query detection, just if the string starts with this

Fix form table detection for primary key auto set trial.
2023-01-27 11:12:46 +09:00
Clemens Schwaighofer
4c28e6d0ec Change DB\IO Returning check regex
Better regex to only get last returning in query, with proper parameter
check
2023-01-26 16:37:22 +09:00
Clemens Schwaighofer
66b7e81463 Bug fix in DB\IO for EOM string build queries with returning
on EOM string build queries it was not checked that RETURNING could have
no space in front.

Fixed and updated test calls
2023-01-25 16:47:31 +09:00
Clemens Schwaighofer
cf58f86802 Remove not needed ?? '' in ACL\Login 2023-01-16 14:29:25 +09:00
Clemens Schwaighofer
ff644310cd Readme file update 2023-01-11 09:22:18 +09:00
Clemens Schwaighofer
58988b9c0f Rename edit schemes pages to schemas 2023-01-11 09:12:56 +09:00
Clemens Schwaighofer
fe75f1d724 Add missing table arrays and name fix schim
missed two table arrays as class EditVisibleGroup and EditAccess

also fix wrong name for EditSchemas (wrong: EditSchemes) with a shim
lookup.

edit_schemes.php file will stay the same for now.
2023-01-11 07:06:28 +09:00
Clemens Schwaighofer
0607cdc3be Add logger $log public entry in Form class
We need that for sub calls to debugger from TableArray loads
2023-01-10 18:19:20 +09:00
Clemens Schwaighofer
6cb14daf49 Move includes/table_arrays to class Output\Form\TableArrays
also remove the legacy edit_base.LEGACY.php file

All previous includes/table_arrays load via include are now moved to a
class system so we have all implemented in one folder and can easy update
and add unit tests to it.
2023-01-10 18:04:29 +09:00
Clemens Schwaighofer
330582f273 Add $this identifier to class in array_edit_users 2023-01-10 16:42:42 +09:00
Clemens Schwaighofer
b0293b52bd Fix edit_users load problem with removed globals
acl_admin/base_acl_leve

Added public access methods to read this when array_* files are included.
2023-01-10 16:01:02 +09:00
Clemens Schwaighofer
00591deb00 Add Check Color class
checks html/css color string for valid
eg, hex #, hex alpha #, rgb/rgba, hsl/hsla
2023-01-10 15:43:33 +09:00
Clemens Schwaighofer
737f70fac5 Fix phpdoc Exception name with missing \ 2023-01-10 14:40:16 +09:00
Clemens Schwaighofer
0328ccd2fe Convert\Colors fixes for from HSB/HSL Hue 360
If hue 360 is given, it is no longer an error but internally converted to 0
2023-01-10 14:07:01 +09:00
Clemens Schwaighofer
eba1e2885f Convert\Byte add exception
And exception is thrown for invalid flags
2023-01-10 14:06:09 +09:00
Clemens Schwaighofer
53813261fb Form\Generate update
- remove auto load _POST vars
- Update color settings to # leading 6/8 digit hex code
- remove any global variable calls/requests
- fix some isset/empty clean ups (isset + set = !empty)
- fix on delete of reference data that loaded data was not shown again
- fix on reference data save error that wrong data is still shown and not removed
2023-01-10 11:25:51 +09:00
Clemens Schwaighofer
df2ae66942 Bug fix for loading after new/save/delete 2023-01-06 15:16:01 +09:00
Clemens Schwaighofer
78e1d73cd9 Move code from edit_base.php to class file 2023-01-06 15:07:15 +09:00
Clemens Schwaighofer
620a5878c1 Update dotenv reader from Composer package 2023-01-06 10:51:12 +09:00
Clemens Schwaighofer
5a0b09a916 Add DB\IO get prepare cursor array entries 2023-01-05 17:26:26 +09:00
Clemens Schwaighofer
98c6033c75 mo to js script set exectueable 2023-01-05 15:31:35 +09:00
Clemens Schwaighofer
6dcebc9b67 mo to js shell script 2023-01-05 15:30:51 +09:00
Clemens Schwaighofer
c97520e186 Update flatpickr javascript lib 2023-01-05 15:14:08 +09:00
Clemens Schwaighofer
764ca1f098 fix Generate\Form test with missing session init 2023-01-05 11:32:39 +09:00
Clemens Schwaighofer
3d23e5b066 Composer update 2023-01-05 10:55:01 +09:00
Clemens Schwaighofer
90e418ba24 Smarty update to 4.3.0 2023-01-05 10:38:51 +09:00
Clemens Schwaighofer
b6a0937e0c autoloader update 2022-12-28 17:46:40 +09:00
Clemens Schwaighofer
b3f6f8ef18 Raname Progressbar.php to ProgressBar.php 2022-12-28 16:14:38 +09:00
Clemens Schwaighofer
d9d5400498 Add Test for get run times for unrun queryies 2022-12-28 11:31:39 +09:00
Clemens Schwaighofer
b1be681afb Bug fix in DB\IO for wrong array check
Did not use empty to check if query called hash entry exists
2022-12-28 11:26:56 +09:00
Clemens Schwaighofer
8ef309d479 PHP unit 8.2, cel builder br/input fix, doctype add, sync .user.ini
- do not sync .user.ini file in sync template
- add PHP 8.2 for test target phpunit
- cel/phfo builder update to not close br or img tags (besides input)
- psalm settings update
- add doctype to all base templates
2022-12-27 16:58:51 +09:00
Clemens Schwaighofer
6e59b63791 DB\IO phpdoc and phpstan fixes 2022-12-14 14:18:33 +09:00
Clemens Schwaighofer
9c7b3cea83 SQL Interface docstring fix 2022-12-14 13:53:54 +09:00
Clemens Schwaighofer
26af6a07f4 PHP unit tests updates for class changes 2022-12-09 16:53:10 +09:00
Clemens Schwaighofer
b7c6d4b478 DB\IO add unescape bytea data 2022-12-09 16:33:58 +09:00
Clemens Schwaighofer
9936fc04da Convert\Byte class fix string in abs call 2022-12-09 16:33:47 +09:00
Clemens Schwaighofer
1e0dfa2106 Update documentation for Convert\Byte Class
add more info in parameters flag
2022-12-09 13:43:15 +09:00
Clemens Schwaighofer
3af6f6a8f0 edit interface, hard set edit.css style sheet 2022-12-07 06:56:47 +09:00
Clemens Schwaighofer
1e793c0d16 Switch all SQL from tab to spaces 2022-12-06 09:27:08 +09:00
Clemens Schwaighofer
5be34453ce Fix in Smarty Template class and PAGE WIDTH set 2022-11-10 10:26:59 +09:00
Clemens Schwaighofer
7773b78e17 Fix in CoreLib Bytes for null to trim 2022-11-09 18:11:14 +09:00
Clemens Schwaighofer
2a3798c8c2 Create mo file update, basic edit css/javascript updates 2022-10-25 16:48:34 +09:00
Clemens Schwaighofer
bc8303fe5f Composer update 2022-10-25 16:48:12 +09:00
Clemens Schwaighofer
ba89b188d9 Mo create script update, phpstan fixes, document updates
create_mo:
set auto base folder bases on current location so we do not need do
adjust paths in script

phpstan fixes:
edit_base.php
CoreLibs/Basci.php
CoreLibs/DB/SQL/PgSQL.php

Update documentation in method headers
CoreLibs/Combined/DateTime.php
2022-10-12 09:48:22 +09:00
Clemens Schwaighofer
d15618cde4 Add JS_TRANSLATE file to smart template flow 2022-10-04 17:35:46 +09:00
2351 changed files with 157436 additions and 138966 deletions

3
.gitignore vendored
View File

@@ -0,0 +1,3 @@
composer.lock
vendor/
.env

View File

@@ -26,6 +26,7 @@
use Phan\Config;
return [
// "target_php_version" => "8.2",
// turn color on (-C)
"color_issue_messages_if_supported" => true,
// If true, missing properties will be created when
@@ -95,7 +96,7 @@ return [
'www/vendor',
'www/tests',
'www/lib/Smarty',
'www/lib/smarty-4.1.0',
'www/lib/smarty-4.3.0',
'www/templates_c',
'www/log',
'www/tmp',
@@ -117,7 +118,9 @@ return [
'www/admin/qq_file_upload_front.php',
'www/admin/qq_file_upload_ajax.php',
// symlink ignore
'www/lib/smarty-4.1.0/libs/Smarty.class.php'
'www/lib/smarty-4.3.0/libs/Smarty.class.php',
// legacy edit base (until removal)
'www/includes/edit_base.LEGACY.php'
],
// what not to show as problem

View File

@@ -1,13 +1,15 @@
#!/usr/bin/env bash
base_folder='/var/www/html/developers/clemens/core_data/php_libraries/trunk/www/';
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
# Assume script is in 4dev/bin
base_folder="${BASE_FOLDER}../../www/";
# locale gettext po to mo translator master
for file in $(ls -1 ${base_folder}../4dev/locale/*.po); do
file=$(basename $file .po);
echo "Translate language ${file}";
locale=$(echo "${file}" | cut -d "-" -f 1);
domain=$(echo "${file}" | cut -d "-" -f 2);
echo "- Translate language file '${file}' for locale '${locale}' and domain '${domain}':";
if [ ! -d "${base_folder}/includes/locale/${locale}/LC_MESSAGES/" ]; then
mkdir -p "${base_folder}/includes/locale/${locale}/LC_MESSAGES/";
fi;

169
4dev/bin/mo_to_js.sh Executable file
View File

@@ -0,0 +1,169 @@
#!/bin/bash
# read source mo files and writes target js files in object form
# check for ARG 1 is "mv"
# then move the files directly and don't do manual check (don't create temp files)
FILE_MOVE=0;
if [ "${1}" = "mv" ]; then
echo "*** Direct write ***";
FILE_MOVE=1;
fi;
target='';
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
# Assume script is in 4dev/bin
base_folder="${BASE_FOLDER}../../www/";
po_folder='../4dev/locale/'
mo_folder='includes/locale/';
target_folder='';
template_file_stump='##SUFFIX##translate-##LANGUAGE##.TMP.js';
# for output file names
source_list=(iw);
language_list=(en ja);
# set target names
if [ "${target}" == '' ]; then
echo "*** Non smarty ***";
TEXTDOMAINDIR=${base_folder}${mo_folder}.
# default is admin
TEXTDOMAIN=admin;
fi;
js_folder="layout/${TEXTDOMAIN}/javascript/";
error=0;
# this checks if the TEXTDOMAIN target actually exists
if [ ! -d "${base_folder}${js_folder}" ]; then
echo "Cannot find target javascript folder ${base_folder}${js_folder}";
error=1;
else
target_folder="${base_folder}${js_folder}";
fi;
if [ ${error} -eq 1 ]; then
exit;
fi;
# locale gettext po to mo translator master
for file in $(ls -1 ${base_folder}../4dev/locale/*.po); do
file=$(basename $file .po);
echo "Translate language ${file}";
locale=$(echo "${file}" | cut -d "-" -f 1);
domain=$(echo "${file}" | cut -d "-" -f 2);
if [ ! -d "${base_folder}/includes/locale/${locale}/LC_MESSAGES/" ]; then
mkdir -p "${base_folder}/includes/locale/${locale}/LC_MESSAGES/";
fi;
msgfmt -o ${base_folder}/includes/locale/${locale}/LC_MESSAGES/${domain}.mo ${base_folder}${po_folder}${locale}-${domain}.po;
done;
rx_msgid_empty="^msgid \"\"";
rx_msgid="^msgid \"";
rx_msgstr="^msgstr \""
# quick copy string at the end
quick_copy='';
for language in ${language_list[*]}; do
# I don't know which one must be set, but I think at least LANGUAGE
case ${language} in
ja)
LANG=ja_JP.UTF-8;
ENCODING=UTF-8;
LANGUAGE=ja;
;;
en)
# was en_JP.UTF-8
LANG=en_US.UTF-8;
ENCODING=UTF-8;
LANGUAGE=en;
;;
esac;
# write only one for language and then symlink files
template_file=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##//" | sed -e "s/##LANGUAGE##/${LANG}/");
original_file=$(echo ${template_file} | sed -e 's/\.TMP//g');
if [ "${FILE_MOVE}" -eq 0 ]; then
file=${target_folder}${template_file};
else
file=${target_folder}${original_file};
fi;
echo "===> Write translation file ${file}";
echo ". = normal, : = escape, x = skip";
# init line [aka don't touch this file]
echo "// AUTO FILL, changes will be overwritten" > $file;
echo "// source: ${suffix}, language: ${language}" >> $file;
echo "// Translation strings in the format" >> $file;
echo "// \"Original\":\"Translated\""$'\n' >> $file;
echo "var i18n = {" >> $file;
# translations stuff
# read the po file
pos=0; # do we add a , for the next line
cat "${base_folder}${po_folder}${language}-${TEXTDOMAIN}.po" |
while read str; do
# echo "S: ${str}";
# skip empty
if [[ "${str}" =~ ${rx_msgid_empty} ]]; then
# skip on empty
echo -n "x";
# msgid is left, msgstr is right
elif [[ "${str}" =~ ${rx_msgid} ]]; then
echo -n ".";
# open left side
# TODO: how to handle multi line strings: or don't use them
# extract from between ""
str_source=$(echo "${str}" | sed -e "s/^msgid \"//" | sed -e "s/\"$//");
# close right side, if not last add ,
if [ "${pos}" -eq 1 ]; then
echo -n "," >> $file;
fi;
# all " inside string need to be escaped
str_source=$(echo "${str_source}" | sed -e 's/"/\\"/g');
# fix with proper layout
echo -n "\"$str_source\":\"$(TEXTDOMAINDIR=${TEXTDOMAINDIR} LANGUAGE=${language} LANG=${LANG} gettext ${TEXTDOMAIN} "${str_source}")\"" >> $file;
pos=1;
elif [[ "${str}" =~ ${rx_msgstr} ]]; then
# open right side (ignore)
echo -n "";
else
# general ignore (anything between or comments)
echo -n "";
fi;
done;
echo "" >> $file;
echo "};" >> $file;
echo " [DONE]";
# on no move
if [ "${FILE_MOVE}" -eq 0 ]; then
echo "===> Confirm all changes in ${file} and then move data to original";
echo "";
quick_copy=${quick_copy}"mv ${template_file} ${original_file}"$'\n';
fi;
# symlink to master file
for suffix in ${source_list[*]}; do
# symlink with full lang name
symlink_file[0]=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##/${suffix}_/" | sed -e "s/##LANGUAGE##/${LANG}/" | sed -e 's/\.TMP//g');
# create second one with lang (no country) + encoding
symlink_file[1]=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##/${suffix}_/" | sed -e "s/##LANGUAGE##/${LANGUAGE}\.${ENCODING}/" | sed -e 's/\.TMP//g');
for template_file in ${symlink_file[@]}; do
# if this is not symlink, create them
if [ ! -h "${template_file}" ]; then
echo "Create symlink: ${template_file}";
# symlik to original
cd "${target_folder}";
ln -sf "${original_file}" "${template_file}";
cd - >/dev/null;
fi;
done;
done;
done;
if [ "${FILE_MOVE}" -eq 0 ]; then
echo "";
echo "-- IN FOLDER: ${target_folder}";
echo "-- START: copy lines below to copy created over original --";
echo "${quick_copy}";
echo "-- END ----------------------------------------------------";
fi;
# __END__

View File

@@ -3,7 +3,7 @@ base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
# --testdox
# call with "t" to give verbose testdox output
# SUPPORTED: https://www.php.net/supported-versions.php
# call with 7.3, 7.4, 8.0, 8.1 to force a certain php version
# call with 7.4, 8.0, 8.1 to force a certain php version
opt_testdox="";
if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
@@ -16,6 +16,7 @@ if [ ! -z "${1}" ]; then
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
@@ -25,6 +26,7 @@ if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;

View File

@@ -3,26 +3,26 @@
CREATE OR REPLACE FUNCTION set_edit_access_uid() RETURNS TRIGGER AS
$$
DECLARE
myrec RECORD;
v_uid VARCHAR;
myrec RECORD;
v_uid VARCHAR;
BEGIN
-- skip if NEW.name is not set
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
-- use NEW.name as base, remove all spaces
-- name data is already unique, so we do not need to worry about this here
v_uid := REPLACE(NEW.name, ' ', '');
IF TG_OP = 'INSERT' THEN
-- always set
NEW.uid := v_uid;
ELSIF TG_OP = 'UPDATE' THEN
-- check if not set, then set
SELECT INTO myrec t.* FROM edit_access t WHERE edit_access_id = NEW.edit_access_id;
IF FOUND THEN
NEW.uid := v_uid;
END IF;
END IF;
END IF;
RETURN NEW;
-- skip if NEW.name is not set
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
-- use NEW.name as base, remove all spaces
-- name data is already unique, so we do not need to worry about this here
v_uid := REPLACE(NEW.name, ' ', '');
IF TG_OP = 'INSERT' THEN
-- always set
NEW.uid := v_uid;
ELSIF TG_OP = 'UPDATE' THEN
-- check if not set, then set
SELECT INTO myrec t.* FROM edit_access t WHERE edit_access_id = NEW.edit_access_id;
IF FOUND THEN
NEW.uid := v_uid;
END IF;
END IF;
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -3,26 +3,26 @@
CREATE OR REPLACE FUNCTION set_edit_group_uid() RETURNS TRIGGER AS
$$
DECLARE
myrec RECORD;
v_uid VARCHAR;
myrec RECORD;
v_uid VARCHAR;
BEGIN
-- skip if NEW.name is not set
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
-- use NEW.name as base, remove all spaces
-- name data is already unique, so we do not need to worry about this here
v_uid := REPLACE(NEW.name, ' ', '');
IF TG_OP = 'INSERT' THEN
-- always set
NEW.uid := v_uid;
ELSIF TG_OP = 'UPDATE' THEN
-- check if not set, then set
SELECT INTO myrec t.* FROM edit_group t WHERE edit_group_id = NEW.edit_group_id;
IF FOUND THEN
NEW.uid := v_uid;
END IF;
END IF;
END IF;
RETURN NEW;
-- skip if NEW.name is not set
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
-- use NEW.name as base, remove all spaces
-- name data is already unique, so we do not need to worry about this here
v_uid := REPLACE(NEW.name, ' ', '');
IF TG_OP = 'INSERT' THEN
-- always set
NEW.uid := v_uid;
ELSIF TG_OP = 'UPDATE' THEN
-- check if not set, then set
SELECT INTO myrec t.* FROM edit_group t WHERE edit_group_id = NEW.edit_group_id;
IF FOUND THEN
NEW.uid := v_uid;
END IF;
END IF;
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -9,142 +9,142 @@ CREATE OR REPLACE FUNCTION edit_log_insert_trigger ()
RETURNS TRIGGER AS
$$
DECLARE
start_date DATE := '2010-01-01';
end_date DATE;
timeformat TEXT := 'YYYY';
selector TEXT := 'year';
base_table TEXT := 'edit_log';
_interval INTERVAL := '1 ' || selector;
_interval_next INTERVAL := '2 ' || selector;
table_name TEXT;
-- compare date column
compare_date DATE := NEW.event_date;
compare_date_name TEXT := 'event_date';
-- the create commands
command_create_table TEXT := 'CREATE TABLE IF NOT EXISTS {TABLE_NAME} (CHECK({COMPARE_DATE_NAME} >= {START_DATE} AND {COMPARE_DATE_NAME} < {END_DATE})) INHERITS ({BASE_NAME})';
command_create_primary_key TEXT := 'ALTER TABLE {TABLE_NAME} ADD PRIMARY KEY ({BASE_TABLE}_id)';
command_create_foreign_key_1 TEXT := 'ALTER TABLE {TABLE_NAME} ADD CONSTRAINT {TABLE_NAME}_euid_fkey FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL';
command_create_trigger_1 TEXT = 'CREATE TRIGGER trg_{TABLE_NAME} BEFORE INSERT OR UPDATE ON {TABLE_NAME} FOR EACH ROW EXECUTE PROCEDURE set_edit_generic()';
start_date DATE := '2010-01-01';
end_date DATE;
timeformat TEXT := 'YYYY';
selector TEXT := 'year';
base_table TEXT := 'edit_log';
_interval INTERVAL := '1 ' || selector;
_interval_next INTERVAL := '2 ' || selector;
table_name TEXT;
-- compare date column
compare_date DATE := NEW.event_date;
compare_date_name TEXT := 'event_date';
-- the create commands
command_create_table TEXT := 'CREATE TABLE IF NOT EXISTS {TABLE_NAME} (CHECK({COMPARE_DATE_NAME} >= {START_DATE} AND {COMPARE_DATE_NAME} < {END_DATE})) INHERITS ({BASE_NAME})';
command_create_primary_key TEXT := 'ALTER TABLE {TABLE_NAME} ADD PRIMARY KEY ({BASE_TABLE}_id)';
command_create_foreign_key_1 TEXT := 'ALTER TABLE {TABLE_NAME} ADD CONSTRAINT {TABLE_NAME}_euid_fkey FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL';
command_create_trigger_1 TEXT = 'CREATE TRIGGER trg_{TABLE_NAME} BEFORE INSERT OR UPDATE ON {TABLE_NAME} FOR EACH ROW EXECUTE PROCEDURE set_edit_generic()';
BEGIN
-- we are in valid start time area
IF (NEW.event_date >= start_date) THEN
-- current table name
table_name := base_table || '_' || to_char(NEW.event_date, timeformat);
BEGIN
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
-- if insert failed because of missing table, create new below
EXCEPTION
WHEN undefined_table THEN
-- another block, so in case the creation fails here too
BEGIN
-- create new table here + all indexes
start_date := date_trunc(selector, NEW.event_date);
end_date := date_trunc(selector, NEW.event_date + _interval);
-- creat table
EXECUTE format(REPLACE( -- end date
REPLACE( -- start date
REPLACE( -- compare date name
REPLACE( -- base name (inherit)
REPLACE( -- table name
command_create_table,
'{TABLE_NAME}',
table_name
),
'{BASE_NAME}',
base_table
),
'{COMPARE_DATE_NAME}',
compare_date_name
),
'{START_DATE}',
quote_literal(start_date)
),
'{END_DATE}',
quote_literal(end_date)
));
-- create all indexes and triggers
EXECUTE format(REPLACE(
REPLACE(
command_create_primary_key,
'{TABLE_NAME}',
table_name
),
'{BASE_TABLE}',
base_table
));
-- FK constraints
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
-- generic trigger
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
-- we are in valid start time area
IF (NEW.event_date >= start_date) THEN
-- current table name
table_name := base_table || '_' || to_char(NEW.event_date, timeformat);
BEGIN
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
-- if insert failed because of missing table, create new below
EXCEPTION
WHEN undefined_table THEN
-- another block, so in case the creation fails here too
BEGIN
-- create new table here + all indexes
start_date := date_trunc(selector, NEW.event_date);
end_date := date_trunc(selector, NEW.event_date + _interval);
-- creat table
EXECUTE format(REPLACE( -- end date
REPLACE( -- start date
REPLACE( -- compare date name
REPLACE( -- base name (inherit)
REPLACE( -- table name
command_create_table,
'{TABLE_NAME}',
table_name
),
'{BASE_NAME}',
base_table
),
'{COMPARE_DATE_NAME}',
compare_date_name
),
'{START_DATE}',
quote_literal(start_date)
),
'{END_DATE}',
quote_literal(end_date)
));
-- create all indexes and triggers
EXECUTE format(REPLACE(
REPLACE(
command_create_primary_key,
'{TABLE_NAME}',
table_name
),
'{BASE_TABLE}',
base_table
));
-- FK constraints
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
-- generic trigger
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
-- insert try again
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
EXCEPTION
WHEN OTHERS THEN
-- if this faled, throw it into the overflow table (so we don't loose anything)
INSERT INTO edit_log_overflow VALUES (NEW.*);
END;
-- other errors, insert into overlow
WHEN OTHERS THEN
-- if this faled, throw it into the overflow table (so we don't loose anything)
INSERT INTO edit_log_overflow VALUES (NEW.*);
END;
-- main insert run done, check if we have to create next months table
BEGIN
-- check if next month table exists
table_name := base_table || '_' || to_char((SELECT NEW.event_date + _interval)::DATE, timeformat);
-- RAISE NOTICE 'SEARCH NEXT: %', table_name;
IF (SELECT to_regclass(table_name)) IS NULL THEN
-- move inner interval same
start_date := date_trunc(selector, NEW.event_date + _interval);
end_date := date_trunc(selector, NEW.event_date + _interval_next);
-- RAISE NOTICE 'CREATE NEXT: %', table_name;
-- create table
EXECUTE format(REPLACE( -- end date
REPLACE( -- start date
REPLACE( -- compare date name
REPLACE( -- base name (inherit)
REPLACE( -- table name
command_create_table,
'{TABLE_NAME}',
table_name
),
'{BASE_NAME}',
base_table
),
'{COMPARE_DATE_NAME}',
compare_date_name
),
'{START_DATE}',
quote_literal(start_date)
),
'{END_DATE}',
quote_literal(end_date)
));
-- create all indexes and triggers
EXECUTE format(REPLACE(
REPLACE(
command_create_primary_key,
'{TABLE_NAME}',
table_name
),
'{BASE_TABLE}',
base_table
));
-- FK constraints
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
-- generic trigger
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Failed to create next table: %', table_name;
END;
ELSE
-- if outside valid date, insert into overflow
INSERT INTO edit_log_overflow VALUES (NEW.*);
END IF;
RETURN NULL;
-- insert try again
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
EXCEPTION
WHEN OTHERS THEN
-- if this faled, throw it into the overflow table (so we don't loose anything)
INSERT INTO edit_log_overflow VALUES (NEW.*);
END;
-- other errors, insert into overlow
WHEN OTHERS THEN
-- if this faled, throw it into the overflow table (so we don't loose anything)
INSERT INTO edit_log_overflow VALUES (NEW.*);
END;
-- main insert run done, check if we have to create next months table
BEGIN
-- check if next month table exists
table_name := base_table || '_' || to_char((SELECT NEW.event_date + _interval)::DATE, timeformat);
-- RAISE NOTICE 'SEARCH NEXT: %', table_name;
IF (SELECT to_regclass(table_name)) IS NULL THEN
-- move inner interval same
start_date := date_trunc(selector, NEW.event_date + _interval);
end_date := date_trunc(selector, NEW.event_date + _interval_next);
-- RAISE NOTICE 'CREATE NEXT: %', table_name;
-- create table
EXECUTE format(REPLACE( -- end date
REPLACE( -- start date
REPLACE( -- compare date name
REPLACE( -- base name (inherit)
REPLACE( -- table name
command_create_table,
'{TABLE_NAME}',
table_name
),
'{BASE_NAME}',
base_table
),
'{COMPARE_DATE_NAME}',
compare_date_name
),
'{START_DATE}',
quote_literal(start_date)
),
'{END_DATE}',
quote_literal(end_date)
));
-- create all indexes and triggers
EXECUTE format(REPLACE(
REPLACE(
command_create_primary_key,
'{TABLE_NAME}',
table_name
),
'{BASE_TABLE}',
base_table
));
-- FK constraints
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
-- generic trigger
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Failed to create next table: %', table_name;
END;
ELSE
-- if outside valid date, insert into overflow
INSERT INTO edit_log_overflow VALUES (NEW.*);
END IF;
RETURN NULL;
END
$$
LANGUAGE 'plpgsql';

View File

@@ -5,22 +5,22 @@ CREATE OR REPLACE FUNCTION set_login_user_id_set_date()
RETURNS TRIGGER AS
$$
BEGIN
-- if new is not null/empty
-- and old one is null or old one different new one
-- set NOW()
-- if new one is NULL
-- set NULL
IF
NEW.login_user_id IS NOT NULL AND NEW.login_user_id <> '' AND
(OLD.login_user_id IS NULL OR NEW.login_user_id <> OLD.login_user_id)
THEN
NEW.login_user_id_set_date = NOW();
NEW.login_user_id_last_revalidate = NOW();
ELSIF NEW.login_user_id IS NULL OR NEW.login_user_id = '' THEN
NEW.login_user_id_set_date = NULL;
NEW.login_user_id_last_revalidate = NULL;
END IF;
RETURN NEW;
-- if new is not null/empty
-- and old one is null or old one different new one
-- set NOW()
-- if new one is NULL
-- set NULL
IF
NEW.login_user_id IS NOT NULL AND NEW.login_user_id <> '' AND
(OLD.login_user_id IS NULL OR NEW.login_user_id <> OLD.login_user_id)
THEN
NEW.login_user_id_set_date = NOW();
NEW.login_user_id_last_revalidate = NOW();
ELSIF NEW.login_user_id IS NULL OR NEW.login_user_id = '' THEN
NEW.login_user_id_set_date = NULL;
NEW.login_user_id_last_revalidate = NULL;
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -4,15 +4,15 @@ CREATE FUNCTION random_string(randomLength int)
RETURNS text AS
$$
SELECT array_to_string(
ARRAY(
SELECT substring(
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
trunc(random() * 62)::int + 1,
1
)
FROM generate_series(1, randomLength) AS gs(x)
),
''
ARRAY(
SELECT substring(
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
trunc(random() * 62)::int + 1,
1
)
FROM generate_series(1, randomLength) AS gs(x)
),
''
)
$$
LANGUAGE SQL

View File

@@ -4,12 +4,12 @@ CREATE OR REPLACE FUNCTION set_date()
RETURNS TRIGGER AS
$$
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -4,15 +4,15 @@ CREATE OR REPLACE FUNCTION set_edit_generic()
RETURNS TRIGGER AS
$$
DECLARE
random_length INT = 12; -- that should be long enough
random_length INT = 25; -- that should be long enough
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
NEW.cuid := random_string(random_length);
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
NEW.cuid := random_string(random_length);
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -5,17 +5,17 @@ CREATE OR REPLACE FUNCTION set_generic()
RETURNS TRIGGER AS
$$
DECLARE
random_length INT = 32; -- long for massive data
random_length INT = 32; -- long for massive data
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
IF NEW.uid IS NULL THEN
NEW.uid := random_string(random_length);
END IF;
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
IF TG_OP = 'INSERT' THEN
NEW.date_created := 'now';
IF NEW.uid IS NULL THEN
NEW.uid := random_string(random_length);
END IF;
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := 'now';
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -4,12 +4,12 @@ CREATE OR REPLACE FUNCTION set_uid()
RETURNS TRIGGER AS
$$
DECLARE
random_length INT = 32; -- that should be long enough
random_length INT = 32; -- that should be long enough
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.uid := random_string(random_length);
END IF;
RETURN NEW;
IF TG_OP = 'INSERT' THEN
NEW.uid := random_string(random_length);
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

View File

@@ -6,14 +6,14 @@
-- RETURNS TRIGGER AS
-- $$
-- BEGIN
-- IF TG_OP = 'INSERT' THEN
-- NEW.date_created := clock_timestamp();
-- NEW.user_created := current_user;
-- ELSIF TG_OP = 'UPDATE' THEN
-- NEW.date_updated := clock_timestamp();
-- NEW.user_updated := current_user;
-- END IF;
-- RETURN NEW;
-- IF TG_OP = 'INSERT' THEN
-- NEW.date_created := clock_timestamp();
-- NEW.user_created := current_user;
-- ELSIF TG_OP = 'UPDATE' THEN
-- NEW.date_updated := clock_timestamp();
-- NEW.user_updated := current_user;
-- END IF;
-- RETURN NEW;
-- END;
-- $$
-- LANGUAGE 'plpgsql';

View File

@@ -7,13 +7,13 @@
-- DROP TABLE edit_access;
CREATE TABLE edit_access (
edit_access_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
protected SMALLINT DEFAULT 0,
deleted SMALLINT DEFAULT 0,
uid VARCHAR,
name VARCHAR UNIQUE,
description VARCHAR,
color VARCHAR,
additional_acl JSONB
edit_access_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
protected SMALLINT DEFAULT 0,
deleted SMALLINT DEFAULT 0,
uid VARCHAR,
name VARCHAR UNIQUE,
description VARCHAR,
color VARCHAR,
additional_acl JSONB
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,12 +7,12 @@
-- DROP TABLE edit_access_data;
CREATE TABLE edit_access_data (
edit_access_data_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
value VARCHAR
edit_access_data_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
value VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;
-- create a unique index for each attached data block for each edit access can

View File

@@ -8,9 +8,9 @@
-- DROP TABLE edit_access_right;
CREATE TABLE edit_access_right (
edit_access_right_id SERIAL PRIMARY KEY,
name VARCHAR,
level SMALLINT,
type VARCHAR,
UNIQUE (level,type)
edit_access_right_id SERIAL PRIMARY KEY,
name VARCHAR,
level SMALLINT,
type VARCHAR,
UNIQUE (level,type)
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,13 +7,13 @@
-- DROP TABLE edit_access_user;
CREATE TABLE edit_access_user (
edit_access_user_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_user_id INT NOT NULL,
FOREIGN KEY (edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_default SMALLINT DEFAULT 0,
enabled SMALLINT NOT NULL DEFAULT 0
edit_access_user_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_user_id INT NOT NULL,
FOREIGN KEY (edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_default SMALLINT DEFAULT 0,
enabled SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_generic;
CREATE TABLE edit_generic (
cuid VARCHAR,
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE
cuid VARCHAR,
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE
);

View File

@@ -7,14 +7,14 @@
-- DROP TABLE edit_group;
CREATE TABLE edit_group (
edit_group_id SERIAL PRIMARY KEY,
edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
deleted SMALLINT DEFAULT 0,
uid VARCHAR,
name VARCHAR,
additional_acl JSONB
edit_group_id SERIAL PRIMARY KEY,
edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
deleted SMALLINT DEFAULT 0,
uid VARCHAR,
name VARCHAR,
additional_acl JSONB
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -8,11 +8,11 @@
-- DROP TABLE edit_language;
CREATE TABLE edit_language (
edit_language_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
lang_default SMALLINT NOT NULL DEFAULT 0,
long_name VARCHAR,
short_name VARCHAR, -- en_US, en or en_US@latin without encoding
iso_name VARCHAR, -- should actually be encoding
order_number INT
edit_language_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
lang_default SMALLINT NOT NULL DEFAULT 0,
long_name VARCHAR,
short_name VARCHAR, -- en_US, en or en_US@latin without encoding
iso_name VARCHAR, -- should actually be encoding
order_number INT
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,35 +7,35 @@
-- DROP TABLE edit_log;
CREATE TABLE edit_log (
edit_log_id SERIAL PRIMARY KEY,
euid INT, -- this is a foreign key, but I don't nedd to reference to it
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
username VARCHAR,
password VARCHAR,
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
ip VARCHAR,
error TEXT,
event TEXT,
data_binary BYTEA,
data TEXT,
page VARCHAR,
action VARCHAR,
action_id VARCHAR,
action_yes VARCHAR,
action_flag VARCHAR,
action_menu VARCHAR,
action_loaded VARCHAR,
action_value VARCHAR,
action_type VARCHAR,
action_error VARCHAR,
user_agent VARCHAR,
referer VARCHAR,
script_name VARCHAR,
query_string VARCHAR,
server_name VARCHAR,
http_host VARCHAR,
http_accept VARCHAR,
http_accept_charset VARCHAR,
http_accept_encoding VARCHAR,
session_id VARCHAR
edit_log_id SERIAL PRIMARY KEY,
euid INT, -- this is a foreign key, but I don't nedd to reference to it
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
username VARCHAR,
password VARCHAR,
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
ip VARCHAR,
error TEXT,
event TEXT,
data_binary BYTEA,
data TEXT,
page VARCHAR,
action VARCHAR,
action_id VARCHAR,
action_yes VARCHAR,
action_flag VARCHAR,
action_menu VARCHAR,
action_loaded VARCHAR,
action_value VARCHAR,
action_type VARCHAR,
action_error VARCHAR,
user_agent VARCHAR,
referer VARCHAR,
script_name VARCHAR,
query_string VARCHAR,
server_name VARCHAR,
http_host VARCHAR,
http_accept VARCHAR,
http_accept_charset VARCHAR,
http_accept_encoding VARCHAR,
session_id VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,10 +7,10 @@
-- DROP TABLE edit_menu_group;
CREATE TABLE edit_menu_group (
edit_menu_group_id SERIAL PRIMARY KEY,
name VARCHAR,
flag VARCHAR,
order_number INT NOT NULL
edit_menu_group_id SERIAL PRIMARY KEY,
name VARCHAR,
flag VARCHAR,
order_number INT NOT NULL
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,16 +7,16 @@
-- DROP TABLE edit_page;
CREATE TABLE edit_page (
edit_page_id SERIAL PRIMARY KEY,
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
filename VARCHAR,
name VARCHAR UNIQUE,
order_number INT NOT NULL,
online SMALLINT NOT NULL DEFAULT 0,
menu SMALLINT NOT NULL DEFAULT 0,
popup SMALLINT NOT NULL DEFAULT 0,
popup_x SMALLINT,
popup_y SMALLINT,
hostname VARCHAR
edit_page_id SERIAL PRIMARY KEY,
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
filename VARCHAR,
name VARCHAR UNIQUE,
order_number INT NOT NULL,
online SMALLINT NOT NULL DEFAULT 0,
menu SMALLINT NOT NULL DEFAULT 0,
popup SMALLINT NOT NULL DEFAULT 0,
popup_x SMALLINT,
popup_y SMALLINT,
hostname VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,14 +7,14 @@
-- DROP TABLE edit_page_access;
CREATE TABLE edit_page_access (
edit_page_access_id SERIAL PRIMARY KEY,
edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0
edit_page_access_id SERIAL PRIMARY KEY,
edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -8,13 +8,13 @@
-- DROP TABLE edit_page_content;
CREATE TABLE edit_page_content (
edit_page_content_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
uid VARCHAR UNIQUE,
name VARCHAR,
order_number INT NOT NULL,
online SMALLINT NOT NULL DEFAULT 0
edit_page_content_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
uid VARCHAR UNIQUE,
name VARCHAR,
order_number INT NOT NULL,
online SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,8 +7,8 @@
-- DROP TABLE edit_page_menu_group;
CREATE TABLE edit_page_menu_group (
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_menu_group_id INT NOT NULL,
FOREIGN KEY (edit_menu_group_id) REFERENCES edit_menu_group (edit_menu_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_menu_group_id INT NOT NULL,
FOREIGN KEY (edit_menu_group_id) REFERENCES edit_menu_group (edit_menu_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
);

View File

@@ -7,8 +7,8 @@
-- DROP TABLE edit_page_visible_group;
CREATE TABLE edit_page_visible_group (
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_visible_group_id INT NOT NULL,
FOREIGN KEY (edit_visible_group_id) REFERENCES edit_visible_group (edit_visible_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_visible_group_id INT NOT NULL,
FOREIGN KEY (edit_visible_group_id) REFERENCES edit_visible_group (edit_visible_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
);

View File

@@ -7,11 +7,11 @@
-- DROP TABLE edit_query_string;
CREATE TABLE edit_query_string (
edit_query_string_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
value VARCHAR,
dynamic SMALLINT NOT NULL DEFAULT 0
edit_query_string_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
value VARCHAR,
dynamic SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,10 +7,10 @@
-- DROP TABLE edit_scheme;
CREATE TABLE edit_scheme (
edit_scheme_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
header_color VARCHAR,
css_file VARCHAR,
template VARCHAR
edit_scheme_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR,
header_color VARCHAR,
css_file VARCHAR,
template VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,6 +7,6 @@
-- DROP TABLE temp_files;
CREATE TABLE temp_files (
filename VARCHAR,
folder VARCHAR
filename VARCHAR,
folder VARCHAR
);

View File

@@ -7,63 +7,63 @@
-- DROP TABLE edit_user;
CREATE TABLE edit_user (
edit_user_id SERIAL PRIMARY KEY,
connect_edit_user_id INT, -- possible reference to other user
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_language_id INT NOT NULL,
FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
-- username/password
username VARCHAR UNIQUE,
password VARCHAR,
-- name block
first_name VARCHAR,
last_name VARCHAR,
first_name_furigana VARCHAR,
last_name_furigana VARCHAR,
-- email
email VARCHAR,
-- eanbled/deleted flag
enabled SMALLINT NOT NULL DEFAULT 0,
deleted SMALLINT NOT NULL DEFAULT 0,
-- general flags
strict SMALLINT DEFAULT 0,
locked SMALLINT DEFAULT 0,
protected SMALLINT NOT NULL DEFAULT 0,
-- legacy, debug flags
debug SMALLINT NOT NULL DEFAULT 0,
db_debug SMALLINT NOT NULL DEFAULT 0,
-- is admin user
admin SMALLINT NOT NULL DEFAULT 0,
-- last login log
last_login TIMESTAMP WITHOUT TIME ZONE,
-- login error
login_error_count INT DEFAULT 0,
login_error_date_last TIMESTAMP WITHOUT TIME ZONE,
login_error_date_first TIMESTAMP WITHOUT TIME ZONE,
-- time locked
lock_until TIMESTAMP WITHOUT TIME ZONE,
lock_after TIMESTAMP WITHOUT TIME ZONE,
-- password change
password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed
password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval
password_reset_time TIMESTAMP WITHOUT TIME ZONE, -- when the password reset was requested
password_reset_uid VARCHAR, -- the uid to access the password reset page
-- _GET login id for direct login
login_user_id VARCHAR UNIQUE, -- the loginUserId, at least 32 chars
login_user_id_set_date TIMESTAMP WITHOUT TIME ZONE, -- when above uid was set
login_user_id_last_revalidate TIMESTAMP WITHOUT TIME ZONE, -- when the last login was done with user name and password
login_user_id_valid_from TIMESTAMP WITHOUT TIME ZONE, -- if set, from when the above uid is valid
login_user_id_valid_until TIMESTAMP WITHOUT TIME ZONE, -- if set, until when the above uid is valid
login_user_id_revalidate_after INTERVAL, -- user must login to revalidated loginUserId after set days, 0 for forever
login_user_id_locked SMALLINT DEFAULT 0, -- lock for loginUserId, but still allow normal login
-- additional ACL json block
additional_acl JSONB -- additional ACL as JSON string (can be set by other pages)
edit_user_id SERIAL PRIMARY KEY,
connect_edit_user_id INT, -- possible reference to other user
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_language_id INT NOT NULL,
FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL,
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
-- username/password
username VARCHAR UNIQUE,
password VARCHAR,
-- name block
first_name VARCHAR,
last_name VARCHAR,
first_name_furigana VARCHAR,
last_name_furigana VARCHAR,
-- email
email VARCHAR,
-- eanbled/deleted flag
enabled SMALLINT NOT NULL DEFAULT 0,
deleted SMALLINT NOT NULL DEFAULT 0,
-- general flags
strict SMALLINT DEFAULT 0,
locked SMALLINT DEFAULT 0,
protected SMALLINT NOT NULL DEFAULT 0,
-- legacy, debug flags
debug SMALLINT NOT NULL DEFAULT 0,
db_debug SMALLINT NOT NULL DEFAULT 0,
-- is admin user
admin SMALLINT NOT NULL DEFAULT 0,
-- last login log
last_login TIMESTAMP WITHOUT TIME ZONE,
-- login error
login_error_count INT DEFAULT 0,
login_error_date_last TIMESTAMP WITHOUT TIME ZONE,
login_error_date_first TIMESTAMP WITHOUT TIME ZONE,
-- time locked
lock_until TIMESTAMP WITHOUT TIME ZONE,
lock_after TIMESTAMP WITHOUT TIME ZONE,
-- password change
password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed
password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval
password_reset_time TIMESTAMP WITHOUT TIME ZONE, -- when the password reset was requested
password_reset_uid VARCHAR, -- the uid to access the password reset page
-- _GET login id for direct login
login_user_id VARCHAR UNIQUE, -- the loginUserId, at least 32 chars
login_user_id_set_date TIMESTAMP WITHOUT TIME ZONE, -- when above uid was set
login_user_id_last_revalidate TIMESTAMP WITHOUT TIME ZONE, -- when the last login was done with user name and password
login_user_id_valid_from TIMESTAMP WITHOUT TIME ZONE, -- if set, from when the above uid is valid
login_user_id_valid_until TIMESTAMP WITHOUT TIME ZONE, -- if set, until when the above uid is valid
login_user_id_revalidate_after INTERVAL, -- user must login to revalidated loginUserId after set days, 0 for forever
login_user_id_locked SMALLINT DEFAULT 0, -- lock for loginUserId, but still allow normal login
-- additional ACL json block
additional_acl JSONB -- additional ACL as JSON string (can be set by other pages)
) INHERITS (edit_generic) WITHOUT OIDS;
-- create unique index

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_visible_group;
CREATE TABLE edit_visible_group (
edit_visible_group_id SERIAL PRIMARY KEY,
name VARCHAR,
flag VARCHAR
edit_visible_group_id SERIAL PRIMARY KEY,
name VARCHAR,
flag VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,7 +7,7 @@
-- DROP TABLE generic;
CREATE TABLE generic (
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE,
uid VARCHAR
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE,
uid VARCHAR
);

View File

@@ -677,9 +677,20 @@ class Login
$_SESSION['GROUP_ACL_TYPE'] = $res['group_type'];
// deprecated TEMPLATE setting
$_SESSION['TEMPLATE'] = $res['template'] ? $res['template'] : '';
$_SESSION['HEADER_COLOR'] = $res['second_header_color'] ?
$_SESSION['HEADER_COLOR'] = !empty($res['second_header_color']) ?
$res['second_header_color'] :
$res['first_header_color'];
// missing # before, this is for legacy data, will be deprecated
if (preg_match("/^[\dA-Fa-f]{6,8}$/", $_SESSION['HEADER_COLOR'])) {
$_SESSION['HEADER_COLOR'] = '#' . $_SESSION['HEADER_COLOR'];
}
// TODO: make sure that header color is valid:
// # + 6 hex
// # + 8 hex (alpha)
// rgb(), rgba(), hsl(), hsla()
// rgb: nnn.n for each
// hsl: nnn.n for first, nnn.n% for 2nd, 3rd
// Check\Colors::validateColor()
$_SESSION['LANG'] = $res['locale'] ?? 'en';
$_SESSION['DEFAULT_CHARSET'] = $res['encoding'] ?? 'UTF-8';
$_SESSION['DEFAULT_LOCALE'] = $_SESSION['LANG']
@@ -1622,7 +1633,7 @@ EOM;
$this->session->checkActiveSession() === true &&
!empty($_SESSION['DEFAULT_LOCALE'])
) {
$locale = $_SESSION['DEFAULT_LOCALE'] ?? '';
$locale = $_SESSION['DEFAULT_LOCALE'];
} else {
$locale = (defined('SITE_LOCALE') && !empty(SITE_LOCALE)) ?
SITE_LOCALE :

View File

@@ -0,0 +1,588 @@
<?php
/*********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2023/1/6
* DESCRIPTION:
* Original created: 2003/06/10
* This is the edit_base.php data as is moved into a class so we can
* more easy update this and also move to a different AJAX style more
* easy
*********************************************************************/
declare(strict_types=1);
namespace CoreLibs\Admin;
use Exception;
use SmartyException;
class EditBase
{
/** @var array<mixed> */
private $HEADER = [];
/** @var array<mixed> */
private $DATA = [];
/** @var array<mixed> */
private $DEBUG_DATA = [];
/** @var string the template name */
private $EDIT_TEMPLATE = '';
/** @var \CoreLibs\Template\SmartyExtend smarty system */
private $smarty;
/** @var \CoreLibs\Output\Form\Generate form generate system */
private $form;
/** @var \CoreLibs\Debug\Logging */
public $log;
/**
* construct form generator
*
* @param array<mixed> $db_config db config array, mandatory
* @param \CoreLibs\Debug\Logging $log Logging class, null auto set
* @param \CoreLibs\Language\L10n $l10n l10n language class, null auto set
* @param array<string,string> $locale locale array from ::setLocale,
* null auto set
*/
public function __construct(
array $db_config,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Language\L10n $l10n,
array $locale
) {
$this->log = $log;
// smarty template engine (extended Translation version)
$this->smarty = new \CoreLibs\Template\SmartyExtend($l10n, $locale);
// turn off set log per class
$log->setLogPer('class', false);
// create form class
$this->form = new \CoreLibs\Output\Form\Generate(
$db_config,
$log,
$l10n,
$locale
);
if ($this->form->mobile_phone) {
echo "I am sorry, but this page cannot be viewed by a mobile phone";
exit;
}
// $this->form->log->debug('POST', $this->form->log->prAr($_POST));
}
/**
* edit order page
*
* @return void
*/
private function editOrderPage(): void
{
// get is for "table_name" and "where" only
$table_name = $_GET['table_name'] ?? $_POST['table_name'] ?? '';
// not in use
// $where_string = $_GET['where'] ?? $_POST['where'] ?? '';
// order name is _always_ order_number for the edit interface
// follwing arrays do exist here:
// $position ... has the positions of the [0..max], cause in a <select>
// I can't put an number into the array field, in this array,
// there are the POSITION stored,
// that should CHANGE there order (up/down)
// $row_data_id ... has ALL ids from the sorting part
// $row_data_order ... has ALL order positions from the soirting part
$position = $_POST['position'] ?? [];
$row_data_id = $_POST['row_data_id'] ?? [];
$original_id = $row_data_id;
$row_data_order = $_POST['row_data_order'] ?? [];
// direction
$up = $_POST['up'] ?? '';
$down = $_POST['down'] ?? '';
if (count($position)) {
// FIRST u have to put right sort, then read again ...
// hast to be >0 or the first one is selected and then there is no move
if (!empty($up) && isset($position[0]) && $position[0] > 0) {
for ($i = 0; $i < count($position); $i++) {
// change position order
// this gets temp, id before that, gets actual (moves one "down")
// this gets the old before (moves one "up")
// is done for every element in row
// echo "A: ".$row_data_id[$position[$i]]
// ." (".$row_data_order[$position[$i]].") -- ".$row_data_id[$position[$i]-1]
// ." (".$row_data_order[$position[$i]-1].")<br>";
$temp_id = $row_data_id[$position[$i]] ?? null;
$row_data_id[$position[$i]] = $row_data_id[(int)$position[$i] - 1] ?? null;
$row_data_id[(int)$position[$i] - 1] = $temp_id;
// echo "A: ".$row_data_id[$position[$i]]
// ." (".$row_data_order[$position[$i]].") -- "
// .$row_data_id[$position[$i]-1]." (".$row_data_order[$position[$i]-1].")<br>";
} // for
} // if up
// the last position id from position array is not to be the count - 1 of
// row_data_id array, or it is the last element
if (!empty($down) && ($position[count($position) - 1] != (count($row_data_id) - 1))) {
for ($i = count($position) - 1; $i >= 0; $i--) {
// same as up, just up in other way, starts from bottom (last element) and moves "up"
// element before actuel gets temp, this element, becomes element after this,
// element after this, gets this
$temp_id = $row_data_id[(int)$position[$i] + 1] ?? null;
$row_data_id[(int)$position[$i] + 1] = $row_data_id[$position[$i]] ?? null;
$row_data_id[$position[$i]] = $temp_id;
} // for
} // if down
// write data ... (which has to be abstrackt ...)
if (
(!empty($up) && $position[0] > 0) ||
(!empty($down) && ($position[count($position) - 1] != (count($row_data_id) - 1)))
) {
for ($i = 0; $i < count($row_data_id); $i++) {
if (isset($row_data_order[$i]) && isset($row_data_id[$i])) {
$q = "UPDATE " . $table_name
. " SET order_number = " . $row_data_order[$i]
. " WHERE " . $table_name . "_id = " . $row_data_id[$i];
$q = $this->form->dbExec($q);
}
} // for all article ids ...
} // if write
} // if there is something to move
// get ...
$q = "SELECT " . $table_name . "_id, name, order_number FROM " . $table_name . " ";
// /* if (!empty($where_string)) {
// $q .= "WHERE $where_string ";
// } */
$q .= "ORDER BY order_number";
// init arrays
$row_data = [];
$options_id = [];
$options_name = [];
$options_selected = [];
// DB read data for menu
while (is_array($res = $this->form->dbReturn($q))) {
$row_data[] = [
"id" => $res[$table_name . "_id"],
"name" => $res["name"],
"order" => $res["order_number"]
];
} // while read data ...
// html title
$this->HEADER['HTML_TITLE'] = $this->form->l->__('Edit Order');
$messages = [];
$error = $_POST['error'] ?? 0;
// error msg
if (!empty($error)) {
$msg = $_POST['msg'] ?? [];
if (!is_array($msg)) {
$msg = [];
}
$messages[] = [
'msg' => $msg,
'class' => 'error',
'width' => '100%'
];
}
$this->DATA['form_error_msg'] = $messages;
// all the row data
for ($i = 0; $i < count($row_data); $i++) {
$options_id[] = $i;
$options_name[] = $row_data[$i]['name'];
// list of points to order
for ($j = 0; $j < count($position); $j++) {
// if matches, put into select array
if (
isset($original_id[$position[$j]]) && isset($row_data[$i]['id']) &&
$original_id[$position[$j]] == $row_data[$i]['id']
) {
$options_selected[] = $i;
}
}
}
$this->DATA['options_id'] = $options_id;
$this->DATA['options_name'] = $options_name;
$this->DATA['options_selected'] = $options_selected;
// hidden list for the data (id, order number)
$row_data_id = [];
$row_data_order = [];
for ($i = 0; $i < count($row_data); $i++) {
$row_data_id[] = $row_data[$i]['id'];
$row_data_order[] = $row_data[$i]['order'];
}
$this->DATA['row_data_id'] = $row_data_id;
$this->DATA['row_data_order'] = $row_data_order;
// hidden names for the table & where string
$this->DATA['table_name'] = $table_name;
$this->DATA['where_string'] = '';
// $this->DATA['where_string'] = $where_string ?? '';
$this->EDIT_TEMPLATE = 'edit_order.tpl';
}
/**
* all edit pages
*
* @return void
*/
private function editPageFlow(): void
{
// set table width
$table_width = '100%';
// load call only if id is set
if (!empty($_POST[$this->form->archive_pk_name])) {
$this->form->formProcedureLoad($_POST[$this->form->archive_pk_name]);
}
$this->form->formProcedureNew();
$this->form->formProcedureSave();
$this->form->formProcedureDelete();
// delete call only if those two are set
// and we are not in new/save/master delete
if (
!$this->form->new &&
!$this->form->save &&
!$this->form->delete &&
!empty($_POST['element_list']) &&
!empty($_POST['remove_name'])
) {
$this->form->formProcedureDeleteFromElementList(
$_POST['element_list'],
$_POST['remove_name']
);
// run a load post element delete to not end up with empty page
$this->form->formLoadTableArray($_POST[$this->form->archive_pk_name]);
$this->form->yes = 1;
}
$this->DATA['table_width'] = $table_width;
$messages = [];
// write out error / status messages
$messages[] = $this->form->formPrintMsg();
$this->DATA['form_error_msg'] = $messages;
// MENU START
// request some session vars
if (empty($_SESSION['HEADER_COLOR'])) {
$this->DATA['HEADER_COLOR'] = '#E0E2FF';
} else {
$this->DATA['HEADER_COLOR'] = $_SESSION['HEADER_COLOR'];
}
$this->DATA['USER_NAME'] = $_SESSION['USER_NAME'];
$this->DATA['EUID'] = $_SESSION['EUID'];
$this->DATA['GROUP_NAME'] = $_SESSION['GROUP_NAME'];
$this->DATA['GROUP_LEVEL'] = $_SESSION['GROUP_ACL_LEVEL'];
$PAGES = $_SESSION['PAGES'];
//$this->form->log->debug('menu', $this->form->log->prAr($PAGES));
// build nav from $PAGES ...
if (!isset($PAGES) || !is_array($PAGES)) {
$PAGES = [];
}
$menuarray = [];
foreach ($PAGES as $PAGE_CUID => $PAGE_DATA) {
if ($PAGE_DATA['menu'] && $PAGE_DATA['online']) {
$menuarray[] = $PAGE_DATA;
}
}
// split point for nav points
$COUNT_NAV_POINTS = count($menuarray);
$SPLIT_FACTOR = 3;
$START_SPLIT_COUNT = 3;
// WTF ?? I dunno what I am doing here ...
for ($i = 9; $i < $COUNT_NAV_POINTS; $i += $START_SPLIT_COUNT) {
if ($COUNT_NAV_POINTS > $i) {
$SPLIT_FACTOR += 1;
}
}
$position = 0;
$menu_data = [];
// for ($i = 1; $i <= count($menuarray); $i ++) {
foreach ($menuarray as $i => $menu_element) {
// do that for new array
$j = $i + 1;
$menu_data[$i]['pagename'] = htmlentities($menu_element['page_name']);
$menu_data[$i]['filename'] =
// prefix folder or host name
(isset($menu_element['hostname']) && $menu_element['hostname'] ?
$menu_element['hostname'] :
''
)
// filename
. ($menu_element['filename'] ?? '')
// query string
. (isset($menu_element['query_string']) && $menu_element['query_string'] ?
$menu_element['query_string'] :
''
);
if ($j == 1 || !($i % $SPLIT_FACTOR)) {
$menu_data[$i]['splitfactor_in'] = 1;
} else {
$menu_data[$i]['splitfactor_in'] = 0;
}
// on matching, we also need to check if we are in the same folder
if (
isset($menu_element['filename']) &&
$menu_element['filename'] == \CoreLibs\Get\System::getPageName() &&
(!isset($menu_element['hostname']) || (
isset($menu_element['hostname']) &&
(!$menu_element['hostname'] || strstr($menu_element['hostname'], CONTENT_PATH) !== false)
))
) {
$position = $i;
$menu_data[$i]['position'] = 1;
$menu_data[$i]['popup'] = 0;
} else {
// add query stuff
// HAS TO DONE LATER ... set urlencode, etc ...
// check if popup needed
if (isset($menu_element['popup']) && $menu_element['popup'] == 1) {
$menu_data[$i]['popup'] = 1;
$menu_data[$i]['rand'] = uniqid((string)rand());
$menu_data[$i]['width'] = $menu_element['popup_x'];
$menu_data[$i]['height'] = $menu_element['popup_y'];
} else {
$menu_data[$i]['popup'] = 0;
}
$menu_data[$i]['position'] = 0;
} // highlight or not
if (!($j % $SPLIT_FACTOR) || (($j + 1) > count($menuarray))) {
$menu_data[$i]['splitfactor_out'] = 1;
} else {
$menu_data[$i]['splitfactor_out'] = 0;
}
} // for
// $this->form->log->debug('MENU ARRAY', $this->form->log->prAr($menu_data));
$this->DATA['menu_data'] = $menu_data;
$this->DATA['page_name'] = $menuarray[$position]['page_name'] ?? '-Undefined [' . $position . '] -';
$L_TITLE = $this->DATA['page_name'];
// html title
$this->HEADER['HTML_TITLE'] = $this->form->l->__($L_TITLE);
// END MENU
// LOAD AND NEW
$this->DATA['load'] = $this->form->formCreateLoad();
$this->DATA['new'] = $this->form->formCreateNew();
// SHOW DATA PART
if ($this->form->yes) {
$this->DATA['form_yes'] = $this->form->yes;
$this->DATA['form_my_page_name'] = $this->form->my_page_name;
$this->DATA['filename_exist'] = 0;
$this->DATA['drop_down_input'] = 0;
$elements = [];
// depending on the "getPageName()" I show different stuff
switch ($this->form->my_page_name) {
case 'edit_users':
$elements[] = $this->form->formCreateElement('login_error_count');
$elements[] = $this->form->formCreateElement('login_error_date_last');
$elements[] = $this->form->formCreateElement('login_error_date_first');
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('deleted');
$elements[] = $this->form->formCreateElement('protected');
$elements[] = $this->form->formCreateElement('username');
$elements[] = $this->form->formCreateElement('password');
$elements[] = $this->form->formCreateElement('password_change_interval');
$elements[] = $this->form->formCreateElement('login_user_id');
$elements[] = $this->form->formCreateElement('login_user_id_set_date');
$elements[] = $this->form->formCreateElement('login_user_id_last_revalidate');
$elements[] = $this->form->formCreateElement('login_user_id_locked');
$elements[] = $this->form->formCreateElement('login_user_id_revalidate_after');
$elements[] = $this->form->formCreateElement('login_user_id_valid_from');
$elements[] = $this->form->formCreateElement('login_user_id_valid_until');
$elements[] = $this->form->formCreateElement('email');
$elements[] = $this->form->formCreateElement('last_name');
$elements[] = $this->form->formCreateElement('first_name');
$elements[] = $this->form->formCreateElement('edit_group_id');
$elements[] = $this->form->formCreateElement('edit_access_right_id');
$elements[] = $this->form->formCreateElement('strict');
$elements[] = $this->form->formCreateElement('locked');
$elements[] = $this->form->formCreateElement('lock_until');
$elements[] = $this->form->formCreateElement('lock_after');
$elements[] = $this->form->formCreateElement('admin');
$elements[] = $this->form->formCreateElement('debug');
$elements[] = $this->form->formCreateElement('db_debug');
$elements[] = $this->form->formCreateElement('edit_language_id');
$elements[] = $this->form->formCreateElement('edit_scheme_id');
$elements[] = $this->form->formCreateElementListTable('edit_access_user');
$elements[] = $this->form->formCreateElement('additional_acl');
break;
case 'edit_schemes':
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('header_color');
$elements[] = $this->form->formCreateElement('template');
break;
case 'edit_pages':
if (!isset($this->form->table_array['edit_page_id']['value'])) {
$q = "DELETE FROM temp_files";
$this->form->dbExec($q);
// gets all files in the current dir and dirs given ending with .php
$folders = ['../admin/', '../frontend/'];
$files = ['*.php'];
$search_glob = [];
foreach ($folders as $folder) {
// make sure this folder actually exists
if (is_dir(ROOT . $folder)) {
foreach ($files as $file) {
$search_glob[] = $folder . $file;
}
}
}
$crap = exec('ls ' . join(' ', $search_glob), $output, $status);
// now get all that are NOT in de DB
$q = "INSERT INTO temp_files (folder, filename) VALUES ";
$t_q = '';
foreach ($output as $output_file) {
// split the ouput into folder and file
$pathinfo = pathinfo($output_file);
if (!empty($pathinfo['dirname'])) {
$pathinfo['dirname'] .= DIRECTORY_SEPARATOR;
} else {
$pathinfo['dirname'] = '';
}
if ($t_q) {
$t_q .= ', ';
}
$t_q .= "('" . $this->form->dbEscapeString($pathinfo['dirname']) . "', '"
. $this->form->dbEscapeString($pathinfo['basename']) . "')";
}
$this->form->dbExec($q . $t_q, 'NULL');
$elements[] = $this->form->formCreateElement('filename');
} else {
// show file menu
// just show name of file ...
$this->DATA['filename_exist'] = 1;
$this->DATA['filename'] = $this->form->table_array['filename']['value'];
} // File Name View IF
$elements[] = $this->form->formCreateElement('hostname');
$elements[] = $this->form->formCreateElement('name');
// $elements[] = $this->form->formCreateElement('tag');
// $elements[] = $this->form->formCreateElement('min_acl');
$elements[] = $this->form->formCreateElement('order_number');
$elements[] = $this->form->formCreateElement('online');
$elements[] = $this->form->formCreateElement('menu');
$elements[] = $this->form->formCreateElementListTable('edit_query_string');
$elements[] = $this->form->formCreateElement('content_alias_edit_page_id');
$elements[] = $this->form->formCreateElementListTable('edit_page_content');
$elements[] = $this->form->formCreateElement('popup');
$elements[] = $this->form->formCreateElement('popup_x');
$elements[] = $this->form->formCreateElement('popup_y');
$elements[] = $this->form->formCreateElementReferenceTable('edit_visible_group');
$elements[] = $this->form->formCreateElementReferenceTable('edit_menu_group');
break;
case 'edit_languages':
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('short_name');
$elements[] = $this->form->formCreateElement('long_name');
$elements[] = $this->form->formCreateElement('iso_name');
break;
case 'edit_groups':
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('edit_access_right_id');
$elements[] = $this->form->formCreateElement('edit_scheme_id');
$elements[] = $this->form->formCreateElementListTable('edit_page_access');
$elements[] = $this->form->formCreateElement('additional_acl');
break;
case 'edit_visible_group':
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('flag');
break;
case 'edit_menu_group':
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('flag');
$elements[] = $this->form->formCreateElement('order_number');
break;
case 'edit_access':
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('protected');
$elements[] = $this->form->formCreateElement('color');
$elements[] = $this->form->formCreateElement('description');
// add name/value list here
$elements[] = $this->form->formCreateElementListTable('edit_access_data');
$elements[] = $this->form->formCreateElement('additional_acl');
break;
default:
print '[No valid page definition given]';
break;
}
// $this->form->log->debug('edit', "Elements: <pre>".$this->form->log->prAr($elements));
$this->DATA['elements'] = $elements;
$this->DATA['hidden'] = $this->form->formCreateHiddenFields();
$this->DATA['save_delete'] = $this->form->formCreateSaveDelete();
} else {
$this->DATA['form_yes'] = 0;
}
$this->EDIT_TEMPLATE = 'edit_body.tpl';
}
/**
* main method that either calls edit order page method or general page
* builds the smarty content and runs smarty display output
*
* @return void
* @throws Exception
* @throws SmartyException
*/
public function editBaseRun()
{
// set the template dir
// WARNING: this has a special check for the mailing tool layout (old layout)
if (defined('LAYOUT')) {
$this->smarty->setTemplateDir(BASE . INCLUDES . TEMPLATES . CONTENT_PATH);
$this->DATA['css'] = LAYOUT . CSS;
$this->DATA['js'] = LAYOUT . JS;
} else {
$this->smarty->setTemplateDir(TEMPLATES);
$this->DATA['css'] = CSS;
$this->DATA['js'] = JS;
}
$ADMIN_STYLESHEET = 'edit.css';
// define all needed smarty stuff for the general HTML/page building
$this->HEADER['CSS'] = CSS;
$this->HEADER['DEFAULT_ENCODING'] = DEFAULT_ENCODING;
/** @phpstan-ignore-next-line because ADMIN_STYLESHEET can be null */
$this->HEADER['STYLESHEET'] = $ADMIN_STYLESHEET ?? ADMIN_STYLESHEET;
// main run
if ($this->form->my_page_name == 'edit_order') {
$this->editOrderPage();
} else {
$this->editPageFlow();
}
// debug data, if DEBUG flag is on, this data is print out
// $this->DEBUG_DATA['DEBUG'] = $DEBUG_TMPL ?? '';
$this->DEBUG_DATA['DEBUG'] = '';
// create main data array
$CONTENT_DATA = array_merge($this->HEADER, $this->DATA, $this->DEBUG_DATA);
// data is 1:1 mapping (all vars, values, etc)
foreach ($CONTENT_DATA as $key => $value) {
$this->smarty->assign($key, $value);
}
if (is_dir(BASE . TEMPLATES_C)) {
$this->smarty->setCompileDir(BASE . TEMPLATES_C);
}
if (is_dir(BASE . CACHE)) {
$this->smarty->setCacheDir(BASE . CACHE);
}
$this->smarty->display(
$this->EDIT_TEMPLATE,
'editAdmin_' . $this->smarty->lang,
'editAdmin_' . $this->smarty->lang
);
$this->form->log->debug('DEBUGEND', '==================================== [Form END]');
}
}
// __END__

View File

@@ -66,7 +66,7 @@ class Basic
// logging interface, Debug\Logging class
/** @var \CoreLibs\Debug\Logging */
public $log;
/** @var\CoreLibs\Create\Session */
/** @var \CoreLibs\Create\Session */
public $session;
// email valid checks

View File

@@ -0,0 +1,187 @@
<?php
/*
* valid checks for css/html based colors
* # hex
* # hex + alpha
* rgb
* rgba
* hsl
* hsla
*/
declare(strict_types=1);
namespace CoreLibs\Check;
use Exception;
class Colors
{
/** @var int 1 for HEX rgb */
public const HEX_RGB = 1;
/** @var int 2 for HEX rgb with alpha */
public const HEX_RGBA = 2;
/** @var int 4 for rgb() */
public const RGB = 4;
/** @var int 8 for rgba() */
public const RGBA = 8;
/** @var int 16 for hsl() */
public const HSL = 16;
/** @var int 32 for hsla() */
public const HSLA = 32;
/** @var int 63 for all bits set (sum of above) */
public const ALL = 63;
/**
* check rgb/hsl content values in detail
* will abort and return false on first error found
*
* @param string $color html/css tring to check
* @param int|false $rgb_flag flag to check for rgb
* @param int|false $hsl_flag flag to check for hsl type
* @return bool True if no error, False if error
*/
private static function rgbHslContentCheck(string $color, $rgb_flag, $hsl_flag): bool
{
// extract string between () and split into elements
preg_match("/\((.*)\)/", $color, $matches);
if (
!is_array($color_list = preg_split("/,\s*/", $matches[1] ?? ''))
) {
throw new \Exception("Could not extract color list from rgg/hsl", 3);
}
// based on rgb/hsl settings check that entries are valid
// rgb: either 0-255 OR 0-100%
// hsl: first: 0-360
foreach ($color_list as $pos => $color_check) {
if (empty($color_check)) {
return false;
}
$percent_check = false;
if (strrpos($color_check, '%', -1) !== false) {
$percent_check = true;
$color_check = str_replace('%', '', $color_check);
}
// first three normal percent or valid number
if ($rgb_flag !== false) {
if ($percent_check === true) {
// for ALL pos
if ($color_check < 0 || $color_check > 100) {
return false;
}
} elseif (
$pos < 3 &&
($color_check < 0 || $color_check > 255)
) {
return false;
} elseif (
// RGBA set pos 3 if not percent
$pos == 3 &&
($color_check < 0 || $color_check > 1)
) {
return false;
}
} elseif ($hsl_flag !== false) {
// pos 0: 0-360
// pos 1,2: %
// pos 3: % or 0-1 (float)
if (
$pos == 0 &&
($color_check < 0 || $color_check > 360)
) {
return false;
} elseif (
// if pos 1/2 are not percent
($pos == 1 || $pos == 2) &&
($percent_check != true ||
($color_check < 0 || $color_check > 100))
) {
return false;
} elseif (
// 3 is either percent or 0~1
$pos == 3 &&
(
($percent_check == false &&
($color_check < 0 || $color_check > 1)) ||
($percent_check === true &&
($color_check < 0 || $color_check > 100))
)
) {
return false;
}
}
}
return true;
}
/**
* check if html/css color string is valid
* @param string $color A color string of any format
* @param int $flags defaults to ALL, else use | to combined from
* HEX_RGB, HEX_RGBA, RGB, RGBA, HSL, HSLA
* @return bool True if valid, False if not
* @throws Exception 1: no valid flag set
*/
public static function validateColor(string $color, int $flags = self::ALL): bool
{
// blocks for each check
$regex_blocks = [];
// set what to check
if ($flags & self::HEX_RGB) {
$regex_blocks[] = '#[\dA-Fa-f]{6}';
}
if ($flags & self::HEX_RGBA) {
$regex_blocks[] = '#[\dA-Fa-f]{8}';
}
if ($flags & self::RGB) {
$regex_blocks[] = 'rgb\(\d{1,3}%?,\s*\d{1,3}%?,\s*\d{1,3}%?\)';
}
if ($flags & self::RGBA) {
$regex_blocks[] = 'rgba\(\d{1,3}%?,\s*\d{1,3}%?,\s*\d{1,3}%?(,\s*(0\.\d{1,2}|1(\.0)?|\d{1,3}%))?\)';
}
if ($flags & self::HSL) {
$regex_blocks[] = 'hsl\(\d{1,3},\s*\d{1,3}(\.\d{1})?%,\s*\d{1,3}(\.\d{1})?%\)';
}
if ($flags & self::HSLA) {
$regex_blocks[] = 'hsla\(\d{1,3},\s*\d{1,3}(\.\d{1})?%,\s*\d{1,3}'
. '(\.\d{1})?%(,\s*(0\.\d{1,2}|1(\.0)?|\d{1,3}%))?\)';
}
// wrong flag set
if ($flags > self::ALL) {
throw new \Exception("Invalid flags parameter: $flags", 1);
}
if (!count($regex_blocks)) {
throw new \Exception("No regex blocks set: $flags", 2);
}
// build regex
$regex = '^('
. join('|', $regex_blocks)
// close regex
. ')$';
// print "C: $color, F: $flags, R: $regex\n";
if (preg_match("/$regex/", $color)) {
// if valid regex, we now need to check if the content is actually valid
// only for rgb/hsl type
/** @var int|false */
$rgb_flag = strpos($color, 'rgb');
/** @var int|false */
$hsl_flag = strpos($color, 'hsl');
// if both not match, return true
if (
$rgb_flag === false &&
$hsl_flag === false
) {
return true;
}
// run detaul rgb/hsl content check
return self::rgbHslContentCheck($color, $rgb_flag, $hsl_flag);
} else {
return false;
}
}
}
// __END__

View File

@@ -312,16 +312,17 @@ class DateTime
}
/**
* plits & checks date, wrap around for check_date function
* returns int in:
* -1 if the first date is smaller the last
* 0 if both are equal
* 1 if the first date is bigger than the last
* false (bool): error
* compares two dates, tries to convert them via strtotime to timestamps
* returns int/bool in:
* -1 if the first date is smaller the last
* 0 if both are equal
* 1 if the first date is bigger than the last
* false if date validation/conversion failed
*
* @param string $start_date start date string in YYYY-MM-DD
* @param string $end_date end date string in YYYY-MM-DD
* @return int|bool false on error, or int -1/0/1 as difference
* @return int|bool false on error
* or int -1 (s<e)/0 (s=e)/1 (s>e) as difference
*/
public static function compareDate($start_date, $end_date)
{
@@ -354,16 +355,17 @@ class DateTime
/**
* compares the two dates + times. if seconds missing in one set,
* add :00, converts / to -
* adds :00, converts date + times via strtotime to timestamps
* returns int/bool in:
* -1 if the first date is smaller the last
* 0 if both are equal
* 1 if the first date is bigger than the last
* false if no valid date/times chould be found
* -1 if the first date is smaller the last
* 0 if both are equal
* 1 if the first date is bigger than the last
* false if date/times validation/conversion failed
*
* @param string $start_datetime start date/time in YYYY-MM-DD HH:mm:ss
* @param string $end_datetime end date/time in YYYY-MM-DD HH:mm:ss
* @return int|bool false for error or -1/0/1 as difference
* @return int|bool false for error
* or -1 (s<e)/0 (s=e)/1 (s>e) as difference
*/
public static function compareDateTime($start_datetime, $end_datetime)
{

View File

@@ -26,14 +26,18 @@ class Byte
* Source Idea: SOURCE: https://programming.guide/worlds-most-copied-so-snippet.html
*
* The class itself hast the following defined
* BYTE_FORMAT_NOSPACE [1] turn off spaces between number and extension
* BYTE_FORMAT_NOSPACE [1] turn off spaces between number and suffix
* BYTE_FORMAT_ADJUST [2] use sprintf to always print two decimals
* BYTE_FORMAT_SI [3] use si standard 1000 instead of bytes 1024
* BYTE_FORMAT_SI [4] use si standard 1000 instead of bytes 1024
* To use the constant from outside use class::CONSTANT
*
* @param string|int|float $bytes bytes as string int or pure int
* @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_NOSPACE: no space between number and suffix
* BYTE_FORMAT_ADJUST: sprintf adjusted two 2 decimals
* BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string converted byte number (float) with suffix
* @throws \Exception 1: no valid flag set
*/
public static function humanReadableByteFormat($bytes, int $flags = 0): string
{
@@ -58,11 +62,14 @@ class Byte
} else {
$si = false;
}
if ($flags > 7) {
throw new \Exception("Invalid flags parameter: $flags", 1);
}
// si or normal
$unit = $si ? 1000 : 1024;
// always positive
$abs_bytes = $bytes == PHP_INT_MIN ? PHP_INT_MAX : abs($bytes);
$abs_bytes = $bytes == PHP_INT_MIN ? PHP_INT_MAX : abs((float)$bytes);
// smaller than unit is always B
if ($abs_bytes < $unit) {
return $bytes . 'B';
@@ -106,11 +113,13 @@ class Byte
* calculates the bytes based on a string with nnG, nnGB, nnM, etc
* NOTE: large exabyte numbers will overflow
* flag allowed:
* BYTE_FORMAT_SI [3] use si standard 1000 instead of bytes 1024
* BYTE_FORMAT_SI [4] use si standard 1000 instead of bytes 1024
*
* @param string|int|float $number any string or number to convert
* @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string|int|float converted value or original value
* @throws \Exception 1: no valid flag set
*/
public static function stringByteFormat($number, int $flags = 0)
{
@@ -120,6 +129,9 @@ class Byte
} else {
$si = false;
}
if ($flags != 0 && $flags != 4) {
throw new \Exception("Invalid flags parameter: $flags", 1);
}
// matches in regex
$matches = [];
// all valid units
@@ -134,7 +146,7 @@ class Byte
// remove all non valid characters from the number
$number = preg_replace('/[^0-9\.]/', '', $matches[2]);
// final clean up and convert to float
$number = (float)trim($number);
$number = (float)trim((string)$number);
// convert any mb/gb/etc to single m/b
$unit = preg_replace('/[^bkmgtpezy]/i', '', $matches[3]);
if ($unit) {

View File

@@ -150,6 +150,9 @@ class Colors
{
// check that H is 0 to 359, 360 = 0
// and S and V are 0 to 1
if ($H == 360) {
$H = 0;
}
if ($H < 0 || $H > 359) {
return false;
}
@@ -287,6 +290,9 @@ class Colors
if (!is_numeric($hue)) {
return false;
}
if ($hue == 360) {
$hue = 0;
}
if ($hue < 0 || $hue > 359) {
return false;
}

View File

@@ -0,0 +1,256 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return default null on invalid entries
*/
declare(strict_types=1);
namespace CoreLibs\Convert\Extends;
class VarSetTypeMain
{
/**
* If input variable is string then returns it, else returns default set
* if not null is true, then null as return is allowed, else return is
* converted to string
*
* @param mixed $val Input variable
* @param string|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return string|null Input var or default value
*/
protected static function setStrMain(
mixed $val,
?string $default = null,
bool $to_null = false
): ?string {
if (is_string($val)) {
return $val;
}
if ($to_null === false) {
return (string)$default;
}
return $default;
}
/**
* Will convert input data to string if possible.
* Runs for string/int/float/bool/null
* Will skip array/object/resource/callable/etc and use default for that
*
* @param mixed $val Input variable
* @param string|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return string|null Converted input data to string/null
*/
protected static function makeStrMain(
mixed $val,
string $default = null,
bool $to_null = false
): ?string {
// int/float/string/bool/null, everything else is ignored
// no: array/object/resource/callable
if (
is_int($val) ||
is_float($val) ||
is_string($val) ||
is_bool($val) ||
is_null($val)
) {
return (string)$val;
}
if ($to_null === false) {
return (string)$default;
}
return $default;
}
/**
* If input variable is int, return it, else return default value. If to_null
* is true then null as return is allowed, else only int is returned
*
* @param mixed $val Input variable
* @param int|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return int|null Input var or default value
*/
protected static function setIntMain(
mixed $val,
?int $default = null,
bool $to_null = false
): ?int {
if (is_int($val)) {
return $val;
}
if ($to_null === false) {
return (int)$default;
}
return $default;
}
/**
* Convert input to int via filter_var. If not convertable return default value.
* If to_null is set to true null return is allowed
* NOTE: this is only a drastic fallback and not recommned for special use.
* It will try to check via filter_var if we can get an int value and then use
* intval to convert it.
* Reason is that filter_var will convert eg 1.5 to 15 instead 1
* One is very wrong, the other is at least better, but not perfect
*
* @param mixed $val Input variable
* @param int|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return int|null Converted input data to int/null
*/
protected static function makeIntMain(
mixed $val,
int $default = null,
bool $to_null = false
): ?int {
// if we can filter it to a valid int, we can convert it
// we so avoid object, array, etc
if (
filter_var(
$val,
FILTER_SANITIZE_NUMBER_INT
) !== false
) {
return intval($val);
}
if ($to_null === false) {
return (int)$default;
}
return $default;
}
/**
* If input is float return it, else set to default value. If to_null is set
* to true, allow null return
*
* @param mixed $val Input variable
* @param float|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return float|null Input var or default value
*/
protected static function setFloatMain(
mixed $val,
?float $default = null,
bool $to_null = false
): ?float {
if (is_float($val)) {
return $val;
}
if ($to_null === false) {
return (float)$default;
}
return $default;
}
/**
* Convert intput var to float via filter_var. If failed to so return default.
* If to_null is set to true allow null return
*
* @param mixed $val Input variable
* @param float|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return float|null Converted intput data to float/null
*/
protected static function makeFloatMain(
mixed $val,
float $default = null,
bool $to_null = false
): ?float {
if (
(
$val = filter_var(
$val,
FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_FRACTION
)
) !== false
) {
return (float)$val;
}
if ($to_null === false) {
return (float)$default;
}
return $default;
}
/**
* If input var is array return it, else return default value. If to_null is
* set to true, allow null return
*
* @param mixed $val Input variable
* @param array<mixed>|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return array<mixed>|null Input var or default value
*/
protected static function setArrayMain(
mixed $val,
?array $default = null,
bool $to_null = false
): ?array {
if (is_array($val)) {
return $val;
}
if ($to_null === false) {
return (array)$default;
}
return $default;
}
/**
* If input var is bool return it, else return default value. If to_null is
* set to true will allow null return.
*
* @param mixed $val Input variable
* @param bool|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return bool|null Input var or default value
*/
protected static function setBoolMain(
mixed $val,
?bool $default = null,
bool $to_null = false
): ?bool {
if (is_bool($val)) {
return $val;
}
if ($to_null === false) {
return (bool)$default;
}
return $default;
}
/**
* Convert anything to bool. If it is a string it will try to use the filter_var
* to convert know true/false strings.
* Else it uses (bool) to convert the rest
* If null is allowed, will return null
*
* @param mixed $val Input variable
* @param bool $default Default value if to_null if false
* @param bool $to_null Convert to null (default no)
* @return bool|null Converted input data to bool/ null
*/
protected static function makeBoolMain(
mixed $val,
bool $default = false,
bool $to_null = false
): ?bool {
$boolvar = is_string($val) ?
filter_var(
$val,
FILTER_VALIDATE_BOOLEAN,
FILTER_NULL_ON_FAILURE
) :
(bool)$val;
return $boolvar === null && !$to_null ? $default : $boolvar;
}
}
// __END__

View File

@@ -0,0 +1,136 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return a default value as always what is expected and never null
* Use this for santize output from multi return functions where we know what
* will come back
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
class VarSetType extends Extends\VarSetTypeMain
{
/**
* Check is input is string, if not return default string.
* Will always return string
*
* @param mixed $val Input value
* @param string $default Default override value
* @return string Input value or default as string
*/
public static function setStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::setStrMain($val, $default, false);
}
/**
* Convert input to string if possible.
* Will only work on string/int/float/bool/null types
* Will always return string
*
* @param mixed $val Input value
* @param string $default Default override value
* @return string Input value as string or default as string
*/
public static function makeStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::makeStrMain($val, $default, false);
}
/**
* Check if input is int, if not return default int value 0.
* Will always return int.
*
* @param mixed $val Input value
* @param int $default Default override value
* @return int Input value or default as int
*/
public static function setInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::setIntMain($val, $default, false);
}
/**
* Convert intput to int if possible, if not return default value 0.
* Will always return int.
*
* @param mixed $val Input value
* @param int $default Default override value
* @return int Input value as int or default as int
*/
public static function makeInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::makeIntMain($val, $default, false);
}
/**
* Check if input is float, if not return default value value 0.0.
* Will always return float
*
* @param mixed $val Input value
* @param float $default Default override value
* @return float Input value or default as float
*/
public static function setFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::setFloatMain($val, $default, false);
}
/**
* Convert input to float, if not possible return default value 0.0.
* Will always return float
*
* @param mixed $val Input value
* @param float $default Default override value
* @return float Input value as float or default as float
*/
public static function makeFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::makeFloatMain($val, $default, false);
}
/**
* Check if input is array, if not return default empty array.
* Will always return array.
*
* @param mixed $val Input value
* @param array<mixed> $default Default override value
* @return array<mixed> Input value or default as array
*/
public static function setArray(mixed $val, array $default = []): array
{
return (array)VarSetTypeMain::setArrayMain($val, $default, false);
}
/**
* Check if input is bool, if not will return default value false.
* Will aways return bool.
*
* @param mixed $val Input value
* @param bool $default Default override value
* @return bool Input value or default as bool
*/
public static function setBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::setBoolMain($val, $default, false);
}
/**
* Convert anything to bool
*
* @param mixed $val Input value
* @param bool $default Default override value
* @return bool Input value as bool or default as bool
*/
public static function makeBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::makeBoolMain($val, $default, false);
}
}
// __END__

View File

@@ -0,0 +1,130 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return default null on invalid entries
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
class VarSetTypeNull extends Extends\VarSetTypeMain
{
/**
* Check is input is string, if not return default string.
* Will return null if no string as default.
*
* @param mixed $val Input value
* @param string|null $default Default override value
* @return string|null Input value or default as string/null
*/
public static function setStr(mixed $val, ?string $default = null): ?string
{
return VarSetTypeMain::setStrMain($val, $default, true);
}
/**
* Convert input to string if possible.
* Will only work on string/int/float/bool/null types.
* Will return null if convert failed as default.
*
* @param mixed $val Input value
* @param string|null $default Default override value
* @return string|null Input value as string or default as string/null
*/
public static function makeStr(mixed $val, string $default = null): ?string
{
return VarSetTypeMain::makeStrMain($val, $default, true);
}
/**
* Check if input is int, if not return default value null.
*
* @param mixed $val Input value
* @param int|null $default Default override value
* @return int|null Input value or default as int/null
*/
public static function setInt(mixed $val, ?int $default = null): ?int
{
return VarSetTypeMain::setIntMain($val, $default, true);
}
/**
* Convert intput to int if possible, if not return default value value null.
*
* @param mixed $val Input value $val
* @param int|null $default Default override value
* @return int|null Input value as int or default as int/null
*/
public static function makeInt(mixed $val, int $default = null): ?int
{
return VarSetTypeMain::makeIntMain($val, $default, true);
}
/**
* Check if input is float, if not return default value value null.
*
* @param mixed $val Input value $val
* @param float|null $default Default override value
* @return float|null Input value or default as float/null
*/
public static function setFloat(mixed $val, ?float $default = null): ?float
{
return VarSetTypeMain::setFloatMain($val, $default, true);
}
/**
* Convert input to float, if not possible return default value null.
*
* @param mixed $val Input value $val
* @param float|null $default Default override value
* @return float|null Input value as float or default as float/null
*/
public static function makeFloat(mixed $val, float $default = null): ?float
{
return VarSetTypeMain::makeFloatMain($val, $default, true);
}
/**
* Check if input is array, if not return default value null.
*
* @param mixed $val Input value $val
* @param array<mixed>|null $default Default override value
* @return array<mixed>|null Input value or default as array/null
*/
public static function setArray(mixed $val, ?array $default = null): ?array
{
return VarSetTypeMain::setArrayMain($val, $default, true);
}
/**
* Check if input is bool, if not will return default value null.
*
* @param mixed $val Input value $val
* @param bool|null $default Default override value
* @return bool|null Input value or default as bool/null
*/
public static function setBool(mixed $val, ?bool $default = null): ?bool
{
return VarSetTypeMain::setBoolMain($val, $default, true);
}
/**
* Convert anything to bool
*
* @param mixed $val Input value $val
* @return bool|null Input value as bool or default as bool/null
*/
public static function makeBool(mixed $val): ?bool
{
// note that the default value here is irrelevant, we return null
// on unsetable string var
return VarSetTypeMain::makeBoolMain($val, false, true);
}
}
// __END__

View File

@@ -12,7 +12,7 @@
* you don't have to write any SQL queries, worry over update/insert
*
* HISTORY:
* 2019/9/11 (cs) error string 21->91, 22->92 for not overlapping with IO
* 2019/9/11 (cs) error string 21->1021, 22->1022 for not overlapping with IO
* 2005/07/07 (cs) updated array class for postgres: set 0 & NULL if int field given, insert uses () values () syntax
* 2005/03/31 (cs) fixed the class call with all debug vars
* 2003-03-10: error_ids where still wrong chagned 11->21 and 12->22
@@ -72,20 +72,24 @@ class ArrayIO extends \CoreLibs\DB\IO
// instance db_io class
parent::__construct($db_config, $log ?? new \CoreLibs\Debug\Logging());
// more error vars for this class
$this->error_string['91'] = 'No Primary Key given';
$this->error_string['92'] = 'Could not run Array Query';
$this->error_string['1999'] = 'No table array or table name set';
$this->error_string['1021'] = 'No Primary Key given';
$this->error_string['1022'] = 'Could not run Array Query';
$this->table_array = $table_array;
$this->table_name = $table_name;
// error abort if no table array or no table name
if (empty($table_array) || empty($table_name)) {
$this->__dbError(1999, false, 'MAJOR ERROR: Core settings missing');
}
// set primary key for given table_array
if (is_array($this->table_array)) {
foreach ($this->table_array as $key => $value) {
if (isset($value['pk'])) {
$this->pk_name = $key;
}
foreach ($this->table_array as $key => $value) {
if (!empty($value['pk'])) {
$this->pk_name = $key;
}
} // set pk_name IF table_array was given
}
$this->dbArrayIOSetAcl($base_acl_level, $acl_admin);
}
@@ -197,7 +201,7 @@ class ArrayIO extends \CoreLibs\DB\IO
// if not set ... produce error
if (!$this->table_array[$this->pk_name]['value']) {
// if no PK found, error ...
$this->__dbError(91);
$this->__dbError(1021);
return false;
} else {
return true;
@@ -282,7 +286,7 @@ class ArrayIO extends \CoreLibs\DB\IO
// if 0, error
$this->pk_id = null;
if (!$this->dbExec($q)) {
$this->__dbError(92);
$this->__dbError(1022);
}
return $this->table_array;
}
@@ -369,7 +373,7 @@ class ArrayIO extends \CoreLibs\DB\IO
// possible dbFetchArray errors ...
$this->pk_id = $this->table_array[$this->pk_name]['value'];
} else {
$this->__dbError(92);
$this->__dbError(1022);
}
return $this->table_array;
}
@@ -631,7 +635,7 @@ class ArrayIO extends \CoreLibs\DB\IO
}
// return success or not
if (!$this->dbExec($q)) {
$this->__dbError(92);
$this->__dbError(1022);
}
// set primary key
if ($insert) {

View File

@@ -266,16 +266,18 @@ class IO
// 1: read new, keep at end, clean before new run
// 2: read new, clean at the end (temporary cache)
// 3: never cache
/** @var int */
/** @var int use cache (default) in dbReturn */
public const USE_CACHE = 0;
/** @var int */
/** @var int reset cache and read new in dbReturn */
public const READ_NEW = 1;
/** @var int */
/** @var int clear cache after read in dbeEturn */
public const CLEAR_CACHE = 2;
/** @var int */
/** @var int do not use any cache in dbReturn */
public const NO_CACHE = 3;
/** @var string */
/** @var string default hash type */
public const ERROR_HASH_TYPE = 'adler32';
/** @var string regex to get returning with matches at position 1 */
public const REGEX_RETURNING = '/\s+returning\s+(.+?);?$/i';
// recommend to set private/protected and only allow setting via method
// can bet set from outside
@@ -452,6 +454,11 @@ class IO
'71' => 'Failed to set search path/schema',
'80' => 'Trying to set an empty encoding',
'81' => 'Failed to set client encoding',
// for prepared cursor return
'101' => 'Statement name empty for get prepare cursor',
'102' => 'Key empty for get prepare cursir',
'103' => 'No prepared cursor with this name',
'104' => 'No Key with this name in the prepared cursor array'
];
// load the core DB functions wrapper class
@@ -568,14 +575,14 @@ class IO
/**
* checks if query is a SELECT, SHOW or WITH, if not error, 0 return
* NOTE:
* Query needs to start with SELECT, SHOW or WITH. if starts with "with" it is ignored
* Query needs to start with SELECT, SHOW or WITH
* @param string $query query to check
* @return bool true if matching, false if not
*/
private function __checkQueryForSelect(string $query): bool
{
// perhaps allow spaces before select ?!?
if (preg_match("/^(select|show|with) /i", $query)) {
// change to string starts with?
if (preg_match("/^\s*(?:SELECT|SHOW|WITH)\s/i", $query)) {
return true;
}
return false;
@@ -592,10 +599,10 @@ class IO
*/
private function __checkQueryForInsert(string $query, bool $pure = false): bool
{
if ($pure && preg_match("/^insert /i", $query)) {
if ($pure && preg_match("/^\s*INSERT\s+?INTO\s/i", $query)) {
return true;
}
if (!$pure && preg_match("/^(insert|update|delete) /i", $query)) {
if (!$pure && preg_match("/^\s*(?:INSERT\s+?INTO|DELETE\s+?FROM|UPDATE)\s/i", $query)) {
return true;
}
return false;
@@ -609,7 +616,7 @@ class IO
*/
private function __checkQueryForUpdate(string $query): bool
{
if (preg_match("/^update /i", $query)) {
if (preg_match("/^\s*UPDATE\s?(.+)/i", $query)) {
return true;
}
return false;
@@ -874,12 +881,33 @@ class IO
private function __dbReturnTable(string $query): array
{
$matches = [];
if (preg_match("/^SELECT /i", $query)) {
preg_match("/ (FROM) \"?(([\w_]+)\.)?([\w_]+)\"? /i", $query, $matches);
$schema_table = [];
if ($this->__checkQueryForSelect($query)) {
// only selects the first one, this is more a fallback
// MATCHES 1 (call), 3 (schema), 4 (table)
preg_match("/\s+?(FROM)\s+?([\"'])?(?:([\w_]+)\.)?([\w_]+)(?:\2)?\s?/i", $query, $matches);
$schema_table = [
$matches[3] ?? '',
$matches[4] ?? '',
];
} else {
preg_match("/(INSERT INTO|DELETE FROM|UPDATE) \"?(([\w_]+)\.)?([\w_]+)\"? /i", $query, $matches);
preg_match(
// must start with
// INSERT INTO (table)
// DELETE FROM (table)
// UPDATE (table) SET
// MATCHES 1 (call), 4 (schema), 5 (table)
"/^\s*(INSERT\s+?INTO|DELETE\s+?FROM|(UPDATE))\s+?"
. "([\"'])?(?:([\w_]+)\.)?([\w_]+)(?:\3)?\s?(?(2)\s+?SET|)/i",
$query,
$matches
);
$schema_table = [
$matches[4] ?? '',
$matches[5] ?? ''
];
}
return [$matches[3] ?? '', $matches[4] ?? ''];
return $schema_table;
}
/**
@@ -1002,7 +1030,7 @@ class IO
$this->pk_name_table[$table] : 'NULL';
}
if (
!preg_match("/ returning /i", $this->query) &&
!preg_match(self::REGEX_RETURNING, $this->query) &&
$this->pk_name && $this->pk_name != 'NULL'
) {
// check if this query has a ; at the end and remove it
@@ -1011,7 +1039,9 @@ class IO
$this->query = !is_string($__query) ? $this->query : $__query;
$this->query .= " RETURNING " . $this->pk_name;
$this->returning_id = true;
} elseif (preg_match("/ returning (.*)/i", $this->query, $matches)) {
} elseif (
preg_match(self::REGEX_RETURNING, $this->query, $matches)
) {
if ($this->pk_name && $this->pk_name != 'NULL') {
// add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1])) {
@@ -1025,7 +1055,7 @@ class IO
// if we have an UPDATE and RETURNING, flag for true, but do not add anything
if (
$this->__checkQueryForUpdate($this->query) &&
preg_match("/ returning (.*)/i", $this->query, $matches)
preg_match(self::REGEX_RETURNING, $this->query, $matches)
) {
$this->returning_id = true;
}
@@ -1481,19 +1511,29 @@ class IO
* @param string $string string to escape
* @return string escaped string
*/
public function dbEscapeIdentifier($string): string
public function dbEscapeIdentifier(string $string): string
{
return $this->db_functions->__dbEscapeIdentifier($string);
}
/**
* escape data for writing to bytea type column field
* @param string $bytea bytea to escape
* @return string escaped bytea
* @param string $data data to escape to bytea
* @return string escaped bytea string
*/
public function dbEscapeBytea($bytea)
public function dbEscapeBytea(string $data): string
{
return $this->db_functions->__dbEscapeBytea($bytea);
return $this->db_functions->__dbEscapeBytea($data);
}
/**
* unescape bytea data back to normal binrary data
* @param string $bytea bytea data stream
* @return string binary data string
*/
public function dbUnescapeBytea(string $bytea): string
{
return $this->db_functions->__dbUnescapeBytea($bytea);
}
/**
@@ -1811,6 +1851,7 @@ class IO
// if cursor exists ...
if ($this->cursor_ext[$query_hash]['cursor']) {
/** @phpstan-ignore-next-line claims this is always false, but can be true */
if ($first_call === true) {
$this->cursor_ext[$query_hash]['log'][] = 'First call';
// count the rows returned (if select)
@@ -2195,7 +2236,7 @@ class IO
public function dbGetQueryCalled(string $query): int
{
$query_hash = $this->dbGetQueryHash($query);
if ($this->query_called[$query_hash]) {
if (!empty($this->query_called[$query_hash])) {
return $this->query_called[$query_hash];
} else {
return 0;
@@ -2272,11 +2313,14 @@ class IO
$this->prepare_cursor[$stm_name]['pk_name'] = $pk_name;
}
// if no returning, then add it
if (!preg_match("/ returning /i", $query) && $this->prepare_cursor[$stm_name]['pk_name']) {
if (
!preg_match(self::REGEX_RETURNING, $query) &&
$this->prepare_cursor[$stm_name]['pk_name']
) {
$query .= " RETURNING " . $this->prepare_cursor[$stm_name]['pk_name'];
$this->prepare_cursor[$stm_name]['returning_id'] = true;
} elseif (
preg_match("/ returning (.*)/i", $query, $matches) &&
preg_match(self::REGEX_RETURNING, $query, $matches) &&
$this->prepare_cursor[$stm_name]['pk_name']
) {
// if returning exists but not pk_name, add it
@@ -3055,6 +3099,60 @@ class IO
return $this->field_names;
}
/**
* Returns the value for given key in statement
* Will write error if statemen id does not exist
* or key is invalid
*
* @param string $stm_name The name of the stored statement
* @param string $key Key field name in prepared cursor array
* Allowed are: pk_name, count, query, returning_id
* @return null|string|int|bool Entry from each of the valid keys
* Will return false on error
* Not ethat returnin_id also can return false
* but will not set an error entry
*/
public function dbGetPrepareCursorValue(string $stm_name, string $key)
{
// if no statement name
if (empty($stm_name)) {
$this->__dbError(
101,
false,
'No statement name given'
);
return false;
}
// if not a valid key
if (!in_array($key, ['pk_name', 'count', 'query', 'returning_id'])) {
$this->__dbError(
102,
false,
'Invalid key name'
);
return false;
}
// statement name not in prepared list
if (empty($this->prepare_cursor[$stm_name])) {
$this->__dbError(
103,
false,
'Statement name does not exist in prepare cursor array'
);
return false;
}
// key doest not exists, this will never hit as we filter out invalid ones
if (!isset($this->prepare_cursor[$stm_name][$key])) {
$this->__dbError(
104,
false,
'Key does not exist in prepare cursor array'
);
return false;
}
return $this->prepare_cursor[$stm_name][$key];
}
// ***************************
// ERROR AND WARNING DATA
// ***************************

View File

@@ -559,15 +559,26 @@ class PgSQL implements \CoreLibs\DB\SQL\SqlInterface\SqlFunctions
/**
* wrapper for pg_escape_byte
*
* @param string $bytea bytea data stream
* @return string escaped bytea string
* @param string $data data stream
* @return string escaped bytea string
*/
public function __dbEscapeBytea(string $bytea): string
public function __dbEscapeBytea(string $data): string
{
if ($this->dbh === false || is_bool($this->dbh)) {
return '';
}
return pg_escape_bytea($this->dbh, $bytea);
return pg_escape_bytea($this->dbh, $data);
}
/**
* unescape bytea data from postgesql
*
* @param string $bytea Bytea data stream
* @return string Unescaped bytea data
*/
public function __dbUnescapeBytea(string $bytea): string
{
return pg_unescape_bytea($bytea);
}
/**
@@ -779,7 +790,6 @@ class PgSQL implements \CoreLibs\DB\SQL\SqlInterface\SqlFunctions
}
// get result
$db_schema = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
/** @phpstan-ignore-next-line Cannot access offset string on array|bool */
return $db_schema[$show_string] ?? '';
}
@@ -806,7 +816,6 @@ class PgSQL implements \CoreLibs\DB\SQL\SqlInterface\SqlFunctions
}
// check if schema does not exists
$row = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
/** @phpstan-ignore-next-line */
if (empty($row['exists']) || $row['exists'] == 'f') {
return 2;
}

View File

@@ -214,10 +214,18 @@ interface SqlFunctions
/**
* Undocumented function
*
* @param string $bytea
* @param string $data
* @return string
*/
public function __dbEscapeBytea(string $bytea): string;
public function __dbEscapeBytea(string $data): string;
/**
* Undocumented function
*
* @param string $bytea
* @return string
*/
public function __dbUnescapeBytea(string $bytea): string;
/**
* Undocumented function

View File

@@ -94,9 +94,11 @@ class Support
* @param bool $no_html set to true to use ##HTMLPRE##or html escape
* @return string
*/
public static function printToString($mixed, bool $no_html = false): string
public static function printToString(mixed $mixed, bool $no_html = false): string
{
if (is_bool($mixed)) {
if (is_null($mixed)) {
return (string)'NULL';
} elseif (is_bool($mixed)) {
return self::printBool($mixed, '', 'TRUE', 'FALSE');
} elseif (is_resource($mixed)) {
return (string)$mixed;

View File

@@ -94,6 +94,10 @@ class DotEnv
// strip ending " and EVERYTHING that follows after that
$line = $matches[1];
}
// just be sure it is init before we fill
if (!isset($_ENV[$var])) {
$_ENV[$var] = '';
}
// strip line of slashes
$_ENV[$var] .= stripslashes($line);
}

View File

@@ -294,6 +294,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// language
/** @var \CoreLibs\Language\L10n */
public $l;
// log
/** @var \CoreLibs\Debug\Logging */
public $log;
// now some default error msgs (english)
/** @var array<mixed> */
@@ -307,17 +310,22 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
* @param \CoreLibs\Language\L10n|null $l10n l10n language class, null auto set
* @param array<string,string>|null $locale locale array from ::setLocale,
* null auto set
* @param array<mixed>|null $table_arrays Override table array data
* instead of try to load from
* include file
* @throws \Exception 1: No table_arrays set/no class found for my page name
*/
public function __construct(
array $db_config,
?\CoreLibs\Debug\Logging $log = null,
?\CoreLibs\Language\L10n $l10n = null,
?array $locale = null
?array $locale = null,
?array $table_arrays = null,
) {
global $table_arrays;
// replace any non valid variable names
// TODO extract only alphanumeric and _ after . to _ replacement
$this->my_page_name = str_replace(['.'], '_', System::getPageName(System::NO_EXTENSION));
// init logger if not set
$this->log = $log ?? new \CoreLibs\Debug\Logging();
// don't log per class
$this->log->setLogPer('class', false);
// if pass on locale is null
if ($locale === null) {
$locale = \CoreLibs\Language\GetLocale::setLocale();
@@ -341,58 +349,39 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// security settings
$this->base_acl_level = (int)$_SESSION['BASE_ACL_LEVEL'];
$this->acl_admin = (int)$_SESSION['ADMIN'];
$GLOBALS['base_acl_level'] = $this->base_acl_level;
$GLOBALS['acl_admin'] = $this->acl_admin;
// replace any non valid variable names and set my page name
$this->my_page_name = str_replace(
['.'],
'_',
System::getPageName(System::NO_EXTENSION)
);
// first check if we have a in page override as $table_arrays[page name]
if (
/* isset($GLOBALS['table_arrays']) &&
is_array($GLOBALS['table_arrays']) &&
isset($GLOBALS['table_arrays'][System::getPageName(System::NO_EXTENSION)]) &&
is_array($GLOBALS['table_arrays'][System::getPageName(System::NO_EXTENSION)]) */
isset($table_arrays[System::getPageName(System::NO_EXTENSION)]) &&
is_array($table_arrays[System::getPageName(System::NO_EXTENSION)])
) {
// $config_array = $GLOBALS['table_arrays'][System::getPageName(1)];
$config_array = $table_arrays[System::getPageName(1)];
} else {
// WARNING: auto spl load does not work with this as it is an array
// and not a function/object
// check if this is the old path or the new path
// check local folder in current path
// then check general global folder
if (
is_dir(TABLE_ARRAYS) &&
is_file(TABLE_ARRAYS . 'array_' . $this->my_page_name . '.php')
) {
include(TABLE_ARRAYS . 'array_' . $this->my_page_name . '.php');
} elseif (
is_dir(BASE . INCLUDES . TABLE_ARRAYS) &&
is_file(BASE . INCLUDES . TABLE_ARRAYS . 'array_' . $this->my_page_name . '.php')
) {
include(BASE . INCLUDES . TABLE_ARRAYS . 'array_' . $this->my_page_name . '.php');
}
// in the include file there must be a variable with the page name matching
if (isset(${$this->my_page_name}) && is_array(${$this->my_page_name})) {
$config_array = ${$this->my_page_name};
// primary try to load the class
/** @var \CoreLibs\Output\Form\TableArraysInterface|false $content_class */
$content_class = $this->loadTableArray();
if (is_object($content_class)) {
$config_array = $content_class->setTableArray();
} else {
// dummy created
$config_array = [
'table_array' => [],
'table_name' => '',
];
// throw an error here as we cannot load the class at all
throw new \Exception("Cannot load " . $this->my_page_name, 1);
}
}
// don't log per class
if ($log !== null) {
$log->setLogPer('class', false);
}
// $log->debug('CONFIG ARRAY', $log->prAr($config_array));
// start the array_io class which will start db_io ...
parent::__construct(
$db_config,
$config_array['table_array'],
$config_array['table_name'],
$log ?? new \CoreLibs\Debug\Logging(),
$this->log,
// set the ACL
$this->base_acl_level,
$this->acl_admin
@@ -474,8 +463,67 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
parent::__destruct();
}
// PRIVATE METHODS |=================================================>
/**
* load table array class based on my page name converted to camel case
* class files are in \TableArrays folder in \Output\Form
* @return object|bool Return class object or false on failure
*/
private function loadTableArray()
{
// note: it schould be Schemas but an original type made it to this
// this file is kept for the old usage, new one should be EditSchemas
$table_array_shim = [
'EditSchemes' => 'EditSchemas'
];
// camel case $this->my_page_name from foo_bar_note to FooBarNote
$page_name_camel_case = '';
foreach (explode('_', $this->my_page_name) as $part) {
$page_name_camel_case .= ucfirst($part);
}
$class_string = __NAMESPACE__ . "\\TableArrays\\"
. (
// shim lookup
$table_array_shim[$page_name_camel_case] ??
$page_name_camel_case
);
try {
/** @var \CoreLibs\Output\Form\TableArraysInterface|false $class */
$class = new $class_string($this);
} catch (\Throwable $t) {
$this->log->debug('CLASS LOAD', 'Failed loading: ' . $class_string . ' => ' . $t->getMessage());
return false;
}
if (is_object($class)) {
return $class;
}
return false;
}
// PUBLIC METHODS |=================================================>
/**
* return current acl admin flag (1/0)
*
* @return int Admin flag 1 for on or 0 for off
*/
public function getAclAdmin(): int
{
return $this->acl_admin;
}
/**
* check if current acl level is match to requested on
*
* @param int $level Requested ACL level
* @return bool if current level equal or larger return tru, else false
*/
public function checkBaseACL(int $level): bool
{
return $this->base_acl_level >= $level ? true : false;
}
/**
* dumps all values into output (for error msg)
*
@@ -1478,7 +1526,8 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// $this->log->debug('edit_error', 'QS: <pre>' . print_r($_POST, true) . '</pre>');
if (is_array($this->element_list)) {
// check the mandatory stuff
// if mandatory, check that at least on pk exists or if at least the mandatory field is filled
// if mandatory, check that at least on pk exists or
// if at least the mandatory field is filled
foreach ($this->element_list as $table_name => $reference_array) {
if (!is_array($reference_array)) {
$reference_array = [];
@@ -1518,7 +1567,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// . count($_POST[$prfx.$key]) . ' | M: $max');
// $this->log->debug('edit_error_chk', 'K: ' . $_POST[$prfx.$key] . ' | ' . $_POST[$prfx.$key][0]);
}
$this->log->debug('POST ARRAY', $this->log->prAr($_POST));
// $this->log->debug('POST ARRAY', $this->log->prAr($_POST));
// init variables before inner loop run
$mand_okay = 0;
$mand_name = '';
@@ -1530,15 +1579,17 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
for ($i = 0; $i < $max; $i++) {
// either one of the post pks is set, or the mandatory
foreach ($reference_array['elements'] as $el_name => $data_array) {
if (isset($data_array['mandatory']) && $data_array['mandatory']) {
if (
isset($data_array['mandatory']) &&
$data_array['mandatory']
) {
$mand_name = $data_array['output_name'];
}
// check if there is a primary ket inside, so it is okay
if (
isset($data_array['pk_id']) &&
count($_POST[$prfx . $el_name]) &&
isset($reference_array['mandatory']) &&
$reference_array['mandatory']
!empty($reference_array['mandatory'])
) {
$mand_okay = 1;
}
@@ -1549,15 +1600,14 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// . $_POST[$prfx . $el_name] . ' - ' . $reference_array['enable_name'] . ' - '
// . $_POST[$reference_array['enable_name']][$_POST[$prfx . $el_name][$i]]);
if (
isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
isset($_POST[$prfx . $el_name][$i]) &&
$_POST[$prfx . $el_name][$i]
!empty($data_array['mandatory']) &&
!empty($_POST[$prfx . $el_name][$i])
) {
$mand_okay = 1;
$row_okay[$i] = 1;
} elseif (
!empty($data_array['type']) && $data_array['type'] == 'radio_group' &&
!empty($data_array['type']) &&
$data_array['type'] == 'radio_group' &&
!isset($_POST[$prfx . $el_name])
) {
// radio group and set where one not active
@@ -1565,20 +1615,22 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$row_okay[$_POST[$prfx . $el_name][$i] ?? 0] = 0;
$default_wrong[$_POST[$prfx . $el_name][$i] ?? 0] = 1;
$error[$_POST[$prfx . $el_name][$i] ?? 0] = 1;
} elseif (isset($_POST[$prfx . $el_name][$i]) && !isset($error[$i])) {
} elseif (
isset($_POST[$prfx . $el_name][$i]) &&
!isset($error[$i])
) {
// $this->log->debug('edit_error_chk', '[$i]');
$element_set[$i] = 1;
$row_okay[$i] = 1;
} elseif (
isset($data_array['mandatory']) &&
$data_array['mandatory'] &&
!empty($data_array['mandatory']) &&
!$_POST[$prfx . $el_name][$i]
) {
$row_okay[$i] = 0;
}
// do optional error checks like for normal fields
// currently active: unique/alphanumeric
if (isset($data_array['error_check'])) {
if (!empty($data_array['error_check'])) {
foreach (explode('|', $data_array['error_check']) as $error_check) {
switch ($error_check) {
// check unique, check if field is filled and not same in _POST set
@@ -1597,6 +1649,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$reference_array['output_name'],
$i
);
$_POST['ERROR'][$prfx][$i] = 1;
}
break;
case 'alphanumericspace':
@@ -1612,6 +1665,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$reference_array['output_name'],
$i
);
$_POST['ERROR'][$prfx][$i] = 1;
}
break;
}
@@ -1623,8 +1677,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// main mandatory is met -> error msg
if (
!$mand_okay &&
isset($reference_array['mandatory']) &&
$reference_array['mandatory']
!empty($reference_array['mandatory'])
) {
$this->msg .= sprintf(
$this->l->__('You need to enter at least one data set for field <b>%s</b>!<br>'),
@@ -2533,12 +2586,13 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
}
// $this->log->debug('CFG QUERY', 'Q: ' . $q);
// only run if we have query strnig
$written_pos = [];
if (isset($q)) {
$prfx = $data['prefix']; // short
$pos = 0; // position in while for overwrite if needed
// read out the list and add the selected data if needed
while (is_array($res = $this->dbReturn($q))) {
$_data = [];
$prfx = $data['prefix']; // short
// go through each res
for ($i = 0, $i_max = count($q_select); $i < $i_max; $i++) {
// query select part, set to the element name
@@ -2568,13 +2622,48 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
}
$data['content'][] = $_data;
$data['pos'][] = [0 => $pos]; // this is for the checkboxes
$written_pos[] = $pos;
$pos++; // move up one
// reset and unset before next run
unset($_data);
}
}
// add lost error ones
$this->log->debug('ERROR', 'P: ' . $data['prefix'] . ', '
. $this->log->prAr($_POST['ERROR'][$data['prefix']] ?? []));
if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) {
$prfx = $data['prefix']; // short
$_post_data = [];
// MAX entries defined via $data['pk_name'] entry (must exist)
$_max_pos = count($_POST[$data['pk_name']] ?? []);
// write all excte previous loaded @ $pos
foreach ($q_select as $_el_name) {
for ($_pos = 0; $_pos <= $_max_pos; $_pos++) {
// if not in data pos
if (!in_array($_pos, $written_pos)) {
$_post_data[$_pos][$prfx . $_el_name] =
$_POST[$prfx . $_el_name][$_pos] ?? '';
}
}
}
// only add if all fields in data are filled, else skip
// pk_name field is excluded of check
foreach ($_post_data as $_pos => $_data) {
$filled = false;
foreach ($_data as $_name => $_value) {
if ($_name != $data['pk_name'] && !empty($_value)) {
$filled = true;
}
}
if ($filled == true) {
$data['content'][] = $_data;
$data['pos'][] = [0 => $_pos];
}
}
}
// if this is normal single reference data check the content on the element count
// if there is a max_empty is set, then fill up new elements (unfilled) until we reach max empty
// if there is a max_empty is set, then fill up new elements (unfilled)
// until we reach max empty
if (
/*isset($this->element_list[$table_name]['type']) &&
$this->element_list[$table_name]['type'] == 'reference_data' &&*/

View File

@@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditAccess implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_access_id' => [
'value' => $_POST['edit_access_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Access Group Name',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumericspace|unique'
],
'description' => [
'value' => $_POST['description'] ?? '',
'output_name' => 'Description',
'type' => 'textarea'
],
'color' => [
'value' => $_POST['color'] ?? '',
'output_name' => 'Color',
'mandatory' => 0,
'type' => 'text',
'size' => 10,
'length' => 9,
'error_check' => 'custom',
// FIXME: update regex check for hex/rgb/hsl with color check class
'error_regex' => '/^#([\dA-Fa-f]{6}|[\dA-Fa-f]{8})$/',
'error_example' => '#F6A544'
],
'enabled' => [
'value' => $_POST['enabled'] ?? 0,
'output_name' => 'Enabled',
'type' => 'binary',
'int' => 1, // OR 'bool' => 1
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'protected' => [
'value' => $_POST['protected'] ?? 0,
'output_name' => 'Protected',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60
],
],
'table_name' => 'edit_access',
"load_query" => "SELECT edit_access_id, name FROM edit_access ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
'element_list' => [
'edit_access_data' => [
'output_name' => 'Edit Access Data',
'delete_name' => 'remove_edit_access_data',
// is not a sub table read and connect, but only a sub table with data
// 'type' => 'reference_data',
// maxium visible if no data is set, if filled add this number to visible
'max_empty' => 5,
'prefix' => 'ead',
'elements' => [
'name' => [
'type' => 'text',
'error_check' => 'alphanumeric|unique',
'output_name' => 'Name',
'mandatory' => 1
],
'value' => [
'type' => 'text',
'output_name' => 'Value'
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1]
],
/*'edit_access_id' => [
'int' => 1,
'type' => 'hidden',
// reference main key from master table above
'fk_id' => 1
],*/
'edit_access_data_id' => [
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
],
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_group_id' => [
'value' => $_POST['edit_group_id'] ?? '',
'pk' => 1,
'type' => 'hidden'
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group Name',
'type' => 'text',
'mandatory' => 1
],
'edit_access_right_id' => [
'value' => $_POST['edit_access_right_id'] ?? '',
'output_name' => 'Group Level',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'output_name' => 'Group Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name"
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60
],
],
'load_query' => "SELECT edit_group_id, name, enabled FROM edit_group ORDER BY name",
'table_name' => 'edit_group',
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'Enabled: '
],
],
'element_list' => [
'edit_page_access' => [
'output_name' => 'Pages',
'mandatory' => 1,
'delete' => 0, // set then reference entries are deleted, else the 'enable' flag is only set
'enable_name' => 'enable_page_access',
'prefix' => 'epa',
'read_data' => [
'table_name' => 'edit_page',
'pk_id' => 'edit_page_id',
'name' => 'name',
'order' => 'order_number'
],
'elements' => [
'edit_page_access_id' => [
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_page_id' => [
'int' => 1,
'type' => 'hidden'
],
/*,
'edit_default' => [
'output_name' => 'Default',
'type' => 'radio',
'mandatory' => 1
],*/
],
], // edit pages ggroup
],
];
}
}
// __END__

View File

@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditLanguages implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_language_id' => [
'value' => $_POST['edit_language_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'short_name' => [
'value' => $_POST['short_name'] ?? '',
'output_name' => 'Language (short)',
'mandatory' => 1,
'type' => 'text',
'size' => 2,
'length' => 2
],
'long_name' => [
'value' => $_POST['long_name'] ?? '',
'output_name' => 'Language (long)',
'mandatory' => 1,
'type' => 'text',
'size' => 40
],
'iso_name' => [
'value' => $_POST['iso_name'] ?? '',
'output_name' => 'ISO Code',
'mandatory' => 1,
'type' => 'text'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'int' => 1,
'order' => 1
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'lang_default' => [
'value' => $_POST['lang_default'] ?? '',
'output_name' => 'Default Language',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
],
'load_query' => "SELECT edit_language_id, long_name, iso_name, enabled "
. "FROM edit_language "
. "ORDER BY long_name",
'show_fields' => [
[
'name' => 'long_name'
],
[
'name' => 'iso_name',
'before_value' => 'ISO: '
],
[
'name' => 'enabled',
'before_value' => 'Enabled: ',
'binary' => ['Yes','No'],
],
],
'table_name' => 'edit_language'
];
}
}
// __END__

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditMenuGroup implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_menu_group_id' => [
'value' => $_POST['edit_menu_group_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group name',
'mandatory' => 1,
'type' => 'text'
],
'flag' => [
'value' => $_POST['flag'] ?? '',
'output_name' => 'Flag',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumeric|unique'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'output_name' => 'Group order',
'type' => 'order',
'int' => 1,
'order' => 1
],
],
'table_name' => 'edit_menu_group',
'load_query' => "SELECT edit_menu_group_id, name FROM edit_menu_group ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,275 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_page_id' => [
'value' => $_POST['edit_page_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'filename' => [
'value' => $_POST['filename'] ?? '',
'output_name' => 'Add File ...',
'mandatory' => 1,
'type' => 'drop_down_db',
'query' => "SELECT DISTINCT temp_files.filename AS id, "
. "temp_files.folder || temp_files.filename AS name "
. "FROM temp_files "
. "LEFT JOIN edit_page ep ON temp_files.filename = ep.filename "
. "WHERE ep.filename IS NULL"
],
'hostname' => [
'value' => $_POST['hostname'] ?? '',
'output_name' => 'Hostname or folder',
'type' => 'text'
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Page name',
'mandatory' => 1,
'type' => 'text'
],
'order_number' => [
'value' => $_POST['order_number'] ?? '',
'output_name' => 'Page order',
'type' => 'order',
'int' => 1,
'order' => 1
],
/* 'flag' => [
'value' => $_POST['flag']) ?? '',
'output_name' => 'Page Flag',
'type' => 'drop_down_array',
'query' => [
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5'
],
],*/
'online' => [
'value' => $_POST['online'] ?? '',
'output_name' => 'Online',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'menu' => [
'value' => $_POST['menu'] ?? '',
'output_name' => 'Menu',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'popup' => [
'value' => $_POST['popup'] ?? '',
'output_name' => 'Popup',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'popup_x' => [
'value' => $_POST['popup_x'] ?? '',
'output_name' => 'Popup Width',
'int_null' => 1,
'type' => 'text',
'size' => 4,
'length' => 4
],
'popup_y' => [
'value' => $_POST['popup_y'] ?? '',
'output_name' => 'Popup Height',
'int_null' => 1,
'type' => 'text',
'size' => 4,
'length' => 4
],
'content_alias_edit_page_id' => [
'value' => $_POST['content_alias_edit_page_id'] ?? '',
'output_name' => 'Content Alias Source',
'int_null' => 1,
'type' => 'drop_down_db',
// query creation
'select_distinct' => 0,
'pk_name' => 'edit_page_id AS content_alias_edit_page_id',
'input_name' => 'name',
'table_name' => 'edit_page',
'where_not_self' => 1,
'order_by' => 'order_number'
// 'query' => "SELECT edit_page_id AS content_alias_edit_page_id, name ".
// "FROM edit_page ".
// (!empty($_POST['edit_page_id']) ? " WHERE edit_page_id <> ".$_POST['edit_page_id'] : "")." ".
// "ORDER BY order_number"
],
],
'load_query' => "SELECT edit_page_id, "
. "CASE WHEN hostname IS NOT NULL THEN hostname ELSE ''::VARCHAR END || filename AS filename, "
. "name, online, menu, popup "
. "FROM edit_page "
. "ORDER BY order_number",
'table_name' => 'edit_page',
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'filename',
'before_value' => 'Filename: '
],
[
'name' => 'online',
'binary' => ['Yes', 'No'],
'before_value' => 'Online: '
],
[
'name' => 'menu',
'binary' => ['Yes', 'No'],
'before_value' => 'Menu: '
],
[
'name' => 'popup',
'binary' => ['Yes', 'No'],
'before_value' => 'Popup: '
],
],
'reference_arrays' => [
'edit_visible_group' => [
'table_name' => 'edit_page_visible_group',
'other_table_pk' => 'edit_visible_group_id',
'output_name' => 'Visible Groups (access)',
'mandatory' => 1,
'select_size' => 10,
'selected' => $_POST['edit_visible_group_id'] ?? '',
'query' => "SELECT edit_visible_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_visible_group ORDER BY name"
],
'edit_menu_group' => [
'table_name' => 'edit_page_menu_group',
'other_table_pk' => 'edit_menu_group_id',
'output_name' => 'Menu Groups (grouping)',
'mandatory' => 1,
'select_size' => 10,
'selected' => $_POST['edit_menu_group_id'] ?? '',
'query' => "SELECT edit_menu_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_menu_group ORDER BY order_number"
],
],
'element_list' => [
'edit_query_string' => [
'output_name' => 'Query Strings',
'delete_name' => 'remove_query_string',
'prefix' => 'eqs',
'elements' => [
'name' => [
'output_name' => 'Name',
'type' => 'text',
'error_check' => 'unique|alphanumeric',
'mandatory' => 1
],
'value' => [
'output_name' => 'Value',
'type' => 'text'
],
'enabled' => [
'output_name' => 'Enabled',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'dynamic' => [
'output_name' => 'Dynamic',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'edit_query_string_id' => [
'type' => 'hidden',
'pk_id' => 1
],
], // elements
], // query_string element list
'edit_page_content' => [
'output_name' => 'Page Content',
'delete_name' => 'remove_page_content',
'prefix' => 'epc',
'elements' => [
'name' => [
'output_name' => 'Content',
'type' => 'text',
'error_check' => 'alphanumeric',
'mandatory' => 1
],
'uid' => [
'output_name' => 'UID',
'type' => 'text',
'error_check' => 'unique|alphanumeric',
'mandatory' => 1
],
'order_number' => [
'output_name' => 'Order',
'type' => 'text',
'error_check' => 'int',
'mandatory' => 1
],
'online' => [
'output_name' => 'Online',
'int' => 1,
'type' => 'checkbox',
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_page_content_id' => [
'type' => 'hidden',
'pk_id' => 1
],
],
],
], // element list
];
}
}
// __END__

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditSchemas implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Scheme Name',
'mandatory' => 1,
'type' => 'text'
],
'header_color' => [
'value' => $_POST['header_color'] ?? '',
'output_name' => 'Header Color',
'mandatory' => 1,
'type' => 'text',
'size' => 10,
'length' => 9,
'error_check' => 'custom',
// FIXME: update regex check for hex/rgb/hsl with color check class
'error_regex' => '/^#([\dA-Fa-f]{6}|[\dA-Fa-f]{8})$/',
'error_example' => '#F6A544'
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'int' => 1,
'type' => 'binary',
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
],
'template' => [
'value' => $_POST['template'] ?? '',
'output_name' => 'Template',
'type' => 'text'
],
],
'table_name' => 'edit_scheme',
'load_query' => "SELECT edit_scheme_id, name, enabled FROM edit_scheme ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'Enabled: '
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,456 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_user_id' => [
'value' => $_POST['edit_user_id'] ?? '',
'type' => 'hidden',
'pk' => 1,
'int' => 1
],
'username' => [
'value' => $_POST['username'] ?? '',
'output_name' => 'Username',
'mandatory' => 1,
'error_check' => 'unique|alphanumericextended',
'type' => 'text',
// if not min_edit_acl only read
// if not min_show_acl not visible
'min_edit_acl' => '100',
'min_show_acl' => '-1',
],
'password' => [
'value' => $_POST['password'] ?? '',
'HIDDEN_value' => $_POST['HIDDEN_password'] ?? '',
'CONFIRM_value' => $_POST['CONFIRM_password'] ?? '',
'output_name' => 'Password',
'mandatory' => 1,
'type' => 'password', // later has to be password for encryption in database
'update' => [ // connected field updates, and update data
'password_change_date' => [ // db row to update
'type' => 'date', // type of field (int/text/date/etc)
'value' => 'NOW()' // value [todo: complex reference
],
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
// password date when first insert and password is set, needs special field with connection to password
// password reset force interval, if set, user needs to reset password after X time period
'password_change_interval' => [
'value' => $_POST['password_change_interval'] ?? '',
'output_name' => 'Password change interval',
// can be any date length format. n Y/M/D [not H/M/S], only one set, no combination
'error_check' => 'intervalshort',
'type' => 'text',
'interval' => 1, // interval needs NULL write for empty
'size' => 5, // make it 5 chars long
'length' => 5,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'enabled' => [
'value' => $_POST['enabled'] ?? '',
'output_name' => 'Enabled',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '-1',
],
'deleted' => [
'value' => $_POST['deleted'] ?? '',
'output_name' => 'Deleted',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'strict' => [
'value' => $_POST['strict'] ?? '',
'output_name' => 'Strict (Lock after errors)',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'locked' => [
'value' => $_POST['locked'] ?? '',
'output_name' => 'Locked (auto set if strict with errors)',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'admin' => [
'value' => $_POST['admin'] ?? '',
'output_name' => 'Admin',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'debug' => [
'value' => $_POST['debug'] ?? '',
'output_name' => 'Debug',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'db_debug' => [
'value' => $_POST['db_debug'] ?? '',
'output_name' => 'DB Debug',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'email' => [
'value' => $_POST['email'] ?? '',
'output_name' => 'E-Mail',
'type' => 'text',
'error_check' => 'email',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'last_name' => [
'value' => $_POST['last_name'] ?? '',
'output_name' => 'Last Name',
'type' => 'text',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'first_name' => [
'value' => $_POST['first_name'] ?? '',
'output_name' => 'First Name',
'type' => 'text',
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'lock_until' => [
'value' => $_POST['lock_until'] ?? '',
'output_name' => 'Lock account until',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'lock_after' => [
'value' => $_POST['lock_after'] ?? '',
'output_name' => 'Lock account after',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id' => [
'value' => $_POST['login_user_id'] ?? '',
'output_name' => '_GET/_POST loginUserId direct login ID',
'type' => 'text',
'error_check' => 'unique|custom',
'error_regex' => "/^[A-Za-z0-9]+$/",
'emptynull' => 1,'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_set_date' => [
'output_name' => 'loginUserId set date',
'value' => $_POST['login_user_id_set_date'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_user_id_last_revalidate' => [
'output_name' => 'loginUserId last revalidate date',
'value' => $_POST['login_user_id_last_revalidate'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_user_id_locked' => [
'value' => $_POST['login_user_id_locked'] ?? '',
'output_name' => 'loginUserId usage locked',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_revalidate_after' => [
'value' => $_POST['login_user_id_revalidate_after'] ?? '',
'output_name' => 'loginUserId, User must login after n days',
'type' => 'text',
'error_check' => 'intervalshort',
'interval' => 1, // interval needs NULL write for empty
'size' => 5, // make it 5 chars long
'length' => 5,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_valid_from' => [
'value' => $_POST['login_user_id_valid_from'] ?? '',
'output_name' => 'loginUserId valid from',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_user_id_valid_until' => [
'value' => $_POST['login_user_id_valid_until'] ?? '',
'output_name' => 'loginUserId valid until',
'type' => 'datetime',
'error_check' => 'datetime',
'sql_read' => 'YYYY-MM-DD HH24:MI',
'datetime' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_language_id' => [
'value' => $_POST['edit_language_id'] ?? '',
'output_name' => 'Language',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_language_id, long_name "
. "FROM edit_language "
. "WHERE enabled = 1"
. "ORDER BY order_number",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'output_name' => 'Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_group_id' => [
'value' => $_POST['edit_group_id'] ?? '',
'output_name' => 'Group',
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_group_id, name FROM edit_group WHERE enabled = 1 ORDER BY name",
'mandatory' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'edit_access_right_id' => [
'value' => $_POST['edit_access_right_id'] ?? '',
'output_name' => 'User Level',
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'login_error_count' => [
'output_name' => 'Login error count',
'value' => $_POST['login_error_count'] ?? '',
'type' => 'view',
'empty' => '0',
'min_show_acl' => '100',
],
'login_error_date_last' => [
'output_name' => 'Last login error',
'value' => $_POST['login_error_date_liast'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'login_error_date_first' => [
'output_name' => 'First login error',
'value' => $_POST['login_error_date_first'] ?? '',
'type' => 'view',
'empty' => '-',
'min_show_acl' => '100',
],
'protected' => [
'value' => $_POST['protected'] ?? '',
'output_name' => 'Protected',
'type' => 'binary',
'int' => 1,
'element_list' => [
'1' => 'Yes',
'0' => 'No'
],
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
'output_name' => 'Additional ACL (as JSON)',
'type' => 'textarea',
'error_check' => 'json',
'rows' => 10,
'cols' => 60,
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
],
'load_query' => "SELECT edit_user_id, username, enabled, deleted, "
. "strict, locked, login_error_count "
. "FROM edit_user "
// if base acl is not 90 only list enabled
// if not admin flag, do not list admin flagged
. (
!$this->form->getAclAdmin() ?
"WHERE admin = 0 "
. (
!$this->form->checkBaseACL(90) ?
// $_POST['base_acl_level'] < 90 ?
"AND enabled = 1 " :
""
)
: ''
)
. "ORDER BY username",
'table_name' => 'edit_user',
'show_fields' => [
[
'name' => 'username'
],
[
'name' => 'enabled',
'binary' => ['Yes', 'No'],
'before_value' => 'ENBL: '
],
[
'name' => 'deleted',
'binary' => ['Yes', 'No'],
'before_value' => 'DEL: '
],
[
'name' => 'strict',
'binary' => ['Yes', 'No'],
'before_value' => 'STRC: '
],
[
'name' => 'locked',
'binary' => ['Yes', 'No'],
'before_value' => 'LCK: '
],
[
'name' => 'login_error_count',
'before_value' => 'ERR: '
],
],
'element_list' => [
'edit_access_user' => [
'output_name' => 'Accounts',
'mandatory' => 1,
// set then reference entries are deleted, else the 'enable' flag is only set
'delete' => 0,
// acl
'min_edit_acl' => '40',
'min_show_acl' => '20',
// table read prefix
'prefix' => 'ecu',
'read_data' => [
'table_name' => 'edit_access',
'pk_id' => 'edit_access_id',
'name' => 'name',
'order' => 'name'
],
'elements' => [
'edit_access_user_id' => [
'output_name' => 'Activate',
'type' => 'hidden',
'int' => 1,
'pk_id' => 1
],
'enabled' => [
'type' => 'checkbox',
'output_name' => 'Activate',
'int' => 1,
'element_list' => [1],
],
'edit_access_right_id' => [
'type' => 'drop_down_db',
'output_name' => 'Access Level',
'preset' => 1, // first of the select
'int' => 1,
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
],
'edit_default' => [
'type' => 'radio_group',
'output_name' => 'Default',
'int' => 1,
'element_list' => 'radio_group'
],
'edit_access_id' => [
'type' => 'hidden',
'int' => 1
],
],
], // edit pages ggroup
],
];
}
}
// __END__

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditVisibleGroup implements \CoreLibs\Output\Form\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
/**
* constructor
* @param \CoreLibs\Output\Form\Generate $form base form class
*/
public function __construct(\CoreLibs\Output\Form\Generate $form)
{
$this->form = $form;
$this->form->log->debug('CLASS LOAD', __NAMESPACE__ . __CLASS__);
}
/**
* return the table array
*
* @return array<mixed>
*/
public function setTableArray(): array
{
return [
'table_array' => [
'edit_visible_group_id' => [
'value' => $_POST['edit_visible_group_id'] ?? '',
'type' => 'hidden',
'pk' => 1
],
'name' => [
'value' => $_POST['name'] ?? '',
'output_name' => 'Group name',
'mandatory' => 1,
'type' => 'text'
],
'flag' => [
'value' => $_POST['flag'] ?? '',
'output_name' => 'Flag',
'mandatory' => 1,
'type' => 'text',
'error_check' => 'alphanumeric|unique'
],
],
'table_name' => 'edit_visible_group',
'load_query' => "SELECT edit_visible_group_id, name FROM edit_visible_group ORDER BY name",
'show_fields' => [
[
'name' => 'name'
],
],
];
}
}
// __END__

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace CoreLibs\Output\Form;
interface TableArraysInterface
{
/**
* setTableArray interface, set the table array
* @return array<mixed>
*/
public function setTableArray(): array;
}
// __END__

Some files were not shown because too many files have changed in this diff Show More