Compare commits

...

7 Commits

Author SHA1 Message Date
Clemens Schwaighofer
605ea06bf0 Add additional_acl column to edit_access table
To be able to have special ACL (json) for edit edit access table too
2019-09-03 09:39:12 +09:00
Clemens Schwaighofer
9ec19f5940 Add list ACR, select update for html options JS, array methods in Basic
* ACR list has new list at level 10 for listing but not reading/opening
* JS update for the html options create
if select multi allow selected as array for highlight
* Basic Class
- array merge recursive implementation
proper implementation that proper merges nested arrays. With key is
always string override
- array flat per key
For multi arrays flatten down a key -> value entry to set the value to
the level up in the leaf
eg:
foo -> bar -> KEY: value
and you go by KEY as search it will change to
foo -> bar: value
2019-08-30 13:02:02 +09:00
Clemens Schwaighofer
a27e4603a8 Add deleted to edit_group/user decl, add assoc only return for fetchrow
DB IO Fetchrow has assoc only true/false
Currently only tested with PgSQL

default returns both,
if set true only returns assoc
2019-08-28 18:49:23 +09:00
Clemens Schwaighofer
54b7af348b Add fix for DB Array IO json error_check type field storage on empty save 2019-08-27 16:01:29 +09:00
Clemens Schwaighofer
c5d624a318 Add Additional ACL jsonb field to edit_pages table 2019-08-27 15:15:40 +09:00
Clemens Schwaighofer
47ffec1fd4 Add JSON additional ACL field to edit user page 2019-08-26 11:18:21 +09:00
Clemens Schwaighofer
72c6844e74 Jquery update to 3.4.1 2019-07-31 17:59:13 +09:00
20 changed files with 231 additions and 56 deletions

View File

@@ -51,6 +51,7 @@ INSERT INTO edit_page_menu_group VALUES ((SELECT edit_page_id FROM edit_page WHE
DELETE FROM edit_access_right; DELETE FROM edit_access_right;
INSERT INTO edit_access_right (name, level, type) VALUES ('Default', -1, 'default'); INSERT INTO edit_access_right (name, level, type) VALUES ('Default', -1, 'default');
INSERT INTO edit_access_right (name, level, type) VALUES ('No Access', 0, 'none'); INSERT INTO edit_access_right (name, level, type) VALUES ('No Access', 0, 'none');
INSERT INTO edit_access_right (name, level, type) VALUES ('List', 10, 'list');
INSERT INTO edit_access_right (name, level, type) VALUES ('Read', 20, 'read'); INSERT INTO edit_access_right (name, level, type) VALUES ('Read', 20, 'read');
INSERT INTO edit_access_right (name, level, type) VALUES ('Translator', 30, 'mod_trans'); INSERT INTO edit_access_right (name, level, type) VALUES ('Translator', 30, 'mod_trans');
INSERT INTO edit_access_right (name, level, type) VALUES ('Modify', 40, 'mod'); INSERT INTO edit_access_right (name, level, type) VALUES ('Modify', 40, 'mod');

View File

@@ -14,5 +14,6 @@ CREATE TABLE edit_access (
uid VARCHAR, uid VARCHAR,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
protected INT, protected INT,
deleted SMALLINT DEFAULT 0 deleted SMALLINT DEFAULT 0,
additional_acl JSONB
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

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

View File

@@ -16,6 +16,7 @@ CREATE TABLE edit_user (
first_name_furigana VARCHAR, first_name_furigana VARCHAR,
last_name_furigana VARCHAR, last_name_furigana VARCHAR,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
deleted SMALLINT NOT NULL DEFAULT 0,
debug SMALLINT NOT NULL DEFAULT 0, debug SMALLINT NOT NULL DEFAULT 0,
db_debug SMALLINT NOT NULL DEFAULT 0, db_debug SMALLINT NOT NULL DEFAULT 0,
email VARCHAR, email VARCHAR,
@@ -32,6 +33,7 @@ CREATE TABLE edit_user (
locked SMALLINT DEFAULT 0, locked SMALLINT DEFAULT 0,
password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed
password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval
additional_acl JSONB, -- additional ACL as JSON string (can be set by other pages)
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,

View File

@@ -340,6 +340,7 @@ if ($form->my_page_name == 'edit_order') {
$elements[] = $form->formCreateElement("edit_language_id"); $elements[] = $form->formCreateElement("edit_language_id");
$elements[] = $form->formCreateElement("edit_scheme_id"); $elements[] = $form->formCreateElement("edit_scheme_id");
$elements[] = $form->formCreateElementListTable("edit_access_user"); $elements[] = $form->formCreateElementListTable("edit_access_user");
$elements[] = $form->formCreateElement("additional_acl");
break; break;
case "edit_schemes": case "edit_schemes":
$elements[] = $form->formCreateElement("enabled"); $elements[] = $form->formCreateElement("enabled");
@@ -391,6 +392,7 @@ if ($form->my_page_name == 'edit_order') {
$elements[] = $form->formCreateElement("edit_access_right_id"); $elements[] = $form->formCreateElement("edit_access_right_id");
$elements[] = $form->formCreateElement("edit_scheme_id"); $elements[] = $form->formCreateElement("edit_scheme_id");
$elements[] = $form->formCreateElementListTable("edit_page_access"); $elements[] = $form->formCreateElementListTable("edit_page_access");
$elements[] = $form->formCreateElement("additional_acl");
break; break;
case "edit_visible_group": case "edit_visible_group":
$elements[] = $form->formCreateElement("name"); $elements[] = $form->formCreateElement("name");
@@ -409,6 +411,7 @@ if ($form->my_page_name == 'edit_order') {
$elements[] = $form->formCreateElement("description"); $elements[] = $form->formCreateElement("description");
// add name/value list here // add name/value list here
$elements[] = $form->formCreateElementListTable("edit_access_data"); $elements[] = $form->formCreateElementListTable("edit_access_data");
$elements[] = $form->formCreateElement("additional_acl");
break; break;
default: default:
print "[No valid page definition given]"; print "[No valid page definition given]";

View File

@@ -49,7 +49,15 @@ $edit_access = array (
"1" => "Yes", "1" => "Yes",
"0" => "No" "0" => "No"
) )
) ),
"additional_acl" => array (
"value" => $GLOBALS["additional_acl"],
"output_name" => "Additional ACL (as JSON)",
"type" => "textarea",
"error_check" => "json",
"rows" => 10,
"cols" => 60
),
), ),
"table_name" => "edit_access", "table_name" => "edit_access",
"load_query" => "SELECT edit_access_id, name FROM edit_access ORDER BY name", "load_query" => "SELECT edit_access_id, name FROM edit_access ORDER BY name",

View File

@@ -37,7 +37,15 @@ $edit_groups = array (
"int_null" => 1, "int_null" => 1,
"type" => "drop_down_db", "type" => "drop_down_db",
"query" => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name" "query" => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name"
) ),
"additional_acl" => array (
"value" => $GLOBALS["additional_acl"],
"output_name" => "Additional ACL (as JSON)",
"type" => "textarea",
"error_check" => "json",
"rows" => 10,
"cols" => 60
),
), ),
"load_query" => "SELECT edit_group_id, name, enabled FROM edit_group ORDER BY name", "load_query" => "SELECT edit_group_id, name, enabled FROM edit_group ORDER BY name",
"table_name" => "edit_group", "table_name" => "edit_group",

View File

@@ -103,7 +103,8 @@ $edit_users = array (
"email" => array ( "email" => array (
"value" => $GLOBALS["email"], "value" => $GLOBALS["email"],
"output_name" => "E-Mail", "output_name" => "E-Mail",
"type" => "text" "type" => "text",
"error_check" => "email"
), ),
"last_name" => array ( "last_name" => array (
"value" => $GLOBALS["last_name"], "value" => $GLOBALS["last_name"],
@@ -173,7 +174,15 @@ $edit_users = array (
"1" => "Yes", "1" => "Yes",
"0" => "No" "0" => "No"
) )
) ),
"additional_acl" => array (
"value" => $GLOBALS["additional_acl"],
"output_name" => "Additional ACL (as JSON)",
"type" => "textarea",
"error_check" => "json",
"rows" => 10,
"cols" => 60
),
), ),
"load_query" => "SELECT edit_user_id, username, enabled, debug, db_debug, strict, locked, login_error_count FROM edit_user ORDER BY username", "load_query" => "SELECT edit_user_id, username, enabled, debug, db_debug, strict, locked, login_error_count FROM edit_user ORDER BY username",
"table_name" => "edit_user", "table_name" => "edit_user",

View File

@@ -605,15 +605,16 @@ function html_options(name, data, selected = '', options_only = false, return_st
// NOTE : USE THIS CALL, the above one is deprecated // NOTE : USE THIS CALL, the above one is deprecated
// METHOD: html_options // METHOD: html_options
// PARAMS: name/id, array for the options, // PARAMS: name/id, array for the options,
// selected item uid // selected item uid [drop down string, multi select array]
// multiple [def false] if this is true, the drop down will be turned into multiple select // multiple [def 0] if this is 1 or larger, the drop down will be turned into multiple select
// the number sets the size value unless it is 1, then it is default
// options_only [def false] if this is true, it will not print the select part // options_only [def false] if this is true, it will not print the select part
// return_string [def false]: return as string and not as element // return_string [def false]: return as string and not as element
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored // sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
// RETURN: html with build options block // RETURN: html with build options block
// DESC : creates an select/options drop down block. // DESC : creates an select/options drop down block.
// the array needs to be key -> value format. key is for the option id and value is for the data output // the array needs to be key -> value format. key is for the option id and value is for the data output
function html_options_block(name, data, selected = '', multiple = false, options_only = false, return_string = false, sort = '') function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '')
{ {
var content = []; var content = [];
var element_select; var element_select;
@@ -622,8 +623,11 @@ function html_options_block(name, data, selected = '', multiple = false, options
var data_list = []; // for sorted output var data_list = []; // for sorted output
var value; var value;
var option; var option;
if (multiple === true) { if (multiple > 0) {
select_options.multiple = ''; select_options.multiple = '';
if (multiple > 1) {
select_options.size = multiple;
}
} }
// set outside select, gets stripped on return if options only is true // set outside select, gets stripped on return if options only is true
element_select = cel('select', name, '', [], select_options); element_select = cel('select', name, '', [], select_options);
@@ -640,14 +644,18 @@ function html_options_block(name, data, selected = '', multiple = false, options
// for (const [key, value] of Object.entries(data)) { // for (const [key, value] of Object.entries(data)) {
for (const key of data_list) { for (const key of data_list) {
value = data[key]; value = data[key];
console.log('create [%s] options: key: %s, value: %s', name, key, value); // console.log('create [%s] options: key: %s, value: %s', name, key, value);
// basic options init // basic options init
options = { options = {
'label': value, 'label': value,
'value': key 'value': key
}; };
// add selected if matching // add selected if matching
if (selected == key) { if (multiple == 0 && !Array.isArray(selected) && selected == key) {
options.selected = '';
}
// for multiple, we match selected as array
if (multiple == 1 && Array.isArray(selected) && selected.indexOf(key) != -1) {
options.selected = ''; options.selected = '';
} }
// create the element option // create the element option

View File

@@ -683,15 +683,16 @@ function html_options(name, data, selected = '', options_only = false, return_st
// NOTE : USE THIS CALL, the above one is deprecated // NOTE : USE THIS CALL, the above one is deprecated
// METHOD: html_options // METHOD: html_options
// PARAMS: name/id, array for the options, // PARAMS: name/id, array for the options,
// selected item uid // selected item uid [drop down string, multi select array]
// multiple [def false] if this is true, the drop down will be turned into multiple select // multiple [def 0] if this is 1 or larger, the drop down will be turned into multiple select
// the number sets the size value unless it is 1, then it is default
// options_only [def false] if this is true, it will not print the select part // options_only [def false] if this is true, it will not print the select part
// return_string [def false]: return as string and not as element // return_string [def false]: return as string and not as element
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored // sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
// RETURN: html with build options block // RETURN: html with build options block
// DESC : creates an select/options drop down block. // DESC : creates an select/options drop down block.
// the array needs to be key -> value format. key is for the option id and value is for the data output // the array needs to be key -> value format. key is for the option id and value is for the data output
function html_options_block(name, data, selected = '', multiple = false, options_only = false, return_string = false, sort = '') function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '')
{ {
var content = []; var content = [];
var element_select; var element_select;
@@ -700,8 +701,11 @@ function html_options_block(name, data, selected = '', multiple = false, options
var data_list = []; // for sorted output var data_list = []; // for sorted output
var value; var value;
var option; var option;
if (multiple === true) { if (multiple > 0) {
select_options.multiple = ''; select_options.multiple = '';
if (multiple > 1) {
select_options.size = multiple;
}
} }
// set outside select, gets stripped on return if options only is true // set outside select, gets stripped on return if options only is true
element_select = cel('select', name, '', [], select_options); element_select = cel('select', name, '', [], select_options);
@@ -718,14 +722,18 @@ function html_options_block(name, data, selected = '', multiple = false, options
// for (const [key, value] of Object.entries(data)) { // for (const [key, value] of Object.entries(data)) {
for (const key of data_list) { for (const key of data_list) {
value = data[key]; value = data[key];
console.log('create [%s] options: key: %s, value: %s', name, key, value); // console.log('create [%s] options: key: %s, value: %s', name, key, value);
// basic options init // basic options init
options = { options = {
'label': value, 'label': value,
'value': key 'value': key
}; };
// add selected if matching // add selected if matching
if (selected == key) { if (multiple == 0 && !Array.isArray(selected) && selected == key) {
options.selected = '';
}
// for multiple, we match selected as array
if (multiple == 1 && Array.isArray(selected) && selected.indexOf(key) != -1) {
options.selected = ''; options.selected = '';
} }
// create the element option // create the element option

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/*! /*!
* jQuery JavaScript Library v3.4.0 * jQuery JavaScript Library v3.4.1
* https://jquery.com/ * https://jquery.com/
* *
* Includes Sizzle.js * Includes Sizzle.js
@@ -9,7 +9,7 @@
* Released under the MIT license * Released under the MIT license
* https://jquery.org/license * https://jquery.org/license
* *
* Date: 2019-04-10T19:48Z * Date: 2019-05-01T21:04Z
*/ */
( function( global, factory ) { ( function( global, factory ) {
@@ -142,7 +142,7 @@ function toType( obj ) {
var var
version = "3.4.0", version = "3.4.1",
// Define a local copy of jQuery // Define a local copy of jQuery
jQuery = function( selector, context ) { jQuery = function( selector, context ) {
@@ -4498,8 +4498,12 @@ var documentElement = document.documentElement;
}, },
composed = { composed: true }; composed = { composed: true };
// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
// Check attachment across shadow DOM boundaries when possible (gh-3504) // Check attachment across shadow DOM boundaries when possible (gh-3504)
if ( documentElement.attachShadow ) { // Support: iOS 10.0-10.2 only
// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
// leading to errors. We need to check for `getRootNode`.
if ( documentElement.getRootNode ) {
isAttached = function( elem ) { isAttached = function( elem ) {
return jQuery.contains( elem.ownerDocument, elem ) || return jQuery.contains( elem.ownerDocument, elem ) ||
elem.getRootNode( composed ) === elem.ownerDocument; elem.getRootNode( composed ) === elem.ownerDocument;
@@ -5359,8 +5363,7 @@ jQuery.event = {
// Claim the first handler // Claim the first handler
if ( rcheckableType.test( el.type ) && if ( rcheckableType.test( el.type ) &&
el.click && nodeName( el, "input" ) && el.click && nodeName( el, "input" ) ) {
dataPriv.get( el, "click" ) === undefined ) {
// dataPriv.set( el, "click", ... ) // dataPriv.set( el, "click", ... )
leverageNative( el, "click", returnTrue ); leverageNative( el, "click", returnTrue );
@@ -5377,8 +5380,7 @@ jQuery.event = {
// Force setup before triggering a click // Force setup before triggering a click
if ( rcheckableType.test( el.type ) && if ( rcheckableType.test( el.type ) &&
el.click && nodeName( el, "input" ) && el.click && nodeName( el, "input" ) ) {
dataPriv.get( el, "click" ) === undefined ) {
leverageNative( el, "click" ); leverageNative( el, "click" );
} }
@@ -5419,7 +5421,9 @@ function leverageNative( el, type, expectSync ) {
// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
if ( !expectSync ) { if ( !expectSync ) {
jQuery.event.add( el, type, returnTrue ); if ( dataPriv.get( el, type ) === undefined ) {
jQuery.event.add( el, type, returnTrue );
}
return; return;
} }
@@ -5434,9 +5438,13 @@ function leverageNative( el, type, expectSync ) {
if ( ( event.isTrigger & 1 ) && this[ type ] ) { if ( ( event.isTrigger & 1 ) && this[ type ] ) {
// Interrupt processing of the outer synthetic .trigger()ed event // Interrupt processing of the outer synthetic .trigger()ed event
if ( !saved ) { // Saved data should be false in such cases, but might be a leftover capture object
// from an async native handler (gh-4350)
if ( !saved.length ) {
// Store arguments for use when handling the inner native event // Store arguments for use when handling the inner native event
// There will always be at least one argument (an event object), so this array
// will not be confused with a leftover capture object.
saved = slice.call( arguments ); saved = slice.call( arguments );
dataPriv.set( this, type, saved ); dataPriv.set( this, type, saved );
@@ -5449,14 +5457,14 @@ function leverageNative( el, type, expectSync ) {
if ( saved !== result || notAsync ) { if ( saved !== result || notAsync ) {
dataPriv.set( this, type, false ); dataPriv.set( this, type, false );
} else { } else {
result = undefined; result = {};
} }
if ( saved !== result ) { if ( saved !== result ) {
// Cancel the outer synthetic event // Cancel the outer synthetic event
event.stopImmediatePropagation(); event.stopImmediatePropagation();
event.preventDefault(); event.preventDefault();
return result; return result.value;
} }
// If this is an inner synthetic event for an event with a bubbling surrogate // If this is an inner synthetic event for an event with a bubbling surrogate
@@ -5471,17 +5479,19 @@ function leverageNative( el, type, expectSync ) {
// If this is a native event triggered above, everything is now in order // If this is a native event triggered above, everything is now in order
// Fire an inner synthetic event with the original arguments // Fire an inner synthetic event with the original arguments
} else if ( saved ) { } else if ( saved.length ) {
// ...and capture the result // ...and capture the result
dataPriv.set( this, type, jQuery.event.trigger( dataPriv.set( this, type, {
value: jQuery.event.trigger(
// Support: IE <=9 - 11+ // Support: IE <=9 - 11+
// Extend with the prototype to reset the above stopImmediatePropagation() // Extend with the prototype to reset the above stopImmediatePropagation()
jQuery.extend( saved.shift(), jQuery.Event.prototype ), jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
saved, saved.slice( 1 ),
this this
) ); )
} );
// Abort handling of the native event // Abort handling of the native event
event.stopImmediatePropagation(); event.stopImmediatePropagation();

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
jquery-3.4.0.js jquery-3.4.1.js

View File

@@ -1 +1 @@
jquery-3.4.0.min.js jquery-3.4.1.min.js

View File

@@ -442,7 +442,7 @@ class Basic
// on second call it sends the end time and then also prints the running time // on second call it sends the end time and then also prints the running time
public function runningTime($simple = false) public function runningTime($simple = false)
{ {
list($micro, $timestamp) = explode(" ", microtime()); list($micro, $timestamp) = explode(' ', microtime());
$string = ''; $string = '';
$running_time = ''; $running_time = '';
if (!$this->starttime) { if (!$this->starttime) {
@@ -1088,6 +1088,84 @@ class Basic
return false; return false;
} }
// METHOD: arrayMergeRecursive
// PARAMS: array, array, ..., true/false flag how to handle key
// key flag: true: handle keys as string or int, default false: all keys are string
// RETURN: merged array
// DESC : correctly recursive merges as an array as array_merge_recursive just glues things together
public static function arrayMergeRecursive()
{
// croak on not enough arguemnts (we need at least two)
if (func_num_args() < 2) {
trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING);
return;
}
// default key is not string
$key_is_string = false;
$arrays = func_get_args();
// if last is not array, then assume it is trigger for key is always string
if (!is_array(end($arrays))) {
if (array_pop($arrays)) {
$key_is_string = true;
}
}
// check that arrays count is at least two, else we don't have enough to do anything
if (count($arrays) < 2) {
trigger_error(__FUNCTION__.' needs two or more array arguments', E_USER_WARNING);
return;
}
$merged = array();
while ($arrays) {
$array = array_shift($arrays);
if (!is_array($array)) {
trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING);
return;
}
if (!$array) {
continue;
}
foreach ($array as $key => $value) {
// if string or if key is assumed to be string do key match else add new entry
if (is_string($key) || $key_is_string === false) {
if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key])) {
// $merged[$key] = call_user_func(__METHOD__, $merged[$key], $value, $key_is_string);
$merged[$key] = Basic::arrayMergeRecursive($merged[$key], $value, $key_is_string);
} else {
$merged[$key] = $value;
}
} else {
$merged[] = $value;
}
}
}
return $merged;
}
// METHOD: arrayFlatForKey
// PARAMS: array (nested)
// search, key to find that has no sub leaf and will be pushed up
// RETURN: modified array
// DESC : searches for key -> value in an array tree and writes the value one level up
// this will remove this leaf will all other values
public static function arrayFlatForKey($array, $search)
{
foreach ($array as $key => $value) {
// if it is not an array do just nothing
if (is_array($value)) {
// probe it has search key
if (isset($value[$search])) {
// set as current
$array[$key] = $value[$search];
} else {
// call up next node down
// $array[$key] = call_user_func(__METHOD__, $value, $search);
$array[$key] = Basic::arrayFlatForKey($value, $search);
}
}
}
return $array;
}
// METHOD: inArrayAny // METHOD: inArrayAny
// WAS : in_array_any // WAS : in_array_any
// PARAMS: needle: array // PARAMS: needle: array

View File

@@ -334,7 +334,7 @@ class ArrayIO extends \CoreLibs\DB\IO
$q_vars = ''; $q_vars = '';
$q_where = ''; $q_where = '';
foreach ($this->table_array as $column => $data_array) { foreach ($this->table_array as $column => $data_array) {
/********************************* START FILE *************************************/ /********************************* START FILE *************************************/
// file upload // file upload
if ($this->table_array[$column]['file']) { if ($this->table_array[$column]['file']) {
// falls was im tmp drinnen, sprich ein upload, datei kopieren, Dateinamen in db schreiben // falls was im tmp drinnen, sprich ein upload, datei kopieren, Dateinamen in db schreiben
@@ -381,7 +381,7 @@ class ArrayIO extends \CoreLibs\DB\IO
} }
} // delete or upload } // delete or upload
} // file IF } // file IF
/********************************* END FILE **************************************/ /********************************* END FILE **************************************/
// do not write 'pk' (primary key) or 'view' values // do not write 'pk' (primary key) or 'view' values
if (!$this->table_array[$column]['pk'] && $this->table_array[$column]['type'] != 'view' && strlen($column) > 0) { if (!$this->table_array[$column]['pk'] && $this->table_array[$column]['type'] != 'view' && strlen($column) > 0) {
@@ -425,15 +425,21 @@ class ArrayIO extends \CoreLibs\DB\IO
} }
$q_data .= $_value; $q_data .= $_value;
} else { } else {
// normal string // if the error check is json, we set field to null if NOT set
$q_data .= "'"; // else normal string write
// if add slashes do convert & add slashes else write AS is if ($this->table_array[$column]['error_check'] == 'json' && !$this->table_array[$column]['value']) {
if ($addslashes) { $q_data .= 'NULL';
$q_data .= $this->dbEscapeString($this->convertEntities($this->table_array[$column]['value']));
} else { } else {
$q_data .= $this->dbEscapeString($this->table_array[$column]['value']); // normal string
$q_data .= "'";
// if add slashes do convert & add slashes else write AS is
if ($addslashes) {
$q_data .= $this->dbEscapeString($this->convertEntities($this->table_array[$column]['value']));
} else {
$q_data .= $this->dbEscapeString($this->table_array[$column]['value']);
}
$q_data .= "'";
} }
$q_data .= "'";
} }
} }
} // while ... } // while ...

View File

@@ -1259,9 +1259,10 @@ class IO extends \CoreLibs\Basic
// WAS : db_fetch_array // WAS : db_fetch_array
// PARAMS: cusors -> the cursor from db_exec or pg_query/pg_exec/mysql_query // PARAMS: cusors -> the cursor from db_exec or pg_query/pg_exec/mysql_query
// if not set will use internal cursor, if not found, stops with 0 (error) // if not set will use internal cursor, if not found, stops with 0 (error)
// assoc_only -> false is default, if true only assoc rows
// RETURN: a mixed row // RETURN: a mixed row
// DESC : executes a cursor and returns the data, if no more data 0 will be returned // DESC : executes a cursor and returns the data, if no more data 0 will be returned
public function dbFetchArray($cursor = 0) public function dbFetchArray($cursor = 0, $assoc_only = false)
{ {
// return false if no query or cursor set ... // return false if no query or cursor set ...
if (!$cursor) { if (!$cursor) {
@@ -1272,15 +1273,21 @@ class IO extends \CoreLibs\Basic
$this->__dbError(); $this->__dbError();
return false; return false;
} }
return $this->__dbConvertEncoding($this->db_functions->__dbFetchArray($cursor)); return $this->__dbConvertEncoding(
$this->db_functions->__dbFetchArray(
$cursor,
$this->db_functions->__dbResultType($assoc_only)
)
);
} }
// METHOD: dbReturnRow // METHOD: dbReturnRow
// WAS : db_return_row // WAS : db_return_row
// PARAMS: query -> the query to be executed // PARAMS: query -> the query to be executed
// assoc_only -> if true, only return assoc entry, else both (pgsql)
// RETURN: mixed db result // RETURN: mixed db result
// DESC : returns the FIRST row of the given query // DESC : returns the FIRST row of the given query
public function dbReturnRow($query) public function dbReturnRow($query, $assoc_only = false)
{ {
if (!$query) { if (!$query) {
$this->error_id = 11; $this->error_id = 11;
@@ -1294,7 +1301,7 @@ class IO extends \CoreLibs\Basic
return false; return false;
} }
$cursor = $this->dbExec($query); $cursor = $this->dbExec($query);
$result = $this->dbFetchArray($cursor); $result = $this->dbFetchArray($cursor, $assoc_only);
return $result; return $result;
} }

View File

@@ -190,6 +190,9 @@ class PgSQL
// DESC : wrapper for pg_fetch_array // DESC : wrapper for pg_fetch_array
public function __dbFetchArray($cursor, $result_type = '') public function __dbFetchArray($cursor, $result_type = '')
{ {
if ($result_type == true) {
$result_type = PGSQL_ASSOC;
}
// result type is passed on as is [should be checked] // result type is passed on as is [should be checked]
if ($result_type) { if ($result_type) {
return pg_fetch_array($cursor, null, $result_type); return pg_fetch_array($cursor, null, $result_type);
@@ -198,6 +201,18 @@ class PgSQL
} }
} }
// METHOD: __dbResultType
// PARAMS: true/false for ASSOC only or BOTH
// RETURN: PGSQL assoc type
// DESC : simple match up between assoc true/false
public function __dbResultType($assoc_type)
{
if ($assoc_type == true) {
return PGSQL_ASSOC;
}
return ''; // fallback to default
}
// METHOD: __dbFetchAll // METHOD: __dbFetchAll
// WAS : _db_fetch_all // WAS : _db_fetch_all
// PARAMS: cursor // PARAMS: cursor

View File

@@ -844,6 +844,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
//if ($value['mandatory'] && $value['error_check']) //if ($value['mandatory'] && $value['error_check'])
// if error value set && somethign input, check if input okay // if error value set && somethign input, check if input okay
if ($value['error_check'] && $this->table_array[$key]['value']) { if ($value['error_check'] && $this->table_array[$key]['value']) {
$this->debug('ERROR CHECK', 'Key: '.$key.' => '.$value['error_check']);
// each error check can be a piped seperated value, lets split it // each error check can be a piped seperated value, lets split it
// $this->debug('edit', $value['error_check']); // $this->debug('edit', $value['error_check']);
foreach (explode('|', $value['error_check']) as $error_check) { foreach (explode('|', $value['error_check']) as $error_check) {
@@ -918,6 +919,14 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// error // error
} }
break; break;
case 'json':
// check if valid json
$json_out = json_decode($this->table_array[$key]['value'], true);
$this->debug('JSON ENCODE', 'LAST ERROR: '.json_last_error());
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 } // switch
} // for each error to check } // for each error to check
} elseif ($value['mandatory'] && } elseif ($value['mandatory'] &&
@@ -1585,7 +1594,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if ($data_array['type'] == 'drop_down_db') { if ($data_array['type'] == 'drop_down_db') {
$md_q = md5($data_array['query']); $md_q = md5($data_array['query']);
while ($res = $this->dbReturn($data_array['query'])) { while ($res = $this->dbReturn($data_array['query'])) {
$this->debug('edit', 'Q[$md_q] pos: '.$this->cursor_ext[$md_q]['pos'].' | want: '.$data_array['preset'].' | set: '.$data['preset'][$el_name]); $this->debug('edit', 'Q['.$md_q.'] pos: '.$this->cursor_ext[$md_q]['pos'].' | want: '.$data_array['preset'].' | set: '.$data['preset'][$el_name]);
// first is default for this element // first is default for this element
if (!$data['preset'][$el_name] && ($this->cursor_ext[$md_q]['pos'] == $data_array['preset'])) { if (!$data['preset'][$el_name] && ($this->cursor_ext[$md_q]['pos'] == $data_array['preset'])) {
$data['preset'][$el_name] = $res[0]; $data['preset'][$el_name] = $res[0];