Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae044bee6f | ||
|
|
529b6a75ba | ||
|
|
8de112ba7e | ||
|
|
ad070ebdf4 | ||
|
|
9edfc2acb6 |
@@ -36,7 +36,7 @@ if [ -n "${2}" ] && [ -z "${php_bin}" ]; then
|
|||||||
fi;
|
fi;
|
||||||
|
|
||||||
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
|
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
|
||||||
phpunit_call="${php_bin}${base}tools/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}4dev/tests/";
|
phpunit_call="${php_bin}${base}vendor/bin/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}4dev/tests/";
|
||||||
|
|
||||||
${phpunit_call};
|
${phpunit_call};
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,36 @@ final class CoreLibsConvertMathTest extends TestCase
|
|||||||
[6, 12, 18],
|
[6, 12, 18],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'inblanaced [2x2,3] x [3x2]' => [
|
||||||
|
'a' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[4, 5]
|
||||||
|
],
|
||||||
|
'b' => [
|
||||||
|
[6, 7],
|
||||||
|
[8, 9],
|
||||||
|
[10, 11]
|
||||||
|
],
|
||||||
|
'result' => [
|
||||||
|
[52, 58],
|
||||||
|
[64, 73],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'inblanaced [2x3] x [3x1,2]' => [
|
||||||
|
'a' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[4, 5, 7]
|
||||||
|
],
|
||||||
|
'b' => [
|
||||||
|
[7, 8],
|
||||||
|
[9, 10],
|
||||||
|
[11]
|
||||||
|
],
|
||||||
|
'result' => [
|
||||||
|
[58, 28],
|
||||||
|
[150, 82],
|
||||||
|
]
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ namespace tests;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use CoreLibs\Logging\Logger\Level;
|
use CoreLibs\Logging;
|
||||||
use CoreLibs\DB\Options\Convert;
|
use CoreLibs\DB\Options\Convert;
|
||||||
|
use CoreLibs\DB\Support\ConvertPlaceholder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for DB\IO + DB\SQL\PgSQL
|
* Test class for DB\IO + DB\SQL\PgSQL
|
||||||
@@ -117,7 +118,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// define basic connection set valid and one invalid
|
// define basic connection set valid and one invalid
|
||||||
self::$log = new \CoreLibs\Logging\Logging([
|
self::$log = new Logging\Logging([
|
||||||
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
||||||
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
||||||
'log_file_id' => 'CoreLibs-DB-IO-Test',
|
'log_file_id' => 'CoreLibs-DB-IO-Test',
|
||||||
@@ -570,11 +571,11 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
);
|
);
|
||||||
$db->dbClose();
|
$db->dbClose();
|
||||||
// second conenction with log set NOT debug
|
// second conenction with log set NOT debug
|
||||||
$log = new \CoreLibs\Logging\Logging([
|
$log = new Logging\Logging([
|
||||||
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
||||||
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
||||||
'log_file_id' => 'CoreLibs-DB-IO-Test',
|
'log_file_id' => 'CoreLibs-DB-IO-Test',
|
||||||
'log_level' => \CoreLibs\Logging\Logger\Level::Notice,
|
'log_level' => Logging\Logger\Level::Notice,
|
||||||
]);
|
]);
|
||||||
$db = new \CoreLibs\DB\IO(
|
$db = new \CoreLibs\DB\IO(
|
||||||
self::$db_config[$connection],
|
self::$db_config[$connection],
|
||||||
@@ -3293,6 +3294,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) '
|
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) '
|
||||||
. 'VALUES ($1, $2) RETURNING table_with_primary_key_id',
|
. 'VALUES ($1, $2) RETURNING table_with_primary_key_id',
|
||||||
'returning_id' => true,
|
'returning_id' => true,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// update
|
// update
|
||||||
@@ -3327,6 +3329,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'query' => 'UPDATE table_with_primary_key SET row_int = $1, '
|
'query' => 'UPDATE table_with_primary_key SET row_int = $1, '
|
||||||
. 'row_varchar = $2 WHERE uid = $3',
|
. 'row_varchar = $2 WHERE uid = $3',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// select
|
// select
|
||||||
@@ -3356,6 +3359,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 1,
|
'count' => 1,
|
||||||
'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1',
|
'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// any query but with no parameters
|
// any query but with no parameters
|
||||||
@@ -3388,6 +3392,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// no statement name (25)
|
// no statement name (25)
|
||||||
@@ -3411,6 +3416,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => '',
|
'query' => '',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// no query (prepare 11)
|
// no query (prepare 11)
|
||||||
@@ -3435,6 +3441,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => '',
|
'query' => '',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// no db connection (prepare/execute 16)
|
// no db connection (prepare/execute 16)
|
||||||
@@ -3464,6 +3471,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// prepare with different statement name
|
// prepare with different statement name
|
||||||
@@ -3489,6 +3497,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
|
||||||
'returning_id' => false,
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// insert wrong data count compared to needed (execute 23)
|
// insert wrong data count compared to needed (execute 23)
|
||||||
@@ -3514,10 +3523,12 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES '
|
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES '
|
||||||
. '($1, $2) RETURNING table_with_primary_key_id',
|
. '($1, $2) RETURNING table_with_primary_key_id',
|
||||||
'returning_id' => true,
|
'returning_id' => true,
|
||||||
|
'placeholder_converted' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// execute does not return a result (22)
|
// execute does not return a result (22)
|
||||||
// TODO execute does not return a result
|
// TODO execute does not return a result
|
||||||
|
// TODO prepared statement with placeholder params auto convert
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3662,7 +3673,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check dbGetPrepareCursorValue
|
// check dbGetPrepareCursorValue
|
||||||
foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
|
foreach (['pk_name', 'count', 'query', 'returning_id', 'placeholder_converted'] as $key) {
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$prepare_cursor[$key],
|
$prepare_cursor[$key],
|
||||||
$db->dbGetPrepareCursorValue($stm_name, $key),
|
$db->dbGetPrepareCursorValue($stm_name, $key),
|
||||||
@@ -5031,8 +5042,151 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
$db->dbClose();
|
$db->dbClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// query placeholder convert
|
// MARK: QUERY PLACEHOLDERS
|
||||||
|
|
||||||
|
// test query placeholder detection for all possible sets
|
||||||
|
// ::dbPrepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* placeholder sql
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerDbCountQueryParams(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'one place holder' => [
|
||||||
|
'query' => 'SELECT row_varchar FROM table_with_primary_key WHERE row_varchar = $1',
|
||||||
|
'count' => 1,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'one place holder, json call' => [
|
||||||
|
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_jsonb->>'data' = $1",
|
||||||
|
'count' => 1,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'one place holder, <> compare' => [
|
||||||
|
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> $1",
|
||||||
|
'count' => 1,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'one place holder, named' => [
|
||||||
|
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar",
|
||||||
|
'count' => 1,
|
||||||
|
'convert' => true,
|
||||||
|
],
|
||||||
|
'no replacement' => [
|
||||||
|
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar = '$1'",
|
||||||
|
'count' => 0,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'insert' => [
|
||||||
|
'query' => "INSERT INTO table_with_primary_key (row_varchar, row_jsonb, row_int) VALUES ($1, $2, $3)",
|
||||||
|
'count' => 3,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'update' => [
|
||||||
|
'query' => "UPDATE table_with_primary_key SET row_varchar = $1, row_jsonb = $2, row_int = $3 WHERE row_numeric = $4",
|
||||||
|
'count' => 4,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'multiple, multline' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT
|
||||||
|
row_varchar
|
||||||
|
FROM
|
||||||
|
table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_varchar = $1 AND row_int = $2
|
||||||
|
AND row_numeric = ANY($3)
|
||||||
|
SQL,
|
||||||
|
'count' => 3,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'two digit numbers' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
INSERT INTO table_with_primary_key (
|
||||||
|
row_int, row_numeric, row_varchar, row_varchar_literal, row_json,
|
||||||
|
row_jsonb, row_bytea, row_timestamp, row_date, row_interval
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5,
|
||||||
|
$6, $7, $8, $9, $10
|
||||||
|
)
|
||||||
|
SQL,
|
||||||
|
'count' => 10,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'things in brackets' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT row_varchar
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_varchar = $1 AND
|
||||||
|
(row_int = ANY($2) OR row_int = $3)
|
||||||
|
AND row_varchar_literal = $4
|
||||||
|
SQL,
|
||||||
|
'count' => 4,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
'number compare' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT row_varchar
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_int >= $1 OR row_int <= $2 OR
|
||||||
|
row_int > $3 OR row_int < $4
|
||||||
|
OR row_int = $5 OR row_int <> $6
|
||||||
|
SQL,
|
||||||
|
'count' => 6,
|
||||||
|
'convert' => false,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder check and convert tests
|
||||||
|
*
|
||||||
|
* @covers ::dbPrepare
|
||||||
|
* @covers ::__dbCountQueryParams
|
||||||
|
* @onvers ::convertPlaceholderInQuery
|
||||||
|
* @dataProvider providerDbCountQueryParams
|
||||||
|
* @testdox Query replacement count test [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string $query
|
||||||
|
* @param int $count
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testDbCountQueryParams(string $query, int $count, bool $convert): void
|
||||||
|
{
|
||||||
|
$db = new \CoreLibs\DB\IO(
|
||||||
|
self::$db_config['valid'],
|
||||||
|
self::$log
|
||||||
|
);
|
||||||
|
$id = sha1($query);
|
||||||
|
$db->dbSetConvertPlaceholder($convert);
|
||||||
|
$db->dbPrepare($id, $query);
|
||||||
|
// print "\n**\n";
|
||||||
|
// print "PCount: " . $db->dbGetPrepareCursorValue($id, 'count') . "\n";
|
||||||
|
// print "\n**\n";
|
||||||
|
$this->assertEquals(
|
||||||
|
$count,
|
||||||
|
$db->dbGetPrepareCursorValue($id, 'count'),
|
||||||
|
'DB count params'
|
||||||
|
);
|
||||||
|
$placeholder = ConvertPlaceholder::convertPlaceholderInQuery($query, null, 'pg');
|
||||||
|
// print "RES: " . print_r($placeholder, true) . "\n";
|
||||||
|
$this->assertEquals(
|
||||||
|
$count,
|
||||||
|
$placeholder['needed'],
|
||||||
|
'convert params'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* query placeholder convert
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function queryPlaceholderReplaceProvider(): array
|
public function queryPlaceholderReplaceProvider(): array
|
||||||
{
|
{
|
||||||
// WHERE row_varchar = $1
|
// WHERE row_varchar = $1
|
||||||
@@ -5076,7 +5230,9 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
WHERE row_varchar = $1
|
WHERE row_varchar = $1
|
||||||
SQL,
|
SQL,
|
||||||
'expected_params' => ['string a'],
|
'expected_params' => ['string a'],
|
||||||
]
|
],
|
||||||
|
// TODO: test with multiple entries
|
||||||
|
// TODO: test with same entry ($1, $1, :var, :var)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5178,6 +5334,8 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
// - data debug
|
// - data debug
|
||||||
// dbDumpData
|
// dbDumpData
|
||||||
|
|
||||||
|
// MARK: ASYNC
|
||||||
|
|
||||||
// ASYNC at the end because it has 1s timeout
|
// ASYNC at the end because it has 1s timeout
|
||||||
// - asynchronous executions
|
// - asynchronous executions
|
||||||
// dbExecAsync, dbCheckAsync
|
// dbExecAsync, dbCheckAsync
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
"php": ">=8.3"
|
"php": ">=8.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.12",
|
"phpstan/phpstan": "^2.0",
|
||||||
"phan/phan": "^5.4",
|
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||||
"phpstan/extension-installer": "^1.4",
|
"phpstan/extension-installer": "^1.4",
|
||||||
|
"phan/phan": "^5.4",
|
||||||
"phpunit/phpunit": "^9",
|
"phpunit/phpunit": "^9",
|
||||||
"phpstan/phpstan-deprecation-rules": "^1.2",
|
|
||||||
"yamadashy/phpstan-friendly-formatter": "^1.1"
|
"yamadashy/phpstan-friendly-formatter": "^1.1"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
includes:
|
includes:
|
||||||
- phpstan-conditional.php
|
- phpstan-conditional.php
|
||||||
#- ./vendor/yamadashy/phpstan-friendly-formatter/extension.neon
|
#- ./vendor/yamadashy/phpstan-friendly-formatter/extension.neon
|
||||||
|
# - phar://phpstan.phar/conf/bleedingEdge.neon
|
||||||
parameters:
|
parameters:
|
||||||
tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs
|
tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs
|
||||||
#errorFormat: friendly
|
#errorFormat: friendly
|
||||||
|
|||||||
@@ -115,9 +115,6 @@ print "ARRAYFLATFORKEY: " . DgS::printAr(ArrayHandler::arrayFlatForKey($test_arr
|
|||||||
*/
|
*/
|
||||||
function rec(string $pre, string $cur, array $node = [])
|
function rec(string $pre, string $cur, array $node = [])
|
||||||
{
|
{
|
||||||
if (!is_array($node)) {
|
|
||||||
$node = [];
|
|
||||||
}
|
|
||||||
print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: "
|
print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: "
|
||||||
. count($node) . " [" . join('|', array_keys($node)) . "]</div>";
|
. count($node) . " [" . join('|', array_keys($node)) . "]</div>";
|
||||||
if (!$pre) {
|
if (!$pre) {
|
||||||
|
|||||||
233
www/admin/class_test.db.convert-placeholder.php
Normal file
233
www/admin/class_test.db.convert-placeholder.php
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
<?php // phpcs:ignore warning
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phan-file-suppress PhanTypeSuspiciousStringExpression
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
// turn on all error reporting
|
||||||
|
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// basic class test file
|
||||||
|
define('USE_DATABASE', true);
|
||||||
|
// sample config
|
||||||
|
require 'config.php';
|
||||||
|
// define log file id
|
||||||
|
$LOG_FILE_ID = 'classTest-db-convert-placeholder';
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
|
use CoreLibs\Debug\Support;
|
||||||
|
use CoreLibs\DB\Support\ConvertPlaceholder;
|
||||||
|
|
||||||
|
$log = new CoreLibs\Logging\Logging([
|
||||||
|
'log_folder' => BASE . LOG,
|
||||||
|
'log_file_id' => $LOG_FILE_ID,
|
||||||
|
'log_per_date' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$PAGE_NAME = 'TEST CLASS: DB CONVERT PLACEHOLDER';
|
||||||
|
print "<!DOCTYPE html>";
|
||||||
|
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
|
||||||
|
print "<body>";
|
||||||
|
print '<div><a href="class_test.php">Class Test Master</a></div>';
|
||||||
|
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
|
||||||
|
|
||||||
|
print "LOGFILE NAME: " . $log->getLogFile() . "<br>";
|
||||||
|
print "LOGFILE ID: " . $log->getLogFileId() . "<br>";
|
||||||
|
|
||||||
|
print "Lookup Regex: <pre>" . ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS . "</pre>";
|
||||||
|
print "Replace Named Regex: <pre>" . ConvertPlaceholder::REGEX_REPLACE_NAMED . "</pre>";
|
||||||
|
print "Replace Named Regex: <pre>" . ConvertPlaceholder::REGEX_REPLACE_QUESTION_MARK . "</pre>";
|
||||||
|
print "Replace Named Regex: <pre>" . ConvertPlaceholder::REGEX_REPLACE_NUMBERED . "</pre>";
|
||||||
|
|
||||||
|
$uniqid = \CoreLibs\Create\Uids::uniqIdShort();
|
||||||
|
// $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
|
||||||
|
// $binary_data = file_get_contents('class_test.db.php') ?: '';
|
||||||
|
$binary_data = '';
|
||||||
|
$params = [
|
||||||
|
$uniqid,
|
||||||
|
true,
|
||||||
|
'STRING A',
|
||||||
|
2,
|
||||||
|
2.5,
|
||||||
|
1,
|
||||||
|
date('H:m:s'),
|
||||||
|
date('Y-m-d H:i:s'),
|
||||||
|
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]),
|
||||||
|
null,
|
||||||
|
'{"a", "b"}',
|
||||||
|
'{1,2}',
|
||||||
|
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}',
|
||||||
|
'("Text", 4, 6.3)',
|
||||||
|
$binary_data
|
||||||
|
];
|
||||||
|
|
||||||
|
$query = <<<SQL
|
||||||
|
INSERT INTO test_foo (
|
||||||
|
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
|
||||||
|
some_time, some_timestamp, json_string, null_var,
|
||||||
|
array_char_1, array_int_1,
|
||||||
|
array_composite,
|
||||||
|
composite_item,
|
||||||
|
some_binary
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6,
|
||||||
|
$7, $8, $9, $10,
|
||||||
|
$11, $12,
|
||||||
|
$13,
|
||||||
|
$14,
|
||||||
|
$15
|
||||||
|
)
|
||||||
|
RETURNING
|
||||||
|
test_foo_id,
|
||||||
|
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
|
||||||
|
some_time, some_timestamp, json_string, null_var,
|
||||||
|
array_char_1, array_int_1,
|
||||||
|
array_composite,
|
||||||
|
composite_item,
|
||||||
|
some_binary
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
print "[ALL] Convert: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
$query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez";
|
||||||
|
$params = [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ'];
|
||||||
|
print "[NO PARAMS] Convert: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
$query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez";
|
||||||
|
$params = null;
|
||||||
|
print "[NO PARAMS] Convert: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
$query = "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar";
|
||||||
|
$params = null;
|
||||||
|
print "[NO PARAMS] Convert: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
$query = "SELECT row_varchar, row_varchar_literal, row_int, row_date FROM table_with_primary_key";
|
||||||
|
$params = null;
|
||||||
|
print "[NO PARAMS] TEST: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
print "[P-CONV]: "
|
||||||
|
. Support::printAr(
|
||||||
|
ConvertPlaceholder::updateParamList([
|
||||||
|
'original' => [
|
||||||
|
'query' => 'SELECT foo FROM bar WHERE baz = :baz AND buz = :biz AND biz = :biz AND boz = :bez',
|
||||||
|
'params' => [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ'],
|
||||||
|
'empty_params' => false,
|
||||||
|
],
|
||||||
|
'type' => 'named',
|
||||||
|
'found' => 3,
|
||||||
|
// 'matches' => [
|
||||||
|
// ':baz'
|
||||||
|
// ],
|
||||||
|
// 'params_lookup' => [
|
||||||
|
// ':baz' => '$1'
|
||||||
|
// ],
|
||||||
|
// 'query' => "SELECT foo FROM bar WHERE baz = $1",
|
||||||
|
// 'parms' => [
|
||||||
|
// 'SETBAZ'
|
||||||
|
// ],
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
echo "<hr>";
|
||||||
|
|
||||||
|
// test connectors: = , <> () for query detection
|
||||||
|
|
||||||
|
// convert placeholder tests
|
||||||
|
// ? -> $n
|
||||||
|
// :name -> $n
|
||||||
|
|
||||||
|
// other way around (just visual)
|
||||||
|
$test_queries = [
|
||||||
|
'skip' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT test, string_a, number_a
|
||||||
|
FROM test_foo
|
||||||
|
SQL,
|
||||||
|
'params' => [],
|
||||||
|
'direction' => 'pg',
|
||||||
|
],
|
||||||
|
'numbers' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT test, string_a, number_a
|
||||||
|
FROM test_foo
|
||||||
|
WHERE
|
||||||
|
foo = $1 AND bar = $1 AND foobar = $2
|
||||||
|
SQL,
|
||||||
|
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
|
||||||
|
'direction' => 'pdo',
|
||||||
|
],
|
||||||
|
'a?' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
INSERT INTO test_foo (
|
||||||
|
test, string_a, number_a
|
||||||
|
) VALUES (
|
||||||
|
?, ?, ?
|
||||||
|
)
|
||||||
|
SQL,
|
||||||
|
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
|
||||||
|
'direction' => 'pg',
|
||||||
|
],
|
||||||
|
'b:' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
INSERT INTO test_foo (
|
||||||
|
test, string_a, number_a
|
||||||
|
) VALUES (
|
||||||
|
:test, :string_a, :number_a
|
||||||
|
)
|
||||||
|
SQL,
|
||||||
|
'params' => [
|
||||||
|
':test' => \CoreLibs\Create\Uids::uniqIdShort(),
|
||||||
|
':string_a' => 'string B-1',
|
||||||
|
':number_a' => 5678
|
||||||
|
],
|
||||||
|
'direction' => 'pg',
|
||||||
|
],
|
||||||
|
'select, compare $' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT row_varchar
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_int >= $1 OR row_int <= $2 OR
|
||||||
|
row_int > $3 OR row_int < $4
|
||||||
|
OR row_int = $5 OR row_int <> $6
|
||||||
|
SQL,
|
||||||
|
'params' => null,
|
||||||
|
'direction' => 'pg'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($test_queries as $info => $data) {
|
||||||
|
$query = $data['query'];
|
||||||
|
$params = $data['params'];
|
||||||
|
$direction = $data['direction'];
|
||||||
|
print "[$info] Convert: "
|
||||||
|
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params, $direction))
|
||||||
|
. "<br>";
|
||||||
|
echo "<hr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "</body></html>";
|
||||||
|
$log->debug('DEBUGEND', '==================================== [END]');
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -70,8 +70,7 @@ for ($i = 1; $i <= 6; $i++) {
|
|||||||
print $i . ") " . $cache_flag . ": "
|
print $i . ") " . $cache_flag . ": "
|
||||||
. "res: " . (is_bool($res) ?
|
. "res: " . (is_bool($res) ?
|
||||||
"<b>Bool:</b> " . Support::prBl($res) :
|
"<b>Bool:</b> " . Support::prBl($res) :
|
||||||
(is_array($res) ?
|
"Array: Yes"
|
||||||
"Array: " . Support::prBl(is_array($res)) : '{-}')
|
|
||||||
) . ", "
|
) . ", "
|
||||||
. "cursor_ext: <pre>" . Support::printAr(
|
. "cursor_ext: <pre>" . Support::printAr(
|
||||||
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
||||||
@@ -89,8 +88,7 @@ for ($i = 1; $i <= 6; $i++) {
|
|||||||
print $i . ") " . $cache_flag . ": "
|
print $i . ") " . $cache_flag . ": "
|
||||||
. "res: " . (is_bool($res) ?
|
. "res: " . (is_bool($res) ?
|
||||||
"<b>Bool:</b> " . Support::prBl($res) :
|
"<b>Bool:</b> " . Support::prBl($res) :
|
||||||
(is_array($res) ?
|
"Array: Yes"
|
||||||
"Array: " . Support::prBl(is_array($res)) : '{-}')
|
|
||||||
) . ", "
|
) . ", "
|
||||||
. "cursor_ext: <pre>" . Support::printAr(
|
. "cursor_ext: <pre>" . Support::printAr(
|
||||||
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
||||||
@@ -108,8 +106,7 @@ for ($i = 1; $i <= 6; $i++) {
|
|||||||
print $i . ") " . $cache_flag . ": "
|
print $i . ") " . $cache_flag . ": "
|
||||||
. "res: " . (is_bool($res) ?
|
. "res: " . (is_bool($res) ?
|
||||||
"<b>Bool:</b> " . Support::prBl($res) :
|
"<b>Bool:</b> " . Support::prBl($res) :
|
||||||
(is_array($res) ?
|
"Array: Yes"
|
||||||
"Array: " . Support::prBl(is_array($res)) : '{-}')
|
|
||||||
) . ", "
|
) . ", "
|
||||||
. "cursor_ext: <pre>" . Support::printAr(
|
. "cursor_ext: <pre>" . Support::printAr(
|
||||||
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
||||||
@@ -127,8 +124,7 @@ for ($i = 1; $i <= 6; $i++) {
|
|||||||
print $i . ") " . $cache_flag . ": "
|
print $i . ") " . $cache_flag . ": "
|
||||||
. "res: " . (is_bool($res) ?
|
. "res: " . (is_bool($res) ?
|
||||||
"<b>Bool:</b> " . Support::prBl($res) :
|
"<b>Bool:</b> " . Support::prBl($res) :
|
||||||
(is_array($res) ?
|
"Array: Yes"
|
||||||
"Array: " . Support::prBl(is_array($res)) : '{-}')
|
|
||||||
) . ", "
|
) . ", "
|
||||||
. "cursor_ext: <pre>" . Support::printAr(
|
. "cursor_ext: <pre>" . Support::printAr(
|
||||||
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
||||||
@@ -146,8 +142,7 @@ for ($i = 1; $i <= 6; $i++) {
|
|||||||
print $i . ") " . $cache_flag . ": "
|
print $i . ") " . $cache_flag . ": "
|
||||||
. "res: " . (is_bool($res) ?
|
. "res: " . (is_bool($res) ?
|
||||||
"<b>Bool:</b> " . Support::prBl($res) :
|
"<b>Bool:</b> " . Support::prBl($res) :
|
||||||
(is_array($res) ?
|
"Array: Yes"
|
||||||
"Array: " . Support::prBl(is_array($res)) : '{-}')
|
|
||||||
) . ", "
|
) . ", "
|
||||||
. "cursor_ext: <pre>" . Support::printAr(
|
. "cursor_ext: <pre>" . Support::printAr(
|
||||||
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
|
||||||
|
|||||||
@@ -316,7 +316,8 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
|
|||||||
$db->dbReturnRowParams(
|
$db->dbReturnRowParams(
|
||||||
$query_select,
|
$query_select,
|
||||||
[$__last_insert_id]
|
[$__last_insert_id]
|
||||||
)
|
),
|
||||||
|
true
|
||||||
) . "<br>";
|
) . "<br>";
|
||||||
// B
|
// B
|
||||||
$status = $db->dbExecParams(
|
$status = $db->dbExecParams(
|
||||||
@@ -345,7 +346,8 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
|
|||||||
$db->dbReturnRowParams(
|
$db->dbReturnRowParams(
|
||||||
$query_select,
|
$query_select,
|
||||||
[$__last_insert_id]
|
[$__last_insert_id]
|
||||||
)
|
),
|
||||||
|
true
|
||||||
) . "<br>";
|
) . "<br>";
|
||||||
// params > 10 for debug
|
// params > 10 for debug
|
||||||
// error catcher
|
// error catcher
|
||||||
@@ -674,7 +676,7 @@ echo "<hr>";
|
|||||||
|
|
||||||
print "COMPOSITE ELEMENT READ<br>";
|
print "COMPOSITE ELEMENT READ<br>";
|
||||||
$res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand");
|
$res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand");
|
||||||
print "ROW: <pre>" . print_r($res) . "</pre>";
|
print "ROW: <pre>" . print_r($res, true) . "</pre>";
|
||||||
var_dump($res);
|
var_dump($res);
|
||||||
print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>";
|
print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>";
|
||||||
echo "<hr>";
|
echo "<hr>";
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ $test_files = [
|
|||||||
'class_test.db.query-placeholder.php' => 'Class Test: DB query placeholder convert',
|
'class_test.db.query-placeholder.php' => 'Class Test: DB query placeholder convert',
|
||||||
'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn',
|
'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn',
|
||||||
'class_test.db.single.php' => 'Class Test: DB single query tests',
|
'class_test.db.single.php' => 'Class Test: DB single query tests',
|
||||||
|
'class_test.db.convert-placeholder.php' => 'Class Test: DB convert placeholder',
|
||||||
'class_test.convert.colors.php' => 'Class Test: CONVERT COLORS',
|
'class_test.convert.colors.php' => 'Class Test: CONVERT COLORS',
|
||||||
'class_test.check.colors.php' => 'Class Test: CHECK COLORS',
|
'class_test.check.colors.php' => 'Class Test: CHECK COLORS',
|
||||||
'class_test.mime.php' => 'Class Test: MIME',
|
'class_test.mime.php' => 'Class Test: MIME',
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
require 'config.php';
|
require getcwd() . DIRECTORY_SEPARATOR . 'config.php';
|
||||||
|
|
||||||
// should be utf8
|
// should be utf8
|
||||||
header("Content-type: text/html; charset=" . DEFAULT_ENCODING);
|
header("Content-type: text/html; charset=" . DEFAULT_ENCODING);
|
||||||
|
|||||||
@@ -960,10 +960,7 @@ class Login
|
|||||||
. "AND ear.edit_access_right_id = epa.edit_access_right_id "
|
. "AND ear.edit_access_right_id = epa.edit_access_right_id "
|
||||||
. "AND epa.enabled = 1 AND epa.edit_group_id = " . $res["edit_group_id"] . " "
|
. "AND epa.enabled = 1 AND epa.edit_group_id = " . $res["edit_group_id"] . " "
|
||||||
. "ORDER BY ep.order_number";
|
. "ORDER BY ep.order_number";
|
||||||
while ($res = $this->db->dbReturn($q)) {
|
while (is_array($res = $this->db->dbReturn($q))) {
|
||||||
if (!is_array($res)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// page id array for sub data readout
|
// page id array for sub data readout
|
||||||
$edit_page_ids[$res['edit_page_id']] = $res['cuid'];
|
$edit_page_ids[$res['edit_page_id']] = $res['cuid'];
|
||||||
// create the array for pages
|
// create the array for pages
|
||||||
@@ -1303,11 +1300,9 @@ class Login
|
|||||||
{
|
{
|
||||||
$is_valid_password = true;
|
$is_valid_password = true;
|
||||||
// check for valid in regex arrays in list
|
// check for valid in regex arrays in list
|
||||||
if (is_array($this->password_valid_chars)) {
|
foreach ($this->password_valid_chars as $password_valid_chars) {
|
||||||
foreach ($this->password_valid_chars as $password_valid_chars) {
|
if (!preg_match("/$password_valid_chars/", $password)) {
|
||||||
if (!preg_match("/$password_valid_chars/", $password)) {
|
$is_valid_password = false;
|
||||||
$is_valid_password = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check for min length
|
// check for min length
|
||||||
|
|||||||
@@ -425,10 +425,7 @@ class Backend
|
|||||||
?string $set_content_path = null,
|
?string $set_content_path = null,
|
||||||
int $flag = 0,
|
int $flag = 0,
|
||||||
): array {
|
): array {
|
||||||
if (
|
if ($set_content_path === null) {
|
||||||
$set_content_path === null ||
|
|
||||||
!is_string($set_content_path)
|
|
||||||
) {
|
|
||||||
/** @deprecated adbTopMenu missing set_content_path parameter */
|
/** @deprecated adbTopMenu missing set_content_path parameter */
|
||||||
trigger_error(
|
trigger_error(
|
||||||
'Calling adbTopMenu without set_content_path parameter is deprecated',
|
'Calling adbTopMenu without set_content_path parameter is deprecated',
|
||||||
|
|||||||
@@ -119,6 +119,13 @@ class Colors
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* check if html/css color string is valid
|
* check if html/css color string is valid
|
||||||
|
*
|
||||||
|
* TODO: update check for correct validate values
|
||||||
|
* - space instead of ","
|
||||||
|
* - / opcatiy checks
|
||||||
|
* - loose numeric values
|
||||||
|
* - lab/lch,oklab/oklch validation too
|
||||||
|
*
|
||||||
* @param string $color A color string of any format
|
* @param string $color A color string of any format
|
||||||
* @param int $flags defaults to ALL, else use | to combined from
|
* @param int $flags defaults to ALL, else use | to combined from
|
||||||
* HEX_RGB, HEX_RGBA, RGB, RGBA, HSL, HSLA
|
* HEX_RGB, HEX_RGBA, RGB, RGBA, HSL, HSLA
|
||||||
@@ -168,9 +175,9 @@ class Colors
|
|||||||
if (preg_match("/$regex/", $color)) {
|
if (preg_match("/$regex/", $color)) {
|
||||||
// if valid regex, we now need to check if the content is actually valid
|
// if valid regex, we now need to check if the content is actually valid
|
||||||
// only for rgb/hsl type
|
// only for rgb/hsl type
|
||||||
/** @var int|false */
|
/** @var int<0, max>|false */
|
||||||
$rgb_flag = strpos($color, 'rgb');
|
$rgb_flag = strpos($color, 'rgb');
|
||||||
/** @var int|false */
|
/** @var int<0, max>|false */
|
||||||
$hsl_flag = strpos($color, 'hsl');
|
$hsl_flag = strpos($color, 'hsl');
|
||||||
// if both not match, return true
|
// if both not match, return true
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ class CieXyz
|
|||||||
self::convertArray(array_map(
|
self::convertArray(array_map(
|
||||||
fn ($k, $v) => $v * $d50[$k],
|
fn ($k, $v) => $v * $d50[$k],
|
||||||
array_keys($xyz),
|
array_keys($xyz),
|
||||||
array_values($xyz),
|
$xyz,
|
||||||
)),
|
)),
|
||||||
options: ["whitepoint" => 'D50']
|
options: ["whitepoint" => 'D50']
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ class Math
|
|||||||
* [0, 0, 0] <- automatically added
|
* [0, 0, 0] <- automatically added
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
|
* The same is done for unbalanced entries, they are filled with 0
|
||||||
|
*
|
||||||
* @param array<float|int|array<int|float>> $a m x n matrice
|
* @param array<float|int|array<int|float>> $a m x n matrice
|
||||||
* @param array<float|int|array<int|float>> $b n x p matrice
|
* @param array<float|int|array<int|float>> $b n x p matrice
|
||||||
*
|
*
|
||||||
@@ -186,7 +188,7 @@ class Math
|
|||||||
// so that we can multiply row by row
|
// so that we can multiply row by row
|
||||||
$bCols = array_map(
|
$bCols = array_map(
|
||||||
callback: fn ($k) => array_map(
|
callback: fn ($k) => array_map(
|
||||||
(fn ($i) => is_array($i) ? $i[$k] : 0),
|
(fn ($i) => is_array($i) ? $i[$k] ?? 0 : 0),
|
||||||
$b,
|
$b,
|
||||||
),
|
),
|
||||||
array: array_keys($b[0]),
|
array: array_keys($b[0]),
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class Uids
|
|||||||
$uniqid_length++;
|
$uniqid_length++;
|
||||||
}
|
}
|
||||||
/** @var int<1,max> make sure that internal this is correct */
|
/** @var int<1,max> make sure that internal this is correct */
|
||||||
$random_bytes_length = ($uniqid_length - ($uniqid_length % 2)) / 2;
|
$random_bytes_length = (int)(($uniqid_length - ($uniqid_length % 2)) / 2);
|
||||||
$uniqid = bin2hex(random_bytes($random_bytes_length));
|
$uniqid = bin2hex(random_bytes($random_bytes_length));
|
||||||
// if not forced shorten return next lower length
|
// if not forced shorten return next lower length
|
||||||
if (!$force_length) {
|
if (!$force_length) {
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
|||||||
public function dbDelete(array $table_array = [], bool $acl_limit = false): array
|
public function dbDelete(array $table_array = [], bool $acl_limit = false): array
|
||||||
{
|
{
|
||||||
// is array and has values, override set and set new
|
// is array and has values, override set and set new
|
||||||
if (is_array($table_array) && count($table_array)) {
|
if (count($table_array)) {
|
||||||
$this->table_array = $table_array;
|
$this->table_array = $table_array;
|
||||||
}
|
}
|
||||||
if (!$this->dbCheckPkSet()) {
|
if (!$this->dbCheckPkSet()) {
|
||||||
@@ -440,7 +440,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
|||||||
public function dbRead(bool $edit = false, array $table_array = []): array
|
public function dbRead(bool $edit = false, array $table_array = []): array
|
||||||
{
|
{
|
||||||
// if array give, overrules internal array
|
// if array give, overrules internal array
|
||||||
if (is_array($table_array) && count($table_array)) {
|
if (count($table_array)) {
|
||||||
$this->table_array = $table_array;
|
$this->table_array = $table_array;
|
||||||
}
|
}
|
||||||
if (!$this->dbCheckPkSet()) {
|
if (!$this->dbCheckPkSet()) {
|
||||||
|
|||||||
@@ -284,7 +284,8 @@ class IO
|
|||||||
public const ERROR_HASH_TYPE = 'adler32';
|
public const ERROR_HASH_TYPE = 'adler32';
|
||||||
/** @var string regex to get returning with matches at position 1 */
|
/** @var string regex to get returning with matches at position 1 */
|
||||||
public const REGEX_RETURNING = '/\s+returning\s+(.+\s*(?:.+\s*)+);?$/i';
|
public const REGEX_RETURNING = '/\s+returning\s+(.+\s*(?:.+\s*)+);?$/i';
|
||||||
/** @var array<string> allowed convert target for placeholder: pg or pdo (currently not available) */
|
/** @var array<string> allowed convert target for placeholder:
|
||||||
|
* pg or pdo (currently not available) */
|
||||||
public const DB_CONVERT_PLACEHOLDER_TARGET = ['pg'];
|
public const DB_CONVERT_PLACEHOLDER_TARGET = ['pg'];
|
||||||
// REGEX_SELECT
|
// REGEX_SELECT
|
||||||
// REGEX_UPDATE
|
// REGEX_UPDATE
|
||||||
@@ -914,7 +915,7 @@ class IO
|
|||||||
if ($cursor !== false) {
|
if ($cursor !== false) {
|
||||||
[$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError($cursor);
|
[$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError($cursor);
|
||||||
}
|
}
|
||||||
if ($cursor === false && method_exists($this->db_functions, '__dbPrintError')) {
|
if ($cursor === false && method_exists($this->db_functions, '__dbPrintError')) { /** @phpstan-ignore-line */
|
||||||
[$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError();
|
[$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError();
|
||||||
}
|
}
|
||||||
// prefix the master if not the same
|
// prefix the master if not the same
|
||||||
@@ -1311,33 +1312,14 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* count $ leading parameters only
|
* count placeholder entries in the query
|
||||||
*
|
*
|
||||||
* @param string $query Query to check
|
* @param string $query Query to check
|
||||||
* @return int Number of parameters found
|
* @return int Number of parameters found
|
||||||
*/
|
*/
|
||||||
private function __dbCountQueryParams(string $query): int
|
private function __dbCountQueryParams(string $query): int
|
||||||
{
|
{
|
||||||
$match = [];
|
return $this->db_functions->__dbCountQueryParams($query);
|
||||||
// regex for params: only stand alone $number allowed
|
|
||||||
// exclude all '' enclosed strings, ignore all numbers [note must start with digit]
|
|
||||||
// can have space/tab/new line
|
|
||||||
// must have <> = , ( [not equal, equal, comma, opening round bracket]
|
|
||||||
// can have space/tab/new line
|
|
||||||
// $ number with 1-9 for first and 0-9 for further digits
|
|
||||||
// /s for matching new line in . list
|
|
||||||
// [disabled, we don't used ^ or $] /m for multi line match
|
|
||||||
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
|
|
||||||
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
|
|
||||||
preg_match_all(
|
|
||||||
'/'
|
|
||||||
. '(?:\'.*?\')?\s*(?:\?\?|<>|' . $query_split . ')\s*'
|
|
||||||
. '(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
|
|
||||||
. '/s',
|
|
||||||
$query,
|
|
||||||
$match
|
|
||||||
);
|
|
||||||
return count(array_unique(array_filter($match[1])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1737,7 +1719,7 @@ class IO
|
|||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
!empty($this->dbh) &&
|
!empty($this->dbh) &&
|
||||||
$this->dbh instanceof \PgSql\Connection
|
$this->dbh instanceof \PgSql\Connection /** @phpstan-ignore-line future could be other */
|
||||||
) {
|
) {
|
||||||
// reset any client encodings set
|
// reset any client encodings set
|
||||||
$this->dbResetEncoding();
|
$this->dbResetEncoding();
|
||||||
@@ -3160,7 +3142,8 @@ class IO
|
|||||||
'count' => 0,
|
'count' => 0,
|
||||||
'query' => '',
|
'query' => '',
|
||||||
'result' => null,
|
'result' => null,
|
||||||
'returning_id' => false
|
'returning_id' => false,
|
||||||
|
'placeholder_converted' => [],
|
||||||
];
|
];
|
||||||
// if this is an insert query, check if we can add a return
|
// if this is an insert query, check if we can add a return
|
||||||
if ($this->dbCheckQueryForInsert($query, true)) {
|
if ($this->dbCheckQueryForInsert($query, true)) {
|
||||||
@@ -3200,6 +3183,39 @@ class IO
|
|||||||
$this->prepare_cursor[$stm_name]['pk_name'] = $pk_name;
|
$this->prepare_cursor[$stm_name]['pk_name'] = $pk_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// QUERY PARAMS: run query params check and rewrite
|
||||||
|
if ($this->dbGetConvertPlaceholder() === true) {
|
||||||
|
try {
|
||||||
|
$this->placeholder_converted = ConvertPlaceholder::convertPlaceholderInQuery(
|
||||||
|
$query,
|
||||||
|
null,
|
||||||
|
$this->dbGetConvertPlaceholderTarget()
|
||||||
|
);
|
||||||
|
// write the new queries over the old
|
||||||
|
if (!empty($this->placeholder_converted['query'])) {
|
||||||
|
$query = $this->placeholder_converted['query'];
|
||||||
|
}
|
||||||
|
$this->prepare_cursor[$stm_name]['placeholder_converted'] = $this->placeholder_converted;
|
||||||
|
} catch (\OutOfRangeException $e) {
|
||||||
|
$this->__dbError($e->getCode(), context:[
|
||||||
|
'statement_name' => $stm_name,
|
||||||
|
'query' => $query,
|
||||||
|
'location' => 'dbPrepare',
|
||||||
|
'error' => 'OutOfRangeException',
|
||||||
|
'exception' => $e
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
$this->__dbError($e->getCode(), context:[
|
||||||
|
'statement_name' => $stm_name,
|
||||||
|
'query' => $query,
|
||||||
|
'location' => 'dbPrepare',
|
||||||
|
'error' => 'RuntimeException',
|
||||||
|
'exception' => $e
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
// check prepared curser parameter count
|
// check prepared curser parameter count
|
||||||
$this->prepare_cursor[$stm_name]['count'] = $this->__dbCountQueryParams($query);
|
$this->prepare_cursor[$stm_name]['count'] = $this->__dbCountQueryParams($query);
|
||||||
$this->prepare_cursor[$stm_name]['query'] = $query;
|
$this->prepare_cursor[$stm_name]['query'] = $query;
|
||||||
@@ -3735,7 +3751,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert db values (set)
|
* convert db values (set) to php matching types
|
||||||
*
|
*
|
||||||
* @param Convert $convert
|
* @param Convert $convert
|
||||||
* @return void
|
* @return void
|
||||||
@@ -3746,7 +3762,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unsert convert db values flag
|
* unsert convert db values flag for converting db to php matching types
|
||||||
*
|
*
|
||||||
* @param Convert $convert
|
* @param Convert $convert
|
||||||
* @return void
|
* @return void
|
||||||
@@ -3757,7 +3773,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset to origincal config file set
|
* Reset to original config file set for converting db to php matching type
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -3769,7 +3785,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if a conert flag is set
|
* check if a convert flag is set for converting db to php matching type
|
||||||
*
|
*
|
||||||
* @param Convert $convert
|
* @param Convert $convert
|
||||||
* @return bool
|
* @return bool
|
||||||
@@ -3783,7 +3799,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set if we want to auto convert PDO/\Pg placeholders
|
* Set if we want to auto convert to PDO/\Pg placeholders
|
||||||
*
|
*
|
||||||
* @param bool $flag
|
* @param bool $flag
|
||||||
* @return void
|
* @return void
|
||||||
@@ -4294,7 +4310,7 @@ class IO
|
|||||||
* @param string $stm_name The name of the stored statement
|
* @param string $stm_name The name of the stored statement
|
||||||
* @param string $key Key field name in prepared cursor array
|
* @param string $key Key field name in prepared cursor array
|
||||||
* Allowed are: pk_name, count, query, returning_id
|
* Allowed are: pk_name, count, query, returning_id
|
||||||
* @return null|string|int|bool Entry from each of the valid keys
|
* @return null|string|int|bool|array<string,mixed> Entry from each of the valid keys
|
||||||
* Will return false on error
|
* Will return false on error
|
||||||
* Not ethat returnin_id also can return false
|
* Not ethat returnin_id also can return false
|
||||||
* but will not set an error entry
|
* but will not set an error entry
|
||||||
@@ -4302,7 +4318,7 @@ class IO
|
|||||||
public function dbGetPrepareCursorValue(
|
public function dbGetPrepareCursorValue(
|
||||||
string $stm_name,
|
string $stm_name,
|
||||||
string $key
|
string $key
|
||||||
): null|string|int|bool {
|
): null|string|int|bool|array {
|
||||||
// if no statement name
|
// if no statement name
|
||||||
if (empty($stm_name)) {
|
if (empty($stm_name)) {
|
||||||
$this->__dbError(
|
$this->__dbError(
|
||||||
@@ -4313,7 +4329,7 @@ class IO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// if not a valid key
|
// if not a valid key
|
||||||
if (!in_array($key, ['pk_name', 'count', 'query', 'returning_id'])) {
|
if (!in_array($key, ['pk_name', 'count', 'query', 'returning_id', 'placeholder_converted'])) {
|
||||||
$this->__dbError(
|
$this->__dbError(
|
||||||
102,
|
102,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace CoreLibs\DB\SQL;
|
namespace CoreLibs\DB\SQL;
|
||||||
|
|
||||||
|
use CoreLibs\DB\Support\ConvertPlaceholder;
|
||||||
|
|
||||||
// below no ignore is needed if we want to use PgSql interface checks with PHP 8.0
|
// below no ignore is needed if we want to use PgSql interface checks with PHP 8.0
|
||||||
// as main system. Currently all @var sets are written as object
|
// as main system. Currently all @var sets are written as object
|
||||||
/** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */
|
/** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */
|
||||||
@@ -102,7 +104,7 @@ class PgSQL implements Interface\SqlFunctions
|
|||||||
* SELECT foo FROM bar WHERE foobar = $1
|
* SELECT foo FROM bar WHERE foobar = $1
|
||||||
*
|
*
|
||||||
* @param string $query Query string with placeholders $1, ..
|
* @param string $query Query string with placeholders $1, ..
|
||||||
* @param array<mixed> $params Matching parameters for each placerhold
|
* @param array<mixed> $params Matching parameters for each placeholder
|
||||||
* @return \PgSql\Result|false Query result
|
* @return \PgSql\Result|false Query result
|
||||||
*/
|
*/
|
||||||
public function __dbQueryParams(string $query, array $params): \PgSql\Result|false
|
public function __dbQueryParams(string $query, array $params): \PgSql\Result|false
|
||||||
@@ -140,7 +142,7 @@ class PgSQL implements Interface\SqlFunctions
|
|||||||
* sends an async query to the server with params
|
* sends an async query to the server with params
|
||||||
*
|
*
|
||||||
* @param string $query Query string with placeholders $1, ..
|
* @param string $query Query string with placeholders $1, ..
|
||||||
* @param array<mixed> $params Matching parameters for each placerhold
|
* @param array<mixed> $params Matching parameters for each placeholder
|
||||||
* @return bool true/false Query sent successful status
|
* @return bool true/false Query sent successful status
|
||||||
*/
|
*/
|
||||||
public function __dbSendQueryParams(string $query, array $params): bool
|
public function __dbSendQueryParams(string $query, array $params): bool
|
||||||
@@ -966,6 +968,34 @@ class PgSQL implements Interface\SqlFunctions
|
|||||||
{
|
{
|
||||||
return $this->__dbShow('client_encoding');
|
return $this->__dbShow('client_encoding');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count placeholder queries. $ only
|
||||||
|
*
|
||||||
|
* @param string $query
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function __dbCountQueryParams(string $query): int
|
||||||
|
{
|
||||||
|
$matches = [];
|
||||||
|
// regex for params: only stand alone $number allowed
|
||||||
|
// exclude all '' enclosed strings, ignore all numbers [note must start with digit]
|
||||||
|
// can have space/tab/new line
|
||||||
|
// must have <> = , ( [not equal, equal, comma, opening round bracket]
|
||||||
|
// can have space/tab/new line
|
||||||
|
// $ number with 1-9 for first and 0-9 for further digits
|
||||||
|
// Collects also PDO ? and :named, but they are ignored
|
||||||
|
// /s for matching new line in . list
|
||||||
|
// [disabled, we don't used ^ or $] /m for multi line match
|
||||||
|
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
|
||||||
|
// Regex located in the ConvertPlaceholder class
|
||||||
|
preg_match_all(
|
||||||
|
ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS,
|
||||||
|
$query,
|
||||||
|
$matches
|
||||||
|
);
|
||||||
|
return count(array_unique(array_filter($matches[3])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
|
|||||||
@@ -14,6 +14,67 @@ namespace CoreLibs\DB\Support;
|
|||||||
|
|
||||||
class ConvertPlaceholder
|
class ConvertPlaceholder
|
||||||
{
|
{
|
||||||
|
/** @var string split regex */
|
||||||
|
private const PATTERN_QUERY_SPLIT = '[(<>=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
|
||||||
|
/** @var string the main regex including the pattern query split */
|
||||||
|
private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:\?\?|' . self::PATTERN_QUERY_SPLIT . ')\s*';
|
||||||
|
/** @var string parts to ignore in the SQL */
|
||||||
|
private const PATTERN_IGNORE =
|
||||||
|
// digit -> ignore
|
||||||
|
'\d+|'
|
||||||
|
// other string -> ignore
|
||||||
|
. '(?:\'.*?\')|';
|
||||||
|
/** @var string named parameters */
|
||||||
|
private const PATTERN_NAMED = '(:\w+)';
|
||||||
|
/** @var string question mark parameters */
|
||||||
|
private const PATTERN_QUESTION_MARK = '(?:(?:\?\?)?\s*(\?{1}))';
|
||||||
|
/** @var string numbered parameters */
|
||||||
|
private const PATTERN_NUMBERED = '(\$[1-9]{1}(?:[0-9]{1,})?)';
|
||||||
|
// below here are full regex that will be used
|
||||||
|
/** @var string replace regex for named (:...) entries */
|
||||||
|
public const REGEX_REPLACE_NAMED = '/'
|
||||||
|
. '(' . self::PATTERN_ELEMENT . ')'
|
||||||
|
. '('
|
||||||
|
. self::PATTERN_IGNORE
|
||||||
|
. self::PATTERN_NAMED
|
||||||
|
. ')'
|
||||||
|
. '/s';
|
||||||
|
/** @var string replace regex for question mark (?) entries */
|
||||||
|
public const REGEX_REPLACE_QUESTION_MARK = '/'
|
||||||
|
. '(' . self::PATTERN_ELEMENT . ')'
|
||||||
|
. '('
|
||||||
|
. self::PATTERN_IGNORE
|
||||||
|
. self::PATTERN_QUESTION_MARK
|
||||||
|
. ')'
|
||||||
|
. '/s';
|
||||||
|
/** @var string replace regex for numbered ($n) entries */
|
||||||
|
public const REGEX_REPLACE_NUMBERED = '/'
|
||||||
|
. '(' . self::PATTERN_ELEMENT . ')'
|
||||||
|
. '('
|
||||||
|
. self::PATTERN_IGNORE
|
||||||
|
. self::PATTERN_NUMBERED
|
||||||
|
. ')'
|
||||||
|
. '/s';
|
||||||
|
/** @var string the main lookup query for all placeholders */
|
||||||
|
public const REGEX_LOOKUP_PLACEHOLDERS = '/'
|
||||||
|
// prefix string part, must match towards
|
||||||
|
// seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
|
||||||
|
. self::PATTERN_ELEMENT
|
||||||
|
// match for replace part
|
||||||
|
. '(?:'
|
||||||
|
// ignore parts
|
||||||
|
. self::PATTERN_IGNORE
|
||||||
|
// :name named part (PDO) [1]
|
||||||
|
. self::PATTERN_NAMED . '|'
|
||||||
|
// ? question mark part (PDO) [2]
|
||||||
|
. self::PATTERN_QUESTION_MARK . '|'
|
||||||
|
// $n numbered part (\PG php) [3]
|
||||||
|
. self::PATTERN_NUMBERED
|
||||||
|
// end match
|
||||||
|
. ')'
|
||||||
|
// single line -> add line break to matches in "."
|
||||||
|
. '/s';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert PDO type query with placeholders to \PG style and vica versa
|
* Convert PDO type query with placeholders to \PG style and vica versa
|
||||||
* For PDO to: ? and :named
|
* For PDO to: ? and :named
|
||||||
@@ -27,44 +88,24 @@ class ConvertPlaceholder
|
|||||||
* found has -1 if an error occoured in the preg_match_all call
|
* found has -1 if an error occoured in the preg_match_all call
|
||||||
*
|
*
|
||||||
* @param string $query Query with placeholders to convert
|
* @param string $query Query with placeholders to convert
|
||||||
* @param array<mixed> $params The parameters that are used for the query, and will be updated
|
* @param ?array<mixed> $params The parameters that are used for the query, and will be updated
|
||||||
* @param string $convert_to Either pdo or pg, will be converted to lower case for check
|
* @param string $convert_to Either pdo or pg, will be converted to lower case for check
|
||||||
* @return array{original:array{query:string,params:array<mixed>},type:''|'named'|'numbered'|'question_mark',found:int,matches:array<string>,params_lookup:array<mixed>,query:string,params:array<mixed>}
|
* @return array{original:array{query:string,params:array<mixed>,empty_params:bool},type:''|'named'|'numbered'|'question_mark',found:int,matches:array<string>,params_lookup:array<mixed>,query:string,params:array<mixed>}
|
||||||
* @throws \OutOfRangeException 200
|
* @throws \OutOfRangeException 200 If mixed placeholder types
|
||||||
|
* @throws \InvalidArgumentException 300 or 301 if wrong convert to with found placeholders
|
||||||
*/
|
*/
|
||||||
public static function convertPlaceholderInQuery(
|
public static function convertPlaceholderInQuery(
|
||||||
string $query,
|
string $query,
|
||||||
array $params,
|
?array $params,
|
||||||
string $convert_to = 'pg'
|
string $convert_to = 'pg'
|
||||||
): array {
|
): array {
|
||||||
$convert_to = strtolower($convert_to);
|
$convert_to = strtolower($convert_to);
|
||||||
$matches = [];
|
$matches = [];
|
||||||
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
|
|
||||||
$pattern = '/'
|
|
||||||
// prefix string part, must match towards
|
|
||||||
// seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
|
|
||||||
. '(?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*'
|
|
||||||
// match for replace part
|
|
||||||
. '(?:'
|
|
||||||
// digit -> ignore
|
|
||||||
. '\d+|'
|
|
||||||
// other string -> ignore
|
|
||||||
. '(?:\'.*?\')|'
|
|
||||||
// :name named part (PDO)
|
|
||||||
. '(:\w+)|'
|
|
||||||
// ? question mark part (PDO)
|
|
||||||
. '(?:(?:\?\?)?\s*(\?{1}))|'
|
|
||||||
// $n numbered part (\PG php)
|
|
||||||
. '(\$[1-9]{1}(?:[0-9]{1,})?)'
|
|
||||||
// end match
|
|
||||||
. ')'
|
|
||||||
// single line -> add line break to matches in "."
|
|
||||||
. '/s';
|
|
||||||
// matches:
|
// matches:
|
||||||
// 1: :named
|
// 1: :named
|
||||||
// 2: ? question mark
|
// 2: ? question mark
|
||||||
// 3: $n numbered
|
// 3: $n numbered
|
||||||
$found = preg_match_all($pattern, $query, $matches, PREG_UNMATCHED_AS_NULL);
|
$found = preg_match_all(self::REGEX_LOOKUP_PLACEHOLDERS, $query, $matches, PREG_UNMATCHED_AS_NULL);
|
||||||
// if false or null set to -1
|
// if false or null set to -1
|
||||||
// || $found === null
|
// || $found === null
|
||||||
if ($found === false) {
|
if ($found === false) {
|
||||||
@@ -77,10 +118,10 @@ class ConvertPlaceholder
|
|||||||
/** @var array<string> 3: $n matches */
|
/** @var array<string> 3: $n matches */
|
||||||
$numbered_matches = array_filter($matches[3]);
|
$numbered_matches = array_filter($matches[3]);
|
||||||
// count matches
|
// count matches
|
||||||
$count_named = count($named_matches);
|
$count_named = count(array_unique($named_matches));
|
||||||
$count_qmark = count($qmark_matches);
|
$count_qmark = count($qmark_matches);
|
||||||
$count_numbered = count($numbered_matches);
|
$count_numbered = count(array_unique($numbered_matches));
|
||||||
// throw if mixed
|
// throw exception if mixed found
|
||||||
if (
|
if (
|
||||||
($count_named && $count_qmark) ||
|
($count_named && $count_qmark) ||
|
||||||
($count_named && $count_numbered) ||
|
($count_named && $count_numbered) ||
|
||||||
@@ -88,140 +129,195 @@ class ConvertPlaceholder
|
|||||||
) {
|
) {
|
||||||
throw new \OutOfRangeException('Cannot have named, question mark and numbered in the same query', 200);
|
throw new \OutOfRangeException('Cannot have named, question mark and numbered in the same query', 200);
|
||||||
}
|
}
|
||||||
// rebuild
|
// // throw if invalid conversion
|
||||||
$matches_return = [];
|
// if (($count_named || $count_qmark) && $convert_to != 'pg') {
|
||||||
$type = '';
|
// throw new \InvalidArgumentException('Cannot convert from named or question mark placeholders to PDO', 300);
|
||||||
|
// }
|
||||||
|
// if ($count_numbered && $convert_to != 'pdo') {
|
||||||
|
// throw new \InvalidArgumentException('Cannot convert from numbered placeholders to Pg', 301);
|
||||||
|
// }
|
||||||
|
// return array
|
||||||
|
$return_placeholders = [
|
||||||
|
// original
|
||||||
|
'original' => [
|
||||||
|
'query' => $query,
|
||||||
|
'params' => $params ?? [],
|
||||||
|
'empty_params' => $params === null ? true : false,
|
||||||
|
],
|
||||||
|
// type found, empty if nothing was done
|
||||||
|
'type' => '',
|
||||||
|
// int: found, not found; -1: problem (set from false)
|
||||||
|
'found' => (int)$found,
|
||||||
|
'matches' => [],
|
||||||
|
// old to new lookup check
|
||||||
|
'params_lookup' => [],
|
||||||
|
// this must match the count in params in new
|
||||||
|
'needed' => 0,
|
||||||
|
// new
|
||||||
|
'query' => '',
|
||||||
|
'params' => [],
|
||||||
|
];
|
||||||
|
// replace basic regex and name settings
|
||||||
|
if ($count_named) {
|
||||||
|
$return_placeholders['type'] = 'named';
|
||||||
|
$return_placeholders['matches'] = $named_matches;
|
||||||
|
$return_placeholders['needed'] = $count_named;
|
||||||
|
} elseif ($count_qmark) {
|
||||||
|
$return_placeholders['type'] = 'question_mark';
|
||||||
|
$return_placeholders['matches'] = $qmark_matches;
|
||||||
|
$return_placeholders['needed'] = $count_qmark;
|
||||||
|
// for each ?:DTN: -> replace with $1 ... $n, any remaining :DTN: remove
|
||||||
|
} elseif ($count_numbered) {
|
||||||
|
$return_placeholders['type'] = 'numbered';
|
||||||
|
$return_placeholders['matches'] = $numbered_matches;
|
||||||
|
$return_placeholders['needed'] = $count_numbered;
|
||||||
|
}
|
||||||
|
// run convert only if matching type and direction
|
||||||
|
if (
|
||||||
|
(($count_named || $count_qmark) && $convert_to == 'pg') ||
|
||||||
|
($count_numbered && $convert_to == 'pdo')
|
||||||
|
) {
|
||||||
|
$param_list = self::updateParamList($return_placeholders);
|
||||||
|
$return_placeholders['params_lookup'] = $param_list['params_lookup'];
|
||||||
|
$return_placeholders['query'] = $param_list['query'];
|
||||||
|
$return_placeholders['params'] = $param_list['params'];
|
||||||
|
}
|
||||||
|
// return data
|
||||||
|
return $return_placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the params list from one style to the other to match the query output
|
||||||
|
* if original.empty_params is set to true, no params replacement is done
|
||||||
|
* if param replacement has been done in a dbPrepare then this has to be run
|
||||||
|
* with the return palceholders array with params in original filled and empty_params turned off
|
||||||
|
*
|
||||||
|
* phpcs:disable Generic.Files.LineLength
|
||||||
|
* @param array{original:array{query:string,params:array<mixed>,empty_params:bool},type:''|'named'|'numbered'|'question_mark',found:int,matches?:array<string>,params_lookup?:array<mixed>,query?:string,params?:array<mixed>} $converted_placeholders
|
||||||
|
* phpcs:enable Generic.Files.LineLength
|
||||||
|
* @return array{params_lookup:array<mixed>,query:string,params:array<mixed>}
|
||||||
|
*/
|
||||||
|
public static function updateParamList(array $converted_placeholders): array
|
||||||
|
{
|
||||||
|
// skip if nothing set
|
||||||
|
if (!$converted_placeholders['found']) {
|
||||||
|
return [
|
||||||
|
'params_lookup' => [],
|
||||||
|
'query' => '',
|
||||||
|
'params' => []
|
||||||
|
];
|
||||||
|
}
|
||||||
$query_new = '';
|
$query_new = '';
|
||||||
$params_new = [];
|
$params_new = [];
|
||||||
$params_lookup = [];
|
$params_lookup = [];
|
||||||
if ($count_named && $convert_to == 'pg') {
|
// set to null if params is empty
|
||||||
$type = 'named';
|
$params = $converted_placeholders['original']['params'];
|
||||||
$matches_return = $named_matches;
|
$empty_params = $converted_placeholders['original']['empty_params'];
|
||||||
// only check for :named
|
switch ($converted_placeholders['type']) {
|
||||||
$pattern_replace = '/'
|
case 'named':
|
||||||
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
|
// 0: full
|
||||||
. '(\d+|(?:\'.*?\')|(:\w+))'
|
// 0: full
|
||||||
. '/s';
|
// 1: pre part
|
||||||
// 0: full
|
// 2: keep part UNLESS '3' is set
|
||||||
// 1: pre part
|
// 3: replace part :named
|
||||||
// 2: keep part UNLESS '3' is set
|
$pos = 0;
|
||||||
// 3: replace part :named
|
$query_new = preg_replace_callback(
|
||||||
$pos = 0;
|
self::REGEX_REPLACE_NAMED,
|
||||||
$query_new = preg_replace_callback(
|
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
||||||
$pattern_replace,
|
// only count up if $match[3] is not yet in lookup table
|
||||||
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params) {
|
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
||||||
// only count up if $match[3] is not yet in lookup table
|
$pos++;
|
||||||
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
$params_lookup[$matches[3]] = '$' . $pos;
|
||||||
$pos++;
|
// skip params setup if param list is empty
|
||||||
$params_lookup[$matches[3]] = '$' . $pos;
|
if (!$empty_params) {
|
||||||
$params_new[] = $params[$matches[3]] ??
|
$params_new[] = $params[$matches[3]] ??
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
'Cannot lookup ' . $matches[3] . ' in params list',
|
'Cannot lookup ' . $matches[3] . ' in params list',
|
||||||
210
|
210
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
}
|
||||||
return $matches[1] . (
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
empty($matches[3]) ?
|
return $matches[1] . (
|
||||||
$matches[2] :
|
empty($matches[3]) ?
|
||||||
$params_lookup[$matches[3]] ??
|
$matches[2] :
|
||||||
|
$params_lookup[$matches[3]] ??
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
||||||
|
211
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
$converted_placeholders['original']['query']
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'question_mark':
|
||||||
|
if (!$empty_params) {
|
||||||
|
// order and data stays the same
|
||||||
|
$params_new = $params ?? [];
|
||||||
|
}
|
||||||
|
// 0: full
|
||||||
|
// 1: pre part
|
||||||
|
// 2: keep part UNLESS '3' is set
|
||||||
|
// 3: replace part ?
|
||||||
|
$pos = 0;
|
||||||
|
$query_new = preg_replace_callback(
|
||||||
|
self::REGEX_REPLACE_QUESTION_MARK,
|
||||||
|
function ($matches) use (&$pos, &$params_lookup) {
|
||||||
|
// only count pos up for actual replacements we will do
|
||||||
|
if (!empty($matches[3])) {
|
||||||
|
$pos++;
|
||||||
|
$params_lookup[] = '$' . $pos;
|
||||||
|
}
|
||||||
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
|
return $matches[1] . (
|
||||||
|
empty($matches[3]) ?
|
||||||
|
$matches[2] :
|
||||||
|
'$' . $pos
|
||||||
|
);
|
||||||
|
},
|
||||||
|
$converted_placeholders['original']['query']
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'numbered':
|
||||||
|
// 0: full
|
||||||
|
// 1: pre part
|
||||||
|
// 2: keep part UNLESS '3' is set
|
||||||
|
// 3: replace part $numbered
|
||||||
|
$pos = 0;
|
||||||
|
$query_new = preg_replace_callback(
|
||||||
|
self::REGEX_REPLACE_NUMBERED,
|
||||||
|
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
||||||
|
// only count up if $match[3] is not yet in lookup table
|
||||||
|
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
||||||
|
$pos++;
|
||||||
|
$params_lookup[$matches[3]] = ':' . $pos . '_named';
|
||||||
|
// skip params setup if param list is empty
|
||||||
|
if (!$empty_params) {
|
||||||
|
$params_new[] = $params[($pos - 1)] ??
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'Cannot lookup ' . ($pos - 1) . ' in params list',
|
||||||
|
220
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
|
return $matches[1] . (
|
||||||
|
empty($matches[3]) ?
|
||||||
|
$matches[2] :
|
||||||
|
$params_lookup[$matches[3]] ??
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
||||||
211
|
221
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
$query
|
$converted_placeholders['original']['query']
|
||||||
);
|
);
|
||||||
} elseif ($count_qmark && $convert_to == 'pg') {
|
break;
|
||||||
$type = 'question_mark';
|
|
||||||
$matches_return = $qmark_matches;
|
|
||||||
// order and data stays the same
|
|
||||||
$params_new = $params;
|
|
||||||
// only check for ?
|
|
||||||
$pattern_replace = '/'
|
|
||||||
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
|
|
||||||
. '(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))'
|
|
||||||
. '/s';
|
|
||||||
// 0: full
|
|
||||||
// 1: pre part
|
|
||||||
// 2: keep part UNLESS '3' is set
|
|
||||||
// 3: replace part ?
|
|
||||||
$pos = 0;
|
|
||||||
$query_new = preg_replace_callback(
|
|
||||||
$pattern_replace,
|
|
||||||
function ($matches) use (&$pos, &$params_lookup) {
|
|
||||||
// only count pos up for actual replacements we will do
|
|
||||||
if (!empty($matches[3])) {
|
|
||||||
$pos++;
|
|
||||||
$params_lookup[] = '$' . $pos;
|
|
||||||
}
|
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
|
||||||
return $matches[1] . (
|
|
||||||
empty($matches[3]) ?
|
|
||||||
$matches[2] :
|
|
||||||
'$' . $pos
|
|
||||||
);
|
|
||||||
},
|
|
||||||
$query
|
|
||||||
);
|
|
||||||
// for each ?:DTN: -> replace with $1 ... $n, any remaining :DTN: remove
|
|
||||||
} elseif ($count_numbered && $convert_to == 'pdo') {
|
|
||||||
// convert numbered to named
|
|
||||||
$type = 'numbered';
|
|
||||||
$matches_return = $numbered_matches;
|
|
||||||
// only check for $n
|
|
||||||
$pattern_replace = '/'
|
|
||||||
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
|
|
||||||
. '(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
|
|
||||||
. '/s';
|
|
||||||
// 0: full
|
|
||||||
// 1: pre part
|
|
||||||
// 2: keep part UNLESS '3' is set
|
|
||||||
// 3: replace part $numbered
|
|
||||||
$pos = 0;
|
|
||||||
$query_new = preg_replace_callback(
|
|
||||||
$pattern_replace,
|
|
||||||
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params) {
|
|
||||||
// only count up if $match[3] is not yet in lookup table
|
|
||||||
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
|
||||||
$pos++;
|
|
||||||
$params_lookup[$matches[3]] = ':' . $pos . '_named';
|
|
||||||
$params_new[] = $params[($pos - 1)] ??
|
|
||||||
throw new \RuntimeException(
|
|
||||||
'Cannot lookup ' . ($pos - 1) . ' in params list',
|
|
||||||
220
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
|
||||||
return $matches[1] . (
|
|
||||||
empty($matches[3]) ?
|
|
||||||
$matches[2] :
|
|
||||||
$params_lookup[$matches[3]] ??
|
|
||||||
throw new \RuntimeException(
|
|
||||||
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
|
||||||
221
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
$query
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// return, old query is always set
|
|
||||||
return [
|
return [
|
||||||
// original
|
|
||||||
'original' => [
|
|
||||||
'query' => $query,
|
|
||||||
'params' => $params,
|
|
||||||
],
|
|
||||||
// type found, empty if nothing was done
|
|
||||||
'type' => $type,
|
|
||||||
// int: found, not found; -1: problem (set from false)
|
|
||||||
'found' => (int)$found,
|
|
||||||
'matches' => $matches_return,
|
|
||||||
// old to new lookup check
|
|
||||||
'params_lookup' => $params_lookup,
|
'params_lookup' => $params_lookup,
|
||||||
// new
|
|
||||||
'query' => $query_new ?? '',
|
'query' => $query_new ?? '',
|
||||||
'params' => $params_new,
|
'params' => $params_new,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ class GetTextReader
|
|||||||
private function loadTables(): void
|
private function loadTables(): void
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
is_array($this->cache_translations) &&
|
|
||||||
is_array($this->table_originals) &&
|
is_array($this->table_originals) &&
|
||||||
is_array($this->table_translations)
|
is_array($this->table_translations)
|
||||||
) {
|
) {
|
||||||
@@ -318,10 +317,7 @@ class GetTextReader
|
|||||||
|
|
||||||
if ($this->enable_cache) {
|
if ($this->enable_cache) {
|
||||||
// Caching enabled, get translated string from cache
|
// Caching enabled, get translated string from cache
|
||||||
if (
|
if (array_key_exists($string, $this->cache_translations)) {
|
||||||
is_array($this->cache_translations) &&
|
|
||||||
array_key_exists($string, $this->cache_translations)
|
|
||||||
) {
|
|
||||||
return $this->cache_translations[$string];
|
return $this->cache_translations[$string];
|
||||||
} else {
|
} else {
|
||||||
return $string;
|
return $string;
|
||||||
@@ -481,7 +477,7 @@ class GetTextReader
|
|||||||
$key = $single . chr(0) . $plural;
|
$key = $single . chr(0) . $plural;
|
||||||
|
|
||||||
if ($this->enable_cache) {
|
if ($this->enable_cache) {
|
||||||
if (is_array($this->cache_translations) && !array_key_exists($key, $this->cache_translations)) {
|
if (!array_key_exists($key, $this->cache_translations)) {
|
||||||
return ($number != 1) ? $plural : $single;
|
return ($number != 1) ? $plural : $single;
|
||||||
} else {
|
} else {
|
||||||
$result = $this->cache_translations[$key];
|
$result = $this->cache_translations[$key];
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ class Generate
|
|||||||
$page_name_camel_case
|
$page_name_camel_case
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
/** @var TableArrays\Interface\TableArraysInterface|false $class */
|
/** @var TableArrays\Interface\TableArraysInterface $class */
|
||||||
$class = new $class_string($this);
|
$class = new $class_string($this);
|
||||||
} catch (\Throwable $t) {
|
} catch (\Throwable $t) {
|
||||||
$this->log->critical('CLASS LOADING: Failed loading: ' . $class_string . ' => ' . $t->getMessage());
|
$this->log->critical('CLASS LOADING: Failed loading: ' . $class_string . ' => ' . $t->getMessage());
|
||||||
@@ -1757,14 +1757,9 @@ class Generate
|
|||||||
$this->dba->setTableArrayEntry($this->dba->getTableArray()[$key]['preset'], $key, 'value');
|
$this->dba->setTableArrayEntry($this->dba->getTableArray()[$key]['preset'], $key, 'value');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_array($this->reference_array)) {
|
reset($this->reference_array);
|
||||||
if (!is_array($this->reference_array)) {
|
foreach ($this->reference_array as $key => $value) {
|
||||||
$this->reference_array = [];
|
unset($this->reference_array[$key]['selected']);
|
||||||
}
|
|
||||||
reset($this->reference_array);
|
|
||||||
foreach ($this->reference_array as $key => $value) {
|
|
||||||
unset($this->reference_array[$key]['selected']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$this->warning = 1;
|
$this->warning = 1;
|
||||||
$this->msg = $this->l->__('Cleared for new Dataset!');
|
$this->msg = $this->l->__('Cleared for new Dataset!');
|
||||||
@@ -1787,20 +1782,15 @@ class Generate
|
|||||||
$this->dba->unsetTableArrayEntry($key, 'input_value');
|
$this->dba->unsetTableArrayEntry($key, 'input_value');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($this->reference_array)) {
|
// load each reference_table
|
||||||
// load each reference_table
|
reset($this->reference_array);
|
||||||
if (!is_array($this->reference_array)) {
|
foreach ($this->reference_array as $key => $value) {
|
||||||
$this->reference_array = [];
|
unset($this->reference_array[$key]['selected']);
|
||||||
}
|
$q = 'SELECT ' . $this->reference_array[$key]['other_table_pk']
|
||||||
reset($this->reference_array);
|
. ' FROM ' . $this->reference_array[$key]['table_name']
|
||||||
foreach ($this->reference_array as $key => $value) {
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
||||||
unset($this->reference_array[$key]['selected']);
|
while (is_array($res = $this->dba->dbReturn($q))) {
|
||||||
$q = 'SELECT ' . $this->reference_array[$key]['other_table_pk']
|
$this->reference_array[$key]['selected'][] = $res[$this->reference_array[$key]['other_table_pk']];
|
||||||
. ' FROM ' . $this->reference_array[$key]['table_name']
|
|
||||||
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
|
||||||
while (is_array($res = $this->dba->dbReturn($q))) {
|
|
||||||
$this->reference_array[$key]['selected'][] = $res[$this->reference_array[$key]['other_table_pk']];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->warning = 1;
|
$this->warning = 1;
|
||||||
@@ -1979,24 +1969,19 @@ class Generate
|
|||||||
// write the object
|
// write the object
|
||||||
$this->dba->dbWrite($addslashes, [], true);
|
$this->dba->dbWrite($addslashes, [], true);
|
||||||
// write reference array (s) if necessary
|
// write reference array (s) if necessary
|
||||||
if (is_array($this->reference_array)) {
|
reset($this->reference_array);
|
||||||
if (!is_array($this->reference_array)) {
|
foreach ($this->reference_array as $reference_array) {
|
||||||
$this->reference_array = [];
|
$q = 'DELETE FROM ' . $reference_array['table_name']
|
||||||
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
||||||
|
$this->dba->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->dba->getTableArray()[$this->int_pk_name]['value'] . ')';
|
||||||
|
$this->dba->dbExec($q . $t_q);
|
||||||
}
|
}
|
||||||
reset($this->reference_array);
|
} // foreach reference arrays
|
||||||
foreach ($this->reference_array as $reference_array) {
|
|
||||||
$q = 'DELETE FROM ' . $reference_array['table_name']
|
|
||||||
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
|
||||||
$this->dba->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->dba->getTableArray()[$this->int_pk_name]['value'] . ')';
|
|
||||||
$this->dba->dbExec($q . $t_q);
|
|
||||||
}
|
|
||||||
} // foreach reference arrays
|
|
||||||
} // if reference arrays
|
|
||||||
// write element list
|
// write element list
|
||||||
if (!empty($this->element_list)) {
|
if (!empty($this->element_list)) {
|
||||||
$type = [];
|
$type = [];
|
||||||
@@ -2230,16 +2215,11 @@ class Generate
|
|||||||
public function formDeleteTableArray()
|
public function formDeleteTableArray()
|
||||||
{
|
{
|
||||||
// remove any reference arrays
|
// remove any reference arrays
|
||||||
if (is_array($this->reference_array)) {
|
reset($this->reference_array);
|
||||||
if (!is_array($this->reference_array)) {
|
foreach ($this->reference_array as $reference_array) {
|
||||||
$this->reference_array = [];
|
$q = 'DELETE FROM ' . $reference_array['table_name']
|
||||||
}
|
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
||||||
reset($this->reference_array);
|
$this->dba->dbExec($q);
|
||||||
foreach ($this->reference_array as $reference_array) {
|
|
||||||
$q = 'DELETE FROM ' . $reference_array['table_name']
|
|
||||||
. ' WHERE ' . $this->int_pk_name . ' = ' . $this->dba->getTableArray()[$this->int_pk_name]['value'];
|
|
||||||
$this->dba->dbExec($q);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// remove any element list references
|
// remove any element list references
|
||||||
if (!empty($this->element_list)) {
|
if (!empty($this->element_list)) {
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ class Image
|
|||||||
}
|
}
|
||||||
// check resize parameters
|
// check resize parameters
|
||||||
if ($inc_width > $thumb_width || $inc_height > $thumb_height) {
|
if ($inc_width > $thumb_width || $inc_height > $thumb_height) {
|
||||||
$thumb_width_r = 0;
|
$thumb_width_r = 1;
|
||||||
$thumb_height_r = 0;
|
$thumb_height_r = 1;
|
||||||
// we need to keep the aspect ration on longest side
|
// we need to keep the aspect ration on longest side
|
||||||
if (
|
if (
|
||||||
($inc_height > $inc_width &&
|
($inc_height > $inc_width &&
|
||||||
@@ -288,6 +288,12 @@ class Image
|
|||||||
!file_exists($thumbnail_write_path . $thumbnail)
|
!file_exists($thumbnail_write_path . $thumbnail)
|
||||||
) {
|
) {
|
||||||
// image, copy source image, offset in image, source x/y, new size, source image size
|
// image, copy source image, offset in image, source x/y, new size, source image size
|
||||||
|
if ($thumb_width_r < 1) {
|
||||||
|
$thumb_width_r = 1;
|
||||||
|
}
|
||||||
|
if ($thumb_height_r < 1) {
|
||||||
|
$thumb_height_r = 1;
|
||||||
|
}
|
||||||
$thumb = imagecreatetruecolor($thumb_width_r, $thumb_height_r);
|
$thumb = imagecreatetruecolor($thumb_width_r, $thumb_height_r);
|
||||||
if ($thumb === false) {
|
if ($thumb === false) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
@@ -380,9 +386,7 @@ class Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add output path
|
// add output path
|
||||||
if ($thumbnail !== false) {
|
$thumbnail = $thumbnail_web_path . $thumbnail;
|
||||||
$thumbnail = $thumbnail_web_path . $thumbnail;
|
|
||||||
}
|
|
||||||
} elseif ($create_dummy === true) {
|
} elseif ($create_dummy === true) {
|
||||||
// create dummy image in the thumbnail size
|
// create dummy image in the thumbnail size
|
||||||
// if one side is missing, use the other side to create a square
|
// if one side is missing, use the other side to create a square
|
||||||
@@ -399,10 +403,10 @@ class Image
|
|||||||
!file_exists($thumbnail_write_path . $thumbnail)
|
!file_exists($thumbnail_write_path . $thumbnail)
|
||||||
) {
|
) {
|
||||||
// if both are unset, set to 250
|
// if both are unset, set to 250
|
||||||
if ($thumb_height == 0) {
|
if ($thumb_height < 1) {
|
||||||
$thumb_height = 250;
|
$thumb_height = 250;
|
||||||
}
|
}
|
||||||
if ($thumb_width == 0) {
|
if ($thumb_width < 1) {
|
||||||
$thumb_width = 250;
|
$thumb_width = 250;
|
||||||
}
|
}
|
||||||
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
|
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
|
||||||
|
|||||||
@@ -599,7 +599,7 @@ class Curl implements Interface\RequestsInterface
|
|||||||
// for post we set POST option
|
// for post we set POST option
|
||||||
if ($type == "post") {
|
if ($type == "post") {
|
||||||
curl_setopt($handle, CURLOPT_POST, true);
|
curl_setopt($handle, CURLOPT_POST, true);
|
||||||
} elseif (in_array($type, self::CUSTOM_REQUESTS)) {
|
} elseif (!empty($type) && in_array($type, self::CUSTOM_REQUESTS)) {
|
||||||
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, strtoupper($type));
|
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, strtoupper($type));
|
||||||
}
|
}
|
||||||
// set body data if not null, will send empty [] for empty data
|
// set body data if not null, will send empty [] for empty data
|
||||||
@@ -700,12 +700,12 @@ class Curl implements Interface\RequestsInterface
|
|||||||
// if we have a timeout signal
|
// if we have a timeout signal
|
||||||
if (!empty($this->config['timeout'])) {
|
if (!empty($this->config['timeout'])) {
|
||||||
$timeout_requires_no_signal = $this->config['timeout'] < 1;
|
$timeout_requires_no_signal = $this->config['timeout'] < 1;
|
||||||
curl_setopt($handle, CURLOPT_TIMEOUT_MS, $this->config['timeout'] * 1000);
|
curl_setopt($handle, CURLOPT_TIMEOUT_MS, (int)round($this->config['timeout'] * 1000));
|
||||||
}
|
}
|
||||||
if (!empty($this->config['connection_timeout'])) {
|
if (!empty($this->config['connection_timeout'])) {
|
||||||
$timeout_requires_no_signal = $timeout_requires_no_signal ||
|
$timeout_requires_no_signal = $timeout_requires_no_signal ||
|
||||||
$this->config['connection_timeout'] < 1;
|
$this->config['connection_timeout'] < 1;
|
||||||
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT_MS, $this->config['connection_timeout'] * 1000);
|
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT_MS, (int)round($this->config['connection_timeout'] * 1000, 1));
|
||||||
}
|
}
|
||||||
if ($timeout_requires_no_signal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
if ($timeout_requires_no_signal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
||||||
curl_setopt($handle, CURLOPT_NOSIGNAL, true);
|
curl_setopt($handle, CURLOPT_NOSIGNAL, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user