2738 lines
100 KiB
PHP
2738 lines
100 KiB
PHP
<?php
|
|
|
|
/********************************************************************
|
|
* AUTHOR: Clemens Schwaighofer
|
|
* CREATED: 2002/10/22
|
|
* VERSION: 3.0.0
|
|
* RELEASED LICENSE: GNU GPL 3
|
|
* SHORT DESCRIPTION:
|
|
* ~ 2003/02/26: decided to move away from single class and change this
|
|
* to extend db_array_io which extends db_io. this is much more efficient
|
|
* in use of vars and use of methods of other classes
|
|
*
|
|
* ~ 2002/10/20: this class contains a set of functions that helps in creating
|
|
* more or less default forms, or supports u in handling normal
|
|
* form data
|
|
*
|
|
* description of the variables && arrays that have to be set ...
|
|
* $name_u_choose = [
|
|
* # this is the description of ALL fields in the main table
|
|
* 'table_array' => [
|
|
* 'name_of_col_in_table' => [
|
|
* 'value' => $name_of_col_in_table',
|
|
* 'pk' => 1/0 - sets the primary key (only one)
|
|
* 'fk' => 1/0 - sets the foreign key (do not use at the moment ... buggy ;)
|
|
* 'mandatory' => 1/0 - triggers * in output, but nor error check
|
|
* 'output_name' => 'text' - text put as label for the element
|
|
* 'type' => 'view/text/textarea/date/drop_down_db/drop_down_array/drop_down_db_input/drop_down_db_same_db/radio_array/binary/hidden/file/password'
|
|
* View is special, it just prints out the data as is, will not be saved
|
|
* 1) more will come
|
|
* 2) keep in mind that binary will not be checked, as it is always set to a value (default is 'no')
|
|
* ---- the next four fields are only NECESSARY (!!!) for drop_down_db_input
|
|
* 'table_name' => the name of the table for the drop down
|
|
* 'pk_name' => the pk_name of the table for the drop down
|
|
* 'input_name' => the text field name in the table for the drop down
|
|
* 'input_value' => the $name of input_name (must be same)
|
|
* 'order_by' => 'order bY' string for drop_down_db(_input) if no query given but fields set
|
|
* 'query' => for drop_down_db/array if no outer query given
|
|
* 'preset' => value to preset when array is unset (available for all types)
|
|
* 'element_list' => ['true', 'false'] - MUST (!) be set for binary
|
|
* 'length' => 'nr' - only available for 'text' (maxlength)
|
|
* 'size' => 'nr' - only available for 'text' (size of input field)
|
|
* 'rows' => 'nr' - only available for 'textarea'
|
|
* 'cols' => 'nr' - only available for 'textarea'
|
|
* 'error_check' => 'custom/email/date/number/unique' - 1) more will come
|
|
* 'error_regex' => 'regex' - if error_check is custom regex here
|
|
* 'error_example' => 'text' - example input text for error_check (only custom right now)
|
|
* 'empty' => 'value/text' - ONLY for view. If no data found, set this value
|
|
* --- file:
|
|
* 'save_dir' => 'directory where it should be saved to
|
|
* 'accept_type' => 'mime types accepted (mime/text,mime/jpeg ... etc)'
|
|
* ],
|
|
* ...
|
|
* ],
|
|
* # all reference tables (n<->n)
|
|
* 'reference_array' => [
|
|
* 'name_u_choose' => [
|
|
* 'table_name' => 'table_u_choose_for_n_to_n_table',
|
|
* 'other_table_pk' => 'primary_key_name_of_reference_table',
|
|
* 'output_name' => 'Printed out next to multiple select field',
|
|
* 'mandatory' => 1/0 for must be selected,
|
|
* 'select_size' => size of multiple select field,
|
|
* 'query' => 'the query to load the multiple select field
|
|
* (select id, concat_ws(' ',name_a, name_b) from reference_table)',
|
|
* 'selected' => $var_name for name='xx' in multiple select
|
|
* ],
|
|
* ...
|
|
* ],
|
|
* # fields that should be shown from the load_query and with what aditions
|
|
* 'show_fields' => [
|
|
* [
|
|
* 'name' => 'name_of_col_in_query' - col from the query that should be shown
|
|
* 'before_value' => 'text' - if set this text will be put in FRONT of the value from the col
|
|
* 'binary' => ['true','false'] - for 1/0 fields in DB changes it int human readable format
|
|
* ],
|
|
* ...
|
|
* ],
|
|
* # the laod query
|
|
* 'load_query' => 'query', - query for generting the list in 'load' function
|
|
* # the name of the main table
|
|
* 'table_name' => 'table_name' - the exakt name of the table ...
|
|
* # security levels for load ... usefull is delete with a low number and load with a high
|
|
* 'security_level' =>
|
|
* 'load' => ... for load to appear
|
|
* 'new' => 1... - security level minimum required for new part to appear (goes in hadn with save)
|
|
* 'save' => ... - should be same level as new [or its a bit useless]
|
|
* 'delete' => ... - for delete
|
|
*
|
|
* example for a page:
|
|
*
|
|
* $form->form_procedure_load(${$form->archive_pk_name});
|
|
* $form->form_procedure_new();
|
|
* $form->form_procedure_save();
|
|
* $form->form_procedure_delete();
|
|
* <HTML start>
|
|
* $form->form_create_load();
|
|
* $form->form_create_new();
|
|
* if ($form->yes)
|
|
* {
|
|
* $from->form_create_element('element_name');
|
|
* $from->form_create_hidden_fields();
|
|
* $form->form_creae_save_delete();
|
|
* }
|
|
* $form->_form();
|
|
* <HTML end>
|
|
*
|
|
* list_of_functions:
|
|
* form_get_col_name_from_key($want_key)
|
|
* returns the value for the key (out of table_array)
|
|
* form_get_col_name_array_from_key($want_key)
|
|
* returns array of values for the searched key ...
|
|
* form_print_msg () [form_error_msg()]
|
|
* returns the HTML formated part with the error msg, if one exists
|
|
* form_procedure_load($id)
|
|
* starts the loading procedure
|
|
* form_procedure_new()
|
|
* starts the new procedure
|
|
* form_procedure_save()
|
|
* starts the save procedure
|
|
* form_procedure_delete()
|
|
* starts the delete procedure
|
|
* form_create_load () [form_load()]
|
|
* returns the HTML part for loading a table row, load_query & field_array have to be set for this!!!!!!
|
|
* form_create_new () [form_new()]
|
|
* returns the HTML part for creating a new table_row
|
|
* form_create_save_delete () [form_delete_save()]
|
|
* returns the HTML part for saveing and deleteing one table_row
|
|
* form_create_element ($element_name, $query='')
|
|
* creates and HTML element based on the description in the table_array array,
|
|
* second parameter is for drop_down fields, either a query for _db or an array for _array
|
|
* form_error_check()
|
|
* checks on errors after submit based on the settings in the table_array array
|
|
* form_set_order()
|
|
* if it finds the order flag set in the table_array sets the order for the current element to MAX+1 from the DB
|
|
* form_unset_table_array()
|
|
* unsets the table_array value fields for new entries
|
|
* form_create_hidden_fields($hidden_array)
|
|
* outputs a string with the HTML hidden fields (array must be $name['hidden_name']=$hidden_value)
|
|
* form_create_element_reference_table($table_name) [form_show_reference_table()]
|
|
* creates and table tr part for the reference table name given
|
|
* form_load_table_array($pk_id=0)
|
|
* loads the table_array and the reference tables for the pk_id set in the class or given via parameter
|
|
* form_save_table_array($addslashes=0)
|
|
* save table array & reference tables
|
|
* form_delete_table_array()
|
|
* deletes table array & reference tables
|
|
*
|
|
* // debug methods
|
|
* form_dump_table_array()
|
|
* returns a formatted string with alle table_array vars
|
|
*
|
|
* HISTORY:
|
|
* 2005/07/14 (cs) fixed the insert for reference tables, prepared drop down text insert to be correct [untested]
|
|
* 2005/07/08 (cs) added int set for integer insert values
|
|
* 2005/07/07 (cs) bug with protected data, error got triggered even if no delete was pressed
|
|
* 2005/06/30 (cs) changed color settings, they get set from CSS file now
|
|
* 2005/06/29 (cs) finished full support for element_lists
|
|
* 2005/06/24 (cs) added full support for a list in a form, a list is written
|
|
* to an other table and the other table has this forms PK as a FK
|
|
* 2005/06/23 (cs) changed all HTML to Smarty Template Type
|
|
* 2005/06/22 (cs) you can put more than one error check into the error field;
|
|
* alphanumeric check and unique in same table are new
|
|
* 2005/06/21 (cs) changed the error_msg writings to debug
|
|
* 2005/03/31 (cs) fixed the class call with all debug vars
|
|
* 2004/11/10 (cs) fix bug with preset: don't check if set, check if variable is set at all
|
|
* 2004/09/30 (cs) layout change
|
|
* 2003-06-13: error with 'protected' flag, fixed and added error msg,
|
|
* if protected flag is detected during delete
|
|
* 2003-06-12: adapted class to register_global_vars off
|
|
* 2003-06-10: in procedure_delete function I added 'protected' variable clause,
|
|
* so if this field exists in the DB and is set, you are not able to delete
|
|
* [at the moment used for admin edit user in DB]
|
|
* 2003-05-30: _temp for drop_down_db was added always and not only for same_db
|
|
* 2003-05-28: added drop_down_db_same_db for drop down/input combinations going into the same DB.
|
|
* WARNING!!! please be careful that input_value var name MUST have the ending _temp
|
|
* This might get change in future
|
|
* added a 'where' field to the field list, this is only used for the drop_down for selecting
|
|
* only a certain field list. If where is filled out and used in combination with insert (not same_db)
|
|
* then this key will be SET when inserted into the DB !!!
|
|
* 2003-04-09: added open_dir for download of file (URL), save_dir is only for upload (absolute path)
|
|
* added require once for class_db_array_io.php
|
|
* 2003-03-31: added a file upload module (type==file)
|
|
* 2003-03-20: added form_procedure_new, etc functions so for default calls it is easier to write
|
|
* also added security levels to all functions where it is needed
|
|
* 2003-03-14: changed the static error msgs to dynamic ones
|
|
* 2003-03-13: very bad bug with getting key function. fixed it (set first array value always)
|
|
* reason was that in second if I forgot to check if the second method field was really
|
|
* set, so I compared to empty which was always right.
|
|
* 2003-03-11: started renaming some functions:
|
|
* form_load, form_new, form_delete_save -> form_create_... (and _save_delete)
|
|
* .._show_reference_table -> create_element_reference_table
|
|
* added language array
|
|
* - kept old var names/function names for backward compatbile
|
|
* 2003-03-10: added flag for form_delete_save, first flag hides delete part, second flag
|
|
* hides checkbox for delete, both are set 0 default
|
|
* added drop_down_db_input element type.
|
|
* next to a drop down with elements froma db, there is an input field,
|
|
* if something is input there and not yet in the DB it will be inserted into
|
|
* the db first and then selected in the drop down, if already in db, the element
|
|
* in the drop down will be selected
|
|
* 2003-03-07: form_create_hidden_fields() has to be called mandatory
|
|
* 2003-03-06: if nothing selected for reference table, do not write
|
|
* a wrong return in form_delete_table_array quit the function to early
|
|
* 2003-03-04: drop_down_array value for option was left from array and
|
|
* not right
|
|
* 2003-02-27: added another check in unset if reference array exists
|
|
* 2003-02-26: change form to extend db_array_io and created load, save,
|
|
* delete functions removed all reference table functions,
|
|
* except show function rewrite config array
|
|
* re-wrote the class info vars into array
|
|
* 2003-02-25: added reference table functions
|
|
* 2002-10-22: create this class so creating basic and medium form pages
|
|
* can be handled easy.
|
|
* with a given config file the class handles error checks,
|
|
* save data, loads data, etc
|
|
*********************************************************************/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CoreLibs\Output\Form;
|
|
|
|
use CoreLibs\Get\System;
|
|
use CoreLibs\Debug\Support;
|
|
|
|
class Generate extends \CoreLibs\DB\Extended\ArrayIO
|
|
{
|
|
// for the load statetment describes which elements from
|
|
// the load query should be shown and i which format
|
|
/** @var array<mixed> */
|
|
public array $field_array = [];
|
|
/** @var string */
|
|
public string $load_query; // the query needed for loading a data set (one row in the table)
|
|
/** @var string */
|
|
public string $col_name; // the name of the columen (before _<type>) [used for order button]
|
|
/** @var int */
|
|
public int $yes; // the yes flag that triggers the template to show ALL and not only new/load
|
|
/** @var string */
|
|
public string $msg; // the error msg
|
|
/** @var int */
|
|
public int $error; // the error flag set for printing red error msg
|
|
/** @var int */
|
|
public int $warning; // warning flag, for information (saved, loaded, etc)
|
|
/** @var string */
|
|
public string $archive_pk_name; // the pk name for the load select form
|
|
/** @var string */
|
|
private string $int_pk_name; // primary key, only internal usage
|
|
/** @var array<mixed> */
|
|
public array $reference_array = []; // reference arrays -> stored in $this->reference_array[$table_name] => [];
|
|
// NOTE: should be changed to this @var mixed[]
|
|
/** @var array<mixed> */
|
|
public array $element_list; // element list for elements next to each other as a special sub group
|
|
/** @var array<mixed> */
|
|
public array $table_array = [];
|
|
/** @var string */
|
|
public string $my_page_name; // the name of the page without .php extension
|
|
/** @var bool */
|
|
public bool $mobile_phone = false;
|
|
/** @var string */
|
|
public string $email_regex;
|
|
// buttons and checkboxes
|
|
/** @var string */
|
|
public string $archive;
|
|
/** @var string */
|
|
public string $new;
|
|
/** @var string */
|
|
public string $really_new;
|
|
/** @var string */
|
|
public string $delete;
|
|
/** @var string */
|
|
public string $really_delete;
|
|
/** @var string */
|
|
public string $save;
|
|
/** @var string */
|
|
public string $remove_button;
|
|
// security values
|
|
/** @var int base acl for current page */
|
|
private int $base_acl_level = 0;
|
|
/** @var int admin master flag (1/0) */
|
|
private int $acl_admin = 0;
|
|
/** @var array<mixed> */
|
|
public array $security_level;
|
|
/** @var array<string,mixed> Login ACL */
|
|
public array $login_acl = [];
|
|
// layout publics
|
|
/** @var int */
|
|
public int $table_width;
|
|
// internal lang & encoding vars
|
|
/** @var string */
|
|
public string $lang_dir = '';
|
|
/** @var string */
|
|
public string $lang;
|
|
/** @var string */
|
|
public string $lang_short;
|
|
/** @var string */
|
|
public string $domain;
|
|
/** @var string */
|
|
public string $encoding;
|
|
// language
|
|
/** @var \CoreLibs\Language\L10n */
|
|
public \CoreLibs\Language\L10n $l;
|
|
// log
|
|
/** @var \CoreLibs\Logging\Logging */
|
|
public \CoreLibs\Logging\Logging $log;
|
|
|
|
// now some default error msgs (english)
|
|
/** @var array<mixed> */
|
|
public array $language_array = [];
|
|
|
|
/**
|
|
* construct form generator
|
|
*
|
|
* @param array<mixed> $db_config db config array, mandatory
|
|
* @param \CoreLibs\Logging\Logging $log Logging class
|
|
* @param \CoreLibs\Language\L10n $l10n l10n language class
|
|
* @param array<string,mixed> $login_acl Login ACL array,
|
|
* at least base/admin should be set
|
|
* @param array<mixed>|null $table_arrays Override table array data
|
|
* instead of try to load from
|
|
* include file
|
|
* @throws \Exception 1: No table_arrays set/no class found for my page name
|
|
*/
|
|
public function __construct(
|
|
array $db_config,
|
|
\CoreLibs\Logging\Logging $log,
|
|
\CoreLibs\Language\L10n $l10n,
|
|
array $login_acl,
|
|
?array $table_arrays = null,
|
|
) {
|
|
// init logger if not set
|
|
$this->log = $log;
|
|
// don't log per class
|
|
$this->log->unsetLogFlag(\CoreLibs\Logging\Logger\Flag::per_class);
|
|
// init the language class
|
|
$this->l = $l10n;
|
|
// parse and read, legacy stuff
|
|
$locale = $this->l->getLocaleAsArray();
|
|
$this->encoding = $locale['encoding'];
|
|
$this->lang = $locale['lang'];
|
|
$this->lang_short = $locale['lang_short'];
|
|
$this->domain = $locale['domain'];
|
|
$this->lang_dir = $locale['path'];
|
|
// load config array
|
|
// get table array definitions for current page name
|
|
$this->login_acl = $login_acl;
|
|
// security settings
|
|
$this->base_acl_level = $this->login_acl['base'] ?? 0;
|
|
$this->acl_admin = $this->login_acl['admin'] ?? 0;
|
|
|
|
// replace any non valid variable names and set my page name
|
|
$this->my_page_name = str_replace(
|
|
['.'],
|
|
'_',
|
|
System::getPageName(System::NO_EXTENSION)
|
|
);
|
|
|
|
// first check if we have a in page override as $table_arrays[page name]
|
|
if (
|
|
isset($table_arrays[System::getPageName(System::NO_EXTENSION)]) &&
|
|
is_array($table_arrays[System::getPageName(System::NO_EXTENSION)])
|
|
) {
|
|
// $config_array = $GLOBALS['table_arrays'][System::getPageName(1)];
|
|
$config_array = $table_arrays[System::getPageName(1)];
|
|
} else {
|
|
// primary try to load the class
|
|
/** @var TableArrays\Interface\TableArraysInterface|false $content_class */
|
|
$content_class = $this->loadTableArray();
|
|
if (is_object($content_class)) {
|
|
$config_array = $content_class->setTableArray();
|
|
} else {
|
|
// throw an error here as we cannot load the class at all
|
|
throw new \Exception("Cannot load " . $this->my_page_name, 1);
|
|
}
|
|
}
|
|
// $log->debug('CONFIG ARRAY', $log->prAr($config_array));
|
|
// start the array_io class which will start db_io ...
|
|
parent::__construct(
|
|
$db_config,
|
|
$config_array['table_array'],
|
|
$config_array['table_name'],
|
|
$this->log,
|
|
// set the ACL
|
|
$this->base_acl_level,
|
|
$this->acl_admin
|
|
);
|
|
// here should be a check if the config_array is correct ...
|
|
if (isset($config_array['show_fields']) && is_array($config_array['show_fields'])) {
|
|
$this->field_array = $config_array['show_fields'];
|
|
}
|
|
if (isset($config_array['load_query']) && $config_array['load_query']) {
|
|
$this->load_query = $config_array['load_query'];
|
|
}
|
|
if (empty($this->load_query)) {
|
|
$this->log->error('Missing Load Query for: ' . $this->my_page_name);
|
|
}
|
|
$this->archive_pk_name = 'a_' . $this->pk_name;
|
|
$this->col_name = str_replace('_id', '', $this->pk_name);
|
|
$this->int_pk_name = $this->pk_name;
|
|
// check if reference_arrays are given and proceed them
|
|
if (isset($config_array['reference_arrays']) && is_array($config_array['reference_arrays'])) {
|
|
foreach ($config_array['reference_arrays'] as $key => $value) {
|
|
$this->reference_array[$key] = $value;
|
|
}
|
|
}
|
|
if (isset($config_array['element_list']) && is_array($config_array['element_list'])) {
|
|
foreach ($config_array['element_list'] as $key => $value) {
|
|
$this->element_list[$key] = $value;
|
|
}
|
|
}
|
|
|
|
// set button vars
|
|
$this->archive = $_POST['archive'] ?? '';
|
|
$this->new = $_POST['new'] ?? '';
|
|
$this->really_new = $_POST['really_new'] ?? '';
|
|
$this->delete = $_POST['delete'] ?? '';
|
|
$this->really_delete = $_POST['really_delete'] ?? '';
|
|
$this->save = $_POST['save'] ?? '';
|
|
$this->remove_button = $_POST['remove_button'] ?? '';
|
|
|
|
// security levels for buttons/actions
|
|
// if array does not exists create basic
|
|
if (
|
|
!isset($config_array['security_level']) ||
|
|
(isset($config_array['security_level']) &&
|
|
(!is_array($config_array['security_level']) ||
|
|
(is_array($config_array['security_level']) && count($config_array['security_level']) < 4))
|
|
)
|
|
) {
|
|
$this->security_level = [
|
|
'load' => 20,
|
|
'new' => 100,
|
|
'save' => 40,
|
|
'delete' => 100
|
|
];
|
|
} else {
|
|
// write array to class var
|
|
$this->security_level = isset($config_array['security_level']) ?
|
|
$config_array['security_level'] :
|
|
[
|
|
'load' => 20,
|
|
'new' => 100,
|
|
'save' => 40,
|
|
'delete' => 100
|
|
];
|
|
}
|
|
|
|
// set email regex
|
|
$this->email_regex = \CoreLibs\Check\Email::getEmailRegex();
|
|
}
|
|
|
|
/**
|
|
* deconstructor
|
|
* writes out error msg to global var
|
|
* closes db connectio
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
// close DB connection
|
|
parent::__destruct();
|
|
}
|
|
|
|
// PRIVATE METHODS |=================================================>
|
|
|
|
/**
|
|
* load table array class based on my page name converted to camel case
|
|
* class files are in \TableArrays folder in \Output\Form
|
|
* @return TableArrays\Interface\TableArraysInterface|false Return class object or false on failure
|
|
*/
|
|
private function loadTableArray(): TableArrays\Interface\TableArraysInterface|false
|
|
{
|
|
// note: it schould be Schemas but an original type made it to this
|
|
// this file is kept for the old usage, new one should be EditSchemas
|
|
$table_array_shim = [
|
|
'EditSchemes' => 'EditSchemas'
|
|
];
|
|
// camel case $this->my_page_name from foo_bar_note to FooBarNote
|
|
$page_name_camel_case = '';
|
|
foreach (explode('_', $this->my_page_name) as $part) {
|
|
$page_name_camel_case .= ucfirst($part);
|
|
}
|
|
$class_string = __NAMESPACE__ . "\\TableArrays\\"
|
|
. (
|
|
// shim lookup
|
|
$table_array_shim[$page_name_camel_case] ??
|
|
$page_name_camel_case
|
|
);
|
|
try {
|
|
/** @var TableArrays\Interface\TableArraysInterface|false $class */
|
|
$class = new $class_string($this);
|
|
} catch (\Throwable $t) {
|
|
$this->log->critical('CLASS LOADING: Failed loading: ' . $class_string . ' => ' . $t->getMessage());
|
|
return false;
|
|
}
|
|
if (is_object($class)) {
|
|
return $class;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// PUBLIC METHODS |=================================================>
|
|
|
|
/**
|
|
* return current acl admin flag (1/0)
|
|
*
|
|
* @return int Admin flag 1 for on or 0 for off
|
|
*/
|
|
public function getAclAdmin(): int
|
|
{
|
|
return $this->acl_admin;
|
|
}
|
|
|
|
/**
|
|
* check if current acl level is match to requested on
|
|
*
|
|
* @param int $level Requested ACL level
|
|
* @return bool if current level equal or larger return tru, else false
|
|
*/
|
|
public function checkBaseACL(int $level): bool
|
|
{
|
|
return $this->base_acl_level >= $level ? true : false;
|
|
}
|
|
|
|
/**
|
|
* dumps all values into output (for error msg)
|
|
*
|
|
* @return string full table array data output as string html formatted
|
|
*/
|
|
public function formDumpTableArray()
|
|
{
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
$string = '<b>TABLE ARRAY DUMP:</b> ' . $this->table_name . '<br>';
|
|
foreach ($this->table_array as $key => $value) {
|
|
$string .= '<b>' . $key . '</b>: ' . $value['value'] . '<br>';
|
|
}
|
|
return $string;
|
|
}
|
|
|
|
/**
|
|
* the value of the $want_key array field
|
|
* works only with fields that appear only ONCE
|
|
* if multiple gets only FIRST
|
|
*
|
|
* @param string $want_key key to search for
|
|
* @param string|null $key_value value to match to (optional)
|
|
* @return string|null returns key found or empty string
|
|
*/
|
|
public function formGetColNameFromKey(
|
|
string $want_key,
|
|
?string $key_value = null
|
|
): ?string {
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
if (isset($value[$want_key]) && !$key_value) {
|
|
return $key;
|
|
} elseif (isset($value[$want_key]) && $value[$want_key] == $key_value && $key_value) {
|
|
return $key;
|
|
}
|
|
}
|
|
// return nothing on nothing
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* array of fields
|
|
*
|
|
* @param string $want_key the key where you want the data from
|
|
* @param string|null $key_value if set searches for special right value
|
|
* @return array<mixed> found key fields
|
|
*/
|
|
public function formGetColNameArrayFromKey(
|
|
string $want_key,
|
|
?string $key_value = null
|
|
): array {
|
|
$key_array = [];
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
if ($value[$want_key] && !$key_value) {
|
|
array_push($key_array, $key);
|
|
}
|
|
if ($value[$want_key] == $key_value) {
|
|
array_push($key_array, $key);
|
|
}
|
|
}
|
|
return $key_array;
|
|
}
|
|
|
|
/**
|
|
* formated output for the error && warning msg
|
|
*
|
|
* @return array<string,string|int> error message with msg, width, clas
|
|
*/
|
|
public function formPrintMsg(): array
|
|
{
|
|
$class = '';
|
|
if ($this->error) {
|
|
$class = 'error';
|
|
}
|
|
if ($this->warning) {
|
|
$class = 'warning';
|
|
}
|
|
return [
|
|
'msg' => $this->msg,
|
|
'width' => $this->table_width,
|
|
'class' => $class
|
|
];
|
|
}
|
|
|
|
// next for functions are pre_test fkts for easier default new,load, etc handling
|
|
/**
|
|
* default load procedure
|
|
*
|
|
* @param string $archive_id archive id to load
|
|
* @return void has no return
|
|
*/
|
|
public function formProcedureLoad(string $archive_id): void
|
|
{
|
|
if (
|
|
isset($this->security_level['load']) &&
|
|
$this->archive &&
|
|
$archive_id &&
|
|
$this->base_acl_level >= $this->security_level['load']
|
|
) {
|
|
$this->formLoadTableArray($archive_id);
|
|
$this->yes = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* default new procedure
|
|
*
|
|
* @return void has no return
|
|
*/
|
|
public function formProcedureNew(): void
|
|
{
|
|
if (
|
|
isset($this->security_level['new']) &&
|
|
$this->new &&
|
|
$this->base_acl_level >= $this->security_level['new']
|
|
) {
|
|
if ($this->really_new == 'yes') {
|
|
$this->formUnsetTableArray();
|
|
} else {
|
|
$this->msg .= $this->l->__('You have to select the <b>Checkbox for New</b>!<br>');
|
|
$this->error = 2;
|
|
}
|
|
$this->yes = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* default save procedure
|
|
*
|
|
* @return void has no return
|
|
*/
|
|
public function formProcedureSave(): void
|
|
{
|
|
if (
|
|
isset($this->security_level['save']) &&
|
|
$this->save &&
|
|
$this->base_acl_level >= $this->security_level['save']
|
|
) {
|
|
$this->formErrorCheck();
|
|
if (!$this->error) {
|
|
$this->formSaveTableArray();
|
|
}
|
|
$this->yes = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* default delete procedure
|
|
*
|
|
* @return void has no return
|
|
*/
|
|
public function formProcedureDelete(): void
|
|
{
|
|
// delete is also by 'protected'
|
|
if (
|
|
isset($this->security_level['delete']) &&
|
|
$this->delete &&
|
|
$this->base_acl_level >= $this->security_level['delete']
|
|
) {
|
|
if (isset($this->table_array['protected']['value']) && $this->table_array['protected']['value']) {
|
|
$this->msg .= $this->l->__('Cannot delete this Dataset, because it is internaly protected!');
|
|
$this->error = 2;
|
|
}
|
|
if ($this->really_delete == 'yes') {
|
|
$this->formDeleteTableArray();
|
|
} else {
|
|
$this->msg .= $this->l->__('You have to select the <b>Checkbox for Delete</b>!<br>');
|
|
$this->error = 2;
|
|
$this->yes = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* default delete procedure
|
|
*
|
|
* @param array<mixed> $element_list element array that should be removed
|
|
* @param array<mixed> $remove_name key names that should be removed
|
|
* @return void has no return
|
|
*/
|
|
public function formProcedureDeleteFromElementList(
|
|
array $element_list,
|
|
array $remove_name
|
|
): void {
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$this->log->debug('REMOVE ELEMENT', 'Remove REF ELEMENT: ' . $this->base_acl_level . ' >= '
|
|
. $this->security_level['delete']);
|
|
$this->log->debug('REMOVE ELEMENT', 'Protected Value set: '
|
|
. (string)isset($this->table_array['protected']['value']));
|
|
$this->log->debug('REMOVE ELEMENT', 'Error: ' . $this->error);
|
|
// only do if the user is allowed to delete
|
|
if (
|
|
isset($this->security_level['delete']) &&
|
|
$this->base_acl_level >= $this->security_level['delete'] &&
|
|
empty($this->table_array['protected']['value']) &&
|
|
!$this->error
|
|
) {
|
|
for ($i = 0, $i_max = count($element_list); $i < $i_max; $i++) {
|
|
// $this->log->debug('form_error', 'Array: '
|
|
// . is_array($this->element_list[$element_list[$i]]['read_data']) . ' | '
|
|
// . $this->element_list[$element_list[$i]]['delete']);
|
|
// if prefix, set it
|
|
$prfx = !empty($this->element_list[$element_list[$i]]['prefix']) ?
|
|
$this->element_list[$element_list[$i]]['prefix'] . '_' :
|
|
'';
|
|
// get the primary key
|
|
$pk_name = '';
|
|
foreach ($this->element_list[$element_list[$i]]['elements'] as $el_name => $data) {
|
|
if (isset($data['pk_id'])) {
|
|
$pk_name = $el_name;
|
|
break;
|
|
}
|
|
}
|
|
// which key should be deleted
|
|
$id = $remove_name[$i];
|
|
if (
|
|
(!empty($this->element_list[$element_list[$i]]['delete_name']) ||
|
|
!empty($this->element_list[$element_list[$i]]['delete'])) &&
|
|
empty($this->element_list[$element_list[$i]]['enable_name'])
|
|
) {
|
|
// flag var name
|
|
$flag = $remove_name[$i] . '_flag';
|
|
if ($_POST[$flag] == 'true') {
|
|
$q = 'DELETE FROM ' . $element_list[$i] . ' WHERE ' . $pk_name . ' = ' . $_POST[$id];
|
|
$this->dbExec($q);
|
|
$this->msg .= $this->l->__('Removed entry from list<br>');
|
|
$this->warning = 1;
|
|
} // post okay true -> delete
|
|
} elseif (
|
|
isset($this->element_list[$element_list[$i]]['read_data']) &&
|
|
!$this->element_list[$element_list[$i]]['delete']
|
|
) {
|
|
if (!isset($_POST[$id])) {
|
|
$_POST[$id] = [];
|
|
}
|
|
for ($j = 0, $j_max = count($_POST[$id]); $j < $j_max; $j++) {
|
|
// if it is not activated
|
|
if (!$_POST[$remove_name[$i]][$j]) {
|
|
$q = 'UPDATE ' . $element_list[$i]
|
|
. ' WHERE ' . $pk_name . ' = ' . $_POST[$prfx . $pk_name][$j];
|
|
// $this->log->debug('edit_db', 'UP: $q');
|
|
// $this->dbExec($q);
|
|
$this->msg .= $this->l->__('Disabled deselected entries from list<br>');
|
|
$this->warning = 1;
|
|
}
|
|
}
|
|
} elseif (
|
|
isset($this->element_list[$element_list[$i]]['read_data']) &&
|
|
$this->element_list[$element_list[$i]]['delete']
|
|
) {
|
|
// $this->log->debug('form_clean', 'ID [$id] [$prfx . $pk_name]');
|
|
// $this->log->debug('form_clean', 'ID arr: ' . $this->log->prAr($_POST[$id]));
|
|
// $this->log->debug('form_clean', 'PK arr: ' . $this->log->prAr($_POST[$prfx.$pk_name]));
|
|
for ($j = 0, $j_max = count($_POST[$prfx . $pk_name]); $j < $j_max; $j++) {
|
|
if (!$_POST[$remove_name[$i]][$j] && $_POST[$prfx . $pk_name][$j]) {
|
|
$q = 'DELETE FROM ' . $element_list[$i]
|
|
. ' WHERE ' . $pk_name . ' = ' . $_POST[$prfx . $pk_name][$j];
|
|
// $this->log->debug('edit_db', 'DEL: $q');
|
|
$this->dbExec($q);
|
|
$this->msg .= $this->l->__('Deleted deselected entries from list<br>');
|
|
$this->warning = 1;
|
|
}
|
|
}
|
|
}
|
|
} // for each element group
|
|
}
|
|
if ($this->remove_button) {
|
|
$this->yes = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* create the load list and return it as an array
|
|
*
|
|
*
|
|
* @return array<string,mixed> load list array with primary key, name and selected entry
|
|
*/
|
|
public function formCreateLoad(): array
|
|
{
|
|
$pk_selected = '';
|
|
$t_pk_name = '';
|
|
$pk_names = [];
|
|
$pk_ids = [];
|
|
$seclevel_okay = false;
|
|
// for error abort only
|
|
$return_array = [
|
|
't_pk_name' => $t_pk_name,
|
|
'pk_ids' => $pk_ids,
|
|
'pk_names' => $pk_names,
|
|
'pk_selected' => $pk_selected,
|
|
'seclevel_okay' => $seclevel_okay,
|
|
];
|
|
// when security level is okay ...
|
|
if (
|
|
empty($this->security_level['load']) ||
|
|
$this->base_acl_level < $this->security_level['load']
|
|
) {
|
|
return $return_array;
|
|
}
|
|
if (empty($this->load_query)) {
|
|
$this->log->error('Missing load list query');
|
|
return $return_array;
|
|
}
|
|
|
|
$t_pk_name = $this->archive_pk_name;
|
|
|
|
// load list data
|
|
$this->dbExec($this->load_query);
|
|
while (is_array($res = $this->dbFetchArray())) {
|
|
$pk_ids[] = $res[$this->int_pk_name];
|
|
if (
|
|
isset($this->table_array[$this->int_pk_name]['value']) &&
|
|
$res[$this->int_pk_name] == $this->table_array[$this->int_pk_name]['value']
|
|
) {
|
|
$pk_selected = $res[$this->int_pk_name];
|
|
}
|
|
$t_string = '';
|
|
foreach ($this->field_array as $i => $field_array) {
|
|
if ($t_string) {
|
|
$t_string .= ', ';
|
|
}
|
|
if (isset($field_array['before_value'])) {
|
|
$t_string .= $field_array['before_value'];
|
|
}
|
|
// must have res element set
|
|
if (
|
|
isset($field_array['name']) &&
|
|
isset($res[$field_array['name']])
|
|
) {
|
|
if (isset($field_array['binary'])) {
|
|
if (isset($field_array['binary'][0])) {
|
|
$t_string .= $field_array['binary'][0];
|
|
} elseif (isset($field_array['binary'][1])) {
|
|
$t_string .= $field_array['binary'][1];
|
|
}
|
|
} else {
|
|
$t_string .= $res[$field_array['name']];
|
|
}
|
|
}
|
|
}
|
|
$pk_names[] = $t_string;
|
|
}
|
|
$seclevel_okay = true;
|
|
return [
|
|
't_pk_name' => $t_pk_name,
|
|
'pk_ids' => $pk_ids,
|
|
'pk_names' => $pk_names,
|
|
'pk_selected' => $pk_selected,
|
|
'seclevel_okay' => $seclevel_okay,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Create new entry element for HTML output
|
|
*
|
|
* @param bool $hide_new_checkbox show or hide the new checkbox, default is false
|
|
* @return array<string,string|bool> return the new create array with name & checkbox show flag
|
|
*/
|
|
public function formCreateNew(bool $hide_new_checkbox = false): array
|
|
{
|
|
$show_checkbox = false;
|
|
$new_name = '';
|
|
$seclevel_okay = false;
|
|
// when security level is okay
|
|
if (
|
|
empty($this->security_level['new']) ||
|
|
$this->base_acl_level < $this->security_level['new']
|
|
) {
|
|
return [
|
|
'new_name' => $new_name,
|
|
'show_checkbox' => $show_checkbox,
|
|
'seclevel_okay' => $seclevel_okay,
|
|
];
|
|
}
|
|
if ($this->yes && !$hide_new_checkbox) {
|
|
$show_checkbox = false;
|
|
}
|
|
// set type of new name
|
|
if ($this->yes) {
|
|
$new_name = $this->l->__('Clear all and create new');
|
|
} else {
|
|
$new_name = $this->l->__('New');
|
|
}
|
|
$seclevel_okay = true;
|
|
return [
|
|
'new_name' => $new_name,
|
|
'show_checkbox' => $show_checkbox,
|
|
'seclevel_okay' => $seclevel_okay,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* create the save and delete element html group data
|
|
* @param bool $hide_delete hide the delete button (default false)
|
|
* @param bool $hide_delete_checkbox hide the delete checkbox (default false)
|
|
* @return array<string,mixed> return the hide/show delete framework
|
|
* for html creation
|
|
*/
|
|
public function formCreateSaveDelete(
|
|
bool $hide_delete = false,
|
|
bool $hide_delete_checkbox = false,
|
|
bool $old_school_hidden = false
|
|
): array {
|
|
$seclevel_okay = false;
|
|
$save = '';
|
|
$pk_name = '';
|
|
$pk_value = '';
|
|
$show_delete = false;
|
|
if (
|
|
(empty($this->security_level['save']) ||
|
|
$this->base_acl_level < $this->security_level['save']) &&
|
|
(empty($this->security_level['delete']) ||
|
|
$this->base_acl_level < $this->security_level['delete'])
|
|
) {
|
|
return [
|
|
'seclevel_okay' => $seclevel_okay,
|
|
'save' => $save,
|
|
'pk_name' => $pk_name,
|
|
'pk_value' => $pk_value,
|
|
'show_delete' => $show_delete,
|
|
'old_school_hidden' => $old_school_hidden,
|
|
'hide_delete_checkbox' => $hide_delete_checkbox
|
|
];
|
|
}
|
|
if (
|
|
!empty($this->security_level['save']) &&
|
|
$this->base_acl_level >= $this->security_level['save']
|
|
) {
|
|
$seclevel_okay = true;
|
|
if (empty($this->table_array[$this->int_pk_name]['value'])) {
|
|
$save = $this->l->__('Save');
|
|
} else {
|
|
$save = $this->l->__('Update');
|
|
}
|
|
// print the old_school hidden if requestet
|
|
if ($old_school_hidden === true) {
|
|
$pk_name = $this->int_pk_name;
|
|
$pk_value = $this->table_array[$this->int_pk_name]['value'];
|
|
}
|
|
} // show save part
|
|
// show delete part only if pk is set && we want to see the delete
|
|
if (
|
|
!empty($this->table_array[$this->int_pk_name]['value']) &&
|
|
!$hide_delete &&
|
|
!empty($this->security_level['delete']) &&
|
|
$this->base_acl_level >= $this->security_level['delete']
|
|
) {
|
|
$show_delete = true;
|
|
}
|
|
return [
|
|
'seclevel_okay' => $seclevel_okay,
|
|
'save' => $save,
|
|
'pk_name' => $pk_name,
|
|
'pk_value' => $pk_value,
|
|
'show_delete' => $show_delete,
|
|
'old_school_hidden' => $old_school_hidden,
|
|
'hide_delete_checkbox' => $hide_delete_checkbox
|
|
];
|
|
// end of function
|
|
}
|
|
|
|
/**
|
|
* create a form element based on the settings in the element array entry
|
|
*
|
|
* @param string $element_name the name from the array, you want to have build
|
|
* @param string|null $query can overrule internal query data,
|
|
* for drop down, as data comes from a reference table
|
|
* for drop_down_text it has to be an
|
|
* array with $key->$value
|
|
* @return array<string,mixed> html settings array
|
|
*/
|
|
public function formCreateElement(string $element_name, ?string $query = null): array
|
|
{
|
|
$data = [];
|
|
// special 2nd color for 'binary' attribut
|
|
if (
|
|
$this->table_array[$element_name]['type'] == 'binary' &&
|
|
!isset($this->table_array[$element_name]['value'])
|
|
) {
|
|
$EDIT_FGCOLOR_T = 'edit_fgcolor_no';
|
|
} else {
|
|
$EDIT_FGCOLOR_T = 'edit_fgcolor';
|
|
}
|
|
$output_name = $this->table_array[$element_name]['output_name'];
|
|
if (
|
|
isset($this->table_array[$element_name]['mandatory']) &&
|
|
$this->table_array[$element_name]['mandatory']
|
|
) {
|
|
$output_name .= ' *';
|
|
}
|
|
// create right side depending on 'definiton' in table_array
|
|
$type = $this->table_array[$element_name]['type'];
|
|
// set default min edit/read to 100 (admin)
|
|
$min_edit_acl = $this->table_array[$element_name]['min_edit_acl'] ?? 100;
|
|
$min_show_acl = $this->table_array[$element_name]['min_show_acl'] ?? 100;
|
|
$show_value = '-';
|
|
// view only output
|
|
if ($this->table_array[$element_name]['type'] == 'view') {
|
|
$data['value'] = empty($this->table_array[$element_name]['value']) ?
|
|
$this->table_array[$element_name]['empty'] :
|
|
$this->table_array[$element_name]['value'];
|
|
$show_value = $data['value'];
|
|
}
|
|
// binary true/false element
|
|
if ($this->table_array[$element_name]['type'] == 'binary') {
|
|
$data['checked'] = 0;
|
|
for ($i = (count($this->table_array[$element_name]['element_list']) - 1); $i >= 0; $i--) {
|
|
$data['value'][] = $i;
|
|
$data['output'][] = $this->table_array[$element_name]['element_list'][$i] ?? null;
|
|
$data['name'] = $element_name;
|
|
if (
|
|
isset($this->table_array[$element_name]['value']) &&
|
|
(($i && $this->table_array[$element_name]['value']) ||
|
|
(!$i && !$this->table_array[$element_name]['value']))
|
|
) {
|
|
$data['checked'] = $this->table_array[$element_name]['value'];
|
|
$show_value = $this->table_array[$element_name]['element_list'][$i] ?? $data['checked'];
|
|
}
|
|
|
|
if ($i) {
|
|
$data['separator'] = '';
|
|
}
|
|
}
|
|
}
|
|
// checkbox element
|
|
if ($this->table_array[$element_name]['type'] == 'checkbox') {
|
|
$data['name'] = $element_name;
|
|
$data['value'][] = $this->table_array[$element_name]['element_list'];
|
|
$data['checked'] = $this->table_array[$element_name]['value'];
|
|
// array map element list + value
|
|
// foreach ($data['checked'] as $checked)
|
|
$show_value = join(', ', $data['checked']);
|
|
}
|
|
// normal text element
|
|
if ($this->table_array[$element_name]['type'] == 'text') {
|
|
$data['name'] = $element_name;
|
|
$data['value'] = $this->table_array[$element_name]['value'] ?? '';
|
|
$data['size'] = $this->table_array[$element_name]['size'] ?? '';
|
|
$data['length'] = $this->table_array[$element_name]['length'] ?? '';
|
|
$show_value = $data['value'];
|
|
}
|
|
// password element, does not write back the value
|
|
if ($this->table_array[$element_name]['type'] == 'password') {
|
|
$data['name'] = $element_name;
|
|
$data['HIDDEN_value'] = $this->table_array[$element_name]['HIDDEN_value'];
|
|
$data['size'] = $this->table_array[$element_name]['size'] ?? '';
|
|
$data['length'] = $this->table_array[$element_name]['length'] ?? '';
|
|
}
|
|
// date (YYYY-MM-DD)
|
|
if ($this->table_array[$element_name]['type'] == 'date') {
|
|
$data['name'] = $element_name;
|
|
$data['value'] = $this->table_array[$element_name]['value'] ?? '';
|
|
$show_value = $data['value'];
|
|
}
|
|
// date time (no sec) (YYYY-MM-DD HH:mm)
|
|
if ($this->table_array[$element_name]['type'] == 'datetime') {
|
|
$data['name'] = $element_name;
|
|
$data['value'] = $this->table_array[$element_name]['value'] ?? '';
|
|
$show_value = $data['value'];
|
|
}
|
|
// textarea
|
|
if ($this->table_array[$element_name]['type'] == 'textarea') {
|
|
$data['name'] = $element_name;
|
|
$data['value'] = $this->table_array[$element_name]['value'] ?? '';
|
|
$data['rows'] = $this->table_array[$element_name]['rows'] ?? '';
|
|
$data['cols'] = $this->table_array[$element_name]['cols'] ?? '';
|
|
$show_value = $data['value'];
|
|
}
|
|
// for drop_down_*
|
|
if (preg_match("/^drop_down_/", $this->table_array[$element_name]['type'])) {
|
|
$type = 'drop_down';
|
|
// outer query overrules inner
|
|
if (empty($query) && !empty($this->table_array[$element_name]['query'])) {
|
|
$query = $this->table_array[$element_name]['query'];
|
|
}
|
|
}
|
|
// for drop_down_db*
|
|
$data['drop_down_input'] = 0;
|
|
if (preg_match("/^drop_down_db/", $this->table_array[$element_name]['type'])) {
|
|
// if still NO query
|
|
if (empty($query)) {
|
|
// select pk_name, input_name from table_name (order by order_by)
|
|
$query = "SELECT "
|
|
. (
|
|
(
|
|
isset($this->table_array[$element_name]['select_distinct']) &&
|
|
$this->table_array[$element_name]['select_distinct']
|
|
) ? "DISTINCT" : ''
|
|
) . " "
|
|
. $this->table_array[$element_name]['pk_name'] . ", "
|
|
. $this->table_array[$element_name]['input_name'] . " ";
|
|
if (!empty($this->table_array[$element_name]['order_by'])) {
|
|
$query .= ", " . $this->table_array[$element_name]['order_by'] . " ";
|
|
}
|
|
$query .= "FROM " . $this->table_array[$element_name]['table_name'];
|
|
// possible where statements
|
|
if (!empty($this->table_array[$element_name]['where'])) {
|
|
$query .= " WHERE " . $this->table_array[$element_name]['where'];
|
|
}
|
|
// not self where
|
|
if (
|
|
!empty($this->table_array[$element_name]['where_not_self']) &&
|
|
isset($this->table_array[$this->int_pk_name]['value']) &&
|
|
$this->table_array[$this->int_pk_name]['value']
|
|
) {
|
|
// check if query has where already
|
|
if (strstr($query, 'WHERE') === false) {
|
|
$query .= " WHERE ";
|
|
} else {
|
|
$query .= " AND ";
|
|
}
|
|
$query .= " " . $this->int_pk_name . " <> " . $this->table_array[$this->int_pk_name]['value'];
|
|
}
|
|
// possible order statements
|
|
if (!empty($this->table_array[$element_name]['order_by'])) {
|
|
$query .= " ORDER BY " . $this->table_array[$element_name]['order_by'];
|
|
}
|
|
}
|
|
// set output data
|
|
$data['selected'] = '';
|
|
$data['name'] = $element_name;
|
|
$data['value'][] = '';
|
|
$data['output'][] = $this->l->__('Please choose .. . ');
|
|
while (is_array($res = $this->dbReturn($query))) {
|
|
$data['value'][] = $res[0];
|
|
$data['output'][] = $res[1];
|
|
if (
|
|
isset($this->table_array[$element_name]['value']) &&
|
|
$this->table_array[$element_name]['value'] == $res[0]
|
|
) {
|
|
$data['selected'] = $this->table_array[$element_name]['value'];
|
|
$show_value = $res[1];
|
|
}
|
|
}
|
|
// for _input put additional field next to drop down
|
|
if (preg_match("/^drop_down_db_input/", $this->table_array[$element_name]['type'])) {
|
|
$data['drop_down_input'] = 1;
|
|
// pre fill the temp if empty and other side is selected, only for same_db
|
|
if (
|
|
$this->table_array[$element_name]['type'] == 'drop_down_db_input_same_db' &&
|
|
!$this->table_array[$element_name]['input_value'] &&
|
|
$this->table_array[$element_name]['value']
|
|
) {
|
|
$this->table_array[$element_name]['input_value'] = $this->table_array[$element_name]['value'];
|
|
}
|
|
$data['input_value'] = $this->table_array[$element_name]['input_value'];
|
|
$data['input_name'] = $this->table_array[$element_name]['input_name']
|
|
. (($this->table_array[$element_name]['type'] == 'drop_down_db_input_same_db') ? '_temp' : '');
|
|
$data['input_size'] = $this->table_array[$element_name]['size'];
|
|
$data['input_length'] = $this->table_array[$element_name]['length'];
|
|
}
|
|
}
|
|
// drop down array
|
|
if ($this->table_array[$element_name]['type'] == 'drop_down_array') {
|
|
$data['selected'] = '';
|
|
$data['name'] = $element_name;
|
|
$data['value'][] = '';
|
|
$data['output'][] = $this->l->__('Please choose .. . ');
|
|
// outer query overrules inner
|
|
foreach ($query as $key => $value) {
|
|
$data['value'][] = $key;
|
|
$data['output'][] = $value;
|
|
if ($this->table_array[$element_name]['value'] == $key) {
|
|
$data['selected'] = $this->table_array[$element_name]['value'];
|
|
$show_value = $value;
|
|
}
|
|
}
|
|
}
|
|
// radio array
|
|
if ($this->table_array[$element_name]['type'] == 'radio_array') {
|
|
if (!$query) {
|
|
$query = $this->table_array[$element_name]['query'];
|
|
}
|
|
$data['name'] = $element_name;
|
|
foreach ($query as $key => $value) {
|
|
$data['value'][] = $key;
|
|
$data['output'][] = $value;
|
|
if ($this->table_array[$element_name]['value'] == $key) {
|
|
$data['checked'] = $this->table_array[$element_name]['value'];
|
|
$show_value = $value;
|
|
}
|
|
$data['separator'] = '';
|
|
}
|
|
}
|
|
// for media / not yet implemented
|
|
if ($this->table_array[$element_name]['type'] == 'media') {
|
|
//media::insert_file($element_name,$this->table_array[$element_name]['value'],$query);
|
|
}
|
|
// order button
|
|
if ($this->table_array[$element_name]['type'] == 'order') {
|
|
$data['output_name'] = $this->table_array[$element_name]['output_name'];
|
|
$data['name'] = $element_name;
|
|
$data['value'] = $this->table_array[$element_name]['value'] ?? 0;
|
|
$data['col_name'] = $this->col_name;
|
|
$data['table_name'] = $this->table_name;
|
|
$data['query'] = $query !== null ? urlencode($query) : '';
|
|
}
|
|
// file upload
|
|
if ($this->table_array[$element_name]['type'] == 'file') {
|
|
$data['name'] = $element_name;
|
|
// if file for this exsists, print 'delete, view stuff'
|
|
if ($this->table_array[$element_name]['value']) {
|
|
$data['content'] = 1;
|
|
$data['url'] = $this->table_array[$element_name]['open_dir']
|
|
. $this->table_array[$element_name]['value'];
|
|
$data['output'] = $this->table_array[$element_name]['value'];
|
|
$data['value'] = $this->table_array[$element_name]['value'];
|
|
}
|
|
}
|
|
return [
|
|
'output_name' => $output_name,
|
|
'color' => $EDIT_FGCOLOR_T,
|
|
'type' => $type,
|
|
'data' => $data,
|
|
'show_value' => $show_value,
|
|
'allow_edit' => $this->base_acl_level >= $min_edit_acl ? 1 : 0,
|
|
'allow_show' => $this->base_acl_level >= $min_show_acl ? 1 : 0,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* full error message string for output
|
|
* checks each filled entry to the table array defined error checks
|
|
* should be cought like this ...
|
|
* if ($msg = $form->form_error_check())
|
|
* $error=1;
|
|
*
|
|
* @return void has no return
|
|
*/
|
|
public function formErrorCheck(): void
|
|
{
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
// skip if we are not allowe to write this anyway
|
|
// $this->log->debug('ERROR CHECK', 'ACL K: ' . $key . ', '
|
|
// . ($value['min_edit_acl'] ?? 100) . ' < ' . $this->base_acl_level);
|
|
if ($this->base_acl_level < ($value['min_edit_acl'] ?? 100)) {
|
|
continue;
|
|
}
|
|
//if ($value['mandatory'] && $value['error_check'])
|
|
// if error value set && somethign input, check if input okay
|
|
if (
|
|
isset($value['error_check']) &&
|
|
isset($this->table_array[$key]['value']) &&
|
|
!empty($this->table_array[$key]['value'])
|
|
) {
|
|
$this->log->debug('ERROR CHECK', 'Key: ' . $key . ' => ' . $value['error_check']);
|
|
// each error check can be a piped seperated value, lets split it
|
|
// $this->log->debug('edit', $value['error_check']);
|
|
foreach (explode('|', $value['error_check']) as $error_check) {
|
|
switch ($error_check) {
|
|
case 'number':
|
|
if (!is_numeric($this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a vailid Number for the <b>%s</b> Field!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'date': // YYYY-MM-DD
|
|
if (!\CoreLibs\Combined\DateTime::checkDate($this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__(
|
|
'Please enter a valid date (YYYY-MM-DD) for the <b>%s</b> Field!<br>'
|
|
),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'time': // HH:MM[:SS]
|
|
if (!\CoreLibs\Combined\DateTime::checkDateTime($this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__(
|
|
'Please enter a valid time (HH:mm[:SS]) for the <b>%s</b> Field!<br>'
|
|
),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'datetime': // YYYY-MM-DD HH:MM[:SS]
|
|
if (!\CoreLibs\Combined\DateTime::checkDateTime($this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__(
|
|
'Please enter a valid date time (YYYY-MM-DD HH:mm) '
|
|
. 'for the <b>%s</b> Field!<br>'
|
|
),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'intervalshort': // ony interval n [Y/M/D] only
|
|
if (
|
|
!preg_match(
|
|
"/^\d{1,3}\ ?([ymd]{1}|day(s)?|year(s)?|month(s)?)$/i",
|
|
$this->table_array[$key]['value']
|
|
)
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__(
|
|
'Please enter a valid time interval in the format '
|
|
. '<length> Y|M|D for the <b>%s</b> Field!<br>'
|
|
),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'email':
|
|
if (!preg_match("/$this->email_regex/", $this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__(
|
|
'Please enter a valid E-Mail Address for the <b>%s</b> Field!<br>'
|
|
),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
// check unique, check if field in table is not yet exist
|
|
case 'unique':
|
|
$q = 'SELECT ' . $key . ' AS unique_row '
|
|
. 'FROM ' . $this->table_name . ' '
|
|
. 'WHERE ' . $key . ' = '
|
|
. "'" . $this->dbEscapeString($this->table_array[$key]['value']) . "'";
|
|
if ($this->table_array[$this->int_pk_name]['value']) {
|
|
$q .= ' AND ' . $this->int_pk_name . ' <> '
|
|
. $this->table_array[$this->int_pk_name]['value'];
|
|
}
|
|
if (
|
|
is_array($s_res = $this->dbReturnRow($q)) &&
|
|
!empty($s_res['unique_row'])
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('The field <b>%s</b> can be used only once!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'custom':
|
|
if (
|
|
!preg_match($this->table_array[$key]['error_regex'], $this->table_array[$key]['value'])
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid (%s) input for the <b>%s</b> Field!<br>'),
|
|
$this->table_array[$key]['error_example'],
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'alphanumericspace':
|
|
// $this->log->debug('edit', 'IN Alphanumericspace');
|
|
if (!preg_match("/^[0-9A-Za-z_\-\ ]+$/", $this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid alphanumeric (Numbers and Letters, -, _ '
|
|
. 'and spaces allowed) value for the <b>%s</b> Field!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'alphanumeric':
|
|
// $this->log->debug('edit', 'IN Alphanumeric');
|
|
if (!preg_match("/^[0-9A-Za-z_\-]+$/", $this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid alphanumeric (Numbers and Letters only '
|
|
. 'also - and _, no spaces) value for the <b>%s</b> Field!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
// this one also allows @ and .
|
|
case 'alphanumericextended':
|
|
// $this->log->debug('edit', 'IN Alphanumericextended');
|
|
if (!preg_match("/^[0-9A-Za-z_\-@\.]+$/", $this->table_array[$key]['value'])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid alphanumeric extended (Numbers, Letters, -, '
|
|
. '_, @ and . only, no spaces) value for the <b>%s</b> Field!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
break;
|
|
case 'password':
|
|
// password can only be alphanumeric + special chars
|
|
// password and CONFIRM_password need to be the same
|
|
if ($this->table_array[$key]['value'] != $this->table_array[$key]['CONFIRM_value']) {
|
|
// error
|
|
}
|
|
break;
|
|
case 'json':
|
|
// check if valid json
|
|
$json_out = json_decode($this->table_array[$key]['value'], true);
|
|
$this->log->debug('JSON ENCODE', 'LAST ERROR: ' . json_last_error()
|
|
. ' WITH: ' . $this->table_array[$key]['value']);
|
|
if (json_last_error()) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid JSON string for the field <b>%s<b>: %s'),
|
|
$this->table_array[$key]['output_name'],
|
|
json_last_error_msg()
|
|
);
|
|
}
|
|
break;
|
|
} // switch
|
|
} // for each error to check
|
|
} elseif (
|
|
isset($value['mandatory']) &&
|
|
$value['mandatory'] &&
|
|
(
|
|
// for all 'normal' fields
|
|
(
|
|
$this->table_array[$key]['type'] != 'password' &&
|
|
$this->table_array[$key]['type'] != 'drop_down_db_input' &&
|
|
!$this->table_array[$key]['value']
|
|
) ||
|
|
// for drop_down_db_input check if one of both fields filled
|
|
(
|
|
$this->table_array[$key]['type'] == 'drop_down_db_input' &&
|
|
!$this->table_array[$key]['input_value'] &&
|
|
!$this->table_array[$key]['value']
|
|
) ||
|
|
// for password
|
|
(
|
|
$this->table_array[$key]['type'] == 'password' &&
|
|
!$this->table_array[$key]['value'] &&
|
|
!$this->table_array[$key]['HIDDEN_value']
|
|
)
|
|
)
|
|
// main if end
|
|
) {
|
|
// if mandatory && no input
|
|
// $this->log->debug('form', 'A: ' . $this->table_array[$key]['type'] . ' -- '
|
|
// . $this->table_array[$key]['input_value'] . ' -- ' . $this->table_array[$key]['value']);
|
|
if (
|
|
empty($this->table_array[$key]['value']) &&
|
|
$this->table_array[$key]['type'] != 'binary'
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter something into the <b>%s</b> field!<br>'),
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
} // mandatory
|
|
// check file upload
|
|
if (
|
|
isset($this->table_array[$key]['type']) &&
|
|
$this->table_array[$key]['type'] == 'file' &&
|
|
$GLOBALS['_FILES'][$key . '_file']['name'] &&
|
|
is_array($this->table_array[$key]['accept_type'])
|
|
) {
|
|
// check against allowed types
|
|
$mime_okay = 0;
|
|
foreach ($this->table_array[$key]['accept_type'] as $mime_type) {
|
|
if ($GLOBALS['_FILES'][$key . '_file']['type'] == $mime_type) {
|
|
$mime_okay = 1;
|
|
}
|
|
}
|
|
if (!$mime_okay) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Uploaded File <b>%s</b> has MIME Type <b>%s</b> which is not in '
|
|
. 'theallowed MIME List for Upload Field <b>%s</b>!<br>'),
|
|
$GLOBALS['_FILES'][$key . '_file']['name'],
|
|
$GLOBALS['_FILES'][$key . '_file']['type'],
|
|
$this->table_array[$key]['output_name']
|
|
);
|
|
}
|
|
}
|
|
} // while
|
|
// do check for reference tables
|
|
reset($this->reference_array);
|
|
foreach ($this->reference_array as $key => $value) {
|
|
// skip if not allowed to write
|
|
if (
|
|
$this->base_acl_level < ($this->reference_array[$key]['min_edit_acl'] ?? 100)
|
|
) {
|
|
continue;
|
|
}
|
|
if (
|
|
isset($this->reference_array[$key]['mandatory']) &&
|
|
$this->reference_array[$key]['mandatory'] &&
|
|
!$this->reference_array[$key]['selected'][0]
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please select at least one Element from field <b>%s</b>!<br>'),
|
|
$this->reference_array[$key]['output_name']
|
|
);
|
|
}
|
|
}
|
|
// $this->log->debug('edit_error', 'QS: <pre>' . print_r($_POST, true) . '</pre>');
|
|
if (is_array($this->element_list)) {
|
|
// check the mandatory stuff
|
|
// if mandatory, check that at least on pk exists or
|
|
// if at least the mandatory field is filled
|
|
foreach ($this->element_list as $table_name => $reference_array) {
|
|
if (!is_array($reference_array)) {
|
|
$reference_array = [];
|
|
}
|
|
// skip if not allowed to write
|
|
if (
|
|
$this->base_acl_level < ($this->reference_array['min_edit_acl'] ?? 100)
|
|
) {
|
|
continue;
|
|
}
|
|
// set pk/fk id for this
|
|
$_pk_name = '';
|
|
$_fk_name = '';
|
|
foreach ($reference_array['elements'] as $_name => $_data) {
|
|
if (isset($_data['pk_id'])) {
|
|
$_pk_name = $_name;
|
|
}
|
|
if (isset($_data['fk_id'])) {
|
|
$_fk_name = $_name;
|
|
}
|
|
}
|
|
// get the leasy of keys from the elements array
|
|
$keys = array_keys($reference_array['elements']);
|
|
// prefix
|
|
$prfx = $reference_array['prefix'] ? $reference_array['prefix'] . '_' : '';
|
|
// get max elements
|
|
$max = 0;
|
|
foreach ($keys as $key) {
|
|
if (
|
|
isset($_POST[$prfx . $key]) &&
|
|
is_array($_POST[$prfx . $key]) &&
|
|
count($_POST[$prfx . $key]) > $max
|
|
) {
|
|
$max = count($_POST[$prfx . $key]);
|
|
}
|
|
// $this->log->debug('edit_error_chk', 'KEY: ' . $prfx . $key . ' | count: '
|
|
// . count($_POST[$prfx.$key]) . ' | M: $max');
|
|
// $this->log->debug('edit_error_chk', 'K: ' . $_POST[$prfx.$key] . ' | ' . $_POST[$prfx.$key][0]);
|
|
}
|
|
// $this->log->debug('POST ARRAY', $this->log->prAr($_POST));
|
|
// init variables before inner loop run
|
|
$mand_okay = 0;
|
|
$mand_name = '';
|
|
$row_okay = [];
|
|
$default_wrong = [];
|
|
$error = [];
|
|
$element_set = [];
|
|
# check each row
|
|
for ($i = 0; $i < $max; $i++) {
|
|
// either one of the post pks is set, or the mandatory
|
|
foreach ($reference_array['elements'] as $el_name => $data_array) {
|
|
if (
|
|
isset($data_array['mandatory']) &&
|
|
$data_array['mandatory']
|
|
) {
|
|
$mand_name = $data_array['output_name'];
|
|
}
|
|
// check if there is a primary ket inside, so it is okay
|
|
if (
|
|
isset($data_array['pk_id']) &&
|
|
count($_POST[$prfx . $el_name]) &&
|
|
!empty($reference_array['mandatory'])
|
|
) {
|
|
$mand_okay = 1;
|
|
}
|
|
// we found a mandatory field. check now if one is set to satisfy the main mandatory
|
|
// also check, if this field is mandatory and its not set, but any other, throw an error
|
|
// $this->log->debug('edit_error_chk', 'RG error - Data[' . $prfx . $el_name
|
|
// . ': ' . $_POST[$prfx . $el_name][$i] . ' | '
|
|
// . $_POST[$prfx . $el_name] . ' - ' . $reference_array['enable_name'] . ' - '
|
|
// . $_POST[$reference_array['enable_name']][$_POST[$prfx . $el_name][$i]]);
|
|
if (
|
|
!empty($data_array['mandatory']) &&
|
|
!empty($_POST[$prfx . $el_name][$i])
|
|
) {
|
|
$mand_okay = 1;
|
|
$row_okay[$i] = 1;
|
|
} elseif (
|
|
!empty($data_array['type']) &&
|
|
$data_array['type'] == 'radio_group' &&
|
|
!isset($_POST[$prfx . $el_name])
|
|
) {
|
|
// radio group and set where one not active
|
|
// $this->log->debug('edit_error_chk', 'RADIO GROUP');
|
|
$row_okay[$_POST[$prfx . $el_name][$i] ?? 0] = 0;
|
|
$default_wrong[$_POST[$prfx . $el_name][$i] ?? 0] = 1;
|
|
$error[$_POST[$prfx . $el_name][$i] ?? 0] = 1;
|
|
} elseif (
|
|
isset($_POST[$prfx . $el_name][$i]) &&
|
|
!isset($error[$i])
|
|
) {
|
|
// $this->log->debug('edit_error_chk', '[$i]');
|
|
$element_set[$i] = 1;
|
|
$row_okay[$i] = 1;
|
|
} elseif (
|
|
!empty($data_array['mandatory']) &&
|
|
!$_POST[$prfx . $el_name][$i]
|
|
) {
|
|
$row_okay[$i] = 0;
|
|
}
|
|
// do optional error checks like for normal fields
|
|
// currently active: unique/alphanumeric
|
|
if (!empty($data_array['error_check'])) {
|
|
foreach (explode('|', $data_array['error_check']) as $error_check) {
|
|
switch ($error_check) {
|
|
// check unique, check if field is filled and not same in _POST set
|
|
case 'unique':
|
|
// must be set for double check
|
|
if (
|
|
$_POST[$prfx . $el_name][$i] &&
|
|
count(array_keys(
|
|
$_POST[$prfx . $el_name],
|
|
$_POST[$prfx . $el_name][$i]
|
|
)) >= 2
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('The field <b>%s</b> in row <b>%s</b> '
|
|
. 'can be used only once!<br>'),
|
|
$reference_array['output_name'],
|
|
$i
|
|
);
|
|
$_POST['ERROR'][$prfx][$i] = 1;
|
|
}
|
|
break;
|
|
case 'alphanumericspace':
|
|
// only check if set
|
|
if (
|
|
$_POST[$prfx . $el_name][$i] &&
|
|
!preg_match("/^[0-9A-Za-z\ ]+$/", $_POST[$prfx . $el_name][$i])
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Please enter a valid alphanumeric (Numbers and Letters, '
|
|
. 'spaces allowed) value for the '
|
|
. '<b>%s</b> Field and row <b>%s</b>!<br>'),
|
|
$reference_array['output_name'],
|
|
$i
|
|
);
|
|
$_POST['ERROR'][$prfx][$i] = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} // if main mandatory
|
|
}
|
|
|
|
// main mandatory is met -> error msg
|
|
if (
|
|
!$mand_okay &&
|
|
!empty($reference_array['mandatory'])
|
|
) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('You need to enter at least one data set for field <b>%s</b>!<br>'),
|
|
$reference_array['output_name']
|
|
);
|
|
}
|
|
for ($i = 0; $i < $max; $i++) {
|
|
if (!isset($row_okay[$i]) && isset($element_set[$i])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('The row <b>%s</b> has <b>%s</b> set as mandatory, '
|
|
. 'please fill at least this field out<br>'),
|
|
$i,
|
|
$mand_name
|
|
);
|
|
}
|
|
if (!isset($row_okay[$i]) && isset($default_wrong[$i])) {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('The row <b>%s</b> would have a default setting, but it would be disabled. '
|
|
. 'Please change the default setting and save again<br>'),
|
|
$i
|
|
);
|
|
}
|
|
}
|
|
} // each element list
|
|
}
|
|
if ($this->msg) {
|
|
$this->error = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* sets the order to the maximum, if order flag is set in array
|
|
*
|
|
* @return array<mixed> table array with set order number
|
|
*/
|
|
public function formSetOrder(): array
|
|
{
|
|
// get order name
|
|
$order_name = $this->formGetColNameFromKey('order');
|
|
if (empty($order_name)) {
|
|
return $this->table_array;
|
|
}
|
|
// first check out of order ...
|
|
if (empty($this->table_array[$order_name]['value'])) {
|
|
// set order (read max)
|
|
$q = 'SELECT MAX(' . $order_name . ') + 1 AS max_page_order '
|
|
. 'FROM ' . $this->table_name;
|
|
if (
|
|
is_array($res = $this->dbReturnRow($q)) &&
|
|
!empty($res['max_page_order'])
|
|
) {
|
|
$this->table_array[$order_name]['value'] = $res['max_page_order'];
|
|
}
|
|
// frist element is 0 because NULL gets returned, set to 1
|
|
if (!$this->table_array[$order_name]['value']) {
|
|
$this->table_array[$order_name]['value'] = 1;
|
|
}
|
|
} elseif (!empty($this->table_array[$this->int_pk_name]['value'])) {
|
|
$q = 'SELECT ' . $order_name . ' AS order_name '
|
|
. 'FROM ' . $this->table_name . ' '
|
|
. 'WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
if (
|
|
is_array($res = $this->dbReturnRow($q)) &&
|
|
!empty($res['order_name'])
|
|
) {
|
|
$this->table_array[$order_name]['value'] = $res['order_name'];
|
|
}
|
|
}
|
|
return $this->table_array;
|
|
}
|
|
|
|
/**
|
|
* resets all values in table_array and in the reference tables
|
|
*
|
|
* @return void has no return
|
|
*/
|
|
public function formUnsetTableArray(): void
|
|
{
|
|
$this->pk_id = null;
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
unset($this->table_array[$key]['value']);
|
|
unset($this->table_array[$key]['input_value']);
|
|
// if preset var present preset
|
|
if (isset($this->table_array[$key]['preset'])) {
|
|
$this->table_array[$key]['value'] = $this->table_array[$key]['preset'];
|
|
}
|
|
}
|
|
if (is_array($this->reference_array)) {
|
|
if (!is_array($this->reference_array)) {
|
|
$this->reference_array = [];
|
|
}
|
|
reset($this->reference_array);
|
|
foreach ($this->reference_array as $key => $value) {
|
|
unset($this->reference_array[$key]['selected']);
|
|
}
|
|
}
|
|
$this->warning = 1;
|
|
$this->msg = $this->l->__('Cleared for new Dataset!');
|
|
}
|
|
|
|
/**
|
|
* load a table & reference
|
|
*
|
|
* @param string|null $pk_id overrule pk_id
|
|
* @return void has no return
|
|
*/
|
|
public function formLoadTableArray(?string $pk_id = null): void
|
|
{
|
|
if ($pk_id) {
|
|
$this->pk_id = $pk_id;
|
|
}
|
|
$this->table_array = $this->dbRead(true);
|
|
|
|
// reset all temp fields
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
unset($this->table_array[$key]['input_value']);
|
|
}
|
|
|
|
if (is_array($this->reference_array)) {
|
|
// load each reference_table
|
|
if (!is_array($this->reference_array)) {
|
|
$this->reference_array = [];
|
|
}
|
|
reset($this->reference_array);
|
|
foreach ($this->reference_array as $key => $value) {
|
|
unset($this->reference_array[$key]['selected']);
|
|
$q = 'SELECT ' . $this->reference_array[$key]['other_table_pk']
|
|
. ' FROM ' . $this->reference_array[$key]['table_name']
|
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
while (is_array($res = $this->dbReturn($q))) {
|
|
$this->reference_array[$key]['selected'][] = $res[$this->reference_array[$key]['other_table_pk']];
|
|
}
|
|
}
|
|
}
|
|
$this->warning = 1;
|
|
$this->msg = $this->l->__('Dataset has been loaded!<br>');
|
|
}
|
|
|
|
/**
|
|
* save a table, reference and all input fields
|
|
* note that the addslashes flag here is passed on to the dbWrite method
|
|
* it only does html conversion, add slashes for DB is done automatically
|
|
*
|
|
* @param bool $addslashes override internal addslasahes flag (default false)
|
|
* @return void has no return
|
|
*/
|
|
public function formSaveTableArray(bool $addslashes = false)
|
|
{
|
|
// for drop_down_db_input check if text field is filled and if, if not yet in db ...
|
|
// and upload files
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
// drop_down_db with input + reference table
|
|
// $this->log->debug('form', 'A: ' . $this->table_array[$key]['type']
|
|
// . ' --- ' . $this->table_array[$key]['input_value']);
|
|
if (
|
|
isset($this->table_array[$key]['type']) &&
|
|
$this->table_array[$key]['type'] == 'drop_down_db_input' &&
|
|
$this->table_array[$key]['input_value']
|
|
) {
|
|
// $this->log->debug('form', 'HERE');
|
|
// check if this text name already exists (lowercase compare)
|
|
$q = 'SELECT ' . $this->table_array[$key]['pk_name'] . ' AS pk_name '
|
|
. ' FROM ' . $this->table_array[$key]['table_name']
|
|
. ' WHERE LCASE(' . $this->table_array[$key]['input_name'] . ') = '
|
|
. "'" . $this->dbEscapeString(strtolower($this->table_array[$key]['input_value'])) . "'";
|
|
// if a where was given, add here
|
|
if ($this->table_array[$key]['where']) {
|
|
$q .= ' AND ' . $this->table_array[$key]['where'];
|
|
}
|
|
if (
|
|
is_array($s_res = $this->dbReturnRow($q)) &&
|
|
!empty($s_res['pk_name'])
|
|
) {
|
|
// $this->table_array[$key]['value'] = $pk_name_temp;
|
|
$this->table_array[$key]['value'] = $s_res['pk_name'];
|
|
} else {
|
|
// if a where was given, set this key also [dangerous!]
|
|
// postgreSQL compatible insert
|
|
$q = 'INSERT INTO ' . $this->table_array[$key]['table_name']
|
|
. ' (' . $this->table_array[$key]['input_name'] . ') VALUES ('
|
|
. "'" . $this->dbEscapeString($this->table_array[$key]['input_value']) . "')";
|
|
$this->dbExec($q);
|
|
if (!empty($this->table_array[$key]['where']) && is_numeric($this->dbGetInsertPK())) {
|
|
// make an update on the just inseted data with the where data als update values
|
|
$q = 'UPDATE ' . $this->table_array[$key]['table_name'] . ' SET ';
|
|
$q .= $this->table_array[$key]['where'] . ' ';
|
|
$q .= 'WHERE ' . $this->table_array[$key]['pk_name'] . ' = ' . $this->dbGetInsertPK();
|
|
$this->dbExec($q);
|
|
}
|
|
$this->table_array[$key]['value'] = $this->dbGetInsertPK();
|
|
} // set value from DB through select or insert
|
|
unset($this->table_array[$key]['input_value']);
|
|
} // if it is certain field type && if there is something in the temp field
|
|
// drop_down_db with input and in same table
|
|
if (
|
|
isset($this->table_array[$key]['type']) &&
|
|
$this->table_array[$key]['type'] == 'drop_down_db_input_same_db' &&
|
|
$this->table_array[$key]['input_value']
|
|
) {
|
|
// if drop down & input are different
|
|
if ($this->table_array[$key]['input_value'] != $this->table_array[$key]['value']) {
|
|
// check if 'right input' is in DB
|
|
$q = 'SELECT ' . $this->table_array[$key]['input_name'] . ' AS temp '
|
|
. ' FROM ' . $this->table_array[$key]['table_name']
|
|
. ' WHERE LCASE(' . $this->table_array[$key]['input_name'] . ') = '
|
|
. "'" . strtolower($this->dbEscapeString($this->table_array[$key]['input_value'])) . "'";
|
|
// if a where was given, add here
|
|
if ($this->table_array[$key]['where']) {
|
|
$q .= ' AND ' . $this->table_array[$key]['where'];
|
|
}
|
|
if (
|
|
is_array($s_res = $this->dbReturnRow($q)) &&
|
|
empty($s_res['temp'])
|
|
) {
|
|
$this->table_array[$key]['value'] = $this->table_array[$key]['input_value'];
|
|
} else {
|
|
// found in DB
|
|
$this->table_array[$key]['input_value'] = $this->table_array[$key]['value'];
|
|
}
|
|
} // key difference ?
|
|
} // for same_db drop down
|
|
|
|
// upload & save files to locations
|
|
if (isset($this->table_array[$key]['type']) && $this->table_array[$key]['type'] == 'file') {
|
|
// if smth in $$key_file -> save or overwrite
|
|
// if smth in $key && $$key_delete && !$$key_file-> delte
|
|
// if smth in $key, keep as is
|
|
// $_file=$key . '_file';
|
|
// $_delete=$key . '_delete';
|
|
// $this->log->debug('form', 'UF: ' . $GLOBALS['_FILES'][$key . '_file']['name']);
|
|
// $this->log->debug('form', 'delete: ' . $key . '_delete => ' . $GLOBALS[$key . '_delete']);
|
|
if ($GLOBALS['_FILES'][$key . '_file']['name']) {
|
|
// check if dir exists
|
|
if (is_dir($this->table_array[$key]['save_dir'])) {
|
|
//if a slash at the end (if not add slash)
|
|
if (!preg_match("|/$|", $this->table_array[$key]['save_dir'])) {
|
|
$this->table_array[$key]['save_dir'] .= '/';
|
|
}
|
|
if (
|
|
move_uploaded_file(
|
|
$GLOBALS['_FILES'][$key . '_file']['tmp_name'],
|
|
$this->table_array[$key]['save_dir'] . $GLOBALS['_FILES'][$key . '_file']['name']
|
|
)
|
|
) {
|
|
// make it unique with a unique number at the beginning
|
|
$this->table_array[$key]['value'] = uniqid((string)rand(), true)
|
|
. '_' . $GLOBALS['_FILES'][$key . '_file']['name'];
|
|
} else {
|
|
$this->msg .= $this->l->__('File could not be copied to target directory! '
|
|
. 'Perhaps wrong directory permissions . ');
|
|
$this->error = 1;
|
|
} // could not move file (dir permissions?)
|
|
} else {
|
|
$this->msg .= sprintf(
|
|
$this->l->__('Target Directory \'%s\' is not a vaild directory!'),
|
|
$this->table_array[$key]['save_dir']
|
|
);
|
|
$this->error = 1;
|
|
} // could not dir check (dir wrong??)
|
|
}
|
|
if (
|
|
!empty($GLOBALS[$key . '_delete']) &&
|
|
$this->table_array[$key]['value'] && !$GLOBALS['_FILES'][$key . '_file']['name']
|
|
) {
|
|
unlink($this->table_array[$key]['save_dir'] . $this->table_array[$key]['value']);
|
|
unset($this->table_array[$key]['value']);
|
|
}
|
|
}
|
|
|
|
// for password crypt it as blowfish, or if not available MD5
|
|
if (isset($this->table_array[$key]['type']) && $this->table_array[$key]['type'] == 'password') {
|
|
if ($this->table_array[$key]['value']) {
|
|
// use the better new passwordSet instead of crypt based
|
|
$this->table_array[$key]['value'] =
|
|
\CoreLibs\Security\Password::passwordSet($this->table_array[$key]['value']);
|
|
$this->table_array[$key]['HIDDEN_value'] = $this->table_array[$key]['value'];
|
|
} else {
|
|
// $this->table_array[$key]['HIDDEN_value'] =
|
|
}
|
|
}
|
|
} // go through each field
|
|
|
|
// set object order (if necessary)
|
|
$this->formSetOrder();
|
|
// $this->log->debug('PK NAME SET', "PK NAME: " . $this->pk_name . "/" . $this->int_pk_name . ": "
|
|
// . $this->table_array[$this->pk_name]['value'] . "/"
|
|
// . $this->table_array[$this->int_pk_name]['value']);
|
|
// write the object
|
|
$this->dbWrite($addslashes, [], true);
|
|
// write reference array (s) if necessary
|
|
if (is_array($this->reference_array)) {
|
|
if (!is_array($this->reference_array)) {
|
|
$this->reference_array = [];
|
|
}
|
|
reset($this->reference_array);
|
|
foreach ($this->reference_array as $reference_array) {
|
|
$q = 'DELETE FROM ' . $reference_array['table_name']
|
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
$this->dbExec($q);
|
|
$q = 'INSERT INTO ' . $reference_array['table_name']
|
|
. ' (' . $reference_array['other_table_pk'] . ', ' . $this->int_pk_name . ') VALUES ';
|
|
for ($i = 0, $i_max = count($reference_array['selected']); $i < $i_max; $i++) {
|
|
$t_q = '(' . $reference_array['selected'][$i] . ', '
|
|
. $this->table_array[$this->int_pk_name]['value'] . ')';
|
|
$this->dbExec($q . $t_q);
|
|
}
|
|
} // foreach reference arrays
|
|
} // if reference arrays
|
|
// write element list
|
|
if (is_array($this->element_list)) {
|
|
$type = [];
|
|
reset($this->element_list);
|
|
foreach ($this->element_list as $table_name => $reference_array) {
|
|
// early skip if not enought ACL
|
|
if ($this->base_acl_level < ($reference_array['min_edit_acl'] ?? 100)) {
|
|
continue;
|
|
}
|
|
// init arrays
|
|
$q_begin = [];
|
|
$q_middle = [];
|
|
$q_end = [];
|
|
$q_names = [];
|
|
$q_data = [];
|
|
$q_values = [];
|
|
$no_write = [];
|
|
$block_write = [];
|
|
// get the number of keys from the elements array
|
|
$keys = array_keys($reference_array['elements']);
|
|
// element prefix name
|
|
$prfx = $reference_array['prefix'] ? $reference_array['prefix'] . '_' : '';
|
|
// get max elements
|
|
$max = 0;
|
|
foreach ($keys as $key) {
|
|
if (
|
|
isset($_POST[$prfx . $key]) &&
|
|
is_array($_POST[$prfx . $key]) &&
|
|
count($_POST[$prfx . $key]) > $max
|
|
) {
|
|
$max = count($_POST[$prfx . $key]);
|
|
}
|
|
}
|
|
$this->log->debug('REF ELEMENT', 'RUN FOR TABLE: ' . $table_name);
|
|
// $this->log->debug('edit_error', 'MAX: $max');
|
|
// check if there is a hidden key, update, else insert
|
|
foreach ($reference_array['elements'] as $el_name => $data_array) {
|
|
// $this->log->debug('edit_error_query', 'QUERY: ' . $this->log->prAr($_POST));
|
|
// go through all submitted data
|
|
// for ($i = 0; $i < count($_POST[$el_name]); $i++)
|
|
for ($i = 0; $i < $max; $i++) {
|
|
if (!isset($no_write[$i])) {
|
|
$no_write[$i] = 0;
|
|
// $this->log->debug('REF ELEMENT', 'Init no write for pos: ' . $i);
|
|
}
|
|
if (!isset($block_write[$i])) {
|
|
$block_write[$i] = 0;
|
|
// $this->log->debug('REF ELEMENT', 'Init block write for pos: ' . $i);
|
|
}
|
|
// if we have enable name & delete set,
|
|
// then only insert/update those which are flagged as active
|
|
// check if mandatory field is set, if not set 'do not write flag'
|
|
if (
|
|
isset($data_array['mandatory']) &&
|
|
$data_array['mandatory'] &&
|
|
(
|
|
!isset($_POST[$prfx . $el_name][$i]) ||
|
|
(isset($_POST[$prfx . $el_name][$i]) &&
|
|
empty($_POST[$prfx . $el_name][$i]))
|
|
)
|
|
) {
|
|
$no_write[$i] = 1;
|
|
}
|
|
// $this->log->debug('REF ELEMENT', "[$i] [" . $prfx . $el_name . "]: '
|
|
// . "MANDATORY: " . isset($data_array['mandatory'])
|
|
// . " SET: " . isset($_POST[$prfx . $el_name][$i])
|
|
// . ", EMPTY: " . empty($_POST[$prfx . $el_name][$i])
|
|
// . " | DO ACTION " . ((!isset($_POST[$prfx . $el_name][$i]) ||
|
|
// (isset($_POST[$prfx . $el_name][$i]) &&
|
|
// empty($_POST[$prfx . $el_name][$i]))) ? 'YES' : 'NO'
|
|
// ) . " => NO WRITE: " . $no_write[$i]);
|
|
if (
|
|
!empty($reference_array['enable_name']) &&
|
|
isset($reference_array['delete']) && $reference_array['delete'] &&
|
|
(!isset($_POST[$reference_array['enable_name']][$i]) ||
|
|
empty($_POST[$reference_array['enable_name']][$i]))
|
|
) {
|
|
$no_write[$i] = 1;
|
|
}
|
|
// $this->log->debug('REF ELEMENT', "[$i] [" . $prfx . $el_name . "]: ENABLED NAME: "
|
|
// . isset($reference_array['enable_name'])
|
|
// . ", DELETE: " . isset($reference_array['delete']) . ", NOT ENABLED FOR POS: "
|
|
// . (isset($reference_array['enable_name']) ?
|
|
// isset($_POST[$reference_array['enable_name']][$i]) : '-'));
|
|
$this->log->debug('REF ELEMENT', "[$i] [" . $prfx . $el_name . "]: WRITE: " . $no_write[$i]);
|
|
// flag if data is in the text field and we are in a reference data set
|
|
if (isset($reference_array['type']) && $reference_array['type'] == 'reference_data') {
|
|
if (
|
|
!empty($data_array['type']) && $data_array['type'] == 'text' &&
|
|
isset($_POST[$prfx . $el_name][$i])
|
|
) {
|
|
$block_write[$i] = 1;
|
|
}
|
|
} else {
|
|
$block_write[$i] = 1;
|
|
}
|
|
// $this->log->debug('REF ELEMENT', "[$i] [" . $prfx . $el_name . "]: "
|
|
// . "REFERENCE TYPE: " . isset($reference_array['type'])
|
|
// . ", SET REFERENCE TYPE: "
|
|
// . (isset($reference_array['type']) ? $reference_array['type'] : '-')
|
|
// . ", DATA TYPE: " . $data_array['type'] . ", SET: " . isset($_POST[$prfx . $el_name][$i])
|
|
// . ", => BLOCK WIRTE: " . $block_write[$i]);
|
|
// set type and boundaries for insert/update
|
|
if (
|
|
isset($data_array['pk_id']) &&
|
|
!empty($data_array['pk_id']) &&
|
|
!empty($_POST[$prfx . $el_name][$i])
|
|
) {
|
|
$q_begin[$i] = 'UPDATE ' . $table_name . ' SET ';
|
|
$q_end[$i] = ' WHERE ' . $el_name . ' = ' . $_POST[$prfx . $el_name][$i];
|
|
$type[$i] = 'update';
|
|
$this->log->debug('REF ELEMENT', 'SET UPDATE');
|
|
} elseif (
|
|
isset($data_array['pk_id']) &&
|
|
!empty($data_array['pk_id']) &&
|
|
empty($_POST[$prfx . $el_name][$i])
|
|
) {
|
|
$q_begin[$i] = 'INSERT INTO ' . $table_name . ' (';
|
|
$q_middle[$i] = ') VALUES (';
|
|
$q_end[$i] = ')';
|
|
$type[$i] = 'insert';
|
|
$this->log->debug('REF ELEMENT', 'SET INSERT');
|
|
}
|
|
// $this->log->debug('REF ELEMENT', "[$i] [" . $prfx . $el_name . "] "
|
|
// . "PK SET: " . isset($data_array['pk_id']) . '/' . empty($data_array['pk_id'])
|
|
// . ', KEY SET: ' . empty($_POST[$prfx . $el_name][$i])
|
|
// . " -> TYPE: " . (isset($type[$i]) ? $type[$i] : '-'));
|
|
// write all data (insert/update) because I don't know until
|
|
// all are processed if it is insert or update
|
|
// don't write primary key backup for update
|
|
// for reference_data type, only write if at least one text type field is set
|
|
// $this->log->debug('edit_error', 'I: $i | EL Name: ' . $prfx . $el_name
|
|
// . ' | Data: ' . $_POST[$prfx . $el_name][$i] . ' | Type: ' . $type[$i]
|
|
// . ' | PK: ' . $data_array['pk_id'] . ', Block write: ' . $block_write[$i]);
|
|
// only add elements that are not PK or FK flaged
|
|
if (!isset($data_array['pk_id']) && !isset($data_array['fk_id'])) {
|
|
// update data list
|
|
if (isset($q_data[$i])) {
|
|
$q_data[$i] .= ', ';
|
|
} else {
|
|
$q_data[$i] = '';
|
|
}
|
|
// insert name part list
|
|
if (isset($q_names[$i])) {
|
|
$q_names[$i] .= ', ';
|
|
} else {
|
|
$q_names[$i] = '';
|
|
}
|
|
// insert value part list
|
|
if (isset($q_values[$i])) {
|
|
$q_values[$i] .= ', ';
|
|
} else {
|
|
$q_values[$i] = '';
|
|
}
|
|
// insert column name add
|
|
$q_names[$i] .= $el_name;
|
|
// data part, read from where [POST]
|
|
// radio group selections (only one can be active)
|
|
if (isset($data_array['type']) && $data_array['type'] == 'radio_group') {
|
|
if (isset($_POST[$prfx . $el_name]) && $i == $_POST[$prfx . $el_name]) {
|
|
$_value = $i + 1;
|
|
} else {
|
|
$_value = 'NULL';
|
|
}
|
|
} else {
|
|
$_value = $_POST[$prfx . $el_name][$i] ?? '';
|
|
}
|
|
// pre write data set. if int value, unset flagged
|
|
// need to be set null or 0 depending on settings
|
|
if (isset($data_array['int']) || isset($data_array['int_null'])) {
|
|
if (!$_value && isset($data_array['int_null'])) {
|
|
$_value = 'NULL';
|
|
} elseif (!$_value) {
|
|
$_value = 0;
|
|
}
|
|
$q_data[$i] .= $el_name . ' = ' . $_value;
|
|
$q_values[$i] .= $_value;
|
|
} else {
|
|
// normal data gets escaped
|
|
$q_data[$i] .= $el_name . ' = ' . "'" . $this->dbEscapeString($_value) . "'";
|
|
$q_values[$i] .= "'" . $this->dbEscapeString($_value) . "'";
|
|
}
|
|
}
|
|
}
|
|
} // eche table elements
|
|
// finalize the queries, add FK key reference for inserts and run the query
|
|
for ($i = 0, $i_max = count($type); $i < $i_max; $i++) {
|
|
$q = '';
|
|
// skip empty or not fully filled rows
|
|
if (isset($no_write[$i]) && !$no_write[$i]) {
|
|
if (!isset($q_begin[$i])) {
|
|
$q_begin[$i] = '';
|
|
}
|
|
if (!isset($q_end[$i])) {
|
|
$q_end[$i] = '';
|
|
}
|
|
// if tpye is update
|
|
if (isset($type[$i]) && $type[$i] == 'update') {
|
|
$q = $q_begin[$i]
|
|
. ($q_data[$i] ?? '')
|
|
. $q_end[$i];
|
|
// or if we have block write, then it is insert (new)
|
|
} elseif (isset($block_write[$i]) && $block_write[$i]) {
|
|
$q = $q_begin[$i]
|
|
. ($q_names[$i] ?? '') . ', '
|
|
. $this->int_pk_name
|
|
. ($q_middle[$i] ?? '')
|
|
. ($q_values[$i] ?? '') . ', '
|
|
. $this->table_array[$this->int_pk_name]['value']
|
|
. $q_end[$i];
|
|
}
|
|
/** @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset */
|
|
$this->log->debug('edit', 'Pos[' . $i . '] => ' . $type[$i] . ' Q: ' . $q . '<br>');
|
|
// write the dataset
|
|
if ($q) {
|
|
$this->dbExec($q);
|
|
}
|
|
}
|
|
} // for each created query
|
|
} // each element list
|
|
}
|
|
$this->warning = 1;
|
|
$this->msg = $this->l->__('Dataset has been saved!<Br>');
|
|
}
|
|
|
|
/**
|
|
* delete a table and reference fields
|
|
*
|
|
* @return void
|
|
*/
|
|
public function formDeleteTableArray()
|
|
{
|
|
// remove any reference arrays
|
|
if (is_array($this->reference_array)) {
|
|
if (!is_array($this->reference_array)) {
|
|
$this->reference_array = [];
|
|
}
|
|
reset($this->reference_array);
|
|
foreach ($this->reference_array as $reference_array) {
|
|
$q = 'DELETE FROM ' . $reference_array['table_name']
|
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
$this->dbExec($q);
|
|
}
|
|
}
|
|
// remove any element list references
|
|
if (is_array($this->element_list)) {
|
|
if (!is_array($this->element_list)) {
|
|
$this->element_list = [];
|
|
}
|
|
reset($this->element_list);
|
|
foreach ($this->element_list as $table_name => $data_array) {
|
|
$q = 'DELETE FROM ' . $table_name
|
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
$this->dbExec($q);
|
|
}
|
|
}
|
|
// unlink ALL files
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
if (isset($this->table_array[$key]['type']) && $this->table_array[$key]['type'] == 'file') {
|
|
unlink($this->table_array[$key]['save_dir'] . $this->table_array[$key]['value']);
|
|
}
|
|
}
|
|
$this->dbDelete();
|
|
$this->warning = 1;
|
|
$this->msg = $this->l->__('Dataset has been deleted!');
|
|
}
|
|
|
|
/**
|
|
* creates HTML hidden input fields out of an hash array
|
|
*
|
|
* @param array<mixed> $hidden_array The list of fields to be added as hidden
|
|
* @return array<mixed> key -> value list of hidden fileds data
|
|
*/
|
|
public function formCreateHiddenFields(array $hidden_array = []): array
|
|
{
|
|
$hidden = [];
|
|
if (!is_array($this->table_array)) {
|
|
$this->table_array = [];
|
|
}
|
|
reset($this->table_array);
|
|
foreach ($this->table_array as $key => $value) {
|
|
if (
|
|
isset($this->table_array[$key]['type']) &&
|
|
$this->table_array[$key]['type'] == 'hidden'
|
|
) {
|
|
if (array_key_exists($key, $this->table_array)) {
|
|
$hidden_array[$key] = $this->table_array[$key]['value'] ?? '';
|
|
} else {
|
|
$hidden_array[$key] = '';
|
|
}
|
|
}
|
|
}
|
|
reset($hidden_array);
|
|
foreach ($hidden_array as $key => $value) {
|
|
$hidden[] = ['key' => $key, 'value' => $value];
|
|
}
|
|
return $hidden;
|
|
}
|
|
|
|
/**
|
|
* creates the multiple select part for a reference_table
|
|
*
|
|
* @param string $table_name Table name for reference array lookup
|
|
* @return array<string,mixed> Reference table output array
|
|
*/
|
|
public function formCreateElementReferenceTable(string $table_name): array
|
|
{
|
|
$data = [];
|
|
//
|
|
$show_value = '';
|
|
// set default min edit/read to 100 (admin)
|
|
$min_edit_acl = $this->reference_array[$table_name]['min_edit_acl'] ?? 100;
|
|
$min_show_acl = $this->reference_array[$table_name]['min_show_acl'] ?? 100;
|
|
// output name
|
|
$output_name = $this->reference_array[$table_name]['output_name'];
|
|
// mandatory flag
|
|
if (
|
|
isset($this->reference_array[$table_name]['mandatory']) &&
|
|
$this->reference_array[$table_name]['mandatory']
|
|
) {
|
|
$output_name .= ' *';
|
|
}
|
|
$data['name'] = $this->reference_array[$table_name]['other_table_pk'];
|
|
$data['size'] = $this->reference_array[$table_name]['select_size'];
|
|
while (is_array($res = $this->dbReturn($this->reference_array[$table_name]['query']))) {
|
|
$data['value'][] = $res[0];
|
|
$data['output'][] = $res[1];
|
|
$selected = (\CoreLibs\Convert\Html::checked(
|
|
$this->reference_array[$table_name]['selected'] ?? '',
|
|
$res[0]
|
|
)) ? $res[0] : '';
|
|
$data['selected'][] = $selected;
|
|
if (!empty($selected)) {
|
|
if (!empty($show_value)) {
|
|
$show_value .= ", ";
|
|
}
|
|
$show_value .= $res[1];
|
|
}
|
|
}
|
|
$type = 'reference_table';
|
|
return [
|
|
'output_name' => $output_name,
|
|
'type' => $type,
|
|
'color' => 'edit_fgcolor',
|
|
'data' => $data,
|
|
'show_value' => empty($show_value) ? '-' : $show_value,
|
|
'allow_edit' => $this->base_acl_level >= $min_edit_acl ? 1 : 0,
|
|
'allow_show' => $this->base_acl_level >= $min_show_acl ? 1 : 0,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* create list of elements next to each other for a group of data in an input field
|
|
* this currently only works for a list that is filled from a sub table and creates
|
|
* only a connection to this one new version will allow a sub list with free input
|
|
* fields to directly fill a sub table to a master table
|
|
*
|
|
* @param string $table_name Which element entry to create
|
|
* @return array<string,mixed> Element for html creation
|
|
*/
|
|
public function formCreateElementListTable(string $table_name): array
|
|
{
|
|
// init data rray
|
|
$data = [
|
|
'delete_name' => '',
|
|
'delete' => 0,
|
|
'enable_name' => '',
|
|
'prefix' => '',
|
|
'pk_name' => '',
|
|
'fk_name' => '',
|
|
'type' => [],
|
|
'output_name' => [],
|
|
'preset' => [],
|
|
'element_list' => [],
|
|
'output_data' => [],
|
|
'content' => [],
|
|
'pos' => [],
|
|
'table_name' => $table_name // sub table name
|
|
];
|
|
$show_value = '-';
|
|
// set default min edit/read to 100 (admin)
|
|
$min_edit_acl = $this->element_list[$table_name]['min_edit_acl'] ?? 100;
|
|
$min_show_acl = $this->element_list[$table_name]['min_show_acl'] ?? 100;
|
|
// output name for the viewable left table td box, prefixed with * if mandatory
|
|
$output_name = $this->element_list[$table_name]['output_name'];
|
|
// mandatory flag
|
|
if (
|
|
isset($this->element_list[$table_name]['mandatory']) &&
|
|
$this->element_list[$table_name]['mandatory']
|
|
) {
|
|
$output_name .= ' *';
|
|
}
|
|
// delete button name, if there is one set
|
|
if (isset($this->element_list[$table_name]['delete_name'])) {
|
|
$data['delete_name'] = $this->element_list[$table_name]['delete_name'];
|
|
}
|
|
// set the enable checkbox for delete, if the delete flag is given if there is one
|
|
if (isset($this->element_list[$table_name]['enable_name'])) {
|
|
$data['enable_name'] = $this->element_list[$table_name]['enable_name'];
|
|
if (isset($this->element_list[$table_name]['delete'])) {
|
|
$data['delete'] = 1;
|
|
}
|
|
}
|
|
// prefix for the elements, to not collide with names in the master set
|
|
if (isset($this->element_list[$table_name]['prefix'])) {
|
|
$data['prefix'] = $this->element_list[$table_name]['prefix'] . '_';
|
|
}
|
|
|
|
// build the select part
|
|
if (
|
|
!isset($this->element_list[$table_name]['elements']) ||
|
|
!is_array($this->element_list[$table_name]['elements'])
|
|
) {
|
|
$this->element_list[$table_name]['elements'] = [];
|
|
}
|
|
reset($this->element_list[$table_name]['elements']);
|
|
// generic data read in (counts for all rows)
|
|
// visible list data output
|
|
$q_select = [];
|
|
$proto = [];
|
|
foreach ($this->element_list[$table_name]['elements'] as $el_name => $data_array) {
|
|
// $this->log->debug('CFG', 'El: ' . $el_name . ' -> ' . $this->log->prAr($data_array));
|
|
// if the element name matches the read array, then set the table as a name prefix
|
|
// this is for reading the data
|
|
$q_select[] = $el_name;
|
|
// prefix the name for any further data parts
|
|
$el_name = $data['prefix'] . $el_name;
|
|
// this are the output names (if given)
|
|
$data['output_name'][$el_name] = $data_array['output_name'] ?? '';
|
|
// this is the type of the field
|
|
$data['type'][$el_name] = $data_array['type'] ?? '';
|
|
// set the primary key name
|
|
if (isset($data_array['pk_id'])) {
|
|
$data['pk_name'] = $el_name;
|
|
}
|
|
if (isset($data_array['fk_id'])) {
|
|
$data['fk_name'] = $el_name;
|
|
}
|
|
// if drop down db read data for element list from the given sub table as from the query
|
|
// only two elements are allowed: pos 0 is key, pso 1 is visible output name
|
|
if (isset($data_array['type']) && $data_array['type'] == 'drop_down_db') {
|
|
while (is_array($res = $this->dbReturn($data_array['query']))) {
|
|
/** @phan-suppress-next-line PhanTypeInvalidDimOffset */
|
|
$this->log->debug('edit', 'Q[' . $this->dbGetQueryHash($data_array['query']) . '] pos: '
|
|
. $this->dbGetCursorPos($data_array['query'])
|
|
. ' | want: ' . ($data_array['preset'] ?? '-')
|
|
. ' | set: ' . ($data['preset'][$el_name] ?? '-'));
|
|
// first is default for this element
|
|
if (
|
|
isset($data_array['preset']) &&
|
|
(!isset($data['preset'][$el_name]) || empty($data['preset'][$el_name])) &&
|
|
($this->dbGetCursorPos($data_array['query']) == $data_array['preset'])
|
|
) {
|
|
$data['preset'][$el_name] = $res[0];
|
|
}
|
|
// split up data, 0 is id, 1 name
|
|
$data['element_list'][$el_name][] = $res[0];
|
|
$data['output_data'][$el_name][] = $res[1];
|
|
}
|
|
} elseif (isset($data_array['element_list'])) {
|
|
$data['element_list'][$el_name] = $data_array['element_list']; // this is for the checkboxes
|
|
}
|
|
$this->log->debug('CREATE ELEMENT LIST TABLE', 'Table: ' . $table_name . ', Post: ' . $el_name . ' => '
|
|
. ((isset($_POST[$el_name]) && is_array($_POST[$el_name])) ?
|
|
'AS ARRAY'/*.$this->log->prAr($_POST[$el_name])*/ :
|
|
'NOT SET/OR NOT ARRAY')
|
|
. ((isset($_POST[$el_name]) && !is_array($_POST[$el_name])) ? $_POST[$el_name] : ''));
|
|
// if error, check new line addition so we don't lose it
|
|
if ($this->error) {
|
|
if (isset($_POST[$el_name]) && is_array($_POST[$el_name])) {
|
|
// this is for the new line
|
|
$proto[$el_name] = $_POST[$el_name][(count($_POST[$el_name]) - 1)] ?? 0;
|
|
} else {
|
|
$proto[$el_name] = 0;
|
|
}
|
|
} else {
|
|
$proto[$el_name] = '';
|
|
}
|
|
// $proto[$el_name] = $this->error ? $_POST[$el_name][(count($_POST[$el_name]) - 1)] : '';
|
|
}
|
|
// $this->log->debug('CFG DATA', 'Data: ' . $this->log->prAr($data));
|
|
// $this->log->debug('CFG PROTO', 'Proto: ' . $this->log->prAr($proto));
|
|
// $this->log->debug('CFG SELECT', 'Proto: ' . $this->log->prAr($q_select));
|
|
// query for reading in the data
|
|
$this->log->debug('edit_error', 'ERR: ' . $this->error);
|
|
// if we got a read data, build the read select for the read, and read out the 'selected'
|
|
/** @phan-assert array $this->element_list[$table_name]['read_data'] */
|
|
if (isset($this->element_list[$table_name]['read_data'])) {
|
|
// we need a second one for the query build only
|
|
// prefix all elements with the $table name
|
|
$_q_select = [];
|
|
foreach ($q_select as $_pos => $element) {
|
|
$_q_select[$_pos] = $table_name . '.' . $element;
|
|
}
|
|
// set if missing
|
|
if (!isset($this->element_list[$table_name]['read_data']['pk_id'])) {
|
|
$this->element_list[$table_name]['read_data']['pk_id'] = '';
|
|
}
|
|
if (!isset($this->element_list[$table_name]['read_data']['name'])) {
|
|
$this->element_list[$table_name]['read_data']['name'] = '';
|
|
}
|
|
if (!isset($this->element_list[$table_name]['read_data']['table_name'])) {
|
|
$this->element_list[$table_name]['read_data']['table_name'] = '';
|
|
}
|
|
// add the read names in here, prefix them with the table name
|
|
// earch to read part is split by |
|
|
if (!empty($this->element_list[$table_name]['read_data']['name'])) {
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
foreach (explode('|', $this->element_list[$table_name]['read_data']['name']) as $read_name) {
|
|
array_unshift(
|
|
$_q_select,
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$this->element_list[$table_name]['read_data']['table_name']
|
|
. '.' . $read_name
|
|
);
|
|
array_unshift($q_select, $read_name);
|
|
}
|
|
}
|
|
// @phan HACK
|
|
$data['prefix'] = $data['prefix'];
|
|
// set the rest of the data so we can print something out
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$data['type'][$data['prefix'] . $this->element_list[$table_name]['read_data']['name']] = 'string';
|
|
// build the read query
|
|
$q = 'SELECT ';
|
|
// if (!$this->table_array[$this->int_pk_name]['value'])
|
|
// $q .= 'DISTINCT ';
|
|
// prefix join key with table name, and implode the query select part
|
|
$q .= str_replace(
|
|
$table_name . '.'
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. $this->element_list[$table_name]['read_data']['pk_id'],
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$this->element_list[$table_name]['read_data']['table_name']
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. '.' . $this->element_list[$table_name]['read_data']['pk_id'],
|
|
implode(', ', $_q_select)
|
|
) . ' ';
|
|
// if (
|
|
// !$this->table_array[$this->int_pk_name]['value'] &&
|
|
// $this->element_list[$table_name]['read_data']['order']
|
|
// ) {
|
|
// $q .= ', ' . $this->element_list[$table_name]['read_data']['order'] . ' ';
|
|
// read from the read table as main, and left join to the sub table to read the actual data
|
|
// }
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$q .= 'FROM ' . $this->element_list[$table_name]['read_data']['table_name'] . ' ';
|
|
$q .= 'LEFT JOIN ' . $table_name . ' ';
|
|
$q .= 'ON (';
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
$q .= $this->element_list[$table_name]['read_data']['table_name'] . '.'
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. $this->element_list[$table_name]['read_data']['pk_id'] . ' = '
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. $table_name . '.' . $this->element_list[$table_name]['read_data']['pk_id'] . ' ';
|
|
// if ($this->table_array[$this->int_pk_name]['value'])
|
|
$q .= 'AND ' . $table_name . '.' . $this->int_pk_name . ' = '
|
|
. (!empty($this->table_array[$this->int_pk_name]['value']) ?
|
|
$this->table_array[$this->int_pk_name]['value'] :
|
|
'NULL') . ' ';
|
|
$q .= ') ';
|
|
if (isset($this->element_list[$table_name]['read_data']['order'])) {
|
|
$q .= ' ORDER BY '
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. $this->element_list[$table_name]['read_data']['table_name']
|
|
/** @phan-suppress-next-line PhanTypeArraySuspiciousNullable */
|
|
. '.' . $this->element_list[$table_name]['read_data']['order'];
|
|
}
|
|
} else {
|
|
// only create query if we have a primary key
|
|
// reads directly from the reference table
|
|
if (
|
|
isset($this->table_array[$this->int_pk_name]['value']) &&
|
|
$this->table_array[$this->int_pk_name]['value']
|
|
) {
|
|
$q = 'SELECT ' . implode(', ', $q_select)
|
|
. ' FROM ' . $table_name
|
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->table_array[$this->int_pk_name]['value'];
|
|
}
|
|
}
|
|
// $this->log->debug('CFG QUERY', 'Q: ' . $q);
|
|
// only run if we have query strnig
|
|
$written_pos = [];
|
|
if (isset($q)) {
|
|
$prfx = $data['prefix']; // short
|
|
$pos = 0; // position in while for overwrite if needed
|
|
// read out the list and add the selected data if needed
|
|
while (is_array($res = $this->dbReturn($q))) {
|
|
$_data = [];
|
|
// go through each res
|
|
for ($i = 0, $i_max = count($q_select); $i < $i_max; $i++) {
|
|
// query select part, set to the element name
|
|
$el_name = $q_select[$i];
|
|
// $this->log->debug('edit_error', '[$i] ELNAME: $el_name | POS[$prfx$el_name]: '
|
|
// . $_POST[$prfx . $el_name][$pos] . ' | RES: ' . $res[$el_name]);
|
|
// if we have an error, we take what we have in the vars, if not we take the data from the db
|
|
if ($this->error) {
|
|
// if we have a radio group, set a bit different
|
|
if (
|
|
isset($data['element_list'][$prfx . $el_name]) &&
|
|
$data['element_list'][$prfx . $el_name] == 'radio_group'
|
|
) {
|
|
$_data[$prfx . $el_name] = ($res[$el_name]) ? ($res[$el_name] - 1) : 0;
|
|
} elseif (isset($_POST[$prfx . $el_name][$pos])) {
|
|
$_data[$prfx . $el_name] = $_POST[$prfx . $el_name][$pos];
|
|
} else {
|
|
$_data[$prfx . $el_name] = '';
|
|
}
|
|
} else {
|
|
if (isset($data['preset'][$prfx . $el_name]) && !isset($res[$el_name])) {
|
|
$_data[$prfx . $el_name] = $data['preset'][$prfx . $el_name];
|
|
} else {
|
|
$_data[$prfx . $el_name] = $res[$el_name];
|
|
}
|
|
}
|
|
}
|
|
$data['content'][] = $_data;
|
|
$data['pos'][] = [0 => $pos]; // this is for the checkboxes
|
|
$written_pos[] = $pos;
|
|
$pos++; // move up one
|
|
// reset and unset before next run
|
|
unset($_data);
|
|
}
|
|
}
|
|
// add lost error ones
|
|
$this->log->error('P: ' . $data['prefix'] . ', '
|
|
. Support::prAr($_POST['ERROR'][$data['prefix']] ?? []));
|
|
if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) {
|
|
$prfx = $data['prefix']; // short
|
|
$_post_data = [];
|
|
// MAX entries defined via $data['pk_name'] entry (must exist)
|
|
$_max_pos = count($_POST[$data['pk_name']] ?? []);
|
|
// write all excte previous loaded @ $pos
|
|
foreach ($q_select as $_el_name) {
|
|
for ($_pos = 0; $_pos <= $_max_pos; $_pos++) {
|
|
// if not in data pos
|
|
if (!in_array($_pos, $written_pos)) {
|
|
$_post_data[$_pos][$prfx . $_el_name] =
|
|
$_POST[$prfx . $_el_name][$_pos] ?? '';
|
|
}
|
|
}
|
|
}
|
|
// only add if all fields in data are filled, else skip
|
|
// pk_name field is excluded of check
|
|
foreach ($_post_data as $_pos => $_data) {
|
|
$filled = false;
|
|
foreach ($_data as $_name => $_value) {
|
|
if ($_name != $data['pk_name'] && !empty($_value)) {
|
|
$filled = true;
|
|
}
|
|
}
|
|
if ($filled == true) {
|
|
$data['content'][] = $_data;
|
|
$data['pos'][] = [0 => $_pos];
|
|
}
|
|
}
|
|
}
|
|
// if this is normal single reference data check the content on the element count
|
|
// if there is a max_empty is set, then fill up new elements (unfilled)
|
|
// until we reach max empty
|
|
if (
|
|
/*isset($this->element_list[$table_name]['type']) &&
|
|
$this->element_list[$table_name]['type'] == 'reference_data' &&*/
|
|
isset($this->element_list[$table_name]['max_empty']) &&
|
|
is_numeric($this->element_list[$table_name]['max_empty']) &&
|
|
$this->element_list[$table_name]['max_empty'] > 0
|
|
) {
|
|
// if the max empty is bigger than 10, just cut it to ten at the moment
|
|
if ($this->element_list[$table_name]['max_empty'] > 10) {
|
|
$this->element_list[$table_name]['max_empty'] = 10;
|
|
}
|
|
// check if we need to fill fields
|
|
$element_count = count($data['content']);
|
|
$missing_empty_count = $this->element_list[$table_name]['max_empty'] - $element_count;
|
|
$this->log->debug('CFG MAX', 'Max empty: '
|
|
. $this->element_list[$table_name]['max_empty'] . ', Missing: ' . $missing_empty_count
|
|
. ', Has: ' . $element_count);
|
|
// set if we need more open entries or if we do not have any entries yet
|
|
if (
|
|
($missing_empty_count < $this->element_list[$table_name]['max_empty']) ||
|
|
$element_count == 0
|
|
) {
|
|
for (
|
|
$pos = $element_count,
|
|
$pos_max = $this->element_list[$table_name]['max_empty'] + $element_count;
|
|
$pos <= $pos_max;
|
|
$pos++
|
|
) {
|
|
$_data = [];
|
|
// the fields that need to be filled are in data->type array:
|
|
// pk fields are unfilled
|
|
// fk fields are filled with the fk_id 'int_pk_name' value
|
|
foreach ($data['type'] as $el_name => $type) {
|
|
$_data[$el_name] = '';
|
|
if (
|
|
!empty($data['pk_name']) &&
|
|
$el_name == $data['pk_name']
|
|
) {
|
|
// do nothing for pk name
|
|
} elseif (
|
|
!empty($data['fk_name']) &&
|
|
$el_name == $data['fk_name'] &&
|
|
isset($this->table_array[$this->int_pk_name]['value'])
|
|
) {
|
|
$_data[$el_name] = $this->table_array[$this->int_pk_name]['value'];
|
|
}
|
|
}
|
|
$data['content'][] = $_data;
|
|
// this is for the checkboxes
|
|
$data['pos'][] = [
|
|
0 => $pos
|
|
];
|
|
$this->log->debug('CFG ELEMENT LIST FILL', 'Pos: ' . $pos . '/'
|
|
. $pos_max . ', Content: ' . count($data['content']) . ', Pos: ' . count($data['pos']));
|
|
}
|
|
}
|
|
}
|
|
|
|
// push in an empty line of this type, but only if we have a delete key that is also filled
|
|
if (!empty($data['delete_name'])) {
|
|
$data['content'][] = $proto;
|
|
// we also need the pos add or we through an error in smarty
|
|
$data['pos'][] = [
|
|
0 => count($data['pos'])
|
|
];
|
|
}
|
|
// $this->log->debug('CFG ELEMENT LIST FILL', 'Data array: ' . $this->log->prAr($data));
|
|
$type = 'element_list';
|
|
return [
|
|
'output_name' => $output_name,
|
|
'type' => $type,
|
|
'color' => 'edit_fgcolor',
|
|
'data' => $data,
|
|
'show_value' => $show_value,
|
|
'allow_edit' => $this->base_acl_level >= $min_edit_acl ? 1 : 0,
|
|
'allow_show' => $this->base_acl_level >= $min_show_acl ? 1 : 0,
|
|
];
|
|
}
|
|
// end of class
|
|
}
|
|
|
|
// __END__
|