Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aff4944ffd | |||
| 1a4c8e188f | |||
| c603922fca | |||
| 7ac13c2ba6 | |||
| 1c66ee34a1 | |||
| 2e101d55d2 | |||
| 4b699d753d | |||
| 254a0e4802 | |||
| 82f35535ae | |||
| c41796a478 | |||
| a310fab3ee |
@@ -22,6 +22,9 @@ parameters:
|
|||||||
# - vendor
|
# - vendor
|
||||||
# ignore errores with
|
# ignore errores with
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
|
-
|
||||||
|
message: '#Expression in empty\(\) is not falsy.#'
|
||||||
|
path: %currentWorkingDirectory%/src/Language/GetLocale.php
|
||||||
#- # this error is ignore because of the PHP 8.0 to 8.1 change for pg_*, only for 8.0 or lower
|
#- # this error is ignore because of the PHP 8.0 to 8.1 change for pg_*, only for 8.0 or lower
|
||||||
# message: "#^Parameter \\#1 \\$(result|connection) of function pg_\\w+ expects resource(\\|null)?, object\\|resource(\\|bool)? given\\.$#"
|
# message: "#^Parameter \\#1 \\$(result|connection) of function pg_\\w+ expects resource(\\|null)?, object\\|resource(\\|bool)? given\\.$#"
|
||||||
# path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php
|
# path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
9.27.0
|
9.31.1
|
||||||
|
|||||||
@@ -924,7 +924,9 @@ class Login
|
|||||||
$mandatory_session_vars = [
|
$mandatory_session_vars = [
|
||||||
'LOGIN_USER_NAME', 'LOGIN_GROUP_NAME', 'LOGIN_EUCUID', 'LOGIN_EUCUUID',
|
'LOGIN_USER_NAME', 'LOGIN_GROUP_NAME', 'LOGIN_EUCUID', 'LOGIN_EUCUUID',
|
||||||
'LOGIN_USER_ADDITIONAL_ACL', 'LOGIN_GROUP_ADDITIONAL_ACL',
|
'LOGIN_USER_ADDITIONAL_ACL', 'LOGIN_GROUP_ADDITIONAL_ACL',
|
||||||
'LOGIN_ADMIN', 'LOGIN_GROUP_ACL_LEVEL', 'LOGIN_PAGES_ACL_LEVEL', 'LOGIN_USER_ACL_LEVEL',
|
'LOGIN_ADMIN', 'LOGIN_GROUP_ACL_LEVEL',
|
||||||
|
'LOGIN_PAGES', 'LOGIN_PAGES_LOOKUP', 'LOGIN_PAGES_ACL_LEVEL',
|
||||||
|
'LOGIN_USER_ACL_LEVEL',
|
||||||
'LOGIN_UNIT', 'LOGIN_UNIT_DEFAULT_EACUID'
|
'LOGIN_UNIT', 'LOGIN_UNIT_DEFAULT_EACUID'
|
||||||
];
|
];
|
||||||
$force_reauth = false;
|
$force_reauth = false;
|
||||||
@@ -1264,6 +1266,7 @@ class Login
|
|||||||
}
|
}
|
||||||
$edit_page_ids = [];
|
$edit_page_ids = [];
|
||||||
$pages = [];
|
$pages = [];
|
||||||
|
$pages_lookup = [];
|
||||||
$pages_acl = [];
|
$pages_acl = [];
|
||||||
// set pages access
|
// set pages access
|
||||||
$q = <<<SQL
|
$q = <<<SQL
|
||||||
@@ -1307,6 +1310,7 @@ class Login
|
|||||||
'query' => [],
|
'query' => [],
|
||||||
'visible' => []
|
'visible' => []
|
||||||
];
|
];
|
||||||
|
$pages_lookup[$res['filename']] = $res['cuid'];
|
||||||
// make reference filename -> level
|
// make reference filename -> level
|
||||||
$pages_acl[$res['filename']] = $res['level'];
|
$pages_acl[$res['filename']] = $res['level'];
|
||||||
} // for each page
|
} // for each page
|
||||||
@@ -1367,6 +1371,7 @@ class Login
|
|||||||
// write back the pages data to the output array
|
// write back the pages data to the output array
|
||||||
$this->session->setMany([
|
$this->session->setMany([
|
||||||
'LOGIN_PAGES' => $pages,
|
'LOGIN_PAGES' => $pages,
|
||||||
|
'LOGIN_PAGES_LOOKUP' => $pages_lookup,
|
||||||
'LOGIN_PAGES_ACL_LEVEL' => $pages_acl,
|
'LOGIN_PAGES_ACL_LEVEL' => $pages_acl,
|
||||||
]);
|
]);
|
||||||
// load the edit_access user rights
|
// load the edit_access user rights
|
||||||
@@ -1526,6 +1531,8 @@ class Login
|
|||||||
) {
|
) {
|
||||||
$this->acl['page'] = $_SESSION['LOGIN_PAGES_ACL_LEVEL'][$this->page_name];
|
$this->acl['page'] = $_SESSION['LOGIN_PAGES_ACL_LEVEL'][$this->page_name];
|
||||||
}
|
}
|
||||||
|
$this->acl['pages_detail'] = $_SESSION['LOGIN_PAGES'];
|
||||||
|
$this->acl['pages_lookup_cuid'] = $_SESSION['LOGIN_PAGES_LOOKUP'];
|
||||||
|
|
||||||
$this->acl['unit_cuid'] = null;
|
$this->acl['unit_cuid'] = null;
|
||||||
$this->acl['unit_name'] = null;
|
$this->acl['unit_name'] = null;
|
||||||
@@ -2728,6 +2735,31 @@ HTML;
|
|||||||
return $this->session->get('LOGIN_PAGES');
|
return $this->session->get('LOGIN_PAGES');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current loaded list of pages the user can access
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function loginGetPageLookupList(): array
|
||||||
|
{
|
||||||
|
return $this->session->get('LOGIN_PAGES_LOOKUP');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check access to a file in the pages list
|
||||||
|
*
|
||||||
|
* @param string $filename File name to check
|
||||||
|
* @return bool True if page in list and anything other than None access, False if failed
|
||||||
|
*/
|
||||||
|
public function loginPageAccessAllowed(string $filename): bool
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$this->session->get('LOGIN_PAGES')[
|
||||||
|
$this->session->get('LOGIN_PAGES_LOOKUP')[$filename] ?? ''
|
||||||
|
] ?? 0
|
||||||
|
) != 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: logged in uid(pk)/eucuid/eucuuid
|
// MARK: logged in uid(pk)/eucuid/eucuuid
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1024,8 +1024,12 @@ class Basic
|
|||||||
*/
|
*/
|
||||||
public function __sha1Short(string $string, bool $use_sha = false): string
|
public function __sha1Short(string $string, bool $use_sha = false): string
|
||||||
{
|
{
|
||||||
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__sha1Short()', E_USER_DEPRECATED);
|
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::sha1Short() or ::__crc32b()', E_USER_DEPRECATED);
|
||||||
return \CoreLibs\Create\Hash::__sha1Short($string, $use_sha);
|
if ($use_sha) {
|
||||||
|
return \CoreLibs\Create\Hash::sha1Short($string);
|
||||||
|
} else {
|
||||||
|
return \CoreLibs\Create\Hash::__crc32b($string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1040,8 +1044,8 @@ class Basic
|
|||||||
*/
|
*/
|
||||||
public function __hash(string $string, string $hash_type = 'adler32'): string
|
public function __hash(string $string, string $hash_type = 'adler32'): string
|
||||||
{
|
{
|
||||||
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__hash()', E_USER_DEPRECATED);
|
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::hash()', E_USER_DEPRECATED);
|
||||||
return \CoreLibs\Create\Hash::__hash($string, $hash_type);
|
return \CoreLibs\Create\Hash::hash($string, $hash_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// *** HASH FUNCTIONS END
|
// *** HASH FUNCTIONS END
|
||||||
|
|||||||
@@ -10,9 +10,14 @@ namespace CoreLibs\Create;
|
|||||||
|
|
||||||
class Hash
|
class Hash
|
||||||
{
|
{
|
||||||
|
/** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */
|
||||||
public const DEFAULT_HASH = 'adler32';
|
public const DEFAULT_HASH = 'adler32';
|
||||||
|
/** @var string default long hash (40 chars) */
|
||||||
public const STANDARD_HASH_LONG = 'ripemd160';
|
public const STANDARD_HASH_LONG = 'ripemd160';
|
||||||
|
/** @var string default short hash (8 chars) */
|
||||||
public const STANDARD_HASH_SHORT = 'adler32';
|
public const STANDARD_HASH_SHORT = 'adler32';
|
||||||
|
/** @var string this is the standard hash to use hashStd and hash (64 chars) */
|
||||||
|
public const STANDARD_HASH = 'sha256';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks php version and if >=5.2.7 it will flip the string
|
* checks php version and if >=5.2.7 it will flip the string
|
||||||
@@ -20,6 +25,7 @@ class Hash
|
|||||||
* hash returns false
|
* hash returns false
|
||||||
* preg_replace fails for older php version
|
* preg_replace fails for older php version
|
||||||
* Use __hash with crc32b or hash('crc32b', ...) for correct output
|
* Use __hash with crc32b or hash('crc32b', ...) for correct output
|
||||||
|
* For future short hashes use hashShort() instead
|
||||||
*
|
*
|
||||||
* @param string $string string to crc
|
* @param string $string string to crc
|
||||||
* @return string crc32b hash (old type)
|
* @return string crc32b hash (old type)
|
||||||
@@ -43,19 +49,31 @@ class Hash
|
|||||||
* replacement for __crc32b call
|
* replacement for __crc32b call
|
||||||
*
|
*
|
||||||
* @param string $string string to hash
|
* @param string $string string to hash
|
||||||
* @param bool $use_sha use sha instead of crc32b (default false)
|
* @param bool $use_sha [default=false] use sha1 instead of crc32b
|
||||||
* @return string hash of the string
|
* @return string hash of the string
|
||||||
|
* @deprecated use __crc32b() for drop in replacement with default, or sha1Short() for use sha true
|
||||||
*/
|
*/
|
||||||
public static function __sha1Short(string $string, bool $use_sha = false): string
|
public static function __sha1Short(string $string, bool $use_sha = false): string
|
||||||
{
|
{
|
||||||
if ($use_sha) {
|
if ($use_sha) {
|
||||||
// return only the first 9 characters
|
return self::sha1Short($string);
|
||||||
return substr(hash('sha1', $string), 0, 9);
|
|
||||||
} else {
|
} else {
|
||||||
return self::__crc32b($string);
|
return self::__crc32b($string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a short sha1
|
||||||
|
*
|
||||||
|
* @param string $string string to hash
|
||||||
|
* @return string hash of the string
|
||||||
|
*/
|
||||||
|
public static function sha1Short(string $string): string
|
||||||
|
{
|
||||||
|
// return only the first 9 characters
|
||||||
|
return substr(hash('sha1', $string), 0, 9);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* replacemend for __crc32b call (alternate)
|
* replacemend for __crc32b call (alternate)
|
||||||
* defaults to adler 32
|
* defaults to adler 32
|
||||||
@@ -63,34 +81,135 @@ class Hash
|
|||||||
* all that create 8 char long hashes
|
* all that create 8 char long hashes
|
||||||
*
|
*
|
||||||
* @param string $string string to hash
|
* @param string $string string to hash
|
||||||
* @param string $hash_type hash type (default adler32)
|
* @param string $hash_type [default=STANDARD_HASH_SHORT] hash type (default adler32)
|
||||||
* @return string hash of the string
|
* @return string hash of the string
|
||||||
|
* @deprecated use hashShort() of short hashes with adler 32 or hash() for other hash types
|
||||||
*/
|
*/
|
||||||
public static function __hash(
|
public static function __hash(
|
||||||
string $string,
|
string $string,
|
||||||
string $hash_type = self::DEFAULT_HASH
|
string $hash_type = self::STANDARD_HASH_SHORT
|
||||||
|
): string {
|
||||||
|
return self::hash($string, $hash_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if hash type is valid, returns false if not
|
||||||
|
*
|
||||||
|
* @param string $hash_type
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isValidHashType(string $hash_type): bool
|
||||||
|
{
|
||||||
|
if (!in_array($hash_type, hash_algos())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if hash hmac type is valid, returns false if not
|
||||||
|
*
|
||||||
|
* @param string $hash_hmac_type
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isValidHashHmacType(string $hash_hmac_type): bool
|
||||||
|
{
|
||||||
|
if (!in_array($hash_hmac_type, hash_hmac_algos())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a hash over string if any valid hash given.
|
||||||
|
* if no hash type set use sha256
|
||||||
|
*
|
||||||
|
* @param string $string string to hash
|
||||||
|
* @param string $hash_type [default=STANDARD_HASH] hash type (default sha256)
|
||||||
|
* @return string hash of the string
|
||||||
|
*/
|
||||||
|
public static function hash(
|
||||||
|
string $string,
|
||||||
|
string $hash_type = self::STANDARD_HASH
|
||||||
): string {
|
): string {
|
||||||
// if not empty, check if in valid list
|
|
||||||
if (
|
if (
|
||||||
empty($hash_type) ||
|
empty($hash_type) ||
|
||||||
!in_array($hash_type, hash_algos())
|
!in_array($hash_type, hash_algos())
|
||||||
) {
|
) {
|
||||||
// fallback to default hash type if none set or invalid
|
// fallback to default hash type if empty or invalid
|
||||||
$hash_type = self::DEFAULT_HASH;
|
$hash_type = self::STANDARD_HASH;
|
||||||
}
|
}
|
||||||
return hash($hash_type, $string);
|
return hash($hash_type, $string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper function for standard long hashd
|
* creates a hash mac key
|
||||||
|
*
|
||||||
|
* @param string $string string to hash mac
|
||||||
|
* @param string $key key to use
|
||||||
|
* @param string $hash_type [default=STANDARD_HASH]
|
||||||
|
* @return string hash mac string
|
||||||
|
*/
|
||||||
|
public static function hashHmac(
|
||||||
|
string $string,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $key,
|
||||||
|
string $hash_type = self::STANDARD_HASH
|
||||||
|
): string {
|
||||||
|
if (
|
||||||
|
empty($hash_type) ||
|
||||||
|
!in_array($hash_type, hash_hmac_algos())
|
||||||
|
) {
|
||||||
|
// fallback to default hash type if e or invalid
|
||||||
|
$hash_type = self::STANDARD_HASH;
|
||||||
|
}
|
||||||
|
return hash_hmac($hash_type, $string, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* short hash with max length of 8, uses adler32
|
||||||
|
*
|
||||||
|
* @param string $string string to hash
|
||||||
|
* @return string hash of the string
|
||||||
|
*/
|
||||||
|
public static function hashShort(string $string): string
|
||||||
|
{
|
||||||
|
return hash(self::STANDARD_HASH_SHORT, $string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper function for standard long hash
|
||||||
|
*
|
||||||
|
* @param string $string String to be hashed
|
||||||
|
* @return string Hashed string
|
||||||
|
* @deprecated use hashLong()
|
||||||
|
*/
|
||||||
|
public static function __hashLong(string $string): string
|
||||||
|
{
|
||||||
|
return self::hashLong($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper function for standard long hash, uses ripmd160
|
||||||
*
|
*
|
||||||
* @param string $string String to be hashed
|
* @param string $string String to be hashed
|
||||||
* @return string Hashed string
|
* @return string Hashed string
|
||||||
*/
|
*/
|
||||||
public static function __hashLong(string $string): string
|
public static function hashLong(string $string): string
|
||||||
{
|
{
|
||||||
return hash(self::STANDARD_HASH_LONG, $string);
|
return hash(self::STANDARD_HASH_LONG, $string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create standard hash basd on STANDAR_HASH, currently sha256
|
||||||
|
*
|
||||||
|
* @param string $string string in
|
||||||
|
* @return string hash of the string
|
||||||
|
*/
|
||||||
|
public static function hashStd(string $string): string
|
||||||
|
{
|
||||||
|
return self::hash($string, self::STANDARD_HASH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
|
|||||||
@@ -303,6 +303,8 @@ class IO
|
|||||||
private string $query = '';
|
private string $query = '';
|
||||||
/** @var array<mixed> current params for query */
|
/** @var array<mixed> current params for query */
|
||||||
private array $params = [];
|
private array $params = [];
|
||||||
|
/** @var string current hash build from query and params */
|
||||||
|
private string $query_hash = '';
|
||||||
// if we do have a convert call, store the convert data in here, else it will be empty
|
// if we do have a convert call, store the convert data in here, else it will be empty
|
||||||
/** @var array{}|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>} */
|
/** @var array{}|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>} */
|
||||||
private array $placeholder_converted = [];
|
private array $placeholder_converted = [];
|
||||||
@@ -1319,7 +1321,7 @@ class IO
|
|||||||
*/
|
*/
|
||||||
private function __dbCountQueryParams(string $query): int
|
private function __dbCountQueryParams(string $query): int
|
||||||
{
|
{
|
||||||
return $this->db_functions->__dbCountQueryParams($query);
|
return count($this->db_functions->__dbGetQueryParams($query));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1382,6 +1384,8 @@ class IO
|
|||||||
$this->query = $query;
|
$this->query = $query;
|
||||||
// current params
|
// current params
|
||||||
$this->params = $params;
|
$this->params = $params;
|
||||||
|
// empty on new
|
||||||
|
$this->query_hash = '';
|
||||||
// no query set
|
// no query set
|
||||||
if (empty($this->query)) {
|
if (empty($this->query)) {
|
||||||
$this->__dbError(11);
|
$this->__dbError(11);
|
||||||
@@ -1441,7 +1445,7 @@ class IO
|
|||||||
$this->returning_id = true;
|
$this->returning_id = true;
|
||||||
}
|
}
|
||||||
// import protection, hash needed
|
// import protection, hash needed
|
||||||
$query_hash = $this->dbGetQueryHash($this->query, $this->params);
|
$query_hash = $this->dbBuildQueryHash($this->query, $this->params);
|
||||||
// QUERY PARAMS: run query params check and rewrite
|
// QUERY PARAMS: run query params check and rewrite
|
||||||
if ($this->dbGetConvertPlaceholder() === true) {
|
if ($this->dbGetConvertPlaceholder() === true) {
|
||||||
try {
|
try {
|
||||||
@@ -1475,7 +1479,8 @@ class IO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// set query hash
|
||||||
|
$this->query_hash = $query_hash;
|
||||||
// $this->debug('DB IO', 'Q: ' . $this->query . ', RETURN: ' . $this->returning_id);
|
// $this->debug('DB IO', 'Q: ' . $this->query . ', RETURN: ' . $this->returning_id);
|
||||||
// for DEBUG, only on first time ;)
|
// for DEBUG, only on first time ;)
|
||||||
$this->__dbDebug(
|
$this->__dbDebug(
|
||||||
@@ -1959,7 +1964,7 @@ class IO
|
|||||||
{
|
{
|
||||||
// set start array
|
// set start array
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$array = $this->cursor_ext[$this->dbGetQueryHash($query)] ?? [];
|
$array = $this->cursor_ext[$this->dbBuildQueryHash($query)] ?? [];
|
||||||
} else {
|
} else {
|
||||||
$array = $this->cursor_ext;
|
$array = $this->cursor_ext;
|
||||||
}
|
}
|
||||||
@@ -2361,7 +2366,7 @@ class IO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// create hash from query ...
|
// create hash from query ...
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
// pre declare array
|
// pre declare array
|
||||||
if (!isset($this->cursor_ext[$query_hash])) {
|
if (!isset($this->cursor_ext[$query_hash])) {
|
||||||
$this->cursor_ext[$query_hash] = [
|
$this->cursor_ext[$query_hash] = [
|
||||||
@@ -2940,7 +2945,7 @@ class IO
|
|||||||
public function dbCacheReset(string $query, array $params = []): bool
|
public function dbCacheReset(string $query, array $params = []): bool
|
||||||
{
|
{
|
||||||
$this->__dbErrorReset();
|
$this->__dbErrorReset();
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
// clears cache for this query
|
// clears cache for this query
|
||||||
if (empty($this->cursor_ext[$query_hash]['query'])) {
|
if (empty($this->cursor_ext[$query_hash]['query'])) {
|
||||||
$this->__dbWarning(18, context: [
|
$this->__dbWarning(18, context: [
|
||||||
@@ -2982,7 +2987,7 @@ class IO
|
|||||||
if ($query === null) {
|
if ($query === null) {
|
||||||
return $this->cursor_ext;
|
return $this->cursor_ext;
|
||||||
}
|
}
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
if (
|
if (
|
||||||
!empty($this->cursor_ext) &&
|
!empty($this->cursor_ext) &&
|
||||||
isset($this->cursor_ext[$query_hash])
|
isset($this->cursor_ext[$query_hash])
|
||||||
@@ -3012,7 +3017,7 @@ class IO
|
|||||||
$this->__dbError(11);
|
$this->__dbError(11);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
if (
|
if (
|
||||||
!empty($this->cursor_ext) &&
|
!empty($this->cursor_ext) &&
|
||||||
isset($this->cursor_ext[$query_hash])
|
isset($this->cursor_ext[$query_hash])
|
||||||
@@ -3038,7 +3043,7 @@ class IO
|
|||||||
$this->__dbError(11);
|
$this->__dbError(11);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
if (
|
if (
|
||||||
!empty($this->cursor_ext) &&
|
!empty($this->cursor_ext) &&
|
||||||
isset($this->cursor_ext[$query_hash])
|
isset($this->cursor_ext[$query_hash])
|
||||||
@@ -3064,7 +3069,7 @@ class IO
|
|||||||
*/
|
*/
|
||||||
public function dbResetQueryCalled(string $query, array $params = []): void
|
public function dbResetQueryCalled(string $query, array $params = []): void
|
||||||
{
|
{
|
||||||
$this->query_called[$this->dbGetQueryHash($query, $params)] = 0;
|
$this->query_called[$this->dbBuildQueryHash($query, $params)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3077,7 +3082,7 @@ class IO
|
|||||||
*/
|
*/
|
||||||
public function dbGetQueryCalled(string $query, array $params = []): int
|
public function dbGetQueryCalled(string $query, array $params = []): int
|
||||||
{
|
{
|
||||||
$query_hash = $this->dbGetQueryHash($query, $params);
|
$query_hash = $this->dbBuildQueryHash($query, $params);
|
||||||
if (!empty($this->query_called[$query_hash])) {
|
if (!empty($this->query_called[$query_hash])) {
|
||||||
return $this->query_called[$query_hash];
|
return $this->query_called[$query_hash];
|
||||||
} else {
|
} else {
|
||||||
@@ -4046,7 +4051,7 @@ class IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns hash for query
|
* Creates hash for query and parameters
|
||||||
* Hash is used in all internal storage systems for return data
|
* Hash is used in all internal storage systems for return data
|
||||||
*
|
*
|
||||||
* @param string $query The query to create the hash from
|
* @param string $query The query to create the hash from
|
||||||
@@ -4054,9 +4059,9 @@ class IO
|
|||||||
* data to create a unique call one, optional
|
* data to create a unique call one, optional
|
||||||
* @return string Hash, as set by hash long
|
* @return string Hash, as set by hash long
|
||||||
*/
|
*/
|
||||||
public function dbGetQueryHash(string $query, array $params = []): string
|
public function dbBuildQueryHash(string $query, array $params = []): string
|
||||||
{
|
{
|
||||||
return Hash::__hashLong(
|
return Hash::hashLong(
|
||||||
$query . (
|
$query . (
|
||||||
$params !== [] ?
|
$params !== [] ?
|
||||||
'#' . json_encode($params) : ''
|
'#' . json_encode($params) : ''
|
||||||
@@ -4104,6 +4109,26 @@ class IO
|
|||||||
$this->params = [];
|
$this->params = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the current set query hash
|
||||||
|
*
|
||||||
|
* @return string Current Query hash
|
||||||
|
*/
|
||||||
|
public function dbGetQueryHash(): string
|
||||||
|
{
|
||||||
|
return $this->query_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset query hash
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function dbResetQueryHash(): void
|
||||||
|
{
|
||||||
|
$this->query_hash = '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the placeholder convert set or empty
|
* Returns the placeholder convert set or empty
|
||||||
*
|
*
|
||||||
@@ -4283,6 +4308,17 @@ class IO
|
|||||||
return $this->field_names[$pos] ?? false;
|
return $this->field_names[$pos] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all the $ placeholders
|
||||||
|
*
|
||||||
|
* @param string $query
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function dbGetQueryParamPlaceholders(string $query): array
|
||||||
|
{
|
||||||
|
return $this->db_functions->__dbGetQueryParams($query);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a field type for a field name or pos,
|
* Return a field type for a field name or pos,
|
||||||
* will return false if field is not found in list
|
* will return false if field is not found in list
|
||||||
|
|||||||
@@ -379,9 +379,9 @@ interface SqlFunctions
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @return int
|
* @return array<string>
|
||||||
*/
|
*/
|
||||||
public function __dbCountQueryParams(string $query): int;
|
public function __dbGetQueryParams(string $query): array;
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
|
|||||||
@@ -978,12 +978,12 @@ class PgSQL implements Interface\SqlFunctions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count placeholder queries. $ only
|
* Get the all the $ params, as a unique list
|
||||||
*
|
*
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @return int
|
* @return array<string>
|
||||||
*/
|
*/
|
||||||
public function __dbCountQueryParams(string $query): int
|
public function __dbGetQueryParams(string $query): array
|
||||||
{
|
{
|
||||||
$matches = [];
|
$matches = [];
|
||||||
// regex for params: only stand alone $number allowed
|
// regex for params: only stand alone $number allowed
|
||||||
@@ -998,11 +998,11 @@ class PgSQL implements Interface\SqlFunctions
|
|||||||
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
|
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
|
||||||
// Regex located in the ConvertPlaceholder class
|
// Regex located in the ConvertPlaceholder class
|
||||||
preg_match_all(
|
preg_match_all(
|
||||||
ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS,
|
ConvertPlaceholder::REGEX_LOOKUP_NUMBERED,
|
||||||
$query,
|
$query,
|
||||||
$matches
|
$matches
|
||||||
);
|
);
|
||||||
return count(array_unique(array_filter($matches[3])));
|
return array_unique(array_filter($matches[ConvertPlaceholder::MATCHING_POS]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,76 +14,57 @@ namespace CoreLibs\DB\Support;
|
|||||||
|
|
||||||
class ConvertPlaceholder
|
class ConvertPlaceholder
|
||||||
{
|
{
|
||||||
// NOTE for missing: range */+ are not iplemented in the regex below, but - is for now
|
/** @var string text block in SQL, single quited
|
||||||
// NOTE some combinations are allowed, but the query will fail before this
|
* Note that does not include $$..$$ strings or anything with token name or nested ones
|
||||||
/** @var string split regex, entries before $ group */
|
*/
|
||||||
private const PATTERN_QUERY_SPLIT =
|
private const PATTERN_TEXT_BLOCK_SINGLE_QUOTE = '(?:\'(?:[^\'\\\\]|\\\\.)*\')';
|
||||||
'\?\?|' // UNKNOWN: double ??, is this to avoid something?
|
/** @var string text block in SQL, dollar quoted
|
||||||
. '[\(,]|' // for ',' and '(' mostly in INSERT or ANY()
|
* NOTE: if this is added everything shifts by one lookup number
|
||||||
. '[<>=]|' // general set for <, >, = in any query with any combination
|
*/
|
||||||
. '\^@|' // text search for start from text with ^@
|
private const PATTERN_TEXT_BLOCK_DOLLAR = '(?:\$(\w*)\$.*?\$\1\$)';
|
||||||
. '\|\||' // concats two elements
|
|
||||||
. '&&|' // array overlap
|
|
||||||
. '\-\|\-|' // range overlap for array
|
|
||||||
. '[^-]-{1}|' // single -, used in JSON too
|
|
||||||
. '->|->>|#>|#>>|@>|<@|@@|@\?|\?{1}|\?\||\?&|#-|' // JSON searches, Array searchs, etc
|
|
||||||
. 'THEN|ELSE' // command parts (CASE)
|
|
||||||
;
|
|
||||||
/** @var string the main regex including the pattern query split */
|
|
||||||
private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:' . self::PATTERN_QUERY_SPLIT . ')\s*';
|
|
||||||
/** @var string comment regex
|
/** @var string comment regex
|
||||||
* anything that starts with -- and ends with a line break but any character that is not line break inbetween */
|
* anything that starts with -- and ends with a line break but any character that is not line break inbetween
|
||||||
private const PATTERN_COMMENT = '(?:\-\-[^\r\n]*?\r?\n)*\s*';
|
* this is the FIRST thing in the line and will skip any further lookups */
|
||||||
/** @var string parts to ignore in the SQL */
|
private const PATTERN_COMMENT = '(?:\-\-[^\r\n]*?\r?\n)';
|
||||||
private const PATTERN_IGNORE =
|
// below are the params lookups
|
||||||
// digit -> ignore
|
/** @var string named parameters, must start with single : */
|
||||||
'\d+|'
|
private const PATTERN_NAMED = '((?<!:):(?:\w+))';
|
||||||
// other string -> ignore
|
/** @var string question mark parameters, will catch any */
|
||||||
. '(?:\'.*?\')|';
|
private const PATTERN_QUESTION_MARK = '(\?{1})';
|
||||||
/** @var string named parameters */
|
/** @var string numbered parameters, can only start 1 to 9, second and further digits can be 0-9
|
||||||
private const PATTERN_NAMED = '(:\w+)';
|
* This ignores the $$ ... $$ escape syntax. If we find something like this will fail
|
||||||
/** @var string question mark parameters */
|
* It is recommended to use proper string escape quiting for writing data to the DB
|
||||||
private const PATTERN_QUESTION_MARK = '(?:(?:\?\?)?\s*(\?{1}))';
|
*/
|
||||||
/** @var string numbered parameters */
|
|
||||||
private const PATTERN_NUMBERED = '(\$[1-9]{1}(?:[0-9]{1,})?)';
|
private const PATTERN_NUMBERED = '(\$[1-9]{1}(?:[0-9]{1,})?)';
|
||||||
// below here are full regex that will be used
|
// below here are full regex that will be used
|
||||||
/** @var string replace regex for named (:...) entries */
|
/** @var string replace regex for named (:...) entries */
|
||||||
public const REGEX_REPLACE_NAMED = '/'
|
public const REGEX_REPLACE_NAMED = '/'
|
||||||
. '(' . self::PATTERN_ELEMENT . ')'
|
. self::PATTERN_COMMENT . '|'
|
||||||
. self::PATTERN_COMMENT
|
. self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|'
|
||||||
. '('
|
. self::PATTERN_TEXT_BLOCK_DOLLAR . '|'
|
||||||
. self::PATTERN_IGNORE
|
|
||||||
. self::PATTERN_NAMED
|
. self::PATTERN_NAMED
|
||||||
. ')'
|
|
||||||
. '/s';
|
. '/s';
|
||||||
/** @var string replace regex for question mark (?) entries */
|
/** @var string replace regex for question mark (?) entries */
|
||||||
public const REGEX_REPLACE_QUESTION_MARK = '/'
|
public const REGEX_REPLACE_QUESTION_MARK = '/'
|
||||||
. '(' . self::PATTERN_ELEMENT . ')'
|
. self::PATTERN_COMMENT . '|'
|
||||||
. self::PATTERN_COMMENT
|
. self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|'
|
||||||
. '('
|
. self::PATTERN_TEXT_BLOCK_DOLLAR . '|'
|
||||||
. self::PATTERN_IGNORE
|
|
||||||
. self::PATTERN_QUESTION_MARK
|
. self::PATTERN_QUESTION_MARK
|
||||||
. ')'
|
|
||||||
. '/s';
|
. '/s';
|
||||||
/** @var string replace regex for numbered ($n) entries */
|
/** @var string replace regex for numbered ($n) entries */
|
||||||
public const REGEX_REPLACE_NUMBERED = '/'
|
public const REGEX_REPLACE_NUMBERED = '/'
|
||||||
. '(' . self::PATTERN_ELEMENT . ')'
|
. self::PATTERN_COMMENT . '|'
|
||||||
. self::PATTERN_COMMENT
|
. self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|'
|
||||||
. '('
|
. self::PATTERN_TEXT_BLOCK_DOLLAR . '|'
|
||||||
. self::PATTERN_IGNORE
|
|
||||||
. self::PATTERN_NUMBERED
|
. self::PATTERN_NUMBERED
|
||||||
. ')'
|
|
||||||
. '/s';
|
. '/s';
|
||||||
/** @var string the main lookup query for all placeholders */
|
/** @var string the main lookup query for all placeholders */
|
||||||
public const REGEX_LOOKUP_PLACEHOLDERS = '/'
|
public const REGEX_LOOKUP_PLACEHOLDERS = '/'
|
||||||
// prefix string part, must match towards
|
. self::PATTERN_COMMENT . '|'
|
||||||
// seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
|
. self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|'
|
||||||
. self::PATTERN_ELEMENT
|
. self::PATTERN_TEXT_BLOCK_DOLLAR . '|'
|
||||||
. self::PATTERN_COMMENT
|
|
||||||
// match for replace part
|
// match for replace part
|
||||||
. '(?:'
|
. '(?:'
|
||||||
// ignore parts
|
|
||||||
. self::PATTERN_IGNORE
|
|
||||||
// :name named part (PDO) [1]
|
// :name named part (PDO) [1]
|
||||||
. self::PATTERN_NAMED . '|'
|
. self::PATTERN_NAMED . '|'
|
||||||
// ? question mark part (PDO) [2]
|
// ? question mark part (PDO) [2]
|
||||||
@@ -94,6 +75,26 @@ class ConvertPlaceholder
|
|||||||
. ')'
|
. ')'
|
||||||
// single line -> add line break to matches in "."
|
// single line -> add line break to matches in "."
|
||||||
. '/s';
|
. '/s';
|
||||||
|
/** @var string lookup for only numbered placeholders */
|
||||||
|
public const REGEX_LOOKUP_NUMBERED = '/'
|
||||||
|
. self::PATTERN_COMMENT . '|'
|
||||||
|
. self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|'
|
||||||
|
. self::PATTERN_TEXT_BLOCK_DOLLAR . '|'
|
||||||
|
// match for replace part
|
||||||
|
. '(?:'
|
||||||
|
// $n numbered part (\PG php) [1]
|
||||||
|
. self::PATTERN_NUMBERED
|
||||||
|
// end match
|
||||||
|
. ')'
|
||||||
|
. '/s';
|
||||||
|
/** @var int position for regex in full placeholder lookup: named */
|
||||||
|
public const LOOOKUP_NAMED_POS = 2;
|
||||||
|
/** @var int position for regex in full placeholder lookup: question mark */
|
||||||
|
public const LOOOKUP_QUESTION_MARK_POS = 3;
|
||||||
|
/** @var int position for regex in full placeholder lookup: numbered */
|
||||||
|
public const LOOOKUP_NUMBERED_POS = 4;
|
||||||
|
/** @var int matches position for replacement and single lookup */
|
||||||
|
public const MATCHING_POS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert PDO type query with placeholders to \PG style and vica versa
|
* Convert PDO type query with placeholders to \PG style and vica versa
|
||||||
@@ -132,11 +133,12 @@ class ConvertPlaceholder
|
|||||||
$found = -1;
|
$found = -1;
|
||||||
}
|
}
|
||||||
/** @var array<string> 1: named */
|
/** @var array<string> 1: named */
|
||||||
$named_matches = array_filter($matches[1]);
|
$named_matches = array_filter($matches[self::LOOOKUP_NAMED_POS]);
|
||||||
/** @var array<string> 2: open ? */
|
/** @var array<string> 2: open ? */
|
||||||
$qmark_matches = array_filter($matches[2]);
|
$qmark_matches = array_filter($matches[self::LOOOKUP_QUESTION_MARK_POS]);
|
||||||
/** @var array<string> 3: $n matches */
|
/** @var array<string> 3: $n matches */
|
||||||
$numbered_matches = array_filter($matches[3]);
|
$numbered_matches = array_filter($matches[self::LOOOKUP_NUMBERED_POS]);
|
||||||
|
// print "**MATCHES**: <pre>" . print_r($matches, true) . "</pre>";
|
||||||
// count matches
|
// count matches
|
||||||
$count_named = count(array_unique($named_matches));
|
$count_named = count(array_unique($named_matches));
|
||||||
$count_qmark = count($qmark_matches);
|
$count_qmark = count($qmark_matches);
|
||||||
@@ -235,38 +237,37 @@ class ConvertPlaceholder
|
|||||||
$empty_params = $converted_placeholders['original']['empty_params'];
|
$empty_params = $converted_placeholders['original']['empty_params'];
|
||||||
switch ($converted_placeholders['type']) {
|
switch ($converted_placeholders['type']) {
|
||||||
case 'named':
|
case 'named':
|
||||||
// 0: full
|
// 1: replace part :named
|
||||||
// 0: full
|
|
||||||
// 1: pre part
|
|
||||||
// 2: keep part UNLESS '3' is set
|
|
||||||
// 3: replace part :named
|
|
||||||
$pos = 0;
|
$pos = 0;
|
||||||
$query_new = preg_replace_callback(
|
$query_new = preg_replace_callback(
|
||||||
self::REGEX_REPLACE_NAMED,
|
self::REGEX_REPLACE_NAMED,
|
||||||
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
||||||
// only count up if $match[3] is not yet in lookup table
|
if (!isset($matches[self::MATCHING_POS])) {
|
||||||
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
throw new \RuntimeException(
|
||||||
|
'Cannot lookup ' . self::MATCHING_POS . ' in matches list',
|
||||||
|
209
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$match = $matches[self::MATCHING_POS];
|
||||||
|
// only count up if $match[1] is not yet in lookup table
|
||||||
|
if (empty($params_lookup[$match])) {
|
||||||
$pos++;
|
$pos++;
|
||||||
$params_lookup[$matches[3]] = '$' . $pos;
|
$params_lookup[$match] = '$' . $pos;
|
||||||
// skip params setup if param list is empty
|
// skip params setup if param list is empty
|
||||||
if (!$empty_params) {
|
if (!$empty_params) {
|
||||||
$params_new[] = $params[$matches[3]] ??
|
$params_new[] = $params[$match] ??
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
'Cannot lookup ' . $matches[3] . ' in params list',
|
'Cannot lookup ' . $match . ' in params list',
|
||||||
210
|
210
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
return $matches[1] . (
|
return $params_lookup[$match] ??
|
||||||
empty($matches[3]) ?
|
throw new \RuntimeException(
|
||||||
$matches[2] :
|
'Cannot lookup ' . $match . ' in params lookup list',
|
||||||
$params_lookup[$matches[3]] ??
|
211
|
||||||
throw new \RuntimeException(
|
);
|
||||||
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
|
||||||
211
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
$converted_placeholders['original']['query']
|
$converted_placeholders['original']['query']
|
||||||
);
|
);
|
||||||
@@ -276,61 +277,61 @@ class ConvertPlaceholder
|
|||||||
// order and data stays the same
|
// order and data stays the same
|
||||||
$params_new = $params ?? [];
|
$params_new = $params ?? [];
|
||||||
}
|
}
|
||||||
// 0: full
|
// 1: replace part ?
|
||||||
// 1: pre part
|
|
||||||
// 2: keep part UNLESS '3' is set
|
|
||||||
// 3: replace part ?
|
|
||||||
$pos = 0;
|
$pos = 0;
|
||||||
$query_new = preg_replace_callback(
|
$query_new = preg_replace_callback(
|
||||||
self::REGEX_REPLACE_QUESTION_MARK,
|
self::REGEX_REPLACE_QUESTION_MARK,
|
||||||
function ($matches) use (&$pos, &$params_lookup) {
|
function ($matches) use (&$pos, &$params_lookup) {
|
||||||
|
if (!isset($matches[self::MATCHING_POS])) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'Cannot lookup ' . self::MATCHING_POS . ' in matches list',
|
||||||
|
229
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$match = $matches[self::MATCHING_POS];
|
||||||
// only count pos up for actual replacements we will do
|
// only count pos up for actual replacements we will do
|
||||||
if (!empty($matches[3])) {
|
if (!empty($match)) {
|
||||||
$pos++;
|
$pos++;
|
||||||
$params_lookup[] = '$' . $pos;
|
$params_lookup[] = '$' . $pos;
|
||||||
}
|
}
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
return $matches[1] . (
|
return '$' . $pos;
|
||||||
empty($matches[3]) ?
|
|
||||||
$matches[2] :
|
|
||||||
'$' . $pos
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
$converted_placeholders['original']['query']
|
$converted_placeholders['original']['query']
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'numbered':
|
case 'numbered':
|
||||||
// 0: full
|
// 1: replace part $numbered
|
||||||
// 1: pre part
|
|
||||||
// 2: keep part UNLESS '3' is set
|
|
||||||
// 3: replace part $numbered
|
|
||||||
$pos = 0;
|
$pos = 0;
|
||||||
$query_new = preg_replace_callback(
|
$query_new = preg_replace_callback(
|
||||||
self::REGEX_REPLACE_NUMBERED,
|
self::REGEX_REPLACE_NUMBERED,
|
||||||
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) {
|
||||||
// only count up if $match[3] is not yet in lookup table
|
if (!isset($matches[self::MATCHING_POS])) {
|
||||||
if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) {
|
throw new \RuntimeException(
|
||||||
|
'Cannot lookup ' . self::MATCHING_POS . ' in matches list',
|
||||||
|
239
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$match = $matches[self::MATCHING_POS];
|
||||||
|
// only count up if $match[1] is not yet in lookup table
|
||||||
|
if (empty($params_lookup[$match])) {
|
||||||
$pos++;
|
$pos++;
|
||||||
$params_lookup[$matches[3]] = ':' . $pos . '_named';
|
$params_lookup[$match] = ':' . $pos . '_named';
|
||||||
// skip params setup if param list is empty
|
// skip params setup if param list is empty
|
||||||
if (!$empty_params) {
|
if (!$empty_params) {
|
||||||
$params_new[] = $params[($pos - 1)] ??
|
$params_new[] = $params[($pos - 1)] ??
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
'Cannot lookup ' . ($pos - 1) . ' in params list',
|
'Cannot lookup ' . ($pos - 1) . ' in params list',
|
||||||
220
|
230
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add the connectors back (1), and the data sets only if no replacement will be done
|
// add the connectors back (1), and the data sets only if no replacement will be done
|
||||||
return $matches[1] . (
|
return $params_lookup[$match] ??
|
||||||
empty($matches[3]) ?
|
throw new \RuntimeException(
|
||||||
$matches[2] :
|
'Cannot lookup ' . $match . ' in params lookup list',
|
||||||
$params_lookup[$matches[3]] ??
|
231
|
||||||
throw new \RuntimeException(
|
);
|
||||||
'Cannot lookup ' . $matches[3] . ' in params lookup list',
|
|
||||||
221
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
$converted_placeholders['original']['query']
|
$converted_placeholders['original']['query']
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1371,7 +1371,7 @@ class Generate
|
|||||||
) {
|
) {
|
||||||
$this->msg .= sprintf(
|
$this->msg .= sprintf(
|
||||||
$this->l->__('Please enter a valid (%s) input for the <b>%s</b> Field!<br>'),
|
$this->l->__('Please enter a valid (%s) input for the <b>%s</b> Field!<br>'),
|
||||||
$this->dba->getTableArray()[$key]['error_example'],
|
$this->dba->getTableArray()[$key]['error_example'] ?? '[MISSING]',
|
||||||
$this->dba->getTableArray()[$key]['output_name']
|
$this->dba->getTableArray()[$key]['output_name']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2602,7 +2602,7 @@ class Generate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add lost error ones
|
// add lost error ones
|
||||||
$this->log->error('P: ' . $data['prefix'] . ', '
|
$this->log->error('Prefix: ' . $data['prefix'] . ', '
|
||||||
. Support::prAr($_POST['ERROR'][$data['prefix']] ?? []));
|
. Support::prAr($_POST['ERROR'][$data['prefix']] ?? []));
|
||||||
if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) {
|
if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) {
|
||||||
$prfx = $data['prefix']; // short
|
$prfx = $data['prefix']; // short
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ class EditUsers implements Interface\TableArraysInterface
|
|||||||
'HIDDEN_value' => $_POST['HIDDEN_password'] ?? '',
|
'HIDDEN_value' => $_POST['HIDDEN_password'] ?? '',
|
||||||
'CONFIRM_value' => $_POST['CONFIRM_password'] ?? '',
|
'CONFIRM_value' => $_POST['CONFIRM_password'] ?? '',
|
||||||
'output_name' => 'Password',
|
'output_name' => 'Password',
|
||||||
'mandatory' => 1,
|
// make it not mandatory to create dummy accounts that can only login via login url id
|
||||||
|
'mandatory' => 0,
|
||||||
'type' => 'password', // later has to be password for encryption in database
|
'type' => 'password', // later has to be password for encryption in database
|
||||||
'update' => [ // connected field updates, and update data
|
'update' => [ // connected field updates, and update data
|
||||||
'password_change_date' => [ // db row to update
|
'password_change_date' => [ // db row to update
|
||||||
@@ -182,6 +183,7 @@ class EditUsers implements Interface\TableArraysInterface
|
|||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'error_check' => 'unique|custom',
|
'error_check' => 'unique|custom',
|
||||||
'error_regex' => "/^[A-Za-z0-9]+$/",
|
'error_regex' => "/^[A-Za-z0-9]+$/",
|
||||||
|
'error_example' => "ABCdef123",
|
||||||
'emptynull' => 1,'min_edit_acl' => '100',
|
'emptynull' => 1,'min_edit_acl' => '100',
|
||||||
'min_show_acl' => '100',
|
'min_show_acl' => '100',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -183,8 +183,9 @@ list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
|
|||||||
define('HOST_NAME', $HOST_NAME);
|
define('HOST_NAME', $HOST_NAME);
|
||||||
// BAIL ON MISSING MASTER SITE CONFIG
|
// BAIL ON MISSING MASTER SITE CONFIG
|
||||||
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
|
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
|
||||||
echo 'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator';
|
throw new \InvalidArgumentException(
|
||||||
exit;
|
'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// BAIL ON MISSING DB CONFIG:
|
// BAIL ON MISSING DB CONFIG:
|
||||||
// we have either no db selction for this host but have db config entries
|
// we have either no db selction for this host but have db config entries
|
||||||
@@ -200,8 +201,9 @@ if (
|
|||||||
empty($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']]))
|
empty($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']]))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
echo 'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator';
|
throw new \InvalidArgumentException(
|
||||||
exit;
|
'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// set SSL on
|
// set SSL on
|
||||||
$is_secure = false;
|
$is_secure = false;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ Not yet covered tests:
|
|||||||
- loginGetLocale
|
- loginGetLocale
|
||||||
- loginGetHeaderColor
|
- loginGetHeaderColor
|
||||||
- loginGetPages
|
- loginGetPages
|
||||||
|
- loginGetPageLookupList
|
||||||
|
- loginPageAccessAllowed
|
||||||
- loginGetEuid
|
- loginGetEuid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
public function hashData(): array
|
public function hashData(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'any string' => [
|
'hash tests' => [
|
||||||
|
// this is the string
|
||||||
'text' => 'Some String Text',
|
'text' => 'Some String Text',
|
||||||
|
// hash list special
|
||||||
'crc32b_reverse' => 'c5c21d91', // crc32b (in revere)
|
'crc32b_reverse' => 'c5c21d91', // crc32b (in revere)
|
||||||
'sha1Short' => '4d2bc9ba0', // sha1Short
|
'sha1Short' => '4d2bc9ba0', // sha1Short
|
||||||
// via hash
|
// via hash
|
||||||
@@ -31,6 +33,8 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
'fnv132' => '9df444f9', // hash: fnv132
|
'fnv132' => '9df444f9', // hash: fnv132
|
||||||
'fnv1a32' => '2c5f91b9', // hash: fnv1a32
|
'fnv1a32' => '2c5f91b9', // hash: fnv1a32
|
||||||
'joaat' => '50dab846', // hash: joaat
|
'joaat' => '50dab846', // hash: joaat
|
||||||
|
'ripemd160' => 'aeae3f041b20136451519edd9361570909300342', // hash: ripemd160,
|
||||||
|
'sha256' => '9055080e022f224fa835929b80582b3c71c672206fa3a49a87412c25d9d42ceb', // hash: sha256
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -81,7 +85,7 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->hashData() as $name => $values) {
|
foreach ($this->hashData() as $name => $values) {
|
||||||
foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) {
|
foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256'] as $_hash_type) {
|
||||||
// default value test
|
// default value test
|
||||||
if ($_hash_type === null) {
|
if ($_hash_type === null) {
|
||||||
$hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT;
|
$hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT;
|
||||||
@@ -114,6 +118,22 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function hashStandardProvider(): array
|
||||||
|
{
|
||||||
|
$hash_source = 'Some String Text';
|
||||||
|
return [
|
||||||
|
'Long Hash check: ' . \CoreLibs\Create\Hash::STANDARD_HASH => [
|
||||||
|
$hash_source,
|
||||||
|
hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source)
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
@@ -136,9 +156,13 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
|
* phpcs:disable Generic.Files.LineLength
|
||||||
* @covers ::__sha1Short
|
* @covers ::__sha1Short
|
||||||
|
* @covers ::__crc32b
|
||||||
|
* @covers ::sha1Short
|
||||||
* @dataProvider sha1ShortProvider
|
* @dataProvider sha1ShortProvider
|
||||||
* @testdox __sha1Short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
|
* @testdox __sha1Short/__crc32b/sha1short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
|
||||||
|
* phpcs:enable Generic.Files.LineLength
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
* @param string $expected
|
* @param string $expected
|
||||||
@@ -149,16 +173,29 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
// uses crc32b
|
// uses crc32b
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Create\Hash::__sha1Short($input)
|
\CoreLibs\Create\Hash::__sha1Short($input),
|
||||||
|
'__sha1Short depreacted'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Create\Hash::__sha1Short($input, false)
|
\CoreLibs\Create\Hash::__sha1Short($input, false),
|
||||||
|
'__sha1Short (false) depreacted'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::__crc32b($input),
|
||||||
|
'__crc32b'
|
||||||
);
|
);
|
||||||
// sha1 type
|
// sha1 type
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected_sha1,
|
$expected_sha1,
|
||||||
\CoreLibs\Create\Hash::__sha1Short($input, true)
|
\CoreLibs\Create\Hash::__sha1Short($input, true),
|
||||||
|
'__sha1Short (true) depreacted'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_sha1,
|
||||||
|
\CoreLibs\Create\Hash::sha1Short($input),
|
||||||
|
'sha1Short'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +203,10 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::__hash
|
* @covers ::__hash
|
||||||
|
* @covers ::hashShort
|
||||||
|
* @covers ::hashShort
|
||||||
* @dataProvider hashProvider
|
* @dataProvider hashProvider
|
||||||
* @testdox __hash $input with $hash_type will be $expected [$_dataName]
|
* @testdox __hash/hashShort/hash $input with $hash_type will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
* @param string|null $hash_type
|
* @param string|null $hash_type
|
||||||
@@ -179,12 +218,24 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
if ($hash_type === null) {
|
if ($hash_type === null) {
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Create\Hash::__hash($input)
|
\CoreLibs\Create\Hash::__hash($input),
|
||||||
|
'__hash'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hashShort($input),
|
||||||
|
'hashShort'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Create\Hash::__hash($input, $hash_type)
|
\CoreLibs\Create\Hash::__hash($input, $hash_type),
|
||||||
|
'__hash with hash type'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hash($input, $hash_type),
|
||||||
|
'hash with hash type'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,8 +244,9 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::__hashLong
|
* @covers ::__hashLong
|
||||||
|
* @covers ::hashLong
|
||||||
* @dataProvider hashLongProvider
|
* @dataProvider hashLongProvider
|
||||||
* @testdox __hashLong $input will be $expected [$_dataName]
|
* @testdox __hashLong/hashLong $input will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
* @param string $expected
|
* @param string $expected
|
||||||
@@ -206,6 +258,168 @@ final class CoreLibsCreateHashTest extends TestCase
|
|||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Create\Hash::__hashLong($input)
|
\CoreLibs\Create\Hash::__hashLong($input)
|
||||||
);
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hashLong($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::hash
|
||||||
|
* @covers ::hashStd
|
||||||
|
* @dataProvider hashStandardProvider
|
||||||
|
* @testdox hash/hashStd $input will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
* @param string $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testHashStandard(string $input, string $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hashStd($input)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hash($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::hash
|
||||||
|
* @testdox hash with invalid type
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testInvalidHashType(): void
|
||||||
|
{
|
||||||
|
$hash_source = 'Some String Text';
|
||||||
|
$expected = hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hash($hash_source, 'DOES_NOT_EXIST')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: this only tests default sha256
|
||||||
|
*
|
||||||
|
* @covers ::hashHmac
|
||||||
|
* @testdox hash hmac test
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testHashMac(): void
|
||||||
|
{
|
||||||
|
$hash_key = 'FIX KEY';
|
||||||
|
$hash_source = 'Some String Text';
|
||||||
|
$expected = '16479b3ef6fa44e1cdd8b2dcfaadf314d1a7763635e8738f1e7996d714d9b6bf';
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::hashHmac
|
||||||
|
* @testdox hash hmac with invalid type
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testInvalidHashMacType(): void
|
||||||
|
{
|
||||||
|
$hash_key = 'FIX KEY';
|
||||||
|
$hash_source = 'Some String Text';
|
||||||
|
$expected = hash_hmac(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source, $hash_key);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key, 'DOES_NOT_EXIST')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function providerHashTypes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Hash crc32b' => [
|
||||||
|
'crc32b',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'Hash adler32' => [
|
||||||
|
'adler32',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'HAsh fnv132' => [
|
||||||
|
'fnv132',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'Hash fnv1a32' => [
|
||||||
|
'fnv1a32',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'Hash: joaat' => [
|
||||||
|
'joaat',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'Hash: ripemd160' => [
|
||||||
|
'ripemd160',
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'Hash: sha256' => [
|
||||||
|
'sha256',
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'Hash: invalid' => [
|
||||||
|
'invalid',
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::isValidHashType
|
||||||
|
* @covers ::isValidHashHmacType
|
||||||
|
* @dataProvider providerHashTypes
|
||||||
|
* @testdox check if $hash_type is valid for hash $hash_ok and hash hmac $hash_hmac_ok [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string $hash_type
|
||||||
|
* @param bool $hash_ok
|
||||||
|
* @param bool $hash_hmac_ok
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testIsValidHashAndHashHmacTypes(string $hash_type, bool $hash_ok, bool $hash_hmac_ok): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$hash_ok,
|
||||||
|
\CoreLibs\Create\Hash::isValidHashType($hash_type),
|
||||||
|
'hash valid'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$hash_hmac_ok,
|
||||||
|
\CoreLibs\Create\Hash::isValidHashHmacType($hash_type),
|
||||||
|
'hash hmac valid'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
// check if they already exist, drop them
|
// check if they already exist, drop them
|
||||||
if ($db->dbShowTableMetaData('table_with_primary_key') !== false) {
|
if ($db->dbShowTableMetaData('table_with_primary_key') !== false) {
|
||||||
|
$db->dbExec("CREATE EXTENSION IF NOT EXISTS pgcrypto");
|
||||||
$db->dbExec("DROP TABLE table_with_primary_key");
|
$db->dbExec("DROP TABLE table_with_primary_key");
|
||||||
$db->dbExec("DROP TABLE table_without_primary_key");
|
$db->dbExec("DROP TABLE table_without_primary_key");
|
||||||
$db->dbExec("DROP TABLE test_meta");
|
$db->dbExec("DROP TABLE test_meta");
|
||||||
@@ -4744,7 +4745,7 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
$res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']);
|
$res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']);
|
||||||
// all hast to be string
|
// all hast to be string
|
||||||
foreach ($res as $key => $value) {
|
foreach ($res as $key => $value) {
|
||||||
$this->assertIsString($value, 'Aseert string for column: ' . $key);
|
$this->assertIsString($value, 'Assert string for column: ' . $key);
|
||||||
}
|
}
|
||||||
// convert base only
|
// convert base only
|
||||||
$db->dbSetConvertFlag(Convert::on);
|
$db->dbSetConvertFlag(Convert::on);
|
||||||
@@ -4757,10 +4758,10 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
switch ($type_layout[$name]) {
|
switch ($type_layout[$name]) {
|
||||||
case 'int':
|
case 'int':
|
||||||
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
|
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
|
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4774,13 +4775,13 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
switch ($type_layout[$name]) {
|
switch ($type_layout[$name]) {
|
||||||
case 'int':
|
case 'int':
|
||||||
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
|
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
|
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
|
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4794,17 +4795,17 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
switch ($type_layout[$name]) {
|
switch ($type_layout[$name]) {
|
||||||
case 'int':
|
case 'int':
|
||||||
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
|
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
|
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'json':
|
case 'json':
|
||||||
case 'jsonb':
|
case 'jsonb':
|
||||||
$this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
|
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
|
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4818,25 +4819,25 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
}
|
}
|
||||||
switch ($type_layout[$name]) {
|
switch ($type_layout[$name]) {
|
||||||
case 'int':
|
case 'int':
|
||||||
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
|
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
|
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'json':
|
case 'json':
|
||||||
case 'jsonb':
|
case 'jsonb':
|
||||||
$this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
|
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
case 'bytea':
|
case 'bytea':
|
||||||
// for hex types it must not start with \x
|
// for hex types it must not start with \x
|
||||||
$this->assertStringStartsNotWith(
|
$this->assertStringStartsNotWith(
|
||||||
'\x',
|
'\x',
|
||||||
$value,
|
$value,
|
||||||
'Aseert bytes not starts with \x for column: ' . $key . '/' . $name
|
'Assert bytes not starts with \x for column: ' . $key . '/' . $name
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
|
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5008,8 +5009,8 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
($params === null ?
|
($params === null ?
|
||||||
$db->dbGetQueryHash($query) :
|
$db->dbBuildQueryHash($query) :
|
||||||
$db->dbGetQueryHash($query, $params)
|
$db->dbBuildQueryHash($query, $params)
|
||||||
),
|
),
|
||||||
'Failed assertdbGetQueryHash '
|
'Failed assertdbGetQueryHash '
|
||||||
);
|
);
|
||||||
@@ -5235,6 +5236,9 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
$3
|
$3
|
||||||
-- comment 3
|
-- comment 3
|
||||||
, $4
|
, $4
|
||||||
|
-- ignore $5, $6
|
||||||
|
-- $7, $8
|
||||||
|
-- digest($9, 10)
|
||||||
)
|
)
|
||||||
SQL,
|
SQL,
|
||||||
'count' => 4,
|
'count' => 4,
|
||||||
@@ -5305,8 +5309,57 @@ final class CoreLibsDBIOTest extends TestCase
|
|||||||
SQL,
|
SQL,
|
||||||
'count' => 2,
|
'count' => 2,
|
||||||
'convert' => false,
|
'convert' => false,
|
||||||
|
],
|
||||||
|
// special $$ string case
|
||||||
|
'text string, with $ placehoders that could be seen as $$ string' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT row_int
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_bytea = digest($3::VARCHAR, $4) OR
|
||||||
|
row_varchar = encode(digest($3, $4), 'hex') OR
|
||||||
|
row_bytea = hmac($3, $5, $4) OR
|
||||||
|
row_varchar = encode(hmac($3, $5, $4), 'hex') OR
|
||||||
|
row_bytea = pgp_sym_encrypt($3, $6) OR
|
||||||
|
row_varchar = encode(pgp_sym_encrypt($1, $6), 'hex') OR
|
||||||
|
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
|
||||||
|
SQL,
|
||||||
|
'count' => 6,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
// NOTE, in SQL heredoc we cannot write $$ strings parts
|
||||||
|
'text string, with $ placehoders are in $$ strings' => [
|
||||||
|
'query' => '
|
||||||
|
SELECT row_int
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_varchar = $$some string$$ OR
|
||||||
|
row_varchar = $tag$some string$tag$ OR
|
||||||
|
row_varchar = $btag$some $1 string$btag$ OR
|
||||||
|
row_varchar = $btag$some $1 $subtag$ something $subtag$string$btag$ OR
|
||||||
|
row_varchar = $1
|
||||||
|
',
|
||||||
|
'count' => 1,
|
||||||
|
'convert' => false,
|
||||||
|
],
|
||||||
|
// a text string with escaped quite
|
||||||
|
'text string, with escaped quote' => [
|
||||||
|
'query' => <<<SQL
|
||||||
|
SELECT row_int
|
||||||
|
FROM table_with_primary_key
|
||||||
|
WHERE
|
||||||
|
row_varchar = 'foo bar bar baz $5' OR
|
||||||
|
row_varchar = 'foo bar '' barbar $6' OR
|
||||||
|
row_varchar = E'foo bar \' barbar $7' OR
|
||||||
|
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
|
||||||
|
SQL,
|
||||||
|
'count' => 2,
|
||||||
|
'convert' => false,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
$string = <<<SQL
|
||||||
|
'''
|
||||||
|
SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user