Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4e2c781c6 | ||
|
|
e80b3b8dfd | ||
|
|
2b079ff836 | ||
|
|
37201799b5 |
@@ -31,6 +31,7 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
|||||||
4,
|
4,
|
||||||
'b',
|
'b',
|
||||||
'c' => 'test',
|
'c' => 'test',
|
||||||
|
'single' => 'single',
|
||||||
'same' => 'same',
|
'same' => 'same',
|
||||||
'deep' => [
|
'deep' => [
|
||||||
'sub' => [
|
'sub' => [
|
||||||
@@ -288,6 +289,188 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function arraySearchKeyProvider(): array
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
0: search in array
|
||||||
|
1: search keys
|
||||||
|
2: flat flag
|
||||||
|
3: prefix flag
|
||||||
|
4: expected array
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
// single
|
||||||
|
'find single, standard' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single'],
|
||||||
|
2 => null,
|
||||||
|
3 => null,
|
||||||
|
4 => [
|
||||||
|
0 => [
|
||||||
|
'value' => 'single',
|
||||||
|
'path' => ['single'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'find single, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single'],
|
||||||
|
2 => null,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'single' => [
|
||||||
|
0 => [
|
||||||
|
'value' => 'single',
|
||||||
|
'path' => ['single'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'find single, flat' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single'],
|
||||||
|
2 => true,
|
||||||
|
3 => null,
|
||||||
|
4 => [
|
||||||
|
'single',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'find single, flat, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single'],
|
||||||
|
2 => true,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'single' => [
|
||||||
|
'single',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// not found
|
||||||
|
'not found, standard' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['NOT FOUND'],
|
||||||
|
2 => null,
|
||||||
|
3 => null,
|
||||||
|
4 => [],
|
||||||
|
],
|
||||||
|
'not found, standard, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['NOT FOUND'],
|
||||||
|
2 => null,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'NOT FOUND' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'not found, flat' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['NOT FOUND'],
|
||||||
|
2 => true,
|
||||||
|
3 => null,
|
||||||
|
4 => [],
|
||||||
|
],
|
||||||
|
'not found, flat, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['NOT FOUND'],
|
||||||
|
2 => true,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'NOT FOUND' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// multi
|
||||||
|
'multiple found, standard' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['same'],
|
||||||
|
2 => null,
|
||||||
|
3 => null,
|
||||||
|
4 => [
|
||||||
|
[
|
||||||
|
'value' => 'same',
|
||||||
|
'path' => ['a', 'same', ],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'value' => 'same',
|
||||||
|
'path' => ['same', ],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'value' => 'same',
|
||||||
|
'path' => ['deep', 'sub', 'same', ],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'multiple found, flat' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['same'],
|
||||||
|
2 => true,
|
||||||
|
3 => null,
|
||||||
|
4 => ['same', 'same', 'same', ],
|
||||||
|
],
|
||||||
|
// search with multiple
|
||||||
|
'search multiple, standard' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single', 'nested'],
|
||||||
|
2 => null,
|
||||||
|
3 => null,
|
||||||
|
4 => [
|
||||||
|
[
|
||||||
|
'value' => 'single',
|
||||||
|
'path' => ['single'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'value' => 'bar',
|
||||||
|
'path' => ['deep', 'sub', 'nested', ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'search multiple, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single', 'nested'],
|
||||||
|
2 => null,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'single' => [
|
||||||
|
[
|
||||||
|
'value' => 'single',
|
||||||
|
'path' => ['single'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'nested' => [
|
||||||
|
[
|
||||||
|
'value' => 'bar',
|
||||||
|
'path' => ['deep', 'sub', 'nested', ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'search multiple, flat' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single', 'nested'],
|
||||||
|
2 => true,
|
||||||
|
3 => null,
|
||||||
|
4 => [
|
||||||
|
'single', 'bar',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'search multiple, flat, prefix' => [
|
||||||
|
0 => self::$array,
|
||||||
|
1 => ['single', 'nested'],
|
||||||
|
2 => true,
|
||||||
|
3 => true,
|
||||||
|
4 => [
|
||||||
|
'single' => ['single', ],
|
||||||
|
'nested' => ['bar', ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* provides array listing for the merge test
|
* provides array listing for the merge test
|
||||||
*
|
*
|
||||||
@@ -691,6 +874,44 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers::arraySearchKey
|
||||||
|
* @dataProvider arraySearchKeyProvider
|
||||||
|
* @testdox arraySearchKey Search array with keys and flat: $flat, prefix: $prefix [$_dataName]
|
||||||
|
*
|
||||||
|
* @param array $input
|
||||||
|
* @param array $needles
|
||||||
|
* @param bool|null $flat
|
||||||
|
* @param bool|null $prefix
|
||||||
|
* @param array $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testArraySearchKey(
|
||||||
|
array $input,
|
||||||
|
array $needles,
|
||||||
|
?bool $flat,
|
||||||
|
?bool $prefix,
|
||||||
|
array $expected
|
||||||
|
): void {
|
||||||
|
if ($flat === null && $prefix === null) {
|
||||||
|
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles);
|
||||||
|
} elseif ($flat === null) {
|
||||||
|
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, prefix: $prefix);
|
||||||
|
} elseif ($prefix === null) {
|
||||||
|
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, flat: $flat);
|
||||||
|
} else {
|
||||||
|
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, $flat, $prefix);
|
||||||
|
}
|
||||||
|
// print "E: " . print_r($expected, true) . "\n";
|
||||||
|
// print "R: " . print_r($result, true) . "\n";
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -149,6 +149,38 @@ function rec(string $pre, string $cur, array $node = [])
|
|||||||
return $node;
|
return $node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'image' => 'foo',
|
||||||
|
'element' => 'w-1',
|
||||||
|
'rotate' => 360,
|
||||||
|
'html' => [
|
||||||
|
'image' => 'bar',
|
||||||
|
'result_image' => 'baz',
|
||||||
|
'rule' => 'wrong'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'image' => 'large'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'nothing' => 'wrong'
|
||||||
|
],
|
||||||
|
'nest' => [
|
||||||
|
'nust' => [
|
||||||
|
'nist' => [
|
||||||
|
'foo' => 'bar',
|
||||||
|
'image' => 'long, long'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
's' => [
|
||||||
|
'image' => 'path?'
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$search = ['image', 'result_image', 'nothing', 'EMPTY'];
|
||||||
|
$result = ArrayHandler::arraySearchKey($data, $search);
|
||||||
|
print "ARRAYSEARCHKEY: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
|
||||||
|
|
||||||
// $test = [
|
// $test = [
|
||||||
// 'A' => [
|
// 'A' => [
|
||||||
// 'B' => [],
|
// 'B' => [],
|
||||||
|
|||||||
@@ -177,6 +177,65 @@ class ArrayHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for one or many keys in array and return matching values
|
||||||
|
* If flat is set to true, return flat array with found values only
|
||||||
|
* If prefix is turned on each found group will be prefixed with the
|
||||||
|
* search key
|
||||||
|
*
|
||||||
|
* @param array<mixed> $array array to search in
|
||||||
|
* @param array<mixed> $needles keys to find in array
|
||||||
|
* @param bool $flat [false] Turn on flat output
|
||||||
|
* @param bool $prefix [false] Prefix found with needle key
|
||||||
|
* @return array<mixed> Found values
|
||||||
|
*/
|
||||||
|
public static function arraySearchKey(
|
||||||
|
array $array,
|
||||||
|
array $needles,
|
||||||
|
bool $flat = false,
|
||||||
|
bool $prefix = false
|
||||||
|
): array {
|
||||||
|
$iterator = new \RecursiveArrayIterator($array);
|
||||||
|
$recursive = new \RecursiveIteratorIterator(
|
||||||
|
$iterator,
|
||||||
|
\RecursiveIteratorIterator::SELF_FIRST
|
||||||
|
);
|
||||||
|
$hit_list = [];
|
||||||
|
if ($prefix === true) {
|
||||||
|
$hit_list = array_fill_keys($needles, []);
|
||||||
|
}
|
||||||
|
$key_path = [];
|
||||||
|
$prev_depth = 0;
|
||||||
|
foreach ($recursive as $key => $value) {
|
||||||
|
if ($prev_depth > $recursive->getDepth()) {
|
||||||
|
// remove all trailing to ne depth
|
||||||
|
$diff = $prev_depth - $recursive->getDepth();
|
||||||
|
array_splice($key_path, -$diff, $diff);
|
||||||
|
}
|
||||||
|
$prev_depth = $recursive->getDepth();
|
||||||
|
if ($flat === false) {
|
||||||
|
$key_path[$recursive->getDepth()] = $key;
|
||||||
|
}
|
||||||
|
if (in_array($key, $needles, true)) {
|
||||||
|
ksort($key_path);
|
||||||
|
if ($flat === true) {
|
||||||
|
$hit = $value;
|
||||||
|
} else {
|
||||||
|
$hit = [
|
||||||
|
'value' => $value,
|
||||||
|
'path' => $key_path
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if ($prefix === true) {
|
||||||
|
$hit_list[$key][] = $hit;
|
||||||
|
} else {
|
||||||
|
$hit_list[] = $hit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $hit_list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* correctly recursive merges as an array as array_merge_recursive
|
* correctly recursive merges as an array as array_merge_recursive
|
||||||
* just glues things together
|
* just glues things together
|
||||||
|
|||||||
@@ -1146,7 +1146,7 @@ class IO
|
|||||||
$this->params
|
$this->params
|
||||||
),
|
),
|
||||||
'__dbPrepareExec',
|
'__dbPrepareExec',
|
||||||
($this->params === [] ? 'Q' : 'Qp'),
|
($this->params === [] ? 'Q' : 'Qp')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// import protection, hash needed
|
// import protection, hash needed
|
||||||
@@ -1166,7 +1166,15 @@ class IO
|
|||||||
$this->query_called[$query_hash] > $this->MAX_QUERY_CALL
|
$this->query_called[$query_hash] > $this->MAX_QUERY_CALL
|
||||||
) {
|
) {
|
||||||
$this->__dbError(30, false, $this->query);
|
$this->__dbError(30, false, $this->query);
|
||||||
$this->__dbDebug('db', $this->query, 'dbExec', 'Q[nc]');
|
$this->__dbDebug(
|
||||||
|
'db',
|
||||||
|
$this->__dbDebugPrepare(
|
||||||
|
$this->query,
|
||||||
|
$this->params
|
||||||
|
),
|
||||||
|
'dbExec',
|
||||||
|
($this->params === [] ? 'Q[nc]' : 'Qp[nc]')
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->query_called[$query_hash] ++;
|
$this->query_called[$query_hash] ++;
|
||||||
@@ -1945,6 +1953,18 @@ class IO
|
|||||||
// check if params count matches
|
// check if params count matches
|
||||||
// checks if the params count given matches the expected count
|
// checks if the params count given matches the expected count
|
||||||
if ($this->__dbCheckQueryParams($query, count($params)) === false) {
|
if ($this->__dbCheckQueryParams($query, count($params)) === false) {
|
||||||
|
// in case we got an error print out query
|
||||||
|
if ($this->db_debug) {
|
||||||
|
$this->__dbDebug(
|
||||||
|
'db',
|
||||||
|
$this->__dbDebugPrepare(
|
||||||
|
$this->query,
|
||||||
|
$this->params
|
||||||
|
),
|
||||||
|
'dbReturn',
|
||||||
|
($this->params === [] ? 'Q[e]' : 'Qp[e]')
|
||||||
|
);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// set first call to false
|
// set first call to false
|
||||||
@@ -1968,7 +1988,15 @@ class IO
|
|||||||
$this->cursor_ext[$query_hash]['log'][] = 'No cursor';
|
$this->cursor_ext[$query_hash]['log'][] = 'No cursor';
|
||||||
// for DEBUG, print out each query executed
|
// for DEBUG, print out each query executed
|
||||||
if ($this->db_debug) {
|
if ($this->db_debug) {
|
||||||
$this->__dbDebug('db', $this->cursor_ext[$query_hash]['query'], 'dbReturn', 'Q');
|
$this->__dbDebug(
|
||||||
|
'db',
|
||||||
|
$this->__dbDebugPrepare(
|
||||||
|
$this->cursor_ext[$query_hash]['query'],
|
||||||
|
$this->cursor_ext[$query_hash]['params']
|
||||||
|
),
|
||||||
|
'dbReturn',
|
||||||
|
($this->cursor_ext[$query_hash]['params'] === [] ? 'Q' : 'Qp'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// if no DB Handler try to reconnect
|
// if no DB Handler try to reconnect
|
||||||
if (!$this->dbh) {
|
if (!$this->dbh) {
|
||||||
@@ -1997,7 +2025,15 @@ class IO
|
|||||||
// if still no cursor ...
|
// if still no cursor ...
|
||||||
if (!$this->cursor_ext[$query_hash]['cursor']) {
|
if (!$this->cursor_ext[$query_hash]['cursor']) {
|
||||||
if ($this->db_debug) {
|
if ($this->db_debug) {
|
||||||
$this->__dbDebug('db', $this->cursor_ext[$query_hash]['query'], 'dbReturn', 'Q');
|
$this->__dbDebug(
|
||||||
|
'db',
|
||||||
|
$this->__dbDebugPrepare(
|
||||||
|
$this->cursor_ext[$query_hash]['query'],
|
||||||
|
$this->cursor_ext[$query_hash]['params']
|
||||||
|
),
|
||||||
|
'dbReturn',
|
||||||
|
($this->cursor_ext[$query_hash]['params'] === [] ? 'Q[e]' : 'Qp[e]'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// internal error handling
|
// internal error handling
|
||||||
$this->__dbError(13, $this->cursor_ext[$query_hash]['cursor']);
|
$this->__dbError(13, $this->cursor_ext[$query_hash]['cursor']);
|
||||||
@@ -2300,10 +2336,6 @@ class IO
|
|||||||
$this->__dbError(17, false, $query);
|
$this->__dbError(17, false, $query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// checks if the params count given matches the expected count
|
|
||||||
if ($this->__dbCheckQueryParams($query, count($params)) === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$cursor = $this->dbExecParams($query, $params);
|
$cursor = $this->dbExecParams($query, $params);
|
||||||
if ($cursor === false) {
|
if ($cursor === false) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2348,10 +2380,6 @@ class IO
|
|||||||
$this->__dbError(17, false, $query);
|
$this->__dbError(17, false, $query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// checks if the params count given matches the expected count
|
|
||||||
if ($this->__dbCheckQueryParams($query, count($params)) === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$cursor = $this->dbExecParams($query, $params);
|
$cursor = $this->dbExecParams($query, $params);
|
||||||
if ($cursor === false) {
|
if ($cursor === false) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2661,6 +2689,17 @@ class IO
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ($this->db_debug) {
|
||||||
|
$this->__dbDebug(
|
||||||
|
'db',
|
||||||
|
$this->__dbDebugPrepare(
|
||||||
|
$this->prepare_cursor[$stm_name]['query'],
|
||||||
|
$data
|
||||||
|
),
|
||||||
|
'dbExecPrep',
|
||||||
|
'Qpe'
|
||||||
|
);
|
||||||
|
}
|
||||||
// if the count does not match
|
// if the count does not match
|
||||||
if ($this->prepare_cursor[$stm_name]['count'] != count($data)) {
|
if ($this->prepare_cursor[$stm_name]['count'] != count($data)) {
|
||||||
$this->__dbError(
|
$this->__dbError(
|
||||||
@@ -2673,17 +2712,6 @@ class IO
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($this->db_debug) {
|
|
||||||
$this->__dbDebug(
|
|
||||||
'db',
|
|
||||||
$this->__dbDebugPrepare(
|
|
||||||
$this->prepare_cursor[$stm_name]['query'],
|
|
||||||
$data
|
|
||||||
),
|
|
||||||
'dbExecPrep',
|
|
||||||
'Qp'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$result = $this->db_functions->__dbExecute($stm_name, $data);
|
$result = $this->db_functions->__dbExecute($stm_name, $data);
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
$this->log->debug('ExecuteData', 'ERROR in STM[' . $stm_name . '|'
|
$this->log->debug('ExecuteData', 'ERROR in STM[' . $stm_name . '|'
|
||||||
|
|||||||
Reference in New Issue
Block a user