Compare commits
131 Commits
v7.2.1
...
composerLi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40e6444c2a | ||
|
|
4b015505ff | ||
|
|
e90387c1fc | ||
|
|
3fb7169531 | ||
|
|
e4dd73d0e9 | ||
|
|
e71c53b887 | ||
|
|
16addc4f4b | ||
|
|
7e845d3954 | ||
|
|
6fcb7a44e0 | ||
|
|
e82e4f6079 | ||
|
|
231897cf5b | ||
|
|
17da804073 | ||
|
|
96ad4b0f48 | ||
|
|
1386afb552 | ||
|
|
86a9ad8789 | ||
|
|
0c4c018ffa | ||
|
|
8b36807a2e | ||
|
|
8daef88e5e | ||
|
|
a59fa7a2c9 | ||
|
|
14c8197a7f | ||
|
|
79bd7fa256 | ||
|
|
9ba09b22f5 | ||
|
|
e88ad00d7f | ||
|
|
9b80fde0d7 | ||
|
|
f99e8bb70c | ||
|
|
b48894d000 | ||
|
|
5ebe7dc06c | ||
|
|
2e6b7b2f5b | ||
|
|
897406456a | ||
|
|
edb0620308 | ||
|
|
90edcbf8c8 | ||
|
|
40f267f3dd | ||
|
|
c8aee19deb | ||
|
|
74c8b8d71e | ||
|
|
c0db3be770 | ||
|
|
e74bd04d6f | ||
|
|
3662b1ab1b | ||
|
|
7abce87653 | ||
|
|
b3e35b5d94 | ||
|
|
6429b77bda | ||
|
|
3c8bdab8fa | ||
|
|
3cf6fee548 | ||
|
|
f5a9757ae3 | ||
|
|
3d6b461b20 | ||
|
|
513b115d57 | ||
|
|
eb16f433e8 | ||
|
|
8f94201478 | ||
|
|
1b2359a934 | ||
|
|
d6187005f4 | ||
|
|
f0e6b5b8e9 | ||
|
|
6b400978ac | ||
|
|
2754a718fa | ||
|
|
37c3b6afeb | ||
|
|
516b11f2f1 | ||
|
|
75a42558fd | ||
|
|
48271a8659 | ||
|
|
35d3032df5 | ||
|
|
7be8bb06c9 | ||
|
|
2aab94a842 | ||
|
|
1cbe4e5c06 | ||
|
|
137fb9a986 | ||
|
|
e1357f5d39 | ||
|
|
8766d4db77 | ||
|
|
b696338324 | ||
|
|
43e66edfd1 | ||
|
|
0e99700bbe | ||
|
|
2f0b9fb360 | ||
|
|
c7cc3c2938 | ||
|
|
f508b607a6 | ||
|
|
f94b350ba4 | ||
|
|
53eef03387 | ||
|
|
5a81445a28 | ||
|
|
4bbbd653cd | ||
|
|
4c28e6d0ec | ||
|
|
66b7e81463 | ||
|
|
cf58f86802 | ||
|
|
ff644310cd | ||
|
|
58988b9c0f | ||
|
|
fe75f1d724 | ||
|
|
0607cdc3be | ||
|
|
6cb14daf49 | ||
|
|
330582f273 | ||
|
|
b0293b52bd | ||
|
|
00591deb00 | ||
|
|
737f70fac5 | ||
|
|
0328ccd2fe | ||
|
|
eba1e2885f | ||
|
|
53813261fb | ||
|
|
df2ae66942 | ||
|
|
78e1d73cd9 | ||
|
|
620a5878c1 | ||
|
|
5a0b09a916 | ||
|
|
98c6033c75 | ||
|
|
6dcebc9b67 | ||
|
|
c97520e186 | ||
|
|
764ca1f098 | ||
|
|
3d23e5b066 | ||
|
|
90e418ba24 | ||
|
|
b6a0937e0c | ||
|
|
b3f6f8ef18 | ||
|
|
d9d5400498 | ||
|
|
b1be681afb | ||
|
|
8ef309d479 | ||
|
|
6e59b63791 | ||
|
|
9c7b3cea83 | ||
|
|
26af6a07f4 | ||
|
|
b7c6d4b478 | ||
|
|
9936fc04da | ||
|
|
1e0dfa2106 | ||
|
|
3af6f6a8f0 | ||
|
|
1e793c0d16 | ||
|
|
5be34453ce | ||
|
|
7773b78e17 | ||
|
|
2a3798c8c2 | ||
|
|
bc8303fe5f | ||
|
|
ba89b188d9 | ||
|
|
d15618cde4 | ||
|
|
0fd89727e9 | ||
|
|
a8e75d158b | ||
|
|
4b3fbaa309 | ||
|
|
1a6c65df0e | ||
|
|
24f553a17e | ||
|
|
9a3ea2f7db | ||
|
|
bcdb877d90 | ||
|
|
6d0e528c38 | ||
|
|
7e6474195b | ||
|
|
1795d3ba6c | ||
|
|
e1340acf55 | ||
|
|
b5ead3e266 | ||
|
|
f5daaca598 | ||
|
|
6b4f310cd2 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -0,0 +1,3 @@
|
||||
composer.lock
|
||||
vendor/
|
||||
.env
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
169
4dev/bin/mo_to_js.sh
Executable 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__
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
LANGUAGE 'plpgsql';
|
||||
|
||||
@@ -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';
|
||||
LANGUAGE 'plpgsql';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
|
||||
-- DROP TABLE temp_files;
|
||||
CREATE TABLE temp_files (
|
||||
filename VARCHAR,
|
||||
folder VARCHAR
|
||||
filename VARCHAR,
|
||||
folder VARCHAR
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
-- 2022/6/17 update edit_user with login uid
|
||||
|
||||
-- the login uid, at least 32 chars
|
||||
ALTER TABLE edit_user ADD login_user_id VARCHAR UNIQUE;
|
||||
-- CREATE UNIQUE INDEX edit_user_login_user_id_key ON edit_user (login_user_id) WHERE login_user_id IS NOT NULL;
|
||||
-- ALTER TABLE edit_user ADD CONSTRAINT edit_user_login_user_id_key UNIQUE (login_user_id);
|
||||
-- when above uid was set
|
||||
ALTER TABLE edit_user ADD login_user_id_set_date TIMESTAMP WITHOUT TIME ZONE;
|
||||
ALTER TABLE edit_user ADD login_user_id_last_revalidate TIMESTAMP WITHOUT TIME ZONE;
|
||||
-- if set, from/until when the above uid is valid
|
||||
ALTER TABLE edit_user ADD login_user_id_valid_from TIMESTAMP WITHOUT TIME ZONE;
|
||||
ALTER TABLE edit_user ADD login_user_id_valid_until TIMESTAMP WITHOUT TIME ZONE;
|
||||
-- user must login to revalidated login id after set days, 0 for forever
|
||||
ALTER TABLE edit_user ADD login_user_id_revalidate_after INTERVAL;
|
||||
-- lock for login user id, but still allow normal login
|
||||
ALTER TABLE edit_user ADD login_user_id_locked SMALLINT NOT NULL DEFAULT 0;
|
||||
|
||||
-- disable login before date
|
||||
ALTER TABLE edit_user ADD lock_until TIMESTAMP WITHOUT TIME ZONE;
|
||||
-- disable login after date
|
||||
ALTER TABLE edit_user ADD lock_after TIMESTAMP WITHOUT TIME ZONE;
|
||||
|
||||
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;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql';
|
||||
|
||||
CREATE TRIGGER trg_edit_user_set_login_user_id_set_date
|
||||
BEFORE INSERT OR UPDATE ON edit_user
|
||||
FOR EACH ROW EXECUTE PROCEDURE set_login_user_id_set_date();
|
||||
|
||||
-- __END__
|
||||
2213
4dev/deprecated/CoreLibs/ACL/Login.php
Normal file
2213
4dev/deprecated/CoreLibs/ACL/Login.php
Normal file
File diff suppressed because it is too large
Load Diff
588
4dev/deprecated/CoreLibs/Admin/EditBase.php
Normal file
588
4dev/deprecated/CoreLibs/Admin/EditBase.php
Normal 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__
|
||||
1549
4dev/deprecated/CoreLibs/Basic.php
Normal file
1549
4dev/deprecated/CoreLibs/Basic.php
Normal file
File diff suppressed because it is too large
Load Diff
187
4dev/deprecated/CoreLibs/Check/Colors.php
Normal file
187
4dev/deprecated/CoreLibs/Check/Colors.php
Normal 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__
|
||||
41
4dev/deprecated/CoreLibs/Check/Jason.php
Normal file
41
4dev/deprecated/CoreLibs/Check/Jason.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DEPRECATED: Use correct Convert\Json:: instead
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Check;
|
||||
|
||||
use CoreLibs\Convert\Json;
|
||||
|
||||
class Jason
|
||||
{
|
||||
/**
|
||||
* @param string|null $json a json string, or null data
|
||||
* @param bool $override if set to true, then on json error
|
||||
* set original value as array
|
||||
* @return array<mixed> returns an array from the json values
|
||||
* @deprecated Use Json::jsonConvertToArray()
|
||||
*/
|
||||
public static function jsonConvertToArray(?string $json, bool $override = false): array
|
||||
{
|
||||
return Json::jsonConvertToArray($json, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|boolean $return_string [default=false] if set to true
|
||||
* it will return the message string and not
|
||||
* the error number
|
||||
* @return int|string Either error number (0 for no error)
|
||||
* or error string ('' for no error)
|
||||
* @deprecated Use Json::jsonGetLastError()
|
||||
*/
|
||||
public static function jsonGetLastError(bool $return_string = false)
|
||||
{
|
||||
return Json::jsonGetLastError($return_string);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
412
4dev/deprecated/CoreLibs/Combined/ArrayHandler.php
Normal file
412
4dev/deprecated/CoreLibs/Combined/ArrayHandler.php
Normal file
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* array search and transform functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Combined;
|
||||
|
||||
class ArrayHandler
|
||||
{
|
||||
/**
|
||||
* searches key = value in an array / array
|
||||
* only returns the first one found
|
||||
*
|
||||
* @param string|int $needle needle (search for)
|
||||
* @param array<mixed> $haystack haystack (search in)
|
||||
* @param string|null $key_search_for the key to look out for, default empty
|
||||
* @return array<mixed> array with the elements where
|
||||
* the needle can be found in the
|
||||
* haystack array
|
||||
*/
|
||||
public static function arraySearchRecursive($needle, array $haystack, ?string $key_search_for = null): array
|
||||
{
|
||||
$path = [];
|
||||
if (!is_array($haystack)) {
|
||||
$haystack = [];
|
||||
}
|
||||
if (
|
||||
$key_search_for != null &&
|
||||
array_key_exists($key_search_for, $haystack) &&
|
||||
$needle === $haystack[$key_search_for]
|
||||
) {
|
||||
$path[] = $key_search_for;
|
||||
} else {
|
||||
foreach ($haystack as $key => $val) {
|
||||
if (
|
||||
is_scalar($val) &&
|
||||
$val === $needle &&
|
||||
empty($key_search_for)
|
||||
) {
|
||||
$path[] = $key;
|
||||
break;
|
||||
} elseif (
|
||||
is_scalar($val) &&
|
||||
!empty($key_search_for) &&
|
||||
$key === $key_search_for &&
|
||||
$val === $needle
|
||||
) {
|
||||
$path[] = $key;
|
||||
break;
|
||||
} elseif (
|
||||
is_array($val) &&
|
||||
$path = self::arraySearchRecursive(
|
||||
$needle,
|
||||
(array)$val,
|
||||
// to avoid PhanTypeMismatchArgumentNullable
|
||||
($key_search_for === null ? $key_search_for : (string)$key_search_for)
|
||||
)
|
||||
) {
|
||||
array_unshift($path, $key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* recursive array search function, which returns all found not only the first one
|
||||
*
|
||||
* @param string|int $needle needle (search for)
|
||||
* @param array<mixed> $haystack haystack (search in)
|
||||
* @param string|int $key_search_for the key to look for in
|
||||
* @param bool $old [true], if set to false will
|
||||
* return new flat layout
|
||||
* @param array<mixed>|null $path recursive call for previous path
|
||||
* @return array<mixed>|null all array elements paths where
|
||||
* the element was found
|
||||
*/
|
||||
public static function arraySearchRecursiveAll(
|
||||
$needle,
|
||||
array $haystack,
|
||||
$key_search_for,
|
||||
bool $old = true,
|
||||
?array $path = null
|
||||
): ?array {
|
||||
// init if not set on null
|
||||
if ($path === null) {
|
||||
$path = [
|
||||
'level' => 0,
|
||||
'work' => []
|
||||
];
|
||||
} else {
|
||||
// init sub sets if not set
|
||||
if (!isset($path['level'])) {
|
||||
$path['level'] = 0;
|
||||
}
|
||||
if (!isset($path['work'])) {
|
||||
$path['work'] = [];
|
||||
}
|
||||
}
|
||||
// should not be needed because it would trigger a php mehtod error
|
||||
if (!is_array($haystack)) {
|
||||
$haystack = [];
|
||||
}
|
||||
|
||||
// go through the array,
|
||||
foreach ($haystack as $_key => $_value) {
|
||||
if (
|
||||
is_scalar($_value) &&
|
||||
$_value === $needle &&
|
||||
empty($key_search_for)
|
||||
) {
|
||||
// only value matches
|
||||
$path['work'][$path['level'] ?? 0] = $_key;
|
||||
$path['found'][] = $path['work'];
|
||||
} elseif (
|
||||
is_scalar($_value) &&
|
||||
!empty($key_search_for) &&
|
||||
$_key === $key_search_for &&
|
||||
$_value === $needle
|
||||
) {
|
||||
// key and value matches
|
||||
$path['work'][$path['level'] ?? 0] = $_key;
|
||||
$path['found'][] = $path['work'];
|
||||
} elseif (is_array($_value)) {
|
||||
// add position to working
|
||||
$path['work'][$path['level'] ?? 0] = $_key;
|
||||
// we will up a level
|
||||
$path['level'] += 1;
|
||||
// call recursive
|
||||
$path = self::arraySearchRecursiveAll($needle, $_value, $key_search_for, $old, $path);
|
||||
}
|
||||
}
|
||||
// be 100% sure the array elements are set
|
||||
$path['level'] = $path['level'] ?? 0;
|
||||
$path['work'] = $path['work'] ?? [];
|
||||
// cut all that is >= level
|
||||
array_splice($path['work'], $path['level']);
|
||||
// step back a level
|
||||
$path['level'] -= 1;
|
||||
if ($old === false && $path['level'] == -1) {
|
||||
return $path['found'] ?? [];
|
||||
} else {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array search simple. looks for key, value combination, if found, returns true
|
||||
* on default does not strict check, so string '4' will match int 4 and vica versa
|
||||
*
|
||||
* @param array<mixed> $array search in as array
|
||||
* @param string|int $key key (key to search in)
|
||||
* @param string|int $value value (what to find)
|
||||
* @param bool $strict [false], if set to true, will strict check key/value
|
||||
* @return bool true on found, false on not found
|
||||
*/
|
||||
public static function arraySearchSimple(array $array, $key, $value, bool $strict = false): bool
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
$array = [];
|
||||
}
|
||||
foreach ($array as $_key => $_value) {
|
||||
// if value is an array, we search
|
||||
if (is_array($_value)) {
|
||||
// call recursive, and return result if it is true, else continue
|
||||
if (($result = self::arraySearchSimple($_value, $key, $value, $strict)) !== false) {
|
||||
return $result;
|
||||
}
|
||||
} elseif ($strict === false && $_key == $key && $_value == $value) {
|
||||
return true;
|
||||
} elseif ($strict === true && $_key === $key && $_value === $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// no true returned, not found
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* correctly recursive merges as an array as array_merge_recursive
|
||||
* just glues things together
|
||||
* array first array to merge
|
||||
* array second array to merge
|
||||
* ... etc
|
||||
* bool key flag: true: handle keys as string or int
|
||||
* default false: all keys are string
|
||||
*
|
||||
* @return array<mixed>|bool merged array
|
||||
*/
|
||||
public static function arrayMergeRecursive()
|
||||
{
|
||||
// croak on not enough arguemnts (we need at least two)
|
||||
if (func_num_args() < 2) {
|
||||
trigger_error(__FUNCTION__ . ' needs two or more array arguments', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
// default key is not string
|
||||
$key_is_string = false;
|
||||
$arrays = func_get_args();
|
||||
// if last is not array, then assume it is trigger for key is always string
|
||||
if (!is_array(end($arrays))) {
|
||||
if (array_pop($arrays)) {
|
||||
$key_is_string = true;
|
||||
}
|
||||
}
|
||||
// check that arrays count is at least two, else we don't have enough to do anything
|
||||
if (count($arrays) < 2) {
|
||||
trigger_error(__FUNCTION__ . ' needs two or more array arguments', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
$merged = [];
|
||||
while ($arrays) {
|
||||
$array = array_shift($arrays);
|
||||
if (!is_array($array)) {
|
||||
trigger_error(__FUNCTION__ . ' encountered a non array argument', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
if (!$array) {
|
||||
continue;
|
||||
}
|
||||
foreach ($array as $key => $value) {
|
||||
// if string or if key is assumed to be string do key match
|
||||
// else add new entry
|
||||
if (is_string($key) || $key_is_string === false) {
|
||||
if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key])) {
|
||||
// $merged[$key] = call_user_func(__METHOD__, $merged[$key], $value, $key_is_string);
|
||||
$merged[$key] = self::arrayMergeRecursive($merged[$key], $value, $key_is_string);
|
||||
} else {
|
||||
$merged[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
$merged[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* correct array_diff that does an actualy difference between two arrays.
|
||||
* array_diff only checks elements from A that are not in B, but not the
|
||||
* other way around.
|
||||
* Note that like array_diff this only checks first level values not keys
|
||||
*
|
||||
* @param array<mixed> $a array to compare a
|
||||
* @param array<mixed> $b array to compare b
|
||||
* @return array<mixed> array with missing elements from a & b
|
||||
*/
|
||||
public static function arrayDiff(array $a, array $b): array
|
||||
{
|
||||
$intersect = array_intersect($a, $b);
|
||||
return array_merge(array_diff($a, $intersect), array_diff($b, $intersect));
|
||||
}
|
||||
|
||||
/**
|
||||
* search for the needle array elements in haystack and
|
||||
* return the ones found as an array,
|
||||
* is there nothing found, it returns FALSE (boolean)
|
||||
*
|
||||
* @param array<mixed> $needle elements to search for
|
||||
* @param array<mixed> $haystack array where the $needle elements should
|
||||
* be searched int
|
||||
* @return array<mixed>|bool either the found elements or
|
||||
* false for nothing found or error
|
||||
*/
|
||||
public static function inArrayAny(array $needle, array $haystack)
|
||||
{
|
||||
$found = [];
|
||||
foreach ($needle as $element) {
|
||||
if (in_array($element, $haystack)) {
|
||||
$found[] = $element;
|
||||
}
|
||||
}
|
||||
if (count($found) == 0) {
|
||||
return false;
|
||||
} else {
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates out of a normal db_return array an assoc array
|
||||
*
|
||||
* @param array<mixed> $db_array return array from the database
|
||||
* @param string|int|bool $key key set, false for not set
|
||||
* @param string|int|bool $value value set, false for not set
|
||||
* @param bool $set_only flag to return all (default), or set only
|
||||
* @return array<mixed> associative array
|
||||
*/
|
||||
public static function genAssocArray(array $db_array, $key, $value, bool $set_only = false): array
|
||||
{
|
||||
$ret_array = [];
|
||||
// do this to only run count once
|
||||
for ($i = 0, $iMax = count($db_array); $i < $iMax; $i++) {
|
||||
// if no key then we make an order reference
|
||||
if (
|
||||
$key !== false &&
|
||||
$value !== false &&
|
||||
(($set_only && !empty($db_array[$i][$value])) ||
|
||||
(!$set_only && isset($db_array[$i][$value]))) &&
|
||||
!empty($db_array[$i][$key])
|
||||
) {
|
||||
$ret_array[$db_array[$i][$key]] = $db_array[$i][$value];
|
||||
} elseif (
|
||||
$key === false && $value !== false &&
|
||||
isset($db_array[$i][$value])
|
||||
) {
|
||||
$ret_array[] = $db_array[$i][$value];
|
||||
} elseif (
|
||||
$key !== false && $value === false &&
|
||||
!empty($db_array[$i][$key])
|
||||
) {
|
||||
$ret_array[$db_array[$i][$key]] = $i;
|
||||
}
|
||||
}
|
||||
return $ret_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts multi dimensional array to a flat array
|
||||
* does NOT preserve keys
|
||||
*
|
||||
* @param array<mixed> $array multi dimensionial array
|
||||
* @return array<mixed> flattened array
|
||||
*/
|
||||
public static function flattenArray(array $array): array
|
||||
{
|
||||
$return = [];
|
||||
array_walk_recursive(
|
||||
$array,
|
||||
function ($value) use (&$return) {
|
||||
$return[] = $value;
|
||||
}
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* will loop through an array recursivly and write the array keys back
|
||||
*
|
||||
* @param array<mixed> $array multidemnsional array to flatten
|
||||
* @param array<mixed> $return recoursive pass on array of keys
|
||||
* @return array<mixed> flattened keys array
|
||||
*/
|
||||
public static function flattenArrayKey(array $array, array $return = []): array
|
||||
{
|
||||
foreach ($array as $key => $sub) {
|
||||
$return[] = $key;
|
||||
if (is_array($sub) && count($sub) > 0) {
|
||||
$return = self::flattenArrayKey($sub, $return);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* as above will flatten an array, but in this case only the outmost
|
||||
* leave nodes, all other keyswill be skipped
|
||||
*
|
||||
* @param array<mixed> $array multidemnsional array to flatten
|
||||
* @return array<mixed> flattened keys array
|
||||
*/
|
||||
public static function flattenArrayKeyLeavesOnly(array $array): array
|
||||
{
|
||||
$return = [];
|
||||
array_walk_recursive(
|
||||
$array,
|
||||
function ($value, $key) use (&$return) {
|
||||
$return[] = $key;
|
||||
}
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* searches for key -> value in an array tree and writes the value one level up
|
||||
* this will remove this leaf will all other values
|
||||
*
|
||||
* @param array<mixed> $array nested array
|
||||
* @param string|int $search key to find that has no sub leaf
|
||||
* and will be pushed up
|
||||
* @return array<mixed> modified, flattened array
|
||||
*/
|
||||
public static function arrayFlatForKey(array $array, $search): array
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
$array = [];
|
||||
}
|
||||
foreach ($array as $key => $value) {
|
||||
// if it is not an array do just nothing
|
||||
if (!is_array($value)) {
|
||||
continue;
|
||||
}
|
||||
// probe it has search key
|
||||
if (isset($value[$search])) {
|
||||
// set as current
|
||||
$array[$key] = $value[$search];
|
||||
} else {
|
||||
// call up next node down
|
||||
// $array[$key] = call_user_func(__METHOD__, $value, $search);
|
||||
$array[$key] = self::arrayFlatForKey($value, $search);
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
452
4dev/deprecated/CoreLibs/Combined/DateTime.php
Normal file
452
4dev/deprecated/CoreLibs/Combined/DateTime.php
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* date convert and check functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Combined;
|
||||
|
||||
use Exception;
|
||||
|
||||
class DateTime
|
||||
{
|
||||
/** @var array<int,string> */
|
||||
public const DAY_SHORT = [
|
||||
1 => 'Mon',
|
||||
2 => 'Tue',
|
||||
3 => 'Wed',
|
||||
4 => 'Thu',
|
||||
5 => 'Fri',
|
||||
6 => 'Sat',
|
||||
7 => 'Sun',
|
||||
];
|
||||
/** @var array<int,string> */
|
||||
public const DAY_LONG = [
|
||||
1 => 'Monday',
|
||||
2 => 'Tuesday',
|
||||
3 => 'Wednesday',
|
||||
4 => 'Thursday',
|
||||
5 => 'Friday',
|
||||
6 => 'Saturday',
|
||||
7 => 'Sunday',
|
||||
];
|
||||
/** @var array<int,string> */
|
||||
public const MONTH_LONG = [
|
||||
1 => 'January',
|
||||
2 => 'February',
|
||||
3 => 'March',
|
||||
4 => 'April',
|
||||
5 => 'May',
|
||||
6 => 'June',
|
||||
7 => 'July',
|
||||
8 => 'August',
|
||||
9 => 'September',
|
||||
10 => 'October',
|
||||
11 => 'November',
|
||||
12 => 'December',
|
||||
];
|
||||
/** @var array<int,string> */
|
||||
public const MONTH_SHORT = [
|
||||
1 => 'Jan',
|
||||
2 => 'Feb',
|
||||
3 => 'Mar',
|
||||
4 => 'Apr',
|
||||
5 => 'May',
|
||||
6 => 'Jun',
|
||||
7 => 'Jul',
|
||||
8 => 'Aug',
|
||||
9 => 'Sep',
|
||||
10 => 'Oct',
|
||||
11 => 'Nov',
|
||||
12 => 'Dec',
|
||||
];
|
||||
|
||||
/**
|
||||
* a simple wrapper for the date format
|
||||
* if an invalid timestamp is give zero timestamp unix time is used
|
||||
*
|
||||
* @param int|float $timestamp unix timestamp
|
||||
* @param bool $show_micro show the micro time (default false)
|
||||
* @param bool $micro_as_float Add the micro time with . instead
|
||||
* of ms (default false)
|
||||
* @return string formated date+time in Y-M-D h:m:s ms
|
||||
*/
|
||||
public static function dateStringFormat(
|
||||
$timestamp,
|
||||
bool $show_micro = false,
|
||||
bool $micro_as_float = false
|
||||
): string {
|
||||
// split up the timestamp, assume . in timestamp
|
||||
// array pad $ms if no microtime
|
||||
list ($timestamp, $ms) = array_pad(explode('.', (string)round($timestamp, 4)), 2, null);
|
||||
$string = date("Y-m-d H:i:s", (int)$timestamp);
|
||||
if ($show_micro && $ms) {
|
||||
if ($micro_as_float == false) {
|
||||
$string .= ' ' . $ms . 'ms';
|
||||
} else {
|
||||
$string .= '.' . $ms;
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* formats a timestamp into interval, not into a date
|
||||
*
|
||||
* @param string|int|float $timestamp interval in seconds and optional
|
||||
* float micro seconds
|
||||
* @param bool $show_micro show micro seconds, default true
|
||||
* @return string interval formatted string or string as is
|
||||
*/
|
||||
public static function timeStringFormat($timestamp, bool $show_micro = true): string
|
||||
{
|
||||
// check if the timestamp has any h/m/s/ms inside, if yes skip
|
||||
if (!preg_match("/(h|m|s|ms)/", (string)$timestamp)) {
|
||||
list($timestamp, $ms) = array_pad(explode('.', (string)round((float)$timestamp, 4)), 2, null);
|
||||
// if negative remember
|
||||
$negative = false;
|
||||
if ((int)$timestamp < 0) {
|
||||
$negative = true;
|
||||
}
|
||||
$timestamp = abs((float)$timestamp);
|
||||
$timegroups = [86400, 3600, 60, 1];
|
||||
$labels = ['d', 'h', 'm', 's'];
|
||||
$time_string = '';
|
||||
// if timestamp is zero, return zero string
|
||||
if ($timestamp == 0) {
|
||||
$time_string = '0s';
|
||||
} else {
|
||||
for ($i = 0, $iMax = count($timegroups); $i < $iMax; $i++) {
|
||||
$output = floor((float)$timestamp / $timegroups[$i]);
|
||||
$timestamp = (float)$timestamp % $timegroups[$i];
|
||||
// output has days|hours|min|sec
|
||||
if ($output || $time_string) {
|
||||
$time_string .= $output . $labels[$i] . (($i + 1) != count($timegroups) ? ' ' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
// only add ms if we have an ms value
|
||||
if ($ms !== null) {
|
||||
// if we have ms and it has leading zeros, remove them, but only if it is nut just 0
|
||||
$ms = preg_replace("/^0+(\d+)$/", '${1}', $ms);
|
||||
if (!is_string($ms) || empty($ms)) {
|
||||
$ms = '0';
|
||||
}
|
||||
// add ms if there
|
||||
if ($show_micro) {
|
||||
$time_string .= ' ' . $ms . 'ms';
|
||||
} elseif (!$time_string) {
|
||||
$time_string .= $ms . 'ms';
|
||||
}
|
||||
}
|
||||
if ($negative) {
|
||||
$time_string = '-' . $time_string;
|
||||
}
|
||||
} else {
|
||||
$time_string = $timestamp;
|
||||
}
|
||||
return (string)$time_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* does a reverse of the timeStringFormat and converts the string from
|
||||
* xd xh xm xs xms to a timestamp.microtime format
|
||||
*
|
||||
* @param string|int|float $timestring formatted interval
|
||||
* @return string|int|float converted float interval, or string as is
|
||||
*/
|
||||
public static function stringToTime($timestring)
|
||||
{
|
||||
$timestamp = 0;
|
||||
if (preg_match("/(d|h|m|s|ms)/", (string)$timestring)) {
|
||||
$timestring = (string)$timestring;
|
||||
// pos for preg match read + multiply factor
|
||||
$timegroups = [2 => 86400, 4 => 3600, 6 => 60, 8 => 1];
|
||||
$matches = [];
|
||||
// if start with -, strip and set negative
|
||||
$negative = false;
|
||||
if (preg_match("/^-/", $timestring)) {
|
||||
$negative = true;
|
||||
$timestring = substr($timestring, 1);
|
||||
}
|
||||
// preg match: 0: full string
|
||||
// 2, 4, 6, 8 are the to need values
|
||||
preg_match("/^((\d+)d ?)?((\d+)h ?)?((\d+)m ?)?((\d+)s ?)?((\d+)ms)?$/", $timestring, $matches);
|
||||
// multiply the returned matches and sum them up. the last one (ms) is added with .
|
||||
foreach ($timegroups as $i => $time_multiply) {
|
||||
if (isset($matches[$i]) && is_numeric($matches[$i])) {
|
||||
$timestamp += (float)$matches[$i] * $time_multiply;
|
||||
}
|
||||
}
|
||||
if (isset($matches[10]) && is_numeric($matches[10])) {
|
||||
$timestamp .= '.' . $matches[10];
|
||||
}
|
||||
if ($negative) {
|
||||
// cast to flaot so we can do a negative multiplication
|
||||
$timestamp = (float)$timestamp * -1;
|
||||
}
|
||||
return $timestamp;
|
||||
} else {
|
||||
return $timestring;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns long or short day of week name based on ISO day of week number
|
||||
* 1: Monday
|
||||
* ...
|
||||
* 7: Sunday
|
||||
*
|
||||
* @param int $isodow 1: Monday, 7: Sunday
|
||||
* @param bool $long Default false 'Mon', if true 'Monday'
|
||||
* @return string Day of week string either short 'Mon' or long 'Monday'
|
||||
*/
|
||||
public static function setWeekdayNameFromIsoDow(int $isodow, bool $long = false): string
|
||||
{
|
||||
// if not valid, set to invalid
|
||||
if ($isodow < 1 || $isodow > 7) {
|
||||
return $long ? 'Invalid' : 'Inv';
|
||||
}
|
||||
return date($long ? 'l' : 'D', strtotime("Sunday +{$isodow} days") ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day of week Name from date
|
||||
*
|
||||
* @param string $date Any valid date
|
||||
* @param bool $long Default false 'Mon', if true 'Monday'
|
||||
* @return string Day of week string either short 'Mon' or long 'Monday'
|
||||
*/
|
||||
public static function setWeekdayNameFromDate(string $date, bool $long = false): string
|
||||
{
|
||||
if (!self::checkDate($date)) {
|
||||
return $long ? 'Invalid' : 'Inv';
|
||||
}
|
||||
return date($long ? 'l' : 'D', strtotime($date) ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day of week Name from date
|
||||
*
|
||||
* @param string $date Any valid date
|
||||
* @return int ISO Weekday number 1: Monday, 7: Sunday, -1 for invalid date
|
||||
*/
|
||||
public static function setWeekdayNumberFromDate(string $date): int
|
||||
{
|
||||
if (!self::checkDate($date)) {
|
||||
return -1;
|
||||
}
|
||||
return (int)date('N', strtotime($date) ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
* splits & checks date, wrap around for check_date function
|
||||
*
|
||||
* @param string $date a date string in the format YYYY-MM-DD
|
||||
* @return bool true if valid date, false if date not valid
|
||||
*/
|
||||
public static function checkDate($date): bool
|
||||
{
|
||||
if (!$date) {
|
||||
return false;
|
||||
}
|
||||
list ($year, $month, $day) = array_pad(
|
||||
preg_split("/[\/-]/", $date) ?: [],
|
||||
3,
|
||||
null
|
||||
);
|
||||
if (!$year || !$month || !$day) {
|
||||
return false;
|
||||
}
|
||||
if (!checkdate((int)$month, (int)$day, (int)$year)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* splits & checks date, wrap around for check_date function
|
||||
*
|
||||
* @param string $datetime date (YYYY-MM-DD) + time (HH:MM:SS), SS can be dropped
|
||||
* @return bool true if valid date, false if date not valid
|
||||
*/
|
||||
public static function checkDateTime(string $datetime): bool
|
||||
{
|
||||
if (!$datetime) {
|
||||
return false;
|
||||
}
|
||||
// catch last overflow if sec has - in front
|
||||
list ($year, $month, $day, $hour, $min, $sec, $sec_overflow) = array_pad(
|
||||
preg_split("/[\/\- :]/", $datetime) ?: [],
|
||||
7,
|
||||
null
|
||||
);
|
||||
if (!$year || !$month || !$day) {
|
||||
return false;
|
||||
}
|
||||
if (!checkdate((int)$month, (int)$day, (int)$year)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_numeric($hour) || !is_numeric($min)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($sec) && !is_numeric($sec)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($sec) && ($sec < 0 || $sec > 60)) {
|
||||
return false;
|
||||
};
|
||||
// in case we have - for seconds
|
||||
if (!empty($sec_overflow)) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
($hour < 0 || $hour > 24) ||
|
||||
($min < 0 || $min > 60)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (s<e)/0 (s=e)/1 (s>e) as difference
|
||||
*/
|
||||
public static function compareDate($start_date, $end_date)
|
||||
{
|
||||
// pre check for empty or wrong
|
||||
if ($start_date == '--' || $end_date == '--' || !$start_date || !$end_date) {
|
||||
return false;
|
||||
}
|
||||
// if invalid, quit
|
||||
if (($start_timestamp = strtotime($start_date)) === false) {
|
||||
return false;
|
||||
}
|
||||
if (($end_timestamp = strtotime($end_date)) === false) {
|
||||
return false;
|
||||
}
|
||||
// convert anything to Y-m-d and then to timestamp
|
||||
// this is to remove any time parts
|
||||
$start_timestamp = strtotime(date('Y-m-d', $start_timestamp));
|
||||
$end_timestamp = strtotime(date('Y-m-d', $end_timestamp));
|
||||
// compare, or end with false
|
||||
if ($start_timestamp < $end_timestamp) {
|
||||
return -1;
|
||||
} elseif ($start_timestamp == $end_timestamp) {
|
||||
return 0;
|
||||
} elseif ($start_timestamp > $end_timestamp) {
|
||||
return 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* compares the two dates + times. if seconds missing in one set,
|
||||
* 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 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 (s<e)/0 (s=e)/1 (s>e) as difference
|
||||
*/
|
||||
public static function compareDateTime($start_datetime, $end_datetime)
|
||||
{
|
||||
// pre check for empty or wrong
|
||||
if ($start_datetime == '--' || $end_datetime == '--' || !$start_datetime || !$end_datetime) {
|
||||
return false;
|
||||
}
|
||||
// quit if invalid timestamp
|
||||
if (($start_timestamp = strtotime($start_datetime)) === false) {
|
||||
return false;
|
||||
}
|
||||
if (($end_timestamp = strtotime($end_datetime)) === false) {
|
||||
return false;
|
||||
}
|
||||
// compare, or return false
|
||||
if ($start_timestamp < $end_timestamp) {
|
||||
return -1;
|
||||
} elseif ($start_timestamp == $end_timestamp) {
|
||||
return 0;
|
||||
} elseif ($start_timestamp > $end_timestamp) {
|
||||
return 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the days between two dates
|
||||
* return: overall days, week days, weekend days as array 0...2 or named
|
||||
* as overall, weekday and weekend
|
||||
*
|
||||
* @param string $start_date valid start date (y/m/d)
|
||||
* @param string $end_date valid end date (y/m/d)
|
||||
* @param bool $return_named return array type, false (default), true for named
|
||||
* @return array<mixed> 0/overall, 1/weekday, 2/weekend
|
||||
*/
|
||||
public static function calcDaysInterval($start_date, $end_date, bool $return_named = false): array
|
||||
{
|
||||
// pos 0 all, pos 1 weekday, pos 2 weekend
|
||||
$days = [];
|
||||
// if anything invalid, return 0,0,0
|
||||
try {
|
||||
$start = new \DateTime($start_date);
|
||||
$end = new \DateTime($end_date);
|
||||
} catch (Exception $e) {
|
||||
if ($return_named === true) {
|
||||
return [
|
||||
'overall' => 0,
|
||||
'weekday' => 0,
|
||||
'weekend' => 0,
|
||||
];
|
||||
} else {
|
||||
return [0, 0, 0];
|
||||
}
|
||||
}
|
||||
// so we include the last day too, we need to add +1 second in the time
|
||||
$end->setTime(0, 0, 1);
|
||||
// if end date before start date, only this will be filled
|
||||
$days[0] = $end->diff($start)->days;
|
||||
$days[1] = 0;
|
||||
$days[2] = 0;
|
||||
// get period for weekends/weekdays
|
||||
$period = new \DatePeriod($start, new \DateInterval('P1D'), $end);
|
||||
foreach ($period as $dt) {
|
||||
$curr = $dt->format('D');
|
||||
if ($curr == 'Sat' || $curr == 'Sun') {
|
||||
$days[2] ++;
|
||||
} else {
|
||||
$days[1] ++;
|
||||
}
|
||||
}
|
||||
if ($return_named === true) {
|
||||
return [
|
||||
'overall' => $days[0],
|
||||
'weekday' => $days[1],
|
||||
'weekend' => $days[2],
|
||||
];
|
||||
} else {
|
||||
return $days;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
167
4dev/deprecated/CoreLibs/Convert/Byte.php
Normal file
167
4dev/deprecated/CoreLibs/Convert/Byte.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* byte conversion from and to human readable
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Convert;
|
||||
|
||||
class Byte
|
||||
{
|
||||
// define byteFormat
|
||||
public const BYTE_FORMAT_NOSPACE = 1;
|
||||
public const BYTE_FORMAT_ADJUST = 2;
|
||||
public const BYTE_FORMAT_SI = 4;
|
||||
|
||||
/**
|
||||
* This function replaces the old byteStringFormat
|
||||
*
|
||||
* Converts any number string to human readable byte format
|
||||
* Maxium is Exobytes and above that the Exobytes suffix is used for all
|
||||
* If more are needed only the correct short name for the suffix has to be
|
||||
* added to the labels array
|
||||
* On no number string it returns string as is
|
||||
* 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 suffix
|
||||
* BYTE_FORMAT_ADJUST [2] use sprintf to always print two decimals
|
||||
* 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
|
||||
{
|
||||
// if not numeric, return as is
|
||||
if (is_numeric($bytes)) {
|
||||
// flags bit wise check
|
||||
// remove space between number and suffix
|
||||
if ($flags & self::BYTE_FORMAT_NOSPACE) {
|
||||
$space = false;
|
||||
} else {
|
||||
$space = true;
|
||||
}
|
||||
// use sprintf instead of round
|
||||
if ($flags & self::BYTE_FORMAT_ADJUST) {
|
||||
$adjust = true;
|
||||
} else {
|
||||
$adjust = false;
|
||||
}
|
||||
// use SI 1000 mod and not 1024 mod
|
||||
if ($flags & self::BYTE_FORMAT_SI) {
|
||||
$si = true;
|
||||
} 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((float)$bytes);
|
||||
// smaller than unit is always B
|
||||
if ($abs_bytes < $unit) {
|
||||
return $bytes . 'B';
|
||||
}
|
||||
// labels in order of size [Y, Z]
|
||||
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
|
||||
// exp position calculation
|
||||
$exp = floor(log($abs_bytes, $unit));
|
||||
// avoid printing out anything larger than max labels
|
||||
if ($exp >= count($labels)) {
|
||||
$exp = count($labels) - 1;
|
||||
}
|
||||
// deviation calculation
|
||||
$dev = pow($unit, $exp) * ($unit - 0.05);
|
||||
// shift the exp +1 for on the border units
|
||||
if (
|
||||
$exp < 6 &&
|
||||
$abs_bytes > ($dev - (((int)$dev & 0xfff) == 0xd00 ? 52 : 0))
|
||||
) {
|
||||
$exp++;
|
||||
}
|
||||
// label name, including leading space if flagged
|
||||
$pre = ($space ? ' ' : '') . ($labels[$exp] ?? '>E') . ($si ? 'i' : '') . 'B';
|
||||
$bytes_calc = $abs_bytes / pow($unit, $exp);
|
||||
// if original is negative, reverse
|
||||
if ($bytes < 0) {
|
||||
$bytes_calc *= -1;
|
||||
}
|
||||
if ($adjust) {
|
||||
return sprintf("%.2f%s", $bytes_calc, $pre);
|
||||
} else {
|
||||
return round($bytes_calc, 2) . $pre;
|
||||
}
|
||||
} else {
|
||||
// if anything other return as string
|
||||
return (string)$bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the bytes based on a string with nnG, nnGB, nnM, etc
|
||||
* NOTE: large exabyte numbers will overflow
|
||||
* flag allowed:
|
||||
* 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)
|
||||
{
|
||||
// use SI 1000 mod and not 1024 mod
|
||||
if ($flags & self::BYTE_FORMAT_SI) {
|
||||
$si = true;
|
||||
} else {
|
||||
$si = false;
|
||||
}
|
||||
if ($flags != 0 && $flags != 4) {
|
||||
throw new \Exception("Invalid flags parameter: $flags", 1);
|
||||
}
|
||||
// matches in regex
|
||||
$matches = [];
|
||||
// all valid units
|
||||
$valid_units_ = 'bkmgtpezy';
|
||||
// detects up to exo bytes
|
||||
preg_match(
|
||||
"/(-)?([\d.,]*)\s?(eib|pib|tib|gib|mib|kib|eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i",
|
||||
strtolower((string)$number),
|
||||
$matches
|
||||
);
|
||||
if (isset($matches[2]) && isset($matches[3])) {
|
||||
// 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((string)$number);
|
||||
// convert any mb/gb/etc to single m/b
|
||||
$unit = preg_replace('/[^bkmgtpezy]/i', '', $matches[3]);
|
||||
if ($unit) {
|
||||
$number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0);
|
||||
}
|
||||
// convert to INT to avoid +E output
|
||||
$number = (int)round($number);
|
||||
// if negative input, keep nnegative
|
||||
if (!empty($matches[1])) {
|
||||
$number *= -1;
|
||||
}
|
||||
}
|
||||
// if not matching return as is
|
||||
return $number;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
344
4dev/deprecated/CoreLibs/Convert/Colors.php
Normal file
344
4dev/deprecated/CoreLibs/Convert/Colors.php
Normal file
@@ -0,0 +1,344 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Convert color spaces
|
||||
* rgb to hex
|
||||
* hex to rgb
|
||||
* rgb to hsb
|
||||
* hsb to rgb
|
||||
* rgb to hsl
|
||||
* hsl to rgb
|
||||
*/
|
||||
|
||||
// TODO: use oklab as base for converting colors
|
||||
// https://bottosson.github.io/posts/oklab/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Convert;
|
||||
|
||||
class Colors
|
||||
{
|
||||
/**
|
||||
* converts the rgb values from int data to the valid rgb html hex string
|
||||
* optional can turn of leading #
|
||||
* if one value is invalid, will return false
|
||||
*
|
||||
* @param int $red red 0-255
|
||||
* @param int $green green 0-255
|
||||
* @param int $blue blue 0-255
|
||||
* @param bool $hex_prefix default true, prefix with "#"
|
||||
* @return string|bool rgb in hex values with leading # if set,
|
||||
* false for invalid color
|
||||
*/
|
||||
public static function rgb2hex(int $red, int $green, int $blue, bool $hex_prefix = true)
|
||||
{
|
||||
$hex_color = '';
|
||||
if ($hex_prefix === true) {
|
||||
$hex_color = '#';
|
||||
}
|
||||
foreach (['red', 'green', 'blue'] as $color) {
|
||||
// if not valid, abort
|
||||
if ($$color < 0 || $$color > 255) {
|
||||
return false;
|
||||
}
|
||||
// pad left with 0
|
||||
$hex_color .= str_pad(dechex($$color), 2, '0', STR_PAD_LEFT);
|
||||
}
|
||||
return $hex_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts a hex RGB color to the int numbers
|
||||
*
|
||||
* @param string $hexStr RGB hexstring
|
||||
* @param bool $return_as_string flag to return as string
|
||||
* @param string $seperator string seperator: default: ","
|
||||
* @return string|array<string,float|int>|bool false on error or array with RGB
|
||||
* or a string with the seperator
|
||||
*/
|
||||
public static function hex2rgb(
|
||||
string $hexStr,
|
||||
bool $return_as_string = false,
|
||||
string $seperator = ','
|
||||
) {
|
||||
$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string
|
||||
if (!is_string($hexStr)) {
|
||||
return false;
|
||||
}
|
||||
$rgbArray = [];
|
||||
if (strlen($hexStr) == 6) {
|
||||
// If a proper hex code, convert using bitwise operation.
|
||||
// No overhead... faster
|
||||
$colorVal = hexdec($hexStr);
|
||||
$rgbArray['r'] = 0xFF & ($colorVal >> 0x10);
|
||||
$rgbArray['g'] = 0xFF & ($colorVal >> 0x8);
|
||||
$rgbArray['b'] = 0xFF & $colorVal;
|
||||
} elseif (strlen($hexStr) == 3) {
|
||||
// If shorthand notation, need some string manipulations
|
||||
$rgbArray['r'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
|
||||
$rgbArray['g'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
|
||||
$rgbArray['b'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
|
||||
} else {
|
||||
// Invalid hex color code
|
||||
return false;
|
||||
}
|
||||
// returns the rgb string or the associative array
|
||||
return $return_as_string ? implode($seperator, $rgbArray) : $rgbArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* rgb2hsb does not clean convert back to rgb in a round trip
|
||||
* converts RGB to HSB/V values
|
||||
* returns:
|
||||
* array with hue (0-360), sat (0-100%), brightness/value (0-100%)
|
||||
*
|
||||
* @param int $red red 0-255
|
||||
* @param int $green green 0-255
|
||||
* @param int $blue blue 0-255
|
||||
* @return array<int|float>|bool Hue, Sat, Brightness/Value
|
||||
* false for input value error
|
||||
*/
|
||||
public static function rgb2hsb(int $red, int $green, int $blue)
|
||||
{
|
||||
// check that rgb is from 0 to 255
|
||||
foreach (['red', 'green', 'blue'] as $c) {
|
||||
if ($$c < 0 || $$c > 255) {
|
||||
return false;
|
||||
}
|
||||
$$c = $$c / 255;
|
||||
}
|
||||
|
||||
$MAX = max($red, $green, $blue);
|
||||
$MIN = min($red, $green, $blue);
|
||||
$HUE = 0;
|
||||
|
||||
if ($MAX == $MIN) {
|
||||
return [0, 0, round($MAX * 100)];
|
||||
}
|
||||
if ($red == $MAX) {
|
||||
$HUE = ($green - $blue) / ($MAX - $MIN);
|
||||
} elseif ($green == $MAX) {
|
||||
$HUE = 2 + (($blue - $red) / ($MAX - $MIN));
|
||||
} elseif ($blue == $MAX) {
|
||||
$HUE = 4 + (($red - $green) / ($MAX - $MIN));
|
||||
}
|
||||
$HUE *= 60;
|
||||
if ($HUE < 0) {
|
||||
$HUE += 360;
|
||||
}
|
||||
|
||||
return [
|
||||
(int)round($HUE),
|
||||
(int)round((($MAX - $MIN) / $MAX) * 100),
|
||||
(int)round($MAX * 100)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* hsb2rgb does not clean convert back to hsb in a round trip
|
||||
* converts HSB/V to RGB values RGB is full INT
|
||||
* if HSB/V value is invalid, sets this value to 0
|
||||
*
|
||||
* @param float $H hue 0-360 (int)
|
||||
* @param float $S saturation 0-100 (int)
|
||||
* @param float $V brightness/value 0-100 (int)
|
||||
* @return array<int>|bool 0 red/1 green/2 blue array as 0-255
|
||||
* false for input value error
|
||||
*/
|
||||
public static function hsb2rgb(float $H, float $S, float $V)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
if ($S < 0 || $S > 100) {
|
||||
return false;
|
||||
}
|
||||
if ($V < 0 || $V > 100) {
|
||||
return false;
|
||||
}
|
||||
// convert to internal 0-1 format
|
||||
$S /= 100;
|
||||
$V /= 100;
|
||||
|
||||
if ($S == 0) {
|
||||
$V = (int)round($V * 255);
|
||||
return [$V, $V, $V];
|
||||
}
|
||||
|
||||
$Hi = floor($H / 60);
|
||||
$f = ($H / 60) - $Hi;
|
||||
$p = $V * (1 - $S);
|
||||
$q = $V * (1 - ($S * $f));
|
||||
$t = $V * (1 - ($S * (1 - $f)));
|
||||
|
||||
switch ($Hi) {
|
||||
case 0:
|
||||
$red = $V;
|
||||
$green = $t;
|
||||
$blue = $p;
|
||||
break;
|
||||
case 1:
|
||||
$red = $q;
|
||||
$green = $V;
|
||||
$blue = $p;
|
||||
break;
|
||||
case 2:
|
||||
$red = $p;
|
||||
$green = $V;
|
||||
$blue = $t;
|
||||
break;
|
||||
case 3:
|
||||
$red = $p;
|
||||
$green = $q;
|
||||
$blue = $V;
|
||||
break;
|
||||
case 4:
|
||||
$red = $t;
|
||||
$green = $p;
|
||||
$blue = $V;
|
||||
break;
|
||||
case 5:
|
||||
$red = $V;
|
||||
$green = $p;
|
||||
$blue = $q;
|
||||
break;
|
||||
default:
|
||||
$red = 0;
|
||||
$green = 0;
|
||||
$blue = 0;
|
||||
}
|
||||
|
||||
return [
|
||||
(int)round($red * 255),
|
||||
(int)round($green * 255),
|
||||
(int)round($blue * 255)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* converts a RGB (0-255) to HSL
|
||||
* return:
|
||||
* array with hue (0-360), saturation (0-100%) and luminance (0-100%)
|
||||
*
|
||||
* @param int $red red 0-255
|
||||
* @param int $green green 0-255
|
||||
* @param int $blue blue 0-255
|
||||
* @return array<float>|bool hue/sat/luminance
|
||||
* false for input value error
|
||||
*/
|
||||
public static function rgb2hsl(int $red, int $green, int $blue)
|
||||
{
|
||||
// check that rgb is from 0 to 255
|
||||
foreach (['red', 'green', 'blue'] as $c) {
|
||||
if ($$c < 0 || $$c > 255) {
|
||||
return false;
|
||||
}
|
||||
$$c = $$c / 255;
|
||||
}
|
||||
|
||||
$min = min($red, $green, $blue);
|
||||
$max = max($red, $green, $blue);
|
||||
$chroma = $max - $min;
|
||||
$sat = 0;
|
||||
$hue = 0;
|
||||
// luminance
|
||||
$lum = ($max + $min) / 2;
|
||||
|
||||
// achromatic
|
||||
if ($chroma == 0) {
|
||||
// H, S, L
|
||||
return [0.0, 0.0, round($lum * 100, 1)];
|
||||
} else {
|
||||
$sat = $chroma / (1 - abs(2 * $lum - 1));
|
||||
if ($max == $red) {
|
||||
$hue = fmod((($green - $blue) / $chroma), 6);
|
||||
if ($hue < 0) {
|
||||
$hue = (6 - fmod(abs($hue), 6));
|
||||
}
|
||||
} elseif ($max == $green) {
|
||||
$hue = ($blue - $red) / $chroma + 2;
|
||||
} elseif ($max == $blue) {
|
||||
$hue = ($red - $green) / $chroma + 4;
|
||||
}
|
||||
$hue = $hue * 60;
|
||||
// $sat = 1 - abs(2 * $lum - 1);
|
||||
return [
|
||||
round($hue, 1),
|
||||
round($sat * 100, 1),
|
||||
round($lum * 100, 1)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* converts an HSL to RGB
|
||||
* if HSL value is invalid, set this value to 0
|
||||
*
|
||||
* @param float $hue hue: 0-360 (degrees)
|
||||
* @param float $sat saturation: 0-100
|
||||
* @param float $lum luminance: 0-100
|
||||
* @return array<int,float|int>|bool red/blue/green 0-255 each
|
||||
*/
|
||||
public static function hsl2rgb(float $hue, float $sat, float $lum)
|
||||
{
|
||||
if (!is_numeric($hue)) {
|
||||
return false;
|
||||
}
|
||||
if ($hue == 360) {
|
||||
$hue = 0;
|
||||
}
|
||||
if ($hue < 0 || $hue > 359) {
|
||||
return false;
|
||||
}
|
||||
if ($sat < 0 || $sat > 100) {
|
||||
return false;
|
||||
}
|
||||
if ($lum < 0 || $lum > 100) {
|
||||
return false;
|
||||
}
|
||||
// calc to internal convert value for hue
|
||||
$hue = (1 / 360) * $hue;
|
||||
// convert to internal 0-1 format
|
||||
$sat /= 100;
|
||||
$lum /= 100;
|
||||
// if saturation is 0
|
||||
if ($sat == 0) {
|
||||
$lum = (int)round($lum * 255);
|
||||
return [$lum, $lum, $lum];
|
||||
} else {
|
||||
$m2 = $lum < 0.5 ? $lum * ($sat + 1) : ($lum + $sat) - ($lum * $sat);
|
||||
$m1 = $lum * 2 - $m2;
|
||||
$hueue = function ($base) use ($m1, $m2) {
|
||||
// base = hue, hue > 360 (1) - 360 (1), else < 0 + 360 (1)
|
||||
$base = $base < 0 ? $base + 1 : ($base > 1 ? $base - 1 : $base);
|
||||
// 6: 60, 2: 180, 3: 240
|
||||
// 2/3 = 240
|
||||
// 1/3 = 120 (all from 360)
|
||||
if ($base * 6 < 1) {
|
||||
return $m1 + ($m2 - $m1) * $base * 6;
|
||||
}
|
||||
if ($base * 2 < 1) {
|
||||
return $m2;
|
||||
}
|
||||
if ($base * 3 < 2) {
|
||||
return $m1 + ($m2 - $m1) * ((2 / 3) - $base) * 6;
|
||||
}
|
||||
return $m1;
|
||||
};
|
||||
|
||||
return [
|
||||
(int)round(255 * $hueue($hue + (1 / 3))),
|
||||
(int)round(255 * $hueue($hue)),
|
||||
(int)round(255 * $hueue($hue - (1 / 3)))
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
60
4dev/deprecated/CoreLibs/Convert/Encoding.php
Normal file
60
4dev/deprecated/CoreLibs/Convert/Encoding.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* convert string frmo one encdoing to another with auto detect flags
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Convert;
|
||||
|
||||
class Encoding
|
||||
{
|
||||
/**
|
||||
* detects the source encoding of the string and if doesn't match
|
||||
* to the given target encoding it convert is
|
||||
* if source encoding is set and auto check is true (default) a second
|
||||
* check is done so that the source string encoding actually matches
|
||||
* will be skipped if source encoding detection is ascii
|
||||
*
|
||||
* @param string $string string to convert
|
||||
* @param string $to_encoding target encoding
|
||||
* @param string $source_encoding optional source encoding, will try to auto detect
|
||||
* @param bool $auto_check default true, if source encoding is set
|
||||
* check that the source is actually matching
|
||||
* to what we sav the source is
|
||||
* @return string encoding converted string
|
||||
*/
|
||||
public static function convertEncoding(
|
||||
string $string,
|
||||
string $to_encoding,
|
||||
string $source_encoding = '',
|
||||
bool $auto_check = true
|
||||
): string {
|
||||
// set if not given
|
||||
if (!$source_encoding) {
|
||||
$source_encoding = mb_detect_encoding($string);
|
||||
} else {
|
||||
$_source_encoding = mb_detect_encoding($string);
|
||||
}
|
||||
if (
|
||||
$auto_check === true &&
|
||||
isset($_source_encoding) &&
|
||||
$_source_encoding == $source_encoding
|
||||
) {
|
||||
// trigger check if we have override source encoding.
|
||||
// if different (_source is all but not ascii) then trigger
|
||||
// skip if matching
|
||||
}
|
||||
if ($source_encoding != $to_encoding) {
|
||||
if ($source_encoding) {
|
||||
$string = mb_convert_encoding($string, $to_encoding, $source_encoding);
|
||||
} else {
|
||||
$string = mb_convert_encoding($string, $to_encoding);
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
256
4dev/deprecated/CoreLibs/Convert/Extends/VarSetTypeMain.php
Normal file
256
4dev/deprecated/CoreLibs/Convert/Extends/VarSetTypeMain.php
Normal 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__
|
||||
71
4dev/deprecated/CoreLibs/Convert/MimeEncode.php
Normal file
71
4dev/deprecated/CoreLibs/Convert/MimeEncode.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* alternate for header mime encode to void problems with long strings and
|
||||
* spaces/strange encoding problems.
|
||||
* Orignal issues during PHP5/7
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Convert;
|
||||
|
||||
class MimeEncode
|
||||
{
|
||||
/**
|
||||
* wrapper function for mb mime convert
|
||||
* for correct conversion with long strings
|
||||
*
|
||||
* @param string $string string to encode
|
||||
* @param string $encoding target encoding
|
||||
* @param string $line_break default line break is \r\n
|
||||
* @return string encoded string
|
||||
*/
|
||||
public static function __mbMimeEncode(
|
||||
string $string,
|
||||
string $encoding,
|
||||
string $line_break = "\r\n"
|
||||
): string {
|
||||
$current_internal_encoding = mb_internal_encoding();
|
||||
// set internal encoding, so the mimeheader encode works correctly
|
||||
mb_internal_encoding($encoding);
|
||||
// if a subject, make a work around for the broken mb_mimencode
|
||||
$pos = 0;
|
||||
// after 36 single bytes characters,
|
||||
// if then comes MB, it is broken
|
||||
// has to 2 x 36 < 74 so the mb_encode_mimeheader
|
||||
// 74 hardcoded split does not get triggered
|
||||
$split = 36;
|
||||
$_string = '';
|
||||
while ($pos < mb_strlen($string, $encoding)) {
|
||||
$output = mb_strimwidth($string, $pos, $split, "", $encoding);
|
||||
$pos += mb_strlen($output, $encoding);
|
||||
// if the strinlen is 0 here, get out of the loop
|
||||
if (!mb_strlen($output, $encoding)) {
|
||||
$pos += mb_strlen($string, $encoding);
|
||||
}
|
||||
$_string_encoded = mb_encode_mimeheader($output, $encoding);
|
||||
// only make linebreaks if we have mime encoded code inside
|
||||
// the space only belongs in the second line
|
||||
if ($_string && preg_match("/^=\?/", $_string_encoded)) {
|
||||
$_string .= $line_break . " ";
|
||||
} elseif (
|
||||
// hack for plain text with space at the end
|
||||
mb_strlen($output, $encoding) == $split &&
|
||||
mb_substr($output, -1, 1, $encoding) == " "
|
||||
) {
|
||||
// if output ends with space, add one more
|
||||
$_string_encoded .= " ";
|
||||
}
|
||||
$_string .= $_string_encoded;
|
||||
}
|
||||
// strip out any spaces BEFORE a line break
|
||||
$string = str_replace(" " . $line_break, $line_break, $_string);
|
||||
// before we end, reset internal encoding
|
||||
mb_internal_encoding($current_internal_encoding);
|
||||
// return mime encoded string
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
123
4dev/deprecated/CoreLibs/Convert/Strings.php
Normal file
123
4dev/deprecated/CoreLibs/Convert/Strings.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* string convert and transform functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Convert;
|
||||
|
||||
class Strings
|
||||
{
|
||||
/**
|
||||
* return the number of elements in the split list
|
||||
* 0 if nothing / invalid split
|
||||
* 1 if no split character found
|
||||
* n for the numbers in the split list
|
||||
*
|
||||
* @param string $split_format
|
||||
* @param string $split_characters
|
||||
* @return int
|
||||
*/
|
||||
public static function countSplitParts(
|
||||
string $split_format,
|
||||
string $split_characters = '-'
|
||||
): int {
|
||||
if (
|
||||
empty($split_format) ||
|
||||
// non valid characters inside, abort
|
||||
!preg_match("/^[0-9" . $split_characters . "]/", $split_format) ||
|
||||
preg_match('/[^\x20-\x7e]/', $split_characters)
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
$split_list = preg_split(
|
||||
// allowed split characters
|
||||
"/([" . $split_characters . "]{1})/",
|
||||
$split_format
|
||||
);
|
||||
if (!is_array($split_list)) {
|
||||
return 0;
|
||||
}
|
||||
return count(array_filter($split_list));
|
||||
}
|
||||
|
||||
/**
|
||||
* split format a string base on a split format string
|
||||
* split format string is eg
|
||||
* 4-4-4 that means 4 characters DASH 4 characters DASH 4 characters
|
||||
* So a string in the format of
|
||||
* ABCD1234EFGH will be ABCD-1234-EFGH
|
||||
* Note a string LONGER then the maxium will be attached with the LAST
|
||||
* split character. In above exmaple
|
||||
* ABCD1234EFGHTOOLONG will be ABCD-1234-EFGH-TOOLONG
|
||||
*
|
||||
* @param string $value string value to split
|
||||
* @param string $split_format split format
|
||||
* @param string $split_characters list of charcters with which we split
|
||||
* if not set uses dash ('-')
|
||||
* @return string split formatted string or original value if not chnaged
|
||||
*/
|
||||
public static function splitFormatString(
|
||||
string $value,
|
||||
string $split_format,
|
||||
string $split_characters = '-'
|
||||
): string {
|
||||
if (
|
||||
// abort if split format is empty
|
||||
empty($split_format) ||
|
||||
// if not in the valid ASCII character range for any of the strings
|
||||
preg_match('/[^\x20-\x7e]/', $value) ||
|
||||
// preg_match('/[^\x20-\x7e]/', $split_format) ||
|
||||
preg_match('/[^\x20-\x7e]/', $split_characters) ||
|
||||
// only numbers and split characters in split_format
|
||||
!preg_match("/[0-9" . $split_characters . "]/", $split_format)
|
||||
) {
|
||||
return $value;
|
||||
}
|
||||
// split format list
|
||||
$split_list = preg_split(
|
||||
// allowed split characters
|
||||
"/([" . $split_characters . "]{1})/",
|
||||
$split_format,
|
||||
-1,
|
||||
PREG_SPLIT_DELIM_CAPTURE
|
||||
);
|
||||
// if this is false, or only one array, abort split
|
||||
if (!is_array($split_list) || count($split_list) == 1) {
|
||||
return $value;
|
||||
}
|
||||
$out = '';
|
||||
$pos = 0;
|
||||
$last_split = '';
|
||||
foreach ($split_list as $offset) {
|
||||
if (is_numeric($offset)) {
|
||||
$_part = substr($value, $pos, (int)$offset);
|
||||
if (empty($_part)) {
|
||||
break;
|
||||
}
|
||||
$out .= $_part;
|
||||
$pos += (int)$offset;
|
||||
} elseif ($pos) { // if first, do not add
|
||||
$out .= $offset;
|
||||
$last_split = $offset;
|
||||
}
|
||||
}
|
||||
if (!empty($out) && $pos < strlen($value)) {
|
||||
$out .= $last_split . substr($value, $pos);
|
||||
}
|
||||
// if last is not alphanumeric remove, remove
|
||||
if (!strcspn(substr($out, -1, 1), $split_characters)) {
|
||||
$out = substr($out, 0, -1);
|
||||
}
|
||||
// overwrite only if out is set
|
||||
if (!empty($out)) {
|
||||
return $out;
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
136
4dev/deprecated/CoreLibs/Convert/VarSetType.php
Normal file
136
4dev/deprecated/CoreLibs/Convert/VarSetType.php
Normal 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__
|
||||
130
4dev/deprecated/CoreLibs/Convert/VarSetTypeNull.php
Normal file
130
4dev/deprecated/CoreLibs/Convert/VarSetTypeNull.php
Normal 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__
|
||||
291
4dev/deprecated/CoreLibs/Create/Email.php
Normal file
291
4dev/deprecated/CoreLibs/Create/Email.php
Normal file
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Create email class
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Create;
|
||||
|
||||
/**
|
||||
* sending simple text emails
|
||||
*/
|
||||
class Email
|
||||
{
|
||||
/** @var array<string> allowed list for encodings that can do KV folding */
|
||||
private static $encoding_kv_allowed = [
|
||||
'UTF-8',
|
||||
'EUC-JP',
|
||||
'SJIS',
|
||||
'SJIS-win',
|
||||
'ISO-2022-JP',
|
||||
'ISO-2022-JP-MS',
|
||||
'JIS',
|
||||
'JIS-ms',
|
||||
];
|
||||
/** @var string normaly this does not need to be changed */
|
||||
private static $mb_convert_kana_mode = 'KV';
|
||||
|
||||
/**
|
||||
* create mime encoded email part for to/from emails.
|
||||
* If encoding is not UTF-8 it will convert the email name to target encoding
|
||||
* FROM UTF-8
|
||||
* Source data is ALWAYS seen as utf-8
|
||||
*
|
||||
* @param string $email E-Mail address
|
||||
* @param string $email_name Name for the email address, in UTF-8, if not set, empty
|
||||
* @param string $encoding Encoding, if not set UTF-8
|
||||
* @param bool $kv_folding If set to true and a valid encoding, do KV folding
|
||||
* @return string Correctly encoded and build email string
|
||||
*/
|
||||
public static function encodeEmailName(
|
||||
string $email,
|
||||
string $email_name = '',
|
||||
string $encoding = 'UTF-8',
|
||||
bool $kv_folding = false
|
||||
): string {
|
||||
if (empty($email_name)) {
|
||||
return $email;
|
||||
}
|
||||
// if encoding is not UTF-8 then we convert
|
||||
if ($encoding != 'UTF-8') {
|
||||
$email_name = mb_convert_encoding($email_name, $encoding, 'UTF-8');
|
||||
}
|
||||
$email_name =
|
||||
mb_encode_mimeheader(
|
||||
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?
|
||||
mb_convert_kana(
|
||||
$email_name,
|
||||
self::$mb_convert_kana_mode,
|
||||
$encoding
|
||||
) :
|
||||
$email_name,
|
||||
$encoding
|
||||
);
|
||||
return '"' . $email_name . '" '
|
||||
. '<' . (string)$email . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Subject/Body replace sub function
|
||||
*
|
||||
* @param string $subject Subject string, in UTF-8
|
||||
* @param string $body Body string, in UTF-8
|
||||
* @param array<string,string> $replace Replace the array as key -> value, in UTF-8
|
||||
* @param string $encoding Encoding for subject encode mime header
|
||||
* @param bool $kv_folding If set to true and a valid encoding,
|
||||
* do KV folding
|
||||
* @return array<string> Pos 0: Subject, Pos 1: Body
|
||||
*/
|
||||
private static function replaceContent(
|
||||
string $subject,
|
||||
string $body,
|
||||
array $replace,
|
||||
string $encoding,
|
||||
bool $kv_folding
|
||||
): array {
|
||||
foreach (['subject', 'body'] as $element) {
|
||||
$$element = str_replace(
|
||||
array_map(
|
||||
function ($key) {
|
||||
return '{' . $key . '}';
|
||||
},
|
||||
array_keys($replace)
|
||||
),
|
||||
array_values($replace),
|
||||
$$element
|
||||
);
|
||||
}
|
||||
// if encoding is NOT UTF-8 convert to target
|
||||
if ($encoding != 'UTF-8') {
|
||||
$subject = mb_convert_encoding($subject, $encoding, 'UTF-8');
|
||||
$body = mb_convert_encoding($body, $encoding, 'UTF-8');
|
||||
}
|
||||
// we need to encodde the subject
|
||||
$subject = mb_encode_mimeheader(
|
||||
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?
|
||||
// for any non UTF-8 encoding convert kana
|
||||
mb_convert_kana(
|
||||
$subject,
|
||||
self::$mb_convert_kana_mode,
|
||||
$encoding
|
||||
) :
|
||||
$subject,
|
||||
$encoding
|
||||
);
|
||||
return [$subject, $body];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plain text email with possible to replace subject/body data
|
||||
* either global or per to email set.
|
||||
* replace to tags are in {} in the subject or body
|
||||
*
|
||||
* @param string $subject Mail subject, mandatory, in UTF-8
|
||||
* @param string $body Mail body, mandatory, in UTF-8
|
||||
* @param string $from_email From email, mandatory
|
||||
* @param string $from_name From email name, in UTF-8
|
||||
* if empty '' then not set
|
||||
* @param array<mixed> $send_to_emails to email or array for email/replace
|
||||
* If array: name/email/replace[key,value]
|
||||
* name and replace must be in UTF-8
|
||||
* At least one must be set
|
||||
* @param array<string,string> $replace_content Subject/Body replace as
|
||||
* search -> replace, in UTF-8
|
||||
* @param string $encoding E-Mail encoding, default UTF-8
|
||||
* @param bool $kv_folding If set to true and a valid encoding,
|
||||
* do KV folding
|
||||
* @param bool $test test flag, default off
|
||||
* @param \CoreLibs\Debug\Logging|null $log Logging class,
|
||||
* only used if test flag is true
|
||||
* @return int 2 test only, no sent
|
||||
* 1 for ok,
|
||||
* 0 for send not ok
|
||||
* -1 for nothing set (emails, subject, body)
|
||||
* -2 for empty to list
|
||||
* -3 encoding target not valid or not installed
|
||||
*/
|
||||
public static function sendEmail(
|
||||
string $subject,
|
||||
string $body,
|
||||
string $from_email,
|
||||
string $from_name,
|
||||
array $send_to_emails,
|
||||
array $replace_content = [],
|
||||
string $encoding = 'UTF-8',
|
||||
bool $kv_folding = false,
|
||||
bool $test = false,
|
||||
?\CoreLibs\Debug\Logging $log = null
|
||||
): int {
|
||||
/** @var array<string> */
|
||||
$to_emails = [];
|
||||
/** @var array<string,array<string,string>> */
|
||||
$to_replace = [];
|
||||
/** @var string */
|
||||
$out_subject = $subject;
|
||||
/** @var string */
|
||||
$out_body = $body;
|
||||
// check basic set
|
||||
if (empty($subject) || empty($body) || empty($from_email)) {
|
||||
return -1;
|
||||
}
|
||||
if (
|
||||
$encoding != 'UTF-8' &&
|
||||
!in_array($encoding, mb_list_encodings())
|
||||
) {
|
||||
return -3;
|
||||
}
|
||||
// if not one valid to, abort
|
||||
foreach ($send_to_emails as $to_email) {
|
||||
// to_email can be string, then only to email
|
||||
// else expect 'email' & 'name'
|
||||
if (
|
||||
is_array($to_email) &&
|
||||
isset($to_email['email'])
|
||||
) {
|
||||
$_to_email = self::encodeEmailName(
|
||||
$to_email['email'],
|
||||
$to_email['name'] ?? '',
|
||||
$encoding,
|
||||
$kv_folding
|
||||
);
|
||||
$to_emails[] = $_to_email;
|
||||
// if we have to replacement, this override replace content
|
||||
if (isset($to_email['replace']) && count($to_email['replace'])) {
|
||||
// merge with original replace content,
|
||||
// to data will override original data
|
||||
$to_replace[$_to_email] = array_merge(
|
||||
$replace_content,
|
||||
$to_email['replace']
|
||||
);
|
||||
}
|
||||
} elseif (is_string($to_email)) {
|
||||
$to_emails[] = $to_email;
|
||||
}
|
||||
}
|
||||
if (!count($to_emails)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
// the email headers needed
|
||||
$headers = [
|
||||
'From' => self::encodeEmailName($from_email, $from_name, $encoding),
|
||||
'Content-type' => "text/plain; charset=" . $encoding,
|
||||
'MIME-Version' => "1.0",
|
||||
];
|
||||
|
||||
// if we have a replace string, we need to do replace run
|
||||
// only if there is no dedicated to replace
|
||||
// also run replace if there is nothing to replace at all
|
||||
// this will mime encode the subject
|
||||
if (!count($to_replace)) {
|
||||
list($out_subject, $out_body) = self::replaceContent(
|
||||
$subject,
|
||||
$body,
|
||||
$replace_content,
|
||||
$encoding,
|
||||
$kv_folding
|
||||
);
|
||||
}
|
||||
|
||||
$mail_delivery_status = 1;
|
||||
// send the email
|
||||
foreach ($to_emails as $to_email) {
|
||||
// default mail status is success
|
||||
$mail_status = true;
|
||||
// if there is a to replace, if not use the original replace content
|
||||
if (count($to_replace)) {
|
||||
$_replace = [];
|
||||
if (!empty($to_replace[$to_email])) {
|
||||
$_replace = $to_replace[$to_email];
|
||||
} elseif (count($replace_content)) {
|
||||
$_replace = $replace_content;
|
||||
}
|
||||
if (count($_replace)) {
|
||||
list($out_subject, $out_body) = self::replaceContent(
|
||||
$subject,
|
||||
$body,
|
||||
$_replace,
|
||||
$encoding,
|
||||
$kv_folding
|
||||
);
|
||||
}
|
||||
}
|
||||
// if we are in test mode, do not send an email and set status to 2
|
||||
if ($test === false) {
|
||||
$mail_status = mail($to_email, $out_subject, $out_body, $headers);
|
||||
} else {
|
||||
$mail_delivery_status = 2;
|
||||
}
|
||||
// log if an log instance exists
|
||||
if ($log instanceof \CoreLibs\Debug\Logging) {
|
||||
// build debug strings: convert to UTF-8 if not utf-8
|
||||
$log->debug('SEND EMAIL', 'HEADERS: ' . $log->prAr($headers) . ', '
|
||||
. 'ENCODING: ' . $encoding . ', '
|
||||
. 'KV FOLDING: ' . $log->prBl($kv_folding) . ', '
|
||||
. 'TO: ' . $to_email . ', '
|
||||
. 'SUBJECT: ' . $out_subject . ', '
|
||||
. 'BODY: ' . ($encoding == 'UTF-8' ?
|
||||
$out_body :
|
||||
mb_convert_encoding($out_body, 'UTF-8', $encoding)));
|
||||
$log->debug('SEND EMAIL JSON', json_encode([
|
||||
'encoding' => $encoding,
|
||||
'kv_folding' => $kv_folding,
|
||||
'header' => $headers,
|
||||
'to' => $to_email,
|
||||
'subject' => $out_subject,
|
||||
'body' => ($encoding == 'UTF-8' ?
|
||||
$out_body :
|
||||
mb_convert_encoding($out_body, 'UTF-8', $encoding))
|
||||
]) ?: '{}');
|
||||
}
|
||||
if (!$mail_status) {
|
||||
$mail_delivery_status = 0;
|
||||
}
|
||||
}
|
||||
return $mail_delivery_status;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
121
4dev/deprecated/CoreLibs/Create/RandomKey.php
Normal file
121
4dev/deprecated/CoreLibs/Create/RandomKey.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* random key functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Create;
|
||||
|
||||
class RandomKey
|
||||
{
|
||||
// key generation
|
||||
/** @var string */
|
||||
private static $key_range = '';
|
||||
/** @var int */
|
||||
private static $one_key_length;
|
||||
/** @var int */
|
||||
private static $key_length = 4; // default key length
|
||||
/** @var int */
|
||||
private static $max_key_length = 256; // max allowed length
|
||||
|
||||
/**
|
||||
* if launched as class, init random key data first
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->initRandomKeyData();
|
||||
}
|
||||
/**
|
||||
* sets the random key range with the default values
|
||||
*
|
||||
* @return void has no return
|
||||
*/
|
||||
private static function initRandomKeyData()
|
||||
{
|
||||
// random key generation base string
|
||||
self::$key_range = join('', array_merge(
|
||||
range('A', 'Z'),
|
||||
range('a', 'z'),
|
||||
range('0', '9')
|
||||
));
|
||||
self::$one_key_length = strlen(self::$key_range);
|
||||
}
|
||||
|
||||
/**
|
||||
* validates they key length for random string generation
|
||||
*
|
||||
* @param int $key_length key length
|
||||
* @return bool true for valid, false for invalid length
|
||||
*/
|
||||
private static function validateRandomKeyLenght(int $key_length): bool
|
||||
{
|
||||
if (
|
||||
is_numeric($key_length) &&
|
||||
$key_length > 0 &&
|
||||
$key_length <= self::$max_key_length
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the key length and checks that they key given is valid
|
||||
* if failed it will not change the default key length and return false
|
||||
*
|
||||
* @param int $key_length key length
|
||||
* @return bool true/false for set status
|
||||
*/
|
||||
public static function setRandomKeyLength(int $key_length): bool
|
||||
{
|
||||
// only if valid int key with valid length
|
||||
if (self::validateRandomKeyLenght($key_length) === true) {
|
||||
self::$key_length = $key_length;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current set random key length
|
||||
*
|
||||
* @return int Current set key length
|
||||
*/
|
||||
public static function getRandomKeyLength(): int
|
||||
{
|
||||
return self::$key_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a random key based on the key_range with key_length
|
||||
* if override key length is set, it will check on valid key and use this
|
||||
* this will not set the class key length variable
|
||||
*
|
||||
* @param int $key_length key length override, -1 for use default
|
||||
* @return string random key
|
||||
*/
|
||||
public static function randomKeyGen(int $key_length = -1): string
|
||||
{
|
||||
// init random key strings if not set
|
||||
if (!is_numeric(self::$one_key_length)) {
|
||||
self::initRandomKeyData();
|
||||
}
|
||||
$use_key_length = 0;
|
||||
// only if valid int key with valid length
|
||||
if (self::validateRandomKeyLenght($key_length) === true) {
|
||||
$use_key_length = $key_length;
|
||||
} else {
|
||||
$use_key_length = self::$key_length;
|
||||
}
|
||||
// create random string
|
||||
$random_string = '';
|
||||
for ($i = 1; $i <= $use_key_length; $i++) {
|
||||
$random_string .= self::$key_range[random_int(0, self::$one_key_length - 1)];
|
||||
}
|
||||
return $random_string;
|
||||
}
|
||||
}
|
||||
655
4dev/deprecated/CoreLibs/DB/Extended/ArrayIO.php
Normal file
655
4dev/deprecated/CoreLibs/DB/Extended/ArrayIO.php
Normal file
@@ -0,0 +1,655 @@
|
||||
<?php
|
||||
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens Schwaighofer
|
||||
* CREATED: 2002/12/17
|
||||
* VERSION: 1.0.0
|
||||
* RELEASED LICENSE: GNU GPL 3
|
||||
* SHORT DESC :RIPTION:
|
||||
* DB Array IO Class:
|
||||
* writes, reads or deletes a complete array (one data set) in/out a
|
||||
* table from the connected DB.
|
||||
* you don't have to write any SQL queries, worry over update/insert
|
||||
*
|
||||
* HISTORY:
|
||||
* 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
|
||||
* 2003-02-26: db_array_io is no longer single class but extens db_io,
|
||||
* as it needs it anyway
|
||||
* moved the class info vars into class_info array into
|
||||
* the constructor, removed info function
|
||||
* 2003-02-24: in db_delete moved query build to top, or pk_name/value
|
||||
* will be reset before delete is done
|
||||
* 2002-12-20: just added info() method
|
||||
* 2002-12-17: splitted the class from other file (with main db wrapper)
|
||||
*********************************************************************/
|
||||
|
||||
// picture upload should be taken out from here and out in media_class
|
||||
// as it actually has nothing to do with this one here ? (or at least
|
||||
// put into separete function in this class)
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\DB\Extended;
|
||||
|
||||
// subclass for one array handling
|
||||
class ArrayIO extends \CoreLibs\DB\IO
|
||||
{
|
||||
// main calss variables
|
||||
/** @var array<mixed> */
|
||||
public $table_array; // the array from the table to work on
|
||||
/** @var string */
|
||||
public $table_name; // the table_name
|
||||
/** @var string */
|
||||
public $pk_name = ''; // the primary key from this table
|
||||
/** @var int|string|null */
|
||||
public $pk_id; // the PK id
|
||||
// security values
|
||||
/** @var int base acl for current page */
|
||||
private $base_acl_level = 0;
|
||||
|
||||
/**
|
||||
* constructor for the array io class, set the
|
||||
* primary key name automatically (from array)
|
||||
*
|
||||
* @param array<mixed> $db_config db connection config
|
||||
* @param array<mixed> $table_array table array config
|
||||
* @param string $table_name table name string
|
||||
* @param \CoreLibs\Debug\Logging|null $log Logging class, default set if not set
|
||||
* @param int $base_acl_level Set base acl level, if needed
|
||||
* @param int $acl_admin Flag if this is an admin ACL access level
|
||||
*/
|
||||
public function __construct(
|
||||
array $db_config,
|
||||
array $table_array,
|
||||
string $table_name,
|
||||
\CoreLibs\Debug\Logging $log = null,
|
||||
int $base_acl_level = 0,
|
||||
int $acl_admin = 0
|
||||
) {
|
||||
// instance db_io class
|
||||
parent::__construct($db_config, $log ?? new \CoreLibs\Debug\Logging());
|
||||
// more error vars for this class
|
||||
$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
|
||||
foreach ($this->table_array as $key => $value) {
|
||||
if (!empty($value['pk'])) {
|
||||
$this->pk_name = $key;
|
||||
}
|
||||
}
|
||||
$this->dbArrayIOSetAcl($base_acl_level, $acl_admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* class deconstructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* set the base acl level and admin acl flag
|
||||
* This is needed for table array ACL checks
|
||||
* if not set I assume 0 (non write/non read/non admin)
|
||||
*
|
||||
* @param int $base_acl_level ACL Level from 0 to 100, -1 is not allowed
|
||||
* Will sett 0 if invalid
|
||||
* @param int $acl_admin 0 for non admin, 1 for admin (base acl is 100)
|
||||
* @return void
|
||||
*/
|
||||
public function dbArrayIOSetAcl(int $base_acl_level, int $acl_admin): void
|
||||
{
|
||||
// default not allowed, must be 0 at least
|
||||
if ($base_acl_level < 0) {
|
||||
$base_acl_level = 0;
|
||||
}
|
||||
// only 0 or 1 allowed
|
||||
if (!in_array($acl_admin, [0, 1])) {
|
||||
$acl_admin = 0;
|
||||
}
|
||||
// if the user is admin flagged, auto set to 100, if not already set to 100
|
||||
if ($acl_admin == 1) {
|
||||
$base_acl_level = 100;
|
||||
}
|
||||
$this->base_acl_level = $base_acl_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes all previously alterd HTML code into visible one,
|
||||
* works for <b>,<i>, and <a> (thought <a> can be / or should
|
||||
* be handled with the magic links functions
|
||||
* used with the read function
|
||||
*
|
||||
* @param string $text any html encoded string
|
||||
* @return string decoded html string
|
||||
*/
|
||||
public function convertData($text): string
|
||||
{
|
||||
$text = str_replace('<b>', '<b>', $text);
|
||||
$text = str_replace('</b>', '</b>', $text);
|
||||
$text = str_replace('<i>', '<i>', $text);
|
||||
$text = str_replace('</i>', '</i>', $text);
|
||||
// my need a change
|
||||
$text = str_replace('<a href="', '<a target="_blank" href="', $text);
|
||||
$text = str_replace('">', '">', $text);
|
||||
$text = str_replace('</a>', '</a>', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* changeds all HTML entities into non HTML ones
|
||||
*
|
||||
* @param string $text encoded html string
|
||||
* @return string decoded html string
|
||||
*/
|
||||
public function convertEntities($text): string
|
||||
{
|
||||
$text = str_replace('<', '<', $text);
|
||||
$text = str_replace('>', '>', $text);
|
||||
$text = str_replace('&', '&', $text);
|
||||
$text = str_replace('"', '"', $text);
|
||||
$text = str_replace(''', "'", $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* dumps the current data
|
||||
*
|
||||
* @param bool $write write to error message, default false
|
||||
* @return string the array data as html string entry
|
||||
*/
|
||||
public function dbDumpArray($write = false): string
|
||||
{
|
||||
reset($this->table_array);
|
||||
$string = '';
|
||||
foreach ($this->table_array as $column => $data_array) {
|
||||
$string .= '<b>' . $column . '</b> -> ' . $data_array['value'] . '<br>';
|
||||
}
|
||||
// add output to internal error_msg
|
||||
if ($write === true) {
|
||||
$this->__dbDebug('dbArray', $string);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if pk is set and if not, set from pk_id and
|
||||
* if this also not set return 0
|
||||
*
|
||||
* @return bool true if pk value is set, else false
|
||||
*/
|
||||
public function dbCheckPkSet()
|
||||
{
|
||||
// if pk_id is set, overrule ...
|
||||
if ($this->pk_id) {
|
||||
$this->table_array[$this->pk_name]['value'] = $this->pk_id;
|
||||
}
|
||||
// if not set ... produce error
|
||||
if (!$this->table_array[$this->pk_name]['value']) {
|
||||
// if no PK found, error ...
|
||||
$this->__dbError(1021);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* resets the whole array values
|
||||
* @param boolean $reset_pk true if we want to reset the pk too
|
||||
* @return void has no return
|
||||
*/
|
||||
public function dbResetArray($reset_pk = false): void
|
||||
{
|
||||
reset($this->table_array);
|
||||
foreach (array_keys($this->table_array) as $column) {
|
||||
if (!$this->table_array[$column]['pk']) {
|
||||
unset($this->table_array[$column]['value']);
|
||||
} elseif ($reset_pk) {
|
||||
unset($this->table_array[$column]['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes one dataset
|
||||
*
|
||||
* @param array<mixed> $table_array optional override for table array set
|
||||
* set this as new table array too
|
||||
* @param boolean $acl_limit [false], if set to true, well do ACL limit check
|
||||
* @return array<mixed> returns the table array that was deleted
|
||||
*/
|
||||
public function dbDelete($table_array = [], $acl_limit = false)
|
||||
{
|
||||
// is array and has values, override set and set new
|
||||
if (is_array($table_array) && count($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
if (!$this->dbCheckPkSet()) {
|
||||
return $this->table_array;
|
||||
}
|
||||
if ($acl_limit === true && $this->base_acl_level < 100) {
|
||||
$this->log->debug('DB DELETE ERROR', 'ACL Limit on, Delete, '
|
||||
. 'but base ACL level of 100 not met: ' . $this->base_acl_level);
|
||||
return $this->table_array;
|
||||
}
|
||||
// delete query
|
||||
$q = 'DELETE FROM ' . $this->table_name . ' WHERE ';
|
||||
$q .= $this->pk_name . ' = ' . $this->table_array[$this->pk_name]['value'] . ' ';
|
||||
// delete files and build FK query
|
||||
reset($this->table_array);
|
||||
$q_where = '';
|
||||
foreach (array_keys($this->table_array) as $column) {
|
||||
// suchen nach bildern und lschen ...
|
||||
if (
|
||||
!empty($this->table_array[$column]['file']) &&
|
||||
file_exists($this->table_array[$column]['url'] . $this->table_array[$column]['value'])
|
||||
) {
|
||||
if (file_exists($this->table_array[$column]['path'] . $this->table_array[$column]['value'])) {
|
||||
unlink($this->table_array[$column]['path'] . $this->table_array[$column]['value']);
|
||||
}
|
||||
$file_name = str_replace('_tn', '', $this->table_array[$column]['value']);
|
||||
if (file_exists($this->table_array[$column]['path'] . $file_name)) {
|
||||
unlink($this->table_array[$column]['path'] . $file_name);
|
||||
}
|
||||
}
|
||||
// if we have a foreign key
|
||||
if (!empty($this->table_array[$column]['fk'])) {
|
||||
// create FK constraint checks
|
||||
if ($q_where) {
|
||||
$q_where .= ' AND ';
|
||||
}
|
||||
$q_where .= $column . ' = ' . $this->table_array[$column]['value'];
|
||||
}
|
||||
// allgemeines zurcksetzen des arrays
|
||||
unset($this->table_array[$column]['value']);
|
||||
}
|
||||
|
||||
// attach fk row if there ...
|
||||
if ($q_where) {
|
||||
$q .= ' AND ' . $q_where;
|
||||
}
|
||||
// if 0, error
|
||||
$this->pk_id = null;
|
||||
if (!$this->dbExec($q)) {
|
||||
$this->__dbError(1022);
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads one row into the array
|
||||
*
|
||||
* @param boolean $edit on true convert data, else as is
|
||||
* @param array<mixed> $table_array optional table array, overwrites
|
||||
* internal set array
|
||||
* @return array<mixed> set table array with values
|
||||
*/
|
||||
public function dbRead($edit = false, $table_array = [])
|
||||
{
|
||||
// if array give, overrules internal array
|
||||
if (is_array($table_array) && count($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
if (!$this->dbCheckPkSet()) {
|
||||
return $this->table_array;
|
||||
}
|
||||
reset($this->table_array);
|
||||
$q_select = '';
|
||||
$q_where = '';
|
||||
// create select part & addition FK part
|
||||
foreach ($this->table_array as $column => $data_array) {
|
||||
if ($q_select) {
|
||||
$q_select .= ', ';
|
||||
}
|
||||
if (
|
||||
!empty($data_array['type']) && $data_array['type'] == 'datetime' &&
|
||||
!empty($data_array['sql_read'])
|
||||
) {
|
||||
// convert tom different timestamp type
|
||||
$q_select .= "TO_CHAR($column, '" . $data_array['sql_read'] . "') AS $column";
|
||||
} else {
|
||||
$q_select .= $column;
|
||||
}
|
||||
|
||||
// check FK ...
|
||||
if (
|
||||
isset($this->table_array[$column]['fk']) &&
|
||||
isset($this->table_array[$column]['value'])
|
||||
) {
|
||||
if (!empty($q_where)) {
|
||||
$q_where .= ' AND ';
|
||||
}
|
||||
$q_where .= $column .= ' = ' . $this->table_array[$column]['value'];
|
||||
}
|
||||
}
|
||||
|
||||
$q = 'SELECT ';
|
||||
$q .= $q_select;
|
||||
$q .= ' FROM ' . $this->table_name . ' WHERE ';
|
||||
$q .= $this->pk_name . ' = ' . $this->table_array[$this->pk_name]['value'] . ' ';
|
||||
if ($q_where) {
|
||||
$q .= ' AND ' . $q_where;
|
||||
}
|
||||
|
||||
// if query was executed okay, else set error
|
||||
if ($this->dbExec($q)) {
|
||||
if (is_array($res = $this->dbFetchArray())) {
|
||||
reset($this->table_array);
|
||||
foreach ($this->table_array as $column => $data_array) {
|
||||
// wenn "edit" dann gib daten wie in DB zurück, ansonten aufbereiten fr ausgabe
|
||||
// ?? sollte das nicht drauen ??? man weis ja net was da drin steht --> is noch zu berlegen
|
||||
// $this->log->debug('DB READ', 'EDIT: $edit | Spalte: $column | type: '
|
||||
// .$this->table_array[$column]['type'].' | Res: '.$res[$column]);
|
||||
if ($edit) {
|
||||
$this->table_array[$column]['value'] = $res[$column];
|
||||
// if password, also write to hidden
|
||||
if (
|
||||
isset($this->table_array[$column]['type']) &&
|
||||
$this->table_array[$column]['type'] == 'password'
|
||||
) {
|
||||
$this->table_array[$column]['HIDDEN_value'] = $res[$column];
|
||||
}
|
||||
} else {
|
||||
$this->table_array[$column]['value'] = $this->convertData(nl2br($res[$column]));
|
||||
// had to put out the htmlentities from the line above as it breaks japanese characters
|
||||
}
|
||||
}
|
||||
}
|
||||
// possible dbFetchArray errors ...
|
||||
$this->pk_id = $this->table_array[$this->pk_name]['value'];
|
||||
} else {
|
||||
$this->__dbError(1022);
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes one set into DB or updates one set (if PK exists)
|
||||
*
|
||||
* @param boolean $addslashes old convert entities and set set escape
|
||||
* @param array<mixed> $table_array optional table array, overwrites internal one
|
||||
* @param boolean $acl_limit [false], if set to true, well do ACL limit check
|
||||
* @return array<mixed> table array or null
|
||||
*/
|
||||
public function dbWrite(
|
||||
bool $addslashes = false,
|
||||
array $table_array = [],
|
||||
bool $acl_limit = false
|
||||
): array {
|
||||
if (is_array($table_array) && count($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
// PK ID check
|
||||
// if ($this->pk_id && !$this->table_array[$this->pk_name]["value"]) {
|
||||
// $this->table_array[$this->pk_name]["value"]=$this->pk_id;
|
||||
// }
|
||||
// checken ob PKs gesetzt, wenn alle -> update, wenn keiner -> insert, wenn ein paar -> ERROR!
|
||||
if (!$this->table_array[$this->pk_name]['value']) {
|
||||
$insert = 1;
|
||||
} else {
|
||||
$insert = 0;
|
||||
}
|
||||
// early abort for new write with not enough ACL level
|
||||
if ($insert && $acl_limit === true && $this->base_acl_level < 100) {
|
||||
$this->log->debug('DB WRITE ERROR', 'ACL Limit on, Insert, '
|
||||
. 'but base ACL level of 100 not met: ' . $this->base_acl_level);
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
reset($this->table_array);
|
||||
$q_data = '';
|
||||
$q_vars = '';
|
||||
$q_where = '';
|
||||
foreach ($this->table_array as $column => $data_array) {
|
||||
/********************************* START FILE *************************************/
|
||||
// file upload
|
||||
if (isset($this->table_array[$column]['file'])) {
|
||||
// falls was im tmp drinnen, sprich ein upload, datei kopieren, Dateinamen in db schreiben
|
||||
// falls datei schon am server (physischer pfad), dann einfach url in db schreiben (update)
|
||||
// falls in 'delete' 'ja' dann loeschen (und gibts eh nur beim update)
|
||||
if ($this->table_array[$column]['delete']) {
|
||||
unset($this->table_array[$column]['delete']);
|
||||
if (file_exists($this->table_array[$column]['path'] . $this->table_array[$column]['value'])) {
|
||||
unlink($this->table_array[$column]['path'] . $this->table_array[$column]['value']);
|
||||
}
|
||||
$file_name = str_replace('_tn', '', $this->table_array[$column]['value']);
|
||||
if (file_exists($this->table_array[$column]['path'] . $file_name)) {
|
||||
unlink($this->table_array[$column]['path'] . $file_name);
|
||||
}
|
||||
$this->table_array[$column]['value'] = '';
|
||||
} else {
|
||||
if ($this->table_array[$column]['tmp'] != 'none' && $this->table_array[$column]['tmp']) {
|
||||
// mozilla, patch
|
||||
$fn_name = explode('/', $this->table_array[$column]['dn']);
|
||||
$this->table_array[$column]['dn'] = $fn_name[count($fn_name) - 1];
|
||||
$filename_parts = explode('.', $this->table_array[$column]['dn']);
|
||||
$ext = end($filename_parts);
|
||||
array_splice($filename_parts, -1, 1);
|
||||
$name = str_replace(' ', '_', implode('.', $filename_parts));
|
||||
$file_name = $name . '.' . $ext;
|
||||
//echo 'Dn: $file_name';
|
||||
copy($this->table_array[$column]['tmp'], $this->table_array[$column]['path'] . $file_name);
|
||||
// automatisch thumbnail generieren, geht nur mit convert (ImageMagic!!!), aber nur bei bild ..
|
||||
if (in_array(strtolower($ext), ['jpeg', 'jpg', 'gif', 'png'])) {
|
||||
$file_name_tn = $name . '_tn.' . $ext;
|
||||
$input = $this->table_array[$column]['path'] . $file_name;
|
||||
$output = $this->table_array[$column]['path'] . $file_name_tn;
|
||||
$com = 'convert -geometry 115 ' . $input . ' ' . $output;
|
||||
exec($com);
|
||||
$this->table_array[$column]['value'] = $file_name_tn;
|
||||
} else {
|
||||
$this->table_array[$column]['value'] = $file_name;
|
||||
}
|
||||
} elseif (file_exists($this->table_array[$column]['path'] . $this->table_array[$column]['value'])) {
|
||||
// mach gar nix, wenn bild schon da ???
|
||||
}
|
||||
} // delete or upload
|
||||
} // file IF
|
||||
/********************************* END FILE **************************************/
|
||||
|
||||
// do not write 'pk' (primary key) or 'view' values
|
||||
// also do not write UPDATE for elements that are
|
||||
// acl flagged, not if we have an ACL limiter, don't insert
|
||||
// $this->log->debug('DB WRITE', 'C: ' . $column . ', '
|
||||
// . 'ACL Level ' . $this->log->prBl($acl_limit) . ', '
|
||||
// . 'TA ACL: ' . ($this->table_array[$column]['min_edit_acl'] ?? 100) . ', '
|
||||
// . 'Base ACL: ' . $this->base_acl_level);
|
||||
if (
|
||||
!isset($this->table_array[$column]['pk']) &&
|
||||
isset($this->table_array[$column]['type']) &&
|
||||
$this->table_array[$column]['type'] != 'view' &&
|
||||
strlen($column) > 0 &&
|
||||
// no acl limiter
|
||||
($acl_limit === false ||
|
||||
(
|
||||
// acl limit is true, min edit must be at larger than set
|
||||
$acl_limit === true &&
|
||||
$this->base_acl_level >=
|
||||
($this->table_array[$column]['min_edit_acl'] ?? 100)
|
||||
))
|
||||
) {
|
||||
// for password use hidden value if main is not set
|
||||
if (
|
||||
isset($this->table_array[$column]['type']) &&
|
||||
$this->table_array[$column]['type'] == 'password' &&
|
||||
empty($this->table_array[$column]['value'])
|
||||
) {
|
||||
$this->table_array[$column]['value'] = $this->table_array[$column]['HIDDEN_value'];
|
||||
}
|
||||
if (!$insert) {
|
||||
if (strlen($q_data)) {
|
||||
$q_data .= ', ';
|
||||
}
|
||||
$q_data .= $column . ' = ';
|
||||
} else {
|
||||
// this is insert
|
||||
if (strlen($q_data)) {
|
||||
$q_data .= ', ';
|
||||
}
|
||||
if (strlen($q_vars)) {
|
||||
$q_vars .= ', ';
|
||||
}
|
||||
$q_vars .= $column;
|
||||
}
|
||||
// integer is different
|
||||
if (isset($this->table_array[$column]['int']) || isset($this->table_array[$column]['int_null'])) {
|
||||
$this->log->debug('WRITE CHECK', '[' . $column . '][' . $this->table_array[$column]['value'] . ']'
|
||||
. '[' . $this->table_array[$column]['type'] . '] '
|
||||
. 'VALUE SET: ' . (string)isset($this->table_array[$column]['value'])
|
||||
. ' | INT NULL: ' . (string)isset($this->table_array[$column]['int_null']));
|
||||
if (
|
||||
isset($this->table_array[$column]['value']) &&
|
||||
!$this->table_array[$column]['value'] &&
|
||||
isset($this->table_array[$column]['int_null'])
|
||||
) {
|
||||
$_value = 'NULL';
|
||||
} elseif (
|
||||
!isset($this->table_array[$column]['value']) ||
|
||||
(isset($this->table_array[$column]['value']) && !$this->table_array[$column]['value'])
|
||||
) {
|
||||
$_value = 0;
|
||||
} else {
|
||||
$_value = $this->table_array[$column]['value'];
|
||||
}
|
||||
$q_data .= $_value;
|
||||
} elseif (isset($this->table_array[$column]['bool'])) {
|
||||
// boolean storeage (reverse check on ifset)
|
||||
$q_data .= "'" . $this->dbBoolean($this->table_array[$column]['value'], true) . "'";
|
||||
} elseif (
|
||||
isset($this->table_array[$column]['interval']) ||
|
||||
isset($this->table_array[$column]['date']) ||
|
||||
isset($this->table_array[$column]['datetime']) ||
|
||||
isset($this->table_array[$column]['emptynull'])
|
||||
) {
|
||||
// for interval we check if no value, then we set null
|
||||
if (
|
||||
!isset($this->table_array[$column]['value']) ||
|
||||
(isset($this->table_array[$column]['value']) && !$this->table_array[$column]['value'])
|
||||
) {
|
||||
$_value = 'NULL';
|
||||
} elseif (isset($this->table_array[$column]['value'])) {
|
||||
$_value = $this->dbEscapeLiteral($this->table_array[$column]['value']);
|
||||
} else {
|
||||
// fallback
|
||||
$_value = 'NULL';
|
||||
}
|
||||
$q_data .= $_value;
|
||||
} else {
|
||||
// if the error check is json, we set field to null if NOT set
|
||||
// else normal string write
|
||||
if (
|
||||
isset($this->table_array[$column]['error_check']) &&
|
||||
$this->table_array[$column]['error_check'] == 'json' &&
|
||||
(
|
||||
!isset($this->table_array[$column]['value']) ||
|
||||
(isset($this->table_array[$column]['value']) &&
|
||||
!$this->table_array[$column]['value'])
|
||||
)
|
||||
) {
|
||||
$q_data .= 'NULL';
|
||||
} else {
|
||||
// normal string
|
||||
$q_data .= "'";
|
||||
// if add slashes do convert & add slashes else write AS is
|
||||
if ($addslashes) {
|
||||
$q_data .= $this->dbEscapeString(
|
||||
$this->convertEntities($this->table_array[$column]['value'])
|
||||
);
|
||||
} else {
|
||||
$q_data .= $this->dbEscapeString($this->table_array[$column]['value']);
|
||||
}
|
||||
$q_data .= "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // while ...
|
||||
|
||||
if (empty($q_data)) {
|
||||
$this->log->debug('DB WRITE ERROR', 'No data to write, possible through ACL');
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
// NOW get PK, and FK settings (FK only for update query)
|
||||
// get it at the end, cause now we can be more sure of no double IDs, etc
|
||||
reset($this->table_array);
|
||||
// create select part & addition FK part
|
||||
foreach ($this->table_array as $column => $data_array) {
|
||||
// check FK ...
|
||||
if (
|
||||
isset($this->table_array[$column]['fk']) &&
|
||||
isset($this->table_array[$column]['value'])
|
||||
) {
|
||||
if (!empty($q_where)) {
|
||||
$q_where .= ' AND ';
|
||||
}
|
||||
$q_where .= $column .= ' = ' . $this->table_array[$column]['value'];
|
||||
}
|
||||
}
|
||||
|
||||
// if no PK set, then get max ID from DB
|
||||
if (!$this->table_array[$this->pk_name]['value']) {
|
||||
// max id, falls INSERT
|
||||
$q = 'SELECT MAX(' . $this->pk_name . ') + 1 AS pk_id FROM ' . $this->table_name;
|
||||
if (is_array($res = $this->dbReturnRow($q))) {
|
||||
$pk_id = $res['pk_id'];
|
||||
} else {
|
||||
$pk_id = 1;
|
||||
}
|
||||
$this->table_array[$this->pk_name]['value'] = $pk_id;
|
||||
}
|
||||
|
||||
if (!$insert) {
|
||||
$q = 'UPDATE ' . $this->table_name . ' SET ';
|
||||
$q .= $q_data;
|
||||
$q .= ' WHERE ';
|
||||
$q .= $this->pk_name . ' = ' . $this->table_array[$this->pk_name]['value'] . ' ';
|
||||
if (!empty($q_where)) {
|
||||
$q .= ' AND ' . $q_where;
|
||||
}
|
||||
// set pk_id ... if it has changed or so
|
||||
$this->pk_id = $this->table_array[$this->pk_name]['value'];
|
||||
} else {
|
||||
$q = 'INSERT INTO ' . $this->table_name . ' ';
|
||||
$q .= '(' . $q_vars . ') ';
|
||||
$q .= 'VALUES (' . $q_data . ')';
|
||||
// write primary key too
|
||||
// if ($q_data)
|
||||
// $q .= ", ";
|
||||
// $q .= $this->pk_name." = ".$this->table_array[$this->pk_name]['value']." ";
|
||||
// $this->pk_id = $this->table_array[$this->pk_name]['value'];
|
||||
}
|
||||
// return success or not
|
||||
if (!$this->dbExec($q)) {
|
||||
$this->__dbError(1022);
|
||||
}
|
||||
// set primary key
|
||||
if ($insert) {
|
||||
$insert_id = $this->dbGetInsertPK();
|
||||
if (is_array($insert_id)) {
|
||||
$insert_id = 0;
|
||||
}
|
||||
$this->table_array[$this->pk_name]['value'] = $insert_id;
|
||||
$this->pk_id = $insert_id;
|
||||
}
|
||||
// return the table if needed
|
||||
return $this->table_array;
|
||||
}
|
||||
// end of class
|
||||
}
|
||||
|
||||
// __END__
|
||||
3342
4dev/deprecated/CoreLibs/DB/IO.php
Normal file
3342
4dev/deprecated/CoreLibs/DB/IO.php
Normal file
File diff suppressed because it is too large
Load Diff
883
4dev/deprecated/CoreLibs/DB/SQL/PgSQL.php
Normal file
883
4dev/deprecated/CoreLibs/DB/SQL/PgSQL.php
Normal file
@@ -0,0 +1,883 @@
|
||||
<?php
|
||||
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens Schwaighofer
|
||||
* CREATED: 2003/04/09
|
||||
* SHORT DESCRIPTION:
|
||||
* 2018/3/23, the whole class system is transformed to namespaces
|
||||
* also all internal class calls are converted to camel case
|
||||
*
|
||||
* pgsql wrapper calls
|
||||
*
|
||||
* HISTORY:
|
||||
* 2008/04/16 (cs) wrapper for pg escape string
|
||||
* 2007/01/11 (cs) add prepare/execute for postgres
|
||||
* 2006/09/12 (cs) in case db_query retuns false, save the query and
|
||||
* run the query through the send/get procedure to get
|
||||
* correct error data from the db
|
||||
* 2006/06/26 (cs) added port for db connection
|
||||
* 2006/04/03 (cs) added meta data for table
|
||||
* 2005/07/25 (cs) removed the plural s remove, not needed and not 100% working
|
||||
* 2005/07/07 (cs) the default it is table_name _ id
|
||||
* 2005/01/19 (cs) changed the pgsql connect, so it dies if it can't connect to the DB
|
||||
* 2004/09/30 (cs) layout cleanup
|
||||
*
|
||||
*
|
||||
* collection of PostgreSQL wrappers
|
||||
*
|
||||
* pg_prepare
|
||||
* pg_execute
|
||||
* pg_num_rows
|
||||
* pg_num_fields
|
||||
* pg_field_name
|
||||
* pg_affected_rows (*)
|
||||
* pg_fetch_array
|
||||
* pg_query
|
||||
* pg_send_query
|
||||
* pg_get_result
|
||||
* pg_connection_busy
|
||||
* pg_close
|
||||
* pg_connect (*)
|
||||
* pg_meta_data
|
||||
* pg_escape_string
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\DB\SQL;
|
||||
|
||||
// below no ignore is needed if we want to use PgSql interface checks with PHP 8.0
|
||||
// as main system. Currently all @var sets are written as object
|
||||
/** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */
|
||||
|
||||
class PgSQL implements \CoreLibs\DB\SQL\SqlInterface\SqlFunctions
|
||||
{
|
||||
/** @var string */
|
||||
private $last_error_query;
|
||||
// NOTE for PHP 8.1 this is no longer a resource
|
||||
/** @var object|resource|bool */ // replace object with PgSql\Connection
|
||||
private $dbh;
|
||||
|
||||
/**
|
||||
* queries last error query and returns true or false if error was set
|
||||
*
|
||||
* @return bool true/false if last error is set
|
||||
*/
|
||||
public function __dbLastErrorQuery(): bool
|
||||
{
|
||||
if ($this->last_error_query) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_query, catches error and stores it in class var
|
||||
*
|
||||
* @param string $query Query string
|
||||
* @return object|resource|bool query result (PgSql\Result)
|
||||
*/
|
||||
public function __dbQuery(string $query)
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
// read out the query status and save the query if needed
|
||||
$result = pg_query($this->dbh, $query);
|
||||
if ($result === false) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proposed
|
||||
* wrapperf or pg_query_params for queries in the style of
|
||||
* SELECT foo FROM bar WHERE foobar = $1
|
||||
*
|
||||
* @param string $query Query string with placeholders $1, ..
|
||||
* @param array<mixed> $params Matching parameters for each placerhold
|
||||
* @return object|resource|bool Query result (PgSql\Result)
|
||||
*/
|
||||
public function __dbQueryParams(string $query, array $params)
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
// parse query and get all $n entries
|
||||
// TODO count of $n must match params
|
||||
// read out the query status and save the query if needed
|
||||
$result = pg_query_params($this->dbh, $query, $params);
|
||||
if ($result === false) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* sends an async query to the server
|
||||
*
|
||||
* @param string $query query string
|
||||
* @return bool true/false if query was sent successful
|
||||
*/
|
||||
public function __dbSendQuery(string $query): bool
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
$result = pg_send_query($this->dbh, $query);
|
||||
return $result ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_get_result
|
||||
*
|
||||
* @return object|resource|bool resource handler or false for error (PgSql\Result)
|
||||
*/
|
||||
public function __dbGetResult()
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
$result = pg_get_result($this->dbh);
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
if ($error = pg_result_error($result)) {
|
||||
$this->last_error_query = $error;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_close
|
||||
*
|
||||
* @return void has no return
|
||||
*/
|
||||
public function __dbClose(): void
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return;
|
||||
}
|
||||
if (pg_connection_status($this->dbh) === PGSQL_CONNECTION_OK) {
|
||||
// in 8.1 this throws an error, and we don't need that anyway
|
||||
// pg_close($this->dbh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_prepare
|
||||
*
|
||||
* @param string $name statement name
|
||||
* @param string $query query string
|
||||
* @return object|resource|bool prepare statement handler or
|
||||
* false for error (PgSql\Result)
|
||||
*/
|
||||
public function __dbPrepare(string $name, string $query)
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
$result = pg_prepare($this->dbh, $name, $query);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_execute for running a prepared statement
|
||||
*
|
||||
* @param string $name statement name
|
||||
* @param array<mixed> $data data array
|
||||
* @return object|resource|bool returns status or false for error (PgSql\Result)
|
||||
*/
|
||||
public function __dbExecute(string $name, array $data)
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
$result = pg_execute($this->dbh, $name, $data);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $name;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_num_rows
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @return int number of rows, -1 on error
|
||||
*/
|
||||
public function __dbNumRows($cursor): int
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return -1;
|
||||
}
|
||||
return pg_num_rows($cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_num_fields
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @return int number for fields in result, -1 on error
|
||||
*/
|
||||
public function __dbNumFields($cursor): int
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return -1;
|
||||
}
|
||||
return pg_num_fields($cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_field_name
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @param int $i field position
|
||||
* @return string|bool name or false on error
|
||||
*/
|
||||
public function __dbFieldName($cursor, int $i)
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return false;
|
||||
}
|
||||
return pg_field_name($cursor, $i);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_fetch_array
|
||||
* if through/true false, use __dbResultType(true)
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @param int $result_type result type as int number
|
||||
* @return array<mixed>|bool array result data or false on end/error
|
||||
*/
|
||||
public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH)
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return false;
|
||||
}
|
||||
// result type is passed on as is [should be checked]
|
||||
return pg_fetch_array($cursor, null, $result_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* simple match up between assoc true/false
|
||||
*
|
||||
* @param bool $assoc_type true (default) for PGSQL_ASSOC, false for PGSQL_BOTH
|
||||
* @return int valid result type for fetch array
|
||||
*/
|
||||
public function __dbResultType(bool $assoc_type = true): int
|
||||
{
|
||||
if ($assoc_type == true) {
|
||||
return PGSQL_ASSOC;
|
||||
}
|
||||
// fallback to default
|
||||
return PGSQL_BOTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_fetch_all
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @return array<mixed>|bool data array or false for end/error
|
||||
*/
|
||||
public function __dbFetchAll($cursor)
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return false;
|
||||
}
|
||||
return pg_fetch_all($cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_affected_rows
|
||||
*
|
||||
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
|
||||
* @return int affected rows, 0 for none, -1 for error
|
||||
*/
|
||||
public function __dbAffectedRows($cursor): int
|
||||
{
|
||||
if ($cursor === false || is_bool($cursor)) {
|
||||
return -1;
|
||||
}
|
||||
return pg_affected_rows($cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the last inserted primary key for the query
|
||||
* if there is no pk_name tries to auto built it from the table name
|
||||
* this only works if db schema is after no plural names
|
||||
* and pk name is table name + _id
|
||||
*
|
||||
* detects schema prefix in table name
|
||||
* @param string $query query string
|
||||
* @param string|null $pk_name primary key name, if '' then auto detect
|
||||
* @return string|int|false primary key value
|
||||
*/
|
||||
public function __dbInsertId(string $query, ?string $pk_name)
|
||||
{
|
||||
// only if an insert has been done
|
||||
if (preg_match("/^insert /i", $query)) {
|
||||
$schema = '';
|
||||
// get table name from insert
|
||||
$array = explode(' ', $query);
|
||||
$_table = $array[2];
|
||||
// if there is a dot inside, we need to split
|
||||
if (strstr($_table, '.')) {
|
||||
list($schema, $table) = explode('.', $_table);
|
||||
} else {
|
||||
$table = $_table;
|
||||
}
|
||||
// no PK name given at all
|
||||
if (empty($pk_name)) {
|
||||
// if name is plurar, make it singular
|
||||
// if (preg_match("/.*s$/i", $table))
|
||||
// $table = substr($table, 0, -1);
|
||||
// set pk_name to "id"
|
||||
$pk_name = $table . "_id";
|
||||
}
|
||||
$seq = ($schema ? $schema . '.' : '') . $table . "_" . $pk_name . "_seq";
|
||||
$q = "SELECT CURRVAL('$seq') AS insert_id";
|
||||
// I have to do manually or I overwrite the original insert internal vars ...
|
||||
if ($q = $this->__dbQuery($q)) {
|
||||
if (is_array($res = $this->__dbFetchArray($q))) {
|
||||
list($id) = $res;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$id = [-1, $q];
|
||||
}
|
||||
return $id;
|
||||
} else {
|
||||
//if not insert, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* queries database for the primary key name to this table in the selected schema
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param string $schema optional schema name, '' for default
|
||||
* @return string|bool primary key name or false if not found
|
||||
*/
|
||||
public function __dbPrimaryKey(string $table, string $schema = '')
|
||||
{
|
||||
if ($table) {
|
||||
// check if schema set is different from schema given,
|
||||
// only needed if schema is not empty
|
||||
$table_prefix = '';
|
||||
if ($schema) {
|
||||
$search_path = $this->__dbGetSchema();
|
||||
if ($search_path != $schema) {
|
||||
$table_prefix = $schema . '.';
|
||||
}
|
||||
}
|
||||
// read from table the PK name
|
||||
// faster primary key get
|
||||
$q = "SELECT pg_attribute.attname AS column_name, "
|
||||
. "format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS type "
|
||||
. "FROM pg_index, pg_class, pg_attribute ";
|
||||
if ($schema) {
|
||||
$q .= ", pg_namespace ";
|
||||
}
|
||||
$q .= "WHERE "
|
||||
// regclass translates the OID to the name
|
||||
. "pg_class.oid = '" . $table_prefix . $table . "'::regclass AND "
|
||||
. "indrelid = pg_class.oid AND ";
|
||||
if ($schema) {
|
||||
$q .= "nspname = '" . $schema . "' AND "
|
||||
. "pg_class.relnamespace = pg_namespace.oid AND ";
|
||||
}
|
||||
$q .= "pg_attribute.attrelid = pg_class.oid AND "
|
||||
. "pg_attribute.attnum = any(pg_index.indkey) "
|
||||
. "AND indisprimary";
|
||||
$cursor = $this->__dbQuery($q);
|
||||
if ($cursor !== false) {
|
||||
$__db_fetch_array = $this->__dbFetchArray($cursor);
|
||||
if (!is_array($__db_fetch_array)) {
|
||||
return false;
|
||||
}
|
||||
return $__db_fetch_array['column_name'] ?? false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_connect, writes out failure to screen if error occurs (hidden var)
|
||||
*
|
||||
* @param string $db_host host name
|
||||
* @param string $db_user user name
|
||||
* @param string $db_pass password
|
||||
* @param string $db_name databse name
|
||||
* @param integer $db_port port (int, 5432 is default)
|
||||
* @param string $db_ssl SSL (allow is default)
|
||||
* @return object|resource|bool db handler PgSql\Connection or false on error
|
||||
*/
|
||||
public function __dbConnect(
|
||||
string $db_host,
|
||||
string $db_user,
|
||||
string $db_pass,
|
||||
string $db_name,
|
||||
int $db_port,
|
||||
string $db_ssl = 'allow'
|
||||
) {
|
||||
if (empty($db_name)) {
|
||||
return false;
|
||||
}
|
||||
// if there is no host, leave it empty, this will try default unix path
|
||||
// same for port (defaults to 5432 if not set)
|
||||
// must set is db name
|
||||
// if no user name, db name is used
|
||||
$connection_string = [];
|
||||
if (!empty($db_host)) {
|
||||
$connection_string[] = 'host=' . $db_host;
|
||||
}
|
||||
if (!empty($db_port)) {
|
||||
$connection_string[] = 'port=' . $db_port;
|
||||
}
|
||||
if (!empty($db_user)) {
|
||||
$connection_string[] = 'user=' . $db_user;
|
||||
}
|
||||
if (!empty($db_pass)) {
|
||||
$connection_string[] = 'password=' . $db_pass;
|
||||
}
|
||||
// we must have at least db name set
|
||||
$connection_string[] = 'dbname=' . $db_name;
|
||||
if (!empty($db_ssl)) {
|
||||
$connection_string[] = 'sslmode=' . $db_ssl;
|
||||
}
|
||||
// connect
|
||||
$this->dbh = pg_connect(join(' ', $connection_string));
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the last error for this cursor and returns
|
||||
* html formatted string with error name
|
||||
*
|
||||
* @param bool|object|resource $cursor cursor PgSql\Result (former resource)
|
||||
* or null
|
||||
* @return string error string
|
||||
*/
|
||||
public function __dbPrintError($cursor = false): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
// run the query again for the error result here
|
||||
if (($cursor === false || is_bool($cursor)) && $this->last_error_query) {
|
||||
pg_send_query($this->dbh, $this->last_error_query);
|
||||
$this->last_error_query = '';
|
||||
$cursor = pg_get_result($this->dbh);
|
||||
}
|
||||
if ($cursor && !is_bool($cursor) && $error_str = pg_result_error($cursor)) {
|
||||
return '-PostgreSQL-Error- '
|
||||
. $error_str;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_meta_data
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param bool $extended show extended info (default true)
|
||||
* @return array<mixed>|bool array data for the table info or false on error
|
||||
*/
|
||||
public function __dbMetaData(string $table, $extended = true)
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
// needs to prefixed with @ or it throws a warning on not existing table
|
||||
return @pg_meta_data($this->dbh, $table, $extended);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_escape_string
|
||||
*
|
||||
* @param string|int|float|bool $string any string/int/float/bool
|
||||
* @return string excaped string
|
||||
*/
|
||||
public function __dbEscapeString($string): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
return pg_escape_string($this->dbh, (string)$string);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_escape_literal
|
||||
* difference to escape string is that this one adds quotes ('') around
|
||||
* the string too
|
||||
*
|
||||
* @param string|int|float|bool $string any string/int/float/bool
|
||||
* @return string excaped string including quites
|
||||
*/
|
||||
public function __dbEscapeLiteral($string): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return (string)'';
|
||||
}
|
||||
// for phpstan, thinks this is string|false?
|
||||
return (string)pg_escape_literal($this->dbh, (string)$string);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_escape_identifier
|
||||
* Only used for table names, column names
|
||||
*
|
||||
* @param string $string any string
|
||||
* @return string escaped string
|
||||
*/
|
||||
public function __dbEscapeIdentifier(string $string): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
// for phpstan, thinks this is string|false?
|
||||
return (string)pg_escape_identifier($this->dbh, (string)$string);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_escape_byte
|
||||
*
|
||||
* @param string $data data stream
|
||||
* @return string escaped bytea string
|
||||
*/
|
||||
public function __dbEscapeBytea(string $data): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_connection_busy
|
||||
*
|
||||
* @return bool True if connection is busy, False if not or no db connection at all
|
||||
*/
|
||||
public function __dbConnectionBusy(): bool
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
return pg_connection_busy($this->dbh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Experimental wrapper with scoket timetout
|
||||
*
|
||||
* @param integer $timeout_seconds Wait how many seconds on timeout
|
||||
* @return boolean True if connection is busy, or false on
|
||||
* not busy or no db connection at all
|
||||
*/
|
||||
public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
$busy = pg_connection_busy($this->dbh);
|
||||
/** @var array<resource>|null */
|
||||
$socket = [pg_socket($this->dbh)];
|
||||
$null = null;
|
||||
while ($busy) {
|
||||
// Will wait on that socket until that happens or the timeout is reached
|
||||
stream_select($socket, $null, $null, $timeout_seconds);
|
||||
$busy = pg_connection_busy($this->dbh);
|
||||
}
|
||||
return $busy;
|
||||
}
|
||||
|
||||
/**
|
||||
* extended wrapper for pg_version
|
||||
* can return any setting in this array block
|
||||
* If no connection, return empty string,
|
||||
* if not in array return empty string
|
||||
* On default 'version' will be stripped of any space attached info
|
||||
* eg 13.5 (other info) will return only 13.5
|
||||
*
|
||||
* @param string $parameter Parameter string to extract from array
|
||||
* @param boolean $strip If parameter is server strip out on default
|
||||
* Set to false to get original string AS is
|
||||
* @return string The parameter value
|
||||
*/
|
||||
public function __dbVersionInfo(string $parameter, bool $strip = true): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
// extract element
|
||||
$return_string = (string)(pg_version($this->dbh)[$parameter] ?? '');
|
||||
// for version, strip if requested
|
||||
if (
|
||||
in_array($parameter, ['server']) &&
|
||||
$strip === true
|
||||
) {
|
||||
$return_string = explode(' ', $return_string, 2)[0] ?? '';
|
||||
}
|
||||
return $return_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all parameters that are possible from the db_version
|
||||
*
|
||||
* @return array<mixed> Parameter key names from pg_version
|
||||
*/
|
||||
public function __dbVersionInfoParameterList(): array
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return [];
|
||||
}
|
||||
return array_keys(pg_version($this->dbh));
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for pg_version
|
||||
* Note: this only returns server version
|
||||
* not connection version OR client version
|
||||
*
|
||||
* @return string version string
|
||||
*/
|
||||
public function __dbVersion(): string
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return '';
|
||||
}
|
||||
// array has client, protocol, server, we just return server stripped
|
||||
return $this->__dbVersionInfo('server', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric version eg 90506 or 130006, etc
|
||||
* Note that this calls a show command on the server
|
||||
* Note:
|
||||
* Old version is 9.5.6 where 9.5 is the major version
|
||||
* Newer Postgresql (10 on) have only one major version so eg 13.5
|
||||
* is returned as 130005
|
||||
*
|
||||
* @return integer Server version
|
||||
*/
|
||||
public function __dbVersionNumeric(): int
|
||||
{
|
||||
return (int)$this->__dbShow('server_version_num');
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: it is recommended to convert arrays to json and parse the json in
|
||||
* PHP itself, array_to_json(array)
|
||||
* This is a fallback for old PostgreSQL versions
|
||||
* postgresql array to php array
|
||||
* https://stackoverflow.com/a/27964420
|
||||
*
|
||||
* @param string $array_text Array text from PostgreSQL
|
||||
* @param int $start Start string position
|
||||
* @param int|null $end End string position from recursive call
|
||||
* @return array<mixed>|null PHP type array
|
||||
*/
|
||||
public function __dbArrayParse(
|
||||
string $array_text,
|
||||
int $start = 0,
|
||||
?int &$end = null
|
||||
): ?array {
|
||||
if (empty($array_text) || $array_text[0] != '{') {
|
||||
return null;
|
||||
}
|
||||
$return = [];
|
||||
$string = false;
|
||||
$quote = '';
|
||||
$len = strlen($array_text);
|
||||
$v = '';
|
||||
// start from offset
|
||||
for ($array_pos = $start + 1; $array_pos < $len; $array_pos += 1) {
|
||||
$ch = $array_text[$array_pos];
|
||||
// check wher ein the string are we
|
||||
// end, one down
|
||||
if (!$string && $ch == '}') {
|
||||
if ($v !== '' || !empty($return)) {
|
||||
$return[] = $v;
|
||||
}
|
||||
$end = $array_pos;
|
||||
break;
|
||||
// open new array, jump recusrive up
|
||||
} elseif (!$string && $ch == '{') {
|
||||
// full string + poff set and end
|
||||
$v = $this->__dbArrayParse($array_text, $array_pos, $array_pos);
|
||||
// next array element
|
||||
} elseif (!$string && $ch == ',') {
|
||||
$return[] = $v;
|
||||
$v = '';
|
||||
// flag that this is a string
|
||||
} elseif (!$string && ($ch == '"' || $ch == "'")) {
|
||||
$string = true;
|
||||
$quote = $ch;
|
||||
// quoted string
|
||||
} elseif ($string && $ch == $quote && $array_text[$array_pos - 1] == "\\") {
|
||||
$v = substr($v, 0, -1) . $ch;
|
||||
} elseif ($string && $ch == $quote && $array_text[$array_pos - 1] != "\\") {
|
||||
$string = false;
|
||||
} else {
|
||||
// build string
|
||||
$v .= $ch;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any server setting
|
||||
* if no connection or empty parameter or other error returns false
|
||||
* else returns a string
|
||||
*
|
||||
* @param string $parameter Parameter to query
|
||||
* @return string|bool Settings value as string
|
||||
*/
|
||||
public function __dbParameter(string $parameter)
|
||||
{
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
if (empty($parameter)) {
|
||||
return false;
|
||||
}
|
||||
return pg_parameter_status($this->dbh, $parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for any SHOW data blocks
|
||||
* eg search_path or client_encoding
|
||||
*
|
||||
* @param string $show_string Part to show, if invalid will return empty string
|
||||
* @return string Found part as is
|
||||
*/
|
||||
public function __dbShow(string $show_string): string
|
||||
{
|
||||
// get search path
|
||||
$cursor = $this->__dbQuery("SHOW " . $this->__dbEscapeIdentifier($show_string));
|
||||
// abort on failure and return empty
|
||||
if ($cursor === false) {
|
||||
return '';
|
||||
}
|
||||
// get result
|
||||
$db_schema = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
|
||||
return $db_schema[$show_string] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new database schema/search_path
|
||||
* Checks if schema exits and if not aborts with error code 2
|
||||
*
|
||||
* @param string $db_schema Schema to set
|
||||
* @return int Returns 0 if no error
|
||||
* 1 for check query failed
|
||||
* 2 for schema not found in database
|
||||
*/
|
||||
public function __dbSetSchema(string $db_schema): int
|
||||
{
|
||||
// check if schema actually exists
|
||||
$query = "SELECT EXISTS("
|
||||
. "SELECT 1 FROM information_schema.schemata "
|
||||
. "WHERE schema_name = " . $this->__dbEscapeLiteral($db_schema)
|
||||
. ")";
|
||||
$cursor = $this->__dbQuery($query);
|
||||
// abort if execution fails
|
||||
if ($cursor === false) {
|
||||
return 1;
|
||||
}
|
||||
// check if schema does not exists
|
||||
$row = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
|
||||
if (empty($row['exists']) || $row['exists'] == 'f') {
|
||||
return 2;
|
||||
}
|
||||
$query = "SET search_path TO " . $this->__dbEscapeLiteral($db_schema);
|
||||
$this->__dbQuery($query);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current set schema/search_path
|
||||
*
|
||||
* @return string Search Path as currently set in DB
|
||||
*/
|
||||
public function __dbGetSchema(): string
|
||||
{
|
||||
return $this->__dbShow('search_path');
|
||||
}
|
||||
|
||||
/**
|
||||
* set the client encoding
|
||||
* Returns 0 on set ok, or 3 if the client encoding could not be set
|
||||
*
|
||||
* @param string $db_encoding
|
||||
* @return int Returns 0 for no error
|
||||
* [not used] 1 for check query failed
|
||||
* [not used] 2 for invalid client encoding
|
||||
* 3 client encoding could not be set
|
||||
*/
|
||||
public function __dbSetEncoding(string $db_encoding): int
|
||||
{
|
||||
// check if ecnoding is valid first
|
||||
// does not take into account aliases
|
||||
// TODO lookup with alisaes so eg ShiftJIS does not get a false
|
||||
// $query = "SELECT EXISTS("
|
||||
// . "SELECT pg_catalog.pg_encoding_to_char(conforencoding) "
|
||||
// . "FROM pg_catalog.pg_conversion "
|
||||
// . "WHERE pg_catalog.pg_encoding_to_char(conforencoding) = "
|
||||
// . $this->dbEscapeLiteral($db_encoding)
|
||||
// . ")";
|
||||
// $cursor = $this->__dbQuery($query);
|
||||
// if ($cursor === false) {
|
||||
// return 1;
|
||||
// }
|
||||
// $row = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
|
||||
// if ($row['exists'] == 'f') {
|
||||
// return 2;
|
||||
// }
|
||||
$query = "SET client_encoding TO " . $this->__dbEscapeLiteral($db_encoding);
|
||||
if ($this->__dbQuery($query) === false) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current set client encoding
|
||||
* @return string Client encoding string, empty if not set
|
||||
*/
|
||||
public function __dbGetEncoding(): string
|
||||
{
|
||||
return $this->__dbShow('client_encoding');
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
305
4dev/deprecated/CoreLibs/DB/SQL/SqlInterface/SqlFunctions.php
Normal file
305
4dev/deprecated/CoreLibs/DB/SQL/SqlInterface/SqlFunctions.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Intrface for all SQL\* functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\DB\SQL\SqlInterface;
|
||||
|
||||
interface SqlFunctions
|
||||
{
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __dbLastErrorQuery(): bool;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $query
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbQuery(string $query);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $query
|
||||
* @param array<mixed> $params
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbQueryParams(string $query, array $params);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $query
|
||||
* @return boolean
|
||||
*/
|
||||
public function __dbSendQuery(string $query): bool;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbGetResult();
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __dbClose(): void;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $query
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbPrepare(string $name, string $query);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $name
|
||||
* @param array<mixed> $data
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbExecute(string $name, array $data);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbNumRows($cursor): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbNumFields($cursor): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @param int $i
|
||||
* @return string|bool
|
||||
*/
|
||||
public function __dbFieldName($cursor, int $i);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @param int $result_type
|
||||
* @return array<mixed>|bool
|
||||
*/
|
||||
public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param boolean $assoc_type
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbResultType(bool $assoc_type = true): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @return array<mixed>|bool
|
||||
*/
|
||||
public function __dbFetchAll($cursor);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbAffectedRows($cursor): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $query
|
||||
* @param string|null $pk_name
|
||||
* @return string|integer|false
|
||||
*/
|
||||
public function __dbInsertId(string $query, ?string $pk_name);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return string|bool
|
||||
*/
|
||||
public function __dbPrimaryKey(string $table, string $schema = '');
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $db_host
|
||||
* @param string $db_user
|
||||
* @param string $db_pass
|
||||
* @param string $db_name
|
||||
* @param integer $db_port
|
||||
* @param string $db_ssl
|
||||
* @return object|resource|bool
|
||||
*/
|
||||
public function __dbConnect(
|
||||
string $db_host,
|
||||
string $db_user,
|
||||
string $db_pass,
|
||||
string $db_name,
|
||||
int $db_port,
|
||||
string $db_ssl = 'allow'
|
||||
);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param object|resource|bool $cursor
|
||||
* @return string
|
||||
*/
|
||||
public function __dbPrintError($cursor = false): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $table
|
||||
* @param boolean $extended
|
||||
* @return array<mixed>|bool
|
||||
*/
|
||||
public function __dbMetaData(string $table, $extended = true);
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string|int|float|bool $string
|
||||
* @return string
|
||||
*/
|
||||
public function __dbEscapeString($string): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string|int|float|bool $string
|
||||
* @return string
|
||||
*/
|
||||
public function __dbEscapeLiteral($string): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function __dbEscapeIdentifier(string $string): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
public function __dbEscapeBytea(string $data): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $bytea
|
||||
* @return string
|
||||
*/
|
||||
public function __dbUnescapeBytea(string $bytea): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function __dbConnectionBusy(): bool;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param integer $timeout_seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __dbVersion(): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $array_text
|
||||
* @param integer $start
|
||||
* @param integer|null $end
|
||||
* @return array<mixed>|null
|
||||
*/
|
||||
public function __dbArrayParse(
|
||||
string $array_text,
|
||||
int $start = 0,
|
||||
?int &$end = null
|
||||
): ?array;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $show_string
|
||||
* @return string
|
||||
*/
|
||||
public function __dbShow(string $show_string): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $db_schema
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbSetSchema(string $db_schema): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __dbGetSchema(): string;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $db_encoding
|
||||
* @return integer
|
||||
*/
|
||||
public function __dbSetEncoding(string $db_encoding): int;
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __dbGetEncoding(): string;
|
||||
}
|
||||
|
||||
// __END__
|
||||
881
4dev/deprecated/CoreLibs/Debug/Logging.php
Normal file
881
4dev/deprecated/CoreLibs/Debug/Logging.php
Normal file
@@ -0,0 +1,881 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Debug support functions
|
||||
*
|
||||
* These are if there is any debug to print out at all at the end
|
||||
* debug_output_all - general yes no
|
||||
* It's recommended to use the method "debug_for" to turn on of the array vars
|
||||
* debug_output - turn on for one level (Array)
|
||||
* debug_output_not - turn off for one level (array)
|
||||
*
|
||||
* Print out the debug at thend of the html
|
||||
* echo_output_all
|
||||
* echo_output
|
||||
* echo_output_not
|
||||
*
|
||||
* Write debug to file
|
||||
* print_output_all
|
||||
* print_output
|
||||
* print_output_not
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Debug;
|
||||
|
||||
use CoreLibs\Debug\Support;
|
||||
use CoreLibs\Create\Uids;
|
||||
use CoreLibs\Get\System;
|
||||
use CoreLibs\Convert\Html;
|
||||
|
||||
class Logging
|
||||
{
|
||||
// options
|
||||
/** @var array<mixed> */
|
||||
private $options = [];
|
||||
// page and host name
|
||||
/** @var string */
|
||||
private $page_name;
|
||||
/** @var string */
|
||||
private $host_name;
|
||||
/** @var int */
|
||||
private $host_port;
|
||||
// internal error reporting vars
|
||||
/** @var array<mixed> */
|
||||
private $error_msg = []; // the "connection" to the outside errors
|
||||
// debug output prefix
|
||||
/** @var string */
|
||||
private $error_msg_prefix = ''; // prefix to the error string (the class name)
|
||||
// debug flags
|
||||
/** @var array<mixed> */
|
||||
private $debug_output = []; // if this is true, show debug on desconstructor
|
||||
/** @var array<mixed> */
|
||||
private $debug_output_not = [];
|
||||
/** @var bool */
|
||||
private $debug_output_all = false;
|
||||
/** @var array<mixed> */
|
||||
private $echo_output = []; // errors: echo out, default is 1
|
||||
/** @var array<mixed> */
|
||||
private $echo_output_not = [];
|
||||
/** @var bool */
|
||||
private $echo_output_all = false;
|
||||
/** @var array<mixed> */
|
||||
private $print_output = []; // errors: print to file, default is 0
|
||||
/** @var array<mixed> */
|
||||
private $print_output_not = [];
|
||||
/** @var bool */
|
||||
private $print_output_all = false;
|
||||
// debug flags/settings
|
||||
/** @var string */
|
||||
private $running_uid = ''; // unique ID set on class init and used in logging as prefix
|
||||
// log file name
|
||||
/** @var string */
|
||||
private $log_folder = '';
|
||||
/** @var string */
|
||||
private $log_file_name_ext = 'log'; // use this for date rotate
|
||||
/** @var string */
|
||||
private $log_file_name = '';
|
||||
/** @var int */
|
||||
private $log_max_filesize = 0; // set in kilobytes
|
||||
/** @var string */
|
||||
private $log_print_file = 'error_msg##LOGID####LEVEL####CLASS####PAGENAME####DATE##';
|
||||
/** @var string */
|
||||
private $log_file_unique_id; // a unique ID set only once for call derived from this class
|
||||
/** @var string */
|
||||
private $log_file_date = ''; // Y-m-d file in file name
|
||||
/** @var bool */
|
||||
private $log_print_file_date = true; // if set add Y-m-d and do automatic daily rotation
|
||||
/** @var string */
|
||||
private $log_file_id = ''; // a alphanumeric name that has to be set as global definition
|
||||
/** @var bool */
|
||||
private $log_per_level = false; // set, it will split per level (first parameter in debug call)
|
||||
/** @var bool */
|
||||
private $log_per_class = false; // set, will split log per class
|
||||
/** @var bool */
|
||||
private $log_per_page = false; // set, will split log per called file
|
||||
/** @var bool */
|
||||
private $log_per_run = false; // create a new log file per run (time stamp + unique ID)
|
||||
// script running time
|
||||
/** @var float */
|
||||
private $script_starttime;
|
||||
|
||||
/**
|
||||
* Init logger
|
||||
*
|
||||
* global vars that can be used
|
||||
* - BASE
|
||||
* - LOG
|
||||
* - LOG_FILE_ID
|
||||
* options array layout
|
||||
* - log_folder:
|
||||
* - print_file_date:
|
||||
* - file_id:
|
||||
* - unique_id:
|
||||
* - log_per_level:
|
||||
* - log_per_class:
|
||||
* - log_per_page:
|
||||
* - log_per_run:
|
||||
* - debug_all:
|
||||
* - echo_all:
|
||||
* - print_all:
|
||||
* - debug (array):
|
||||
* - echo (array):
|
||||
* - print (array):
|
||||
* - debug_not (array):
|
||||
* - echo_not (array):
|
||||
* - print_not (array):
|
||||
*
|
||||
* @param array<mixed> $options Array with settings options
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
// copy the options over
|
||||
$this->options = $options;
|
||||
// set log folder from options
|
||||
$this->log_folder = $this->options['log_folder'] ?? '';
|
||||
// legacy flow, check must set constants
|
||||
if (empty($this->log_folder) && defined('BASE') && defined('LOG')) {
|
||||
// make sure this is writeable, else skip
|
||||
$this->log_folder = BASE . LOG;
|
||||
}
|
||||
// fallback + notice
|
||||
if (empty($this->log_folder)) {
|
||||
/* trigger_error(
|
||||
'options or constant not set or folder not writable. fallback to: ' . getcwd(),
|
||||
E_USER_NOTICE
|
||||
); */
|
||||
$this->log_folder = getcwd() . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
// if folder is not writeable, abort
|
||||
if (!is_writeable($this->log_folder)) {
|
||||
trigger_error(
|
||||
'Folder: ' . $this->log_folder . ' is not writeable for logging',
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
// check if log_folder has a trailing /
|
||||
if (substr($this->log_folder, -1, 1) != DIRECTORY_SEPARATOR) {
|
||||
$this->log_folder .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
// running time start for script
|
||||
$this->script_starttime = microtime(true);
|
||||
// set per run UID for logging
|
||||
$this->running_uid = Uids::uniqIdShort();
|
||||
// set the page name
|
||||
$this->page_name = System::getPageName();
|
||||
// set host name
|
||||
list($this->host_name , $this->host_port) = System::getHostName();
|
||||
// add port to host name if not port 80
|
||||
if ($this->host_port != 80) {
|
||||
$this->host_name .= ':' . $this->host_port;
|
||||
}
|
||||
|
||||
// can be overridden with basicSetLogFileId later
|
||||
if (!empty($this->options['file_id'])) {
|
||||
$this->setLogId($this->options['file_id']);
|
||||
} elseif (!empty($GLOBALS['LOG_FILE_ID'])) {
|
||||
// legacy flow, should be removed and only set via options
|
||||
$this->setLogId($GLOBALS['LOG_FILE_ID']);
|
||||
// TODO trigger deprecation error
|
||||
// trigger_error(
|
||||
// 'Debug\Logging: Do not use globals LOG_FILE_ID to set log id for Logging',
|
||||
// E_USER_DEPRECATED
|
||||
// );
|
||||
} elseif (defined('LOG_FILE_ID')) {
|
||||
// legacy flow, should be removed and only set via options
|
||||
$this->setLogId(LOG_FILE_ID);
|
||||
// trigger deprecation error
|
||||
// trigger_error(
|
||||
// 'Debug\Logging: Do not use constant LOG_FILE_ID to set log id for Logging',
|
||||
// E_USER_DEPRECATED
|
||||
// );
|
||||
}
|
||||
|
||||
// init the log levels
|
||||
$this->initLogLevels();
|
||||
}
|
||||
|
||||
// *** PRIVATE ***
|
||||
|
||||
/**
|
||||
* init the basic log levels based on global set variables
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function initLogLevels(): void
|
||||
{
|
||||
// if given via parameters, only for all
|
||||
// globals overrule given settings, for one (array), eg $ECHO['db'] = 1;
|
||||
foreach (['debug', 'echo', 'print'] as $type) {
|
||||
// include or exclude (off) from output
|
||||
foreach (['on', 'off'] as $flag) {
|
||||
$in_type = $type;
|
||||
if ($flag == 'off') {
|
||||
$in_type .= '_not';
|
||||
}
|
||||
$up_type = strtoupper($in_type);
|
||||
if (
|
||||
isset($this->options[$in_type]) &&
|
||||
is_array($this->options[$in_type])
|
||||
) {
|
||||
$this->setLogLevel($type, $flag, $this->options[$in_type]);
|
||||
} elseif (
|
||||
isset($GLOBALS[$up_type]) &&
|
||||
is_array($GLOBALS[$up_type])
|
||||
) {
|
||||
// TODO trigger deprecation error
|
||||
$this->setLogLevel($type, $flag, $GLOBALS[$up_type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove all $GLOBALS call and only use options
|
||||
// all overrule
|
||||
$this->setLogLevelAll(
|
||||
'debug',
|
||||
$this->options['debug_all'] ??
|
||||
// for user login, should be handled outside like globals
|
||||
$_SESSION['DEBUG_ALL'] ??
|
||||
$GLOBALS['DEBUG_ALL'] ??
|
||||
false
|
||||
);
|
||||
$this->setLogLevelAll(
|
||||
'print',
|
||||
$this->options['print_all'] ??
|
||||
// for user login, should be handled outside like globals
|
||||
$_SESSION['DEBUG_ALL'] ??
|
||||
$GLOBALS['PRINT_ALL'] ??
|
||||
false
|
||||
);
|
||||
$this->setLogLevelAll(
|
||||
'echo',
|
||||
$this->options['echo_all'] ??
|
||||
$GLOBALS['ECHO_ALL'] ??
|
||||
false
|
||||
);
|
||||
|
||||
// GLOBAL rules for log writing
|
||||
// add file date is default on
|
||||
$this->setGetLogPrintFileDate(
|
||||
$this->options['print_file_date'] ??
|
||||
$GLOBALS['LOG_PRINT_FILE_DATE'] ??
|
||||
true
|
||||
);
|
||||
// all other logging file name flags are off
|
||||
$this->setLogPer(
|
||||
'level',
|
||||
$this->options['per_level'] ??
|
||||
$GLOBALS['LOG_PER_LEVEL'] ??
|
||||
false
|
||||
);
|
||||
$this->setLogPer(
|
||||
'class',
|
||||
$this->options['per_class'] ??
|
||||
$GLOBALS['LOG_PER_CLASS'] ??
|
||||
false
|
||||
);
|
||||
$this->setLogPer(
|
||||
'page',
|
||||
$this->options['per_page'] ??
|
||||
$GLOBALS['LOG_PER_PAGE'] ??
|
||||
false
|
||||
);
|
||||
$this->setLogPer(
|
||||
'run',
|
||||
$this->options['per_run'] ??
|
||||
$GLOBALS['LOG_PER_RUN'] ??
|
||||
false
|
||||
);
|
||||
// set log per date
|
||||
if ($this->setGetLogPrintFileDate()) {
|
||||
$this->log_file_date = date('Y-m-d');
|
||||
}
|
||||
// set per run ID
|
||||
if ($this->log_per_run) {
|
||||
$this->setLogUniqueId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if we have a need to work on certain debug output
|
||||
* Needs debug/echo/print ad target for which of the debug flag groups we check
|
||||
* also needs level string to check in the per level output flag check.
|
||||
* In case we have invalid target it will return false
|
||||
*
|
||||
* @param string $target target group to check debug/echo/print
|
||||
* @param string $level level to check in detailed level flag
|
||||
* @return bool true on access allowed or false on no access
|
||||
*/
|
||||
private function doDebugTrigger(string $target, string $level): bool
|
||||
{
|
||||
$access = false;
|
||||
// check if we do debug, echo or print
|
||||
if (
|
||||
(
|
||||
$this->getLogLevel($target, 'on', $level) ||
|
||||
$this->getLogLevelAll($target)
|
||||
) &&
|
||||
!$this->getLogLevel($target, 'off', $level)
|
||||
) {
|
||||
$access = true;
|
||||
}
|
||||
return $access;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes error msg data to file for current level
|
||||
*
|
||||
* @param string $level the level to write
|
||||
* @param string $error_string error string to write
|
||||
* @return bool True if message written, FAlse if not
|
||||
*/
|
||||
private function writeErrorMsg(string $level, string $error_string): bool
|
||||
{
|
||||
// only write if write is requested
|
||||
if (
|
||||
!($this->doDebugTrigger('debug', $level) &&
|
||||
$this->doDebugTrigger('print', $level))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// init base file path
|
||||
$fn = $this->log_folder . $this->log_print_file . '.' . $this->log_file_name_ext;
|
||||
// log ID prefix settings, if not valid, replace with empty
|
||||
if (!empty($this->log_file_id)) {
|
||||
$rpl_string = '_' . $this->log_file_id;
|
||||
} else {
|
||||
$rpl_string = '';
|
||||
}
|
||||
$fn = str_replace('##LOGID##', $rpl_string, $fn); // log id (like a log file prefix)
|
||||
|
||||
if ($this->log_per_run) {
|
||||
$rpl_string = '_' . $this->log_file_unique_id; // add 8 char unique string
|
||||
} elseif ($this->setGetLogPrintFileDate()) {
|
||||
$rpl_string = '_' . $this->log_file_date; // add date to file
|
||||
} else {
|
||||
$rpl_string = '';
|
||||
}
|
||||
$fn = str_replace('##DATE##', $rpl_string, $fn); // create output filename
|
||||
|
||||
// write per level
|
||||
$rpl_string = !$this->log_per_level ? '' :
|
||||
// normalize level, replace all non alphanumeric characters with -
|
||||
'_' . (
|
||||
// if return is only - then set error string
|
||||
preg_match(
|
||||
"/^-+$/",
|
||||
$level_string = preg_replace("/[^A-Za-z0-9-_]/", '-', $level) ?? ''
|
||||
) ?
|
||||
'INVALID-LEVEL-STRING' :
|
||||
$level_string
|
||||
);
|
||||
$fn = str_replace('##LEVEL##', $rpl_string, $fn); // create output filename
|
||||
// set per class, but don't use get_class as we will only get self
|
||||
$rpl_string = !$this->log_per_class ? '' : '_'
|
||||
// set sub class settings
|
||||
. str_replace('\\', '-', Support::getCallerClass());
|
||||
$fn = str_replace('##CLASS##', $rpl_string, $fn); // create output filename
|
||||
|
||||
// if request to write to one file
|
||||
$rpl_string = !$this->log_per_page ?
|
||||
'' :
|
||||
'_' . System::getPageName(System::NO_EXTENSION);
|
||||
$fn = str_replace('##PAGENAME##', $rpl_string, $fn); // create output filename
|
||||
|
||||
// write to file
|
||||
// first check if max file size is is set and file is bigger
|
||||
if (
|
||||
$this->log_max_filesize > 0 &&
|
||||
((filesize($fn) / 1024) > $this->log_max_filesize)
|
||||
) {
|
||||
// for easy purpose, rename file only to attach timestamp, nur sequence numbering
|
||||
rename($fn, $fn . '.' . date("YmdHis"));
|
||||
}
|
||||
$this->log_file_name = $fn;
|
||||
$fp = fopen($this->log_file_name, 'a');
|
||||
if ($fp !== false) {
|
||||
fwrite($fp, $error_string);
|
||||
fclose($fp);
|
||||
return true;
|
||||
} else {
|
||||
echo "<!-- could not open file: " . $this->log_file_name . " //-->";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// *** PUBLIC ***
|
||||
|
||||
/**
|
||||
* Temporary method to read all class variables for testing purpose
|
||||
*
|
||||
* @param string $name what variable to return
|
||||
* @return mixed can be anything, bool, string, int, array
|
||||
*/
|
||||
public function getSetting(string $name) //:mixed DOES not work with PHP 7.4
|
||||
{
|
||||
// for debug purpose only
|
||||
return $this->{$name};
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the internal log file prefix id
|
||||
* string must be a alphanumeric string
|
||||
* if non valid string is given it returns the previous set one only
|
||||
*
|
||||
* @param string $string log file id string value
|
||||
* @return string returns the set log file id string
|
||||
* @deprecated Use $log->setLogId()
|
||||
*/
|
||||
public function basicSetLogId(string $string): string
|
||||
{
|
||||
return $this->setLogId($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the internal log file prefix id
|
||||
* string must be a alphanumeric string
|
||||
* if non valid string is given it returns the previous set one only
|
||||
*
|
||||
* @param string $string log file id string value
|
||||
* @return string returns the set log file id string
|
||||
*/
|
||||
public function setLogId(string $string): string
|
||||
{
|
||||
if (preg_match("/^[\w\-]+$/", $string)) {
|
||||
$this->log_file_id = $string;
|
||||
}
|
||||
return $this->log_file_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* return current set log file id
|
||||
* @return string
|
||||
*/
|
||||
public function getLogId(): string
|
||||
{
|
||||
return $this->log_file_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* old name for setLogLevel
|
||||
*
|
||||
* @param string $type debug, echo, print
|
||||
* @param string $flag on/off
|
||||
* array $array of levels to turn on/off debug
|
||||
* @return bool Return false if type or flag is invalid
|
||||
* @deprecated Use setLogLevel
|
||||
*/
|
||||
public function debugFor(string $type, string $flag): bool
|
||||
{
|
||||
/** @phan-suppress-next-line PhanTypeMismatchArgumentReal, PhanParamTooFew @phpstan-ignore-next-line */
|
||||
return $this->setLogLevel(...[func_get_args()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* set log level settings for All types
|
||||
* if invalid type, skip
|
||||
*
|
||||
* @param string $type Type to get: debug, echo, print
|
||||
* @param bool $set True or False
|
||||
* @return bool Return false if type invalid
|
||||
*/
|
||||
public function setLogLevelAll(string $type, bool $set): bool
|
||||
{
|
||||
// skip set if not valid
|
||||
if (!in_array($type, ['debug', 'echo', 'print'])) {
|
||||
return false;
|
||||
}
|
||||
$this->{$type . '_output_all'} = $set;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current log level setting for All level blocks
|
||||
*
|
||||
* @param string $type Type to get: debug, echo, print
|
||||
* @return bool False on failure, or the boolean flag from the all var
|
||||
*/
|
||||
public function getLogLevelAll(string $type): bool
|
||||
{
|
||||
// type check for debug/echo/print
|
||||
if (!in_array($type, ['debug', 'echo', 'print'])) {
|
||||
return false;
|
||||
}
|
||||
return $this->{$type . '_output_all'};
|
||||
}
|
||||
|
||||
/**
|
||||
* passes list of level names, to turn on debug
|
||||
* eg $foo->debugFor('print', 'on', ['LOG', 'DEBUG', 'INFO']);
|
||||
*
|
||||
* @param string $type debug, echo, print
|
||||
* @param string $flag on/off
|
||||
* @param array<mixed> $debug_on Array of levels to turn on/off debug
|
||||
* To turn off a level set 'Level' => false,
|
||||
* If not set, switches to on
|
||||
* @return bool Return false if type or flag invalid
|
||||
* also false if debug array is empty
|
||||
*/
|
||||
public function setLogLevel(string $type, string $flag, array $debug_on): bool
|
||||
{
|
||||
// abort if not valid type
|
||||
if (!in_array($type, ['debug', 'echo', 'print'])) {
|
||||
return false;
|
||||
}
|
||||
// invalid flag type
|
||||
if (!in_array($flag, ['on', 'off'])) {
|
||||
return false;
|
||||
}
|
||||
if (count($debug_on) >= 1) {
|
||||
foreach ($debug_on as $level => $set) {
|
||||
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
|
||||
if (!is_bool($set)) {
|
||||
$level = $set;
|
||||
$set = true;
|
||||
}
|
||||
$this->{$switch}[$level] = $set;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the log level for the array type normal and not (disable)
|
||||
*
|
||||
* @param string $type debug, echo, print
|
||||
* @param string $flag on/off
|
||||
* @param string|null $level if not null then check if this array entry is set
|
||||
* else return false
|
||||
* @return bool|array<mixed> if $level is null, return array, else boolean true/false
|
||||
*/
|
||||
public function getLogLevel(string $type, string $flag, ?string $level = null)
|
||||
{
|
||||
// abort if not valid type
|
||||
if (!in_array($type, ['debug', 'echo', 'print'])) {
|
||||
return false;
|
||||
}
|
||||
// invalid flag type
|
||||
if (!in_array($flag, ['on', 'off'])) {
|
||||
return false;
|
||||
}
|
||||
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
|
||||
// log level direct check must be not null or not empty string
|
||||
if (!empty($level)) {
|
||||
return $this->{$switch}[$level] ?? false;
|
||||
}
|
||||
// array
|
||||
return $this->{$switch};
|
||||
}
|
||||
|
||||
/**
|
||||
* set flags for per log level type
|
||||
* - level: set per sub group level
|
||||
* - class: split by class
|
||||
* - page: split per page called
|
||||
* - run: for each run
|
||||
*
|
||||
* @param string $type Type to get: level, class, page, run
|
||||
* @param bool $set True or False
|
||||
* @return bool Return false if type invalid
|
||||
*/
|
||||
public function setLogPer(string $type, bool $set): bool
|
||||
{
|
||||
if (!in_array($type, ['level', 'class', 'page', 'run'])) {
|
||||
return false;
|
||||
}
|
||||
$this->{'log_per_' . $type} = $set;
|
||||
// if per run set unique id
|
||||
if ($type == 'run' && $set == true) {
|
||||
$this->setLogUniqueId();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* return current set log per flag in bool
|
||||
*
|
||||
* @param string $type Type to get: level, class, page, run
|
||||
* @return bool True of false for turned on or off
|
||||
*/
|
||||
public function getLogPer(string $type): bool
|
||||
{
|
||||
if (!in_array($type, ['level', 'class', 'page', 'run'])) {
|
||||
return false;
|
||||
}
|
||||
return $this->{'log_per_' . $type};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a unique id based on current date (y/m/d, h:i:s) and a unique id (8 chars)
|
||||
* if override is set to true it will be newly set, else if already set nothing changes
|
||||
*
|
||||
* @param bool $override True to force new set
|
||||
* @return void
|
||||
*/
|
||||
public function setLogUniqueId(bool $override = false): void
|
||||
{
|
||||
if (!$this->log_file_unique_id || $override == true) {
|
||||
$this->log_file_unique_id =
|
||||
date('Y-m-d_His') . '_U_'
|
||||
. substr(hash('sha1', uniqid((string)mt_rand(), true)), 0, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current set log file unique id,
|
||||
* empty string for not set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLogUniqueId(): string
|
||||
{
|
||||
return $this->log_file_unique_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or get the log file date extension flag
|
||||
* if null or empty parameter gets current flag
|
||||
*
|
||||
* @param boolean|null $set Set the date suffix for log files
|
||||
* If set to null return current set
|
||||
* @return boolean Current set flag
|
||||
*/
|
||||
public function setGetLogPrintFileDate(?bool $set = null): bool
|
||||
{
|
||||
if ($set !== null) {
|
||||
$this->log_print_file_date = $set;
|
||||
}
|
||||
return $this->log_print_file_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current set log file name
|
||||
*
|
||||
* @return string Filename set set after the last time debug was called
|
||||
*/
|
||||
public function getLogFileName(): string
|
||||
{
|
||||
return $this->log_file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* A replacement for the \CoreLibs\Debug\Support::printAr
|
||||
* But this does not wrap it in <pre></pre>
|
||||
* It uses some special code sets so we can convert that to pre flags
|
||||
* for echo output {##HTMLPRE##} ... {##/HTMLPRE##}
|
||||
* Do not use this without using it in a string in debug function
|
||||
*
|
||||
* @param array<mixed> $a Array to format
|
||||
* @return string print_r formated
|
||||
*/
|
||||
public function prAr(array $a): string
|
||||
{
|
||||
return '##HTMLPRE##' . print_r($a, true) . '##/HTMLPRE##';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bool value to string value
|
||||
*
|
||||
* @param bool $bool Bool value to be transformed
|
||||
* @param string $true Override default string 'true'
|
||||
* @param string $false Override default string 'false'
|
||||
* @return string $true or $false string for true/false bool
|
||||
*/
|
||||
public function prBl(
|
||||
bool $bool,
|
||||
string $true = 'true',
|
||||
string $false = 'false'
|
||||
): string {
|
||||
return $bool ? $true : $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* write debug data to error_msg array
|
||||
*
|
||||
* @param string $level id for error message, groups messages together
|
||||
* @param string $string the actual error message
|
||||
* @param bool $strip default on false, if set to true,
|
||||
* all html tags will be stripped and <br> changed to \n
|
||||
* this is only used for debug output
|
||||
* @param string $prefix Attach some block before $string.
|
||||
* Will not be stripped even
|
||||
* when strip is true
|
||||
* if strip is false, recommended to add that to $string
|
||||
* @return bool True if logged, false if not logged
|
||||
*/
|
||||
public function debug(
|
||||
string $level,
|
||||
string $string,
|
||||
bool $strip = false,
|
||||
string $prefix = ''
|
||||
): bool {
|
||||
$status = false;
|
||||
// must be debug on and either echo or print on
|
||||
if (
|
||||
!$this->doDebugTrigger('debug', $level) ||
|
||||
(
|
||||
// if debug is on, either print or echo must be set to on
|
||||
!$this->doDebugTrigger('print', $level) &&
|
||||
!$this->doDebugTrigger('echo', $level)
|
||||
)
|
||||
) {
|
||||
return $status;
|
||||
}
|
||||
// get the last class entry and wrie that
|
||||
$class = Support::getCallerClass();
|
||||
// get timestamp
|
||||
$timestamp = Support::printTime();
|
||||
// same string put for print (no html data inside)
|
||||
// write to file if set
|
||||
$status = $this->writeErrorMsg(
|
||||
$level,
|
||||
'[' . $timestamp . '] '
|
||||
. '[' . $this->host_name . '] '
|
||||
. '[' . System::getPageName(System::FULL_PATH) . '] '
|
||||
. '[' . $this->running_uid . '] '
|
||||
. '{' . $class . '} '
|
||||
. '<' . $level . '> - '
|
||||
// strip the htmlpre special tags if exist
|
||||
. str_replace(
|
||||
['##HTMLPRE##', '##/HTMLPRE##'],
|
||||
'',
|
||||
// if stripping all html, etc is requested, only for write error msg
|
||||
($strip ?
|
||||
// find any <br> and replace them with \n
|
||||
// strip rest of html elements (base only)
|
||||
preg_replace(
|
||||
"/(<\/?)(\w+)([^>]*>)/",
|
||||
'',
|
||||
str_replace('<br>', "\n", $prefix . $string)
|
||||
) :
|
||||
$prefix . $string
|
||||
) ?: ''
|
||||
)
|
||||
. "\n"
|
||||
);
|
||||
// write to error level msg array if there is an echo request
|
||||
if ($this->doDebugTrigger('echo', $level)) {
|
||||
// init if not set
|
||||
if (!isset($this->error_msg[$level])) {
|
||||
$this->error_msg[$level] = [];
|
||||
}
|
||||
// HTML string
|
||||
$this->error_msg[$level][] = '<div>'
|
||||
. '[<span style="font-weight: bold; color: #5e8600;">' . $timestamp . '</span>] '
|
||||
. '[<span style="font-weight: bold; color: #c56c00;">' . $level . '</span>] '
|
||||
. '[<span style="color: #b000ab;">' . $this->host_name . '</span>] '
|
||||
. '[<span style="color: #08b369;">' . $this->page_name . '</span>] '
|
||||
. '[<span style="color: #0062A2;">' . $this->running_uid . '</span>] '
|
||||
. '{<span style="font-style: italic; color: #928100;">' . $class . '</span>} - '
|
||||
// as is prefix, allow HTML
|
||||
. $prefix
|
||||
// we replace special HTMLPRE with <pre> entries
|
||||
. str_replace(
|
||||
['##HTMLPRE##', '##/HTMLPRE##'],
|
||||
['<pre>', '</pre>'],
|
||||
Html::htmlent($string)
|
||||
)
|
||||
. "</div><!--#BR#-->";
|
||||
$status = true;
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* for ECHO ON only
|
||||
* returns error data as string so it can be echoed out
|
||||
*
|
||||
* @param string $header_prefix prefix string for header
|
||||
* @return string error msg for all levels
|
||||
*/
|
||||
public function printErrorMsg(string $header_prefix = ''): string
|
||||
{
|
||||
$string_output = '';
|
||||
// if not debug && echo on, do not return anything
|
||||
if (
|
||||
!$this->getLogLevelAll('debug') ||
|
||||
!$this->getLogLevelAll('echo')
|
||||
) {
|
||||
return $string_output;
|
||||
}
|
||||
if ($this->error_msg_prefix) {
|
||||
$header_prefix = $this->error_msg_prefix;
|
||||
}
|
||||
$script_end = microtime(true) - $this->script_starttime;
|
||||
foreach ($this->error_msg as $level => $temp_debug_output) {
|
||||
if ($this->doDebugTrigger('debug', $level)) {
|
||||
if ($this->doDebugTrigger('echo', $level)) {
|
||||
$string_output .= '<div style="font-size: 12px;">'
|
||||
. '[<span style="font-style: italic; color: #c56c00;">' . $level . '</span>] '
|
||||
. ($header_prefix ? "<b>**** " . Html::htmlent($header_prefix) . " ****</br>\n" : '')
|
||||
. '</div>'
|
||||
. join('', $temp_debug_output);
|
||||
} // echo it out
|
||||
} // do printout
|
||||
} // for each level
|
||||
// create the output wrapper around
|
||||
// so we have a nice formated output per class
|
||||
if ($string_output) {
|
||||
$string_prefix = '<div style="text-align: left; padding: 5px; font-size: 10px; '
|
||||
. 'font-family: sans-serif; border-top: 1px solid black; '
|
||||
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
|
||||
. 'background-color: white; color: black;">'
|
||||
. '<div style="font-size: 12px;">{<span style="font-style: italic; color: #928100;">'
|
||||
. Support::getCallerClass() . '</span>}</div>';
|
||||
$string_output = $string_prefix . $string_output
|
||||
. '<div><span style="font-style: italic; color: #108db3;">Script Run Time:</span> '
|
||||
. $script_end . '</div>'
|
||||
. '</div>';
|
||||
}
|
||||
// }
|
||||
return $string_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* for ECHO ON only
|
||||
* unsests the error message array
|
||||
* can be used if writing is primary to file
|
||||
* if no level given resets all
|
||||
*
|
||||
* @param string $level optional level
|
||||
* @return void has no return
|
||||
*/
|
||||
public function resetErrorMsg(string $level = ''): void
|
||||
{
|
||||
if (!$level) {
|
||||
$this->error_msg = [];
|
||||
} elseif (isset($this->error_msg[$level])) {
|
||||
unset($this->error_msg[$level]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for ECHO ON only
|
||||
* Get current error message array
|
||||
*
|
||||
* @return array<mixed> error messages collected
|
||||
*/
|
||||
public function getErrorMsg(): array
|
||||
{
|
||||
return $this->error_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* for ECHO ON only
|
||||
* merges the given error array with the one from this class
|
||||
* only merges visible ones
|
||||
*
|
||||
* @param array<mixed> $error_msg error array
|
||||
* @return void has no return
|
||||
*/
|
||||
public function mergeErrors(array $error_msg = []): void
|
||||
{
|
||||
array_push($this->error_msg, ...$error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
219
4dev/deprecated/CoreLibs/Debug/Support.php
Normal file
219
4dev/deprecated/CoreLibs/Debug/Support.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Debug support functions
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Debug;
|
||||
|
||||
use CoreLibs\Convert\Html;
|
||||
|
||||
class Support
|
||||
{
|
||||
/**
|
||||
* wrapper around microtime function to print out y-m-d h:i:s.ms
|
||||
*
|
||||
* @param int $set_microtime -1 to set micro time, 0 for none,
|
||||
* positive for rounding
|
||||
* @return string formated datetime string with microtime
|
||||
*/
|
||||
public static function printTime(int $set_microtime = -1): string
|
||||
{
|
||||
list($microtime, $timestamp) = explode(' ', microtime());
|
||||
$string = date("Y-m-d H:i:s", (int)$timestamp);
|
||||
// if microtime flag is -1 no round, if 0, no microtime, if >= 1, round that size
|
||||
if ($set_microtime == -1) {
|
||||
$string .= substr($microtime, 1);
|
||||
} elseif ($set_microtime >= 1) {
|
||||
// in round case we run this through number format to always get the same amount of digits
|
||||
$string .= substr(number_format(round((float)$microtime, $set_microtime), $set_microtime), 1);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* prints a html formatted (pre) array
|
||||
*
|
||||
* @param array<mixed> $array any array
|
||||
* @param bool $no_html set to true to use ##HTMLPRE##
|
||||
* @return string formatted array for output with <pre> tag added
|
||||
*/
|
||||
public static function printAr(array $array, bool $no_html = false): string
|
||||
{
|
||||
if ($no_html === false) {
|
||||
return "<pre>" . print_r($array, true) . "</pre>";
|
||||
} else {
|
||||
return '##HTMLPRE##' . print_r($array, true) . '##/HTMLPRE##';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* alternate name for printAr function
|
||||
*
|
||||
* @param array<mixed> $array any array
|
||||
* @param bool $no_html set to true to use ##HTMLPRE##
|
||||
* @return string formatted array for output with <pre> tag added
|
||||
*/
|
||||
public static function printArray(array $array, bool $no_html = false): string
|
||||
{
|
||||
return self::printAr($array, $no_html);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert bool value to string
|
||||
* if $name is set prefix with nae
|
||||
* default true: true, false: false
|
||||
*
|
||||
* @param bool $bool Variable to convert
|
||||
* @param string $name [default: ''] Prefix name
|
||||
* @param string $true [default: true] True string
|
||||
* @param string $false [default: false] False string
|
||||
* @return string String with converted bool text for debug
|
||||
*/
|
||||
public static function printBool(
|
||||
bool $bool,
|
||||
string $name = '',
|
||||
string $true = 'true',
|
||||
string $false = 'false'
|
||||
): string {
|
||||
$string = (!empty($name) ? '<b>' . $name . '</b>: ' : '')
|
||||
. ($bool ? $true : $false);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* print out any data as string
|
||||
* will convert boolean to TRUE/FALSE
|
||||
* if object return get_class
|
||||
* for array use printAr function, can be controlled with no_html for
|
||||
* Debug\Logging compatible output
|
||||
*
|
||||
* @param mixed $mixed
|
||||
* @param bool $no_html set to true to use ##HTMLPRE##or html escape
|
||||
* @return string
|
||||
*/
|
||||
public static function printToString(mixed $mixed, bool $no_html = false): string
|
||||
{
|
||||
if (is_null($mixed)) {
|
||||
return (string)'NULL';
|
||||
} elseif (is_bool($mixed)) {
|
||||
return self::printBool($mixed, '', 'TRUE', 'FALSE');
|
||||
} elseif (is_resource($mixed)) {
|
||||
return (string)$mixed;
|
||||
} elseif (is_object($mixed)) {
|
||||
return get_class($mixed);
|
||||
} elseif (is_array($mixed)) {
|
||||
// use the pre one OR debug one
|
||||
return self::printAr($mixed, $no_html);
|
||||
} elseif (is_string($mixed)) {
|
||||
if ($no_html) {
|
||||
return Html::htmlent((string)$mixed);
|
||||
} else {
|
||||
return (string)$mixed;
|
||||
}
|
||||
} else {
|
||||
// should be int/float/string
|
||||
return (string)$mixed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if there is a need to find out which parent method called a child method,
|
||||
* eg for debugging, this function does this
|
||||
*
|
||||
* call this method in the child method and you get the parent function that called
|
||||
* @param int $level debug level, default 1
|
||||
* @return ?string null or the function that called the function
|
||||
* where this method is called
|
||||
*/
|
||||
public static function getCallerMethod(int $level = 1): ?string
|
||||
{
|
||||
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
// print \CoreLibs\Debug\Support::printAr($traces);
|
||||
// We should check from top down if unset?
|
||||
// sets the start point here, and in level two (the sub call) we find this
|
||||
if (isset($traces[$level])) {
|
||||
return $traces[$level]['function'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array with all methods in the call stack in the order so that last
|
||||
* called is last in order
|
||||
* Will start with start_level to skip unwanted from stack
|
||||
* Defaults to skip level 0 wich is this methid
|
||||
*
|
||||
* @param integer $start_level From what level on, as defaul starts with 1
|
||||
* to exclude self
|
||||
* @return array<mixed> All method names in list where max is last called
|
||||
*/
|
||||
public static function getCallerMethodList(int $start_level = 1): array
|
||||
{
|
||||
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
$methods = [];
|
||||
foreach ($traces as $level => $data) {
|
||||
if ($level >= $start_level) {
|
||||
if (!empty($data['function'])) {
|
||||
array_unshift($methods, $data['function']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current class where this function is called
|
||||
* Is mostly used in debug log statements to get the class where the debug
|
||||
* was called
|
||||
* gets top level class
|
||||
* loops over the debug backtrace until if finds the first class (from the end)
|
||||
*
|
||||
* @return string Class name with namespace
|
||||
*/
|
||||
public static function getCallerClass(): string
|
||||
{
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
// ?? [['class' => get_called_class()]];
|
||||
// TODO make sure that this doesn't loop forver
|
||||
$class = null;
|
||||
while ($class === null && count($backtrace) > 0) {
|
||||
// if current is
|
||||
// [function] => debug
|
||||
// [class] => CoreLibs\Debug\Logging
|
||||
// then return
|
||||
// (OUTSIDE) because it was not called from a class method
|
||||
// or return file name
|
||||
$get_class = array_pop($backtrace);
|
||||
$class = $get_class['class'] ?? null;
|
||||
}
|
||||
// on null or empty return empty string
|
||||
return empty($class) ? '' : $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a string is empty, sets '-' for return, or if given any other string
|
||||
*
|
||||
* @param string|null $string The string to check
|
||||
* @param string $replace [default '-'] What to replace the empty string with
|
||||
* @return string String itself or the replaced value
|
||||
*/
|
||||
public static function debugString(
|
||||
?string $string,
|
||||
string $replace = '-',
|
||||
bool $no_html = false
|
||||
): string {
|
||||
if (empty($string)) {
|
||||
$string = $replace;
|
||||
}
|
||||
if ($no_html) {
|
||||
return Html::htmlent($string);
|
||||
} else {
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
110
4dev/deprecated/CoreLibs/Get/DotEnv.php
Normal file
110
4dev/deprecated/CoreLibs/Get/DotEnv.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Get;
|
||||
|
||||
class DotEnv
|
||||
{
|
||||
/** @var string constant comment char, set to # */
|
||||
private const COMMENT_CHAR = '#';
|
||||
|
||||
/**
|
||||
* parses .env file
|
||||
*
|
||||
* Rules for .env file
|
||||
* variable is any alphanumeric string followed by = on the same line
|
||||
* content starts with the first non space part
|
||||
* strings can be contained in "
|
||||
* strings MUST be contained in " if they are multiline
|
||||
* if string starts with " it will match until another " is found
|
||||
* anything AFTER " is ignored
|
||||
* if there are two variables with the same name only the first is used
|
||||
* variables are case sensitive
|
||||
*
|
||||
* @param string $path Folder to file, default is __DIR__
|
||||
* @param string $env_file What file to load, default is .env
|
||||
* @return int -1 other error
|
||||
* 0 for success full load
|
||||
* 1 for file loadable, no data or data already loaded
|
||||
* 2 for file not readable or open failed
|
||||
* 3 for file not found
|
||||
*/
|
||||
public static function readEnvFile(
|
||||
string $path = __DIR__,
|
||||
string $env_file = '.env'
|
||||
): int {
|
||||
// default -1;
|
||||
$status = -1;
|
||||
$env_file_target = $path . DIRECTORY_SEPARATOR . $env_file;
|
||||
// this is not a file -> abort
|
||||
if (!is_file($env_file_target)) {
|
||||
$status = 3;
|
||||
return $status;
|
||||
}
|
||||
// cannot open file -> abort
|
||||
if (!is_readable($env_file_target)) {
|
||||
$status = 2;
|
||||
return $status;
|
||||
}
|
||||
// open file
|
||||
if (($fp = fopen($env_file_target, 'r')) === false) {
|
||||
$status = 2;
|
||||
return $status;
|
||||
}
|
||||
// set to readable but not yet any data loaded
|
||||
$status = 1;
|
||||
$block = false;
|
||||
$var = '';
|
||||
while ($line = fgets($fp)) {
|
||||
// main match for variable = value part
|
||||
if (preg_match("/^\s*([\w_.]+)\s*=\s*((\"?).*)/", $line, $matches)) {
|
||||
$var = $matches[1];
|
||||
$value = $matches[2];
|
||||
$quotes = $matches[3];
|
||||
// write only if env is not set yet, and write only the first time
|
||||
if (empty($_ENV[$var])) {
|
||||
if (!empty($quotes)) {
|
||||
// match greedy for first to last so we move any " if there are
|
||||
if (preg_match('/^"(.*[^\\\])"/U', $value, $matches)) {
|
||||
$value = $matches[1];
|
||||
} else {
|
||||
// this is a multi line
|
||||
$block = true;
|
||||
// first " in string remove
|
||||
// add removed new line back because this is a multi line
|
||||
$value = ltrim($value, '"') . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
// strip any quotes at end for unquoted single line
|
||||
// an right hand spaces are removed too
|
||||
$value = false !== ($pos = strpos($value, self::COMMENT_CHAR)) ?
|
||||
rtrim(substr($value, 0, $pos)) : $value;
|
||||
}
|
||||
// if block is set, we strip line of slashes
|
||||
$_ENV[$var] = $block === true ? stripslashes($value) : $value;
|
||||
// set successful load
|
||||
$status = 0;
|
||||
}
|
||||
} elseif ($block === true) {
|
||||
// read line until there is a unescaped "
|
||||
// this also strips everything after the last "
|
||||
if (preg_match("/(.*[^\\\])\"/", $line, $matches)) {
|
||||
$block = false;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
2748
4dev/deprecated/CoreLibs/Output/Form/Generate.php
Normal file
2748
4dev/deprecated/CoreLibs/Output/Form/Generate.php
Normal file
File diff suppressed because it is too large
Load Diff
140
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditAccess.php
Normal file
140
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditAccess.php
Normal 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__
|
||||
137
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditGroups.php
Normal file
137
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditGroups.php
Normal 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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
275
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditPages.php
Normal file
275
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditPages.php
Normal 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__
|
||||
@@ -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__
|
||||
456
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditUsers.php
Normal file
456
4dev/deprecated/CoreLibs/Output/Form/TableArrays/EditUsers.php
Normal 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__
|
||||
@@ -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__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user