Compare commits

...

10 Commits

15 changed files with 487 additions and 119 deletions

View File

@@ -1 +1 @@
9.26.6.1 9.27.0

View File

@@ -423,14 +423,9 @@ class Login
// LOGOUT TARGET // LOGOUT TARGET
if (!isset($options['logout_target'])) { if (!isset($options['logout_target'])) {
if (defined('LOGOUT_TARGET')) { // defaults to ''
trigger_error( $options['logout_target'] = '';
'loginMainCall: LOGOUT_TARGET should not be used', $this->logout_target = $options['logout_target'];
E_USER_DEPRECATED
);
$options['logout_target'] = LOGOUT_TARGET;
$this->logout_target = $options['logout_target'];
}
} }
// *** PASSWORD SETTINGS // *** PASSWORD SETTINGS
@@ -1560,6 +1555,7 @@ class Login
'uid' => $unit['uid'], 'uid' => $unit['uid'],
'cuuid' => $unit['cuuid'], 'cuuid' => $unit['cuuid'],
'level' => $this->default_acl_list[$this->acl['unit'][$ea_cuid]]['name'] ?? -1, 'level' => $this->default_acl_list[$this->acl['unit'][$ea_cuid]]['name'] ?? -1,
'level_number' => $this->acl['unit'][$ea_cuid],
'default' => $unit['default'], 'default' => $unit['default'],
'data' => $unit['data'], 'data' => $unit['data'],
'additional_acl' => $unit['additional_acl'] 'additional_acl' => $unit['additional_acl']
@@ -2538,7 +2534,7 @@ HTML;
$this->login_user_id, $this->login_user_id,
-1, -1,
$login_user_id_changed $login_user_id_changed
); ) ?? '';
// flag unclean input data // flag unclean input data
if ($login_user_id_changed > 0) { if ($login_user_id_changed > 0) {
$this->login_user_id_unclear = true; $this->login_user_id_unclear = true;

View File

@@ -76,7 +76,7 @@ class EditBase
); );
if ($this->form->mobile_phone) { if ($this->form->mobile_phone) {
echo "I am sorry, but this page cannot be viewed by a mobile phone"; echo "I am sorry, but this page cannot be viewed by a mobile phone";
exit; exit(1);
} }
// $this->log->debug('POST', $this->log->prAr($_POST)); // $this->log->debug('POST', $this->log->prAr($_POST));
} }

View File

@@ -103,11 +103,7 @@ class Basic
'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS', 'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS',
'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES', 'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES',
'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH', 'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH',
'DEFAULT_ACL_LEVEL', 'LOGOUT_TARGET', 'PASSWORD_CHANGE', 'AJAX_REQUEST_TYPE', 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET'
'USE_PROTOTYPE', 'USE_SCRIPTACULOUS', 'USE_JQUERY', 'PAGE_WIDTH',
'MASTER_TEMPLATE_NAME', 'PUBLIC_SCHEMA', 'TEST_SCHEMA', 'DEV_SCHEMA',
'LIVE_SCHEMA', 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET', 'DEBUG',
'SHOW_ALL_ERRORS'
] as $constant ] as $constant
) { ) {
if (!defined($constant)) { if (!defined($constant)) {

View File

@@ -639,16 +639,26 @@ class DateTime
* *
* @param string $start_date valid start date (y/m/d) * @param string $start_date valid start date (y/m/d)
* @param string $end_date valid end date (y/m/d) * @param string $end_date valid end date (y/m/d)
* @param bool $return_named return array type, false (default), true for named * @param bool $return_named [default=false] return array type, false (default), true for named
* @return array<mixed> 0/overall, 1/weekday, 2/weekend * @param bool $include_end_date [default=true] include end date in calc
* @param bool $exclude_start_date [default=false] include end date in calc
* @return array{0:int,1:int,2:int,3:bool}|array{overall:int,weekday:int,weekend:int,reverse:bool}
* 0/overall, 1/weekday, 2/weekend, 3/reverse
*/ */
public static function calcDaysInterval( public static function calcDaysInterval(
string $start_date, string $start_date,
string $end_date, string $end_date,
bool $return_named = false bool $return_named = false,
bool $include_end_date = true,
bool $exclude_start_date = false
): array { ): array {
// pos 0 all, pos 1 weekday, pos 2 weekend // pos 0 all, pos 1 weekday, pos 2 weekend
$days = []; $days = [
0 => 0,
1 => 0,
2 => 0,
3 => false,
];
// if anything invalid, return 0,0,0 // if anything invalid, return 0,0,0
try { try {
$start = new \DateTime($start_date); $start = new \DateTime($start_date);
@@ -659,19 +669,30 @@ class DateTime
'overall' => 0, 'overall' => 0,
'weekday' => 0, 'weekday' => 0,
'weekend' => 0, 'weekend' => 0,
'reverse' => false
]; ];
} else { } else {
return [0, 0, 0]; return $days;
} }
} }
// so we include the last day too, we need to add +1 second in the time // so we include the last day too, we need to add +1 second in the time
$end->setTime(0, 0, 1); // if start is before end, switch dates and flag
// if end date before start date, only this will be filled $days[3] = false;
$days[0] = $end->diff($start)->days; if ($start > $end) {
$days[1] = 0; $new_start = $end;
$days[2] = 0; $end = $start;
$start = $new_start;
$days[3] = true;
}
// get period for weekends/weekdays // get period for weekends/weekdays
$period = new \DatePeriod($start, new \DateInterval('P1D'), $end); $options = 0;
if ($include_end_date) {
$options |= \DatePeriod::INCLUDE_END_DATE;
}
if ($exclude_start_date) {
$options |= \DatePeriod::EXCLUDE_START_DATE;
}
$period = new \DatePeriod($start, new \DateInterval('P1D'), $end, $options);
foreach ($period as $dt) { foreach ($period as $dt) {
$curr = $dt->format('D'); $curr = $dt->format('D');
if ($curr == 'Sat' || $curr == 'Sun') { if ($curr == 'Sat' || $curr == 'Sun') {
@@ -679,18 +700,80 @@ class DateTime
} else { } else {
$days[1]++; $days[1]++;
} }
$days[0]++;
} }
if ($return_named === true) { if ($return_named === true) {
return [ return [
'overall' => $days[0], 'overall' => $days[0],
'weekday' => $days[1], 'weekday' => $days[1],
'weekend' => $days[2], 'weekend' => $days[2],
'reverse' => $days[3],
]; ];
} else { } else {
return $days; return $days;
} }
} }
/**
* wrapper for calcDaysInterval with numeric return only
*
* @param string $start_date valid start date (y/m/d)
* @param string $end_date valid end date (y/m/d)
* @param bool $include_end_date [default=true] include end date in calc
* @param bool $exclude_start_date [default=false] include end date in calc
* @return array{0:int,1:int,2:int,3:bool}
*/
public static function calcDaysIntervalNumIndex(
string $start_date,
string $end_date,
bool $include_end_date = true,
bool $exclude_start_date = false
): array {
$values = self::calcDaysInterval(
$start_date,
$end_date,
false,
$include_end_date,
$exclude_start_date
);
return [
$values[0] ?? 0,
$values[1] ?? 0,
$values[2] ?? 0,
$values[3] ?? false,
];
}
/**
* wrapper for calcDaysInterval with named return only
*
* @param string $start_date valid start date (y/m/d)
* @param string $end_date valid end date (y/m/d)
* @param bool $include_end_date [default=true] include end date in calc
* @param bool $exclude_start_date [default=false] include end date in calc
* @return array{overall:int,weekday:int,weekend:int,reverse:bool}
*/
public static function calcDaysIntervalNamedIndex(
string $start_date,
string $end_date,
bool $include_end_date = true,
bool $exclude_start_date = false
): array {
$values = self::calcDaysInterval(
$start_date,
$end_date,
true,
$include_end_date,
$exclude_start_date
);
return [
'overall' => $values['overall'] ?? 0,
'weekday' => $values['weekday'] ?? 0,
'weekend' => $values['weekend'] ?? 0,
'reverse' => $values['reverse'] ?? false,
];
}
/** /**
* check if a weekend day (sat/sun) is in the given date range * check if a weekend day (sat/sun) is in the given date range
* Can have time too, but is not needed * Can have time too, but is not needed
@@ -705,6 +788,13 @@ class DateTime
): bool { ): bool {
$dd_start = new \DateTime($start_date); $dd_start = new \DateTime($start_date);
$dd_end = new \DateTime($end_date); $dd_end = new \DateTime($end_date);
// flip if start is after end
if ($dd_start > $dd_end) {
$new_start = $dd_end;
$dd_end = $dd_start;
$dd_start = $new_start;
}
// if start > end, flip
if ( if (
// starts with a weekend // starts with a weekend
$dd_start->format('N') >= 6 || $dd_start->format('N') >= 6 ||

View File

@@ -10,9 +10,16 @@ namespace CoreLibs\Convert;
class Html class Html
{ {
/** @var int */
public const SELECTED = 0; public const SELECTED = 0;
/** @var int */
public const CHECKED = 1; public const CHECKED = 1;
// TODO: check for not valid htmlentites encoding
// as of PHP 8.4: https://www.php.net/manual/en/function.htmlentities.php
/** @#var array<string> */
// public const VALID_HTMLENT_ENCODINGS = [];
/** /**
* full wrapper for html entities * full wrapper for html entities
* *
@@ -22,14 +29,19 @@ class Html
* encodes in UTF-8 * encodes in UTF-8
* does not double encode * does not double encode
* *
* @param mixed $string string to html encode * @param mixed $string string to html encode
* @param int $flags [default: ENT_QUOTES | ENT_HTML5] * @param int $flags [default=ENT_QUOTES | ENT_HTML5]
* @param string $encoding [default=UTF-8]
* @return mixed if string, encoded, else as is (eg null) * @return mixed if string, encoded, else as is (eg null)
*/ */
public static function htmlent(mixed $string, int $flags = ENT_QUOTES | ENT_HTML5): mixed public static function htmlent(
{ mixed $string,
int $flags = ENT_QUOTES | ENT_HTML5,
string $encoding = 'UTF-8'
): mixed {
if (is_string($string)) { if (is_string($string)) {
return htmlentities($string, $flags, 'UTF-8', false); // if not a valid encoding this will throw a warning and use UTF-8
return htmlentities($string, $flags, $encoding, false);
} }
return $string; return $string;
} }
@@ -37,7 +49,7 @@ class Html
/** /**
* strips out all line breaks or replaced with given string * strips out all line breaks or replaced with given string
* @param string $string string * @param string $string string
* @param string $replace replace character, default ' ' * @param string $replace [default=' '] replace character
* @return string cleaned string without any line breaks * @return string cleaned string without any line breaks
*/ */
public static function removeLB(string $string, string $replace = ' '): string public static function removeLB(string $string, string $replace = ' '): string

View File

@@ -500,7 +500,7 @@ class IO
die('<!-- Cannot load db functions class for: ' . $this->db_type . ' -->'); die('<!-- Cannot load db functions class for: ' . $this->db_type . ' -->');
} }
// write to internal one, once OK // write to internal one, once OK
$this->db_functions = $db_functions; $this->db_functions = $db_functions; /** @phan-suppress-current-line PhanPossiblyNullTypeMismatchProperty */
// connect to DB // connect to DB
if (!$this->__connectToDB()) { if (!$this->__connectToDB()) {
@@ -1413,10 +1413,7 @@ class IO
$this->pk_name_table[$table] ? $this->pk_name_table[$table] ?
$this->pk_name_table[$table] : 'NULL'; $this->pk_name_table[$table] : 'NULL';
} }
if ( if (!preg_match(self::REGEX_RETURNING, $this->query) && $this->pk_name != 'NULL') {
!preg_match(self::REGEX_RETURNING, $this->query) &&
$this->pk_name && $this->pk_name != 'NULL'
) {
// check if this query has a ; at the end and remove it // check if this query has a ; at the end and remove it
$__query = preg_replace("/(;\s*)$/", '', $this->query); $__query = preg_replace("/(;\s*)$/", '', $this->query);
// must be query, if preg replace failed, use query as before // must be query, if preg replace failed, use query as before
@@ -1426,7 +1423,7 @@ class IO
} elseif ( } elseif (
preg_match(self::REGEX_RETURNING, $this->query, $matches) preg_match(self::REGEX_RETURNING, $this->query, $matches)
) { ) {
if ($this->pk_name && $this->pk_name != 'NULL') { if ($this->pk_name != 'NULL') {
// add the primary key if it is not in the returning set // add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1])) { if (!preg_match("/$this->pk_name/", $matches[1])) {
$this->query .= " , " . $this->pk_name; $this->query .= " , " . $this->pk_name;
@@ -2946,7 +2943,7 @@ class IO
$query_hash = $this->dbGetQueryHash($query, $params); $query_hash = $this->dbGetQueryHash($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->__dbError(18, context: [ $this->__dbWarning(18, context: [
'query' => $query, 'query' => $query,
'params' => $params, 'params' => $params,
'hash' => $query_hash, 'hash' => $query_hash,
@@ -3141,6 +3138,7 @@ class IO
'pk_name' => '', 'pk_name' => '',
'count' => 0, 'count' => 0,
'query' => '', 'query' => '',
'query_raw' => $query,
'result' => null, 'result' => null,
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [], 'placeholder_converted' => [],
@@ -3237,11 +3235,12 @@ class IO
} }
} else { } else {
// if we try to use the same statement name for a differnt query, error abort // if we try to use the same statement name for a differnt query, error abort
if ($this->prepare_cursor[$stm_name]['query'] != $query) { if ($this->prepare_cursor[$stm_name]['query_raw'] != $query) {
// thrown error // thrown error
$this->__dbError(26, false, context: [ $this->__dbError(26, false, context: [
'statement_name' => $stm_name, 'statement_name' => $stm_name,
'prepared_query' => $this->prepare_cursor[$stm_name]['query'], 'prepared_query' => $this->prepare_cursor[$stm_name]['query'],
'prepared_query_raw' => $this->prepare_cursor[$stm_name]['query_raw'],
'query' => $query, 'query' => $query,
'pk_name' => $pk_name, 'pk_name' => $pk_name,
]); ]);
@@ -4364,6 +4363,37 @@ class IO
return $this->prepare_cursor[$stm_name][$key]; return $this->prepare_cursor[$stm_name][$key];
} }
/**
* Checks if a prepared query eixsts
*
* @param string $stm_name Statement to check
* @param string $query [default=''] If set then query must also match
* @return false|int<0,2> False on missing stm_name
* 0: ok, 1: stm_name matchin, 2: stm_name and query matching
*/
public function dbPreparedCursorStatus(string $stm_name, string $query = ''): false|int
{
if (empty($stm_name)) {
$this->__dbError(
101,
false,
'No statement name given'
);
return false;
}
// does not exist
$return_value = 0;
if (!empty($this->prepare_cursor[$stm_name]['query_raw'])) {
// statement name eixts
$return_value = 1;
if ($this->prepare_cursor[$stm_name]['query_raw'] == $query) {
// query also matches
$return_value = 2;
}
}
return $return_value;
}
// *************************** // ***************************
// ERROR AND WARNING DATA // ERROR AND WARNING DATA
// *************************** // ***************************

View File

@@ -50,7 +50,6 @@ class GetLocale
$locale = defined('SITE_LOCALE') && !empty(SITE_LOCALE) ? $locale = defined('SITE_LOCALE') && !empty(SITE_LOCALE) ?
SITE_LOCALE : SITE_LOCALE :
// else parse from default, if not 'en' // else parse from default, if not 'en'
/** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */
(defined('DEFAULT_LOCALE') && !empty(DEFAULT_LOCALE) ? (defined('DEFAULT_LOCALE') && !empty(DEFAULT_LOCALE) ?
DEFAULT_LOCALE : 'en'); DEFAULT_LOCALE : 'en');
} }
@@ -97,8 +96,7 @@ class GetLocale
$encoding = defined('SITE_ENCODING') && !empty(SITE_ENCODING) ? $encoding = defined('SITE_ENCODING') && !empty(SITE_ENCODING) ?
SITE_ENCODING : SITE_ENCODING :
// or default encoding, if not 'UTF-8' // or default encoding, if not 'UTF-8'
/** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */ (defined('DEFAULT_ENCODING') ?
(defined('DEFAULT_ENCODING') && !empty(DEFAULT_ENCODING) ?
DEFAULT_ENCODING : 'UTF-8'); DEFAULT_ENCODING : 'UTF-8');
} }
} }

View File

@@ -418,9 +418,7 @@ class ProgressBar
// if this is percent, we ignore anything, it is auto positioned // if this is percent, we ignore anything, it is auto positioned
if ($this->label[$name]['type'] != 'percent') { if ($this->label[$name]['type'] != 'percent') {
foreach (['top', 'left', 'width', 'height'] as $pos_name) { foreach (['top', 'left', 'width', 'height'] as $pos_name) {
if ($$pos_name !== false) { $this->label[$name][$pos_name] = intval($$pos_name);
$this->label[$name][$pos_name] = intval($$pos_name);
}
} }
if ($align != '') { if ($align != '') {

View File

@@ -48,7 +48,7 @@ header("Content-Type: application/json; charset=UTF-8");
if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) { if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) {
header("HTTP/1.1 401 Unauthorized"); header("HTTP/1.1 401 Unauthorized");
print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}'); print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}');
exit; exit(1);
} }
// if server request type is get set file_get to null -> no body // if server request type is get set file_get to null -> no body
@@ -57,7 +57,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") {
} elseif (($file_get = file_get_contents('php://input')) === false) { } elseif (($file_get = file_get_contents('php://input')) === false) {
header("HTTP/1.1 404 Not Found"); header("HTTP/1.1 404 Not Found");
print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}'); print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}');
exit; exit(1);
} }
print buildContent($http_headers, $file_get); print buildContent($http_headers, $file_get);

View File

@@ -152,7 +152,6 @@ final class CoreLibsACLLoginTest extends TestCase
// TARGET // TARGET
define('TARGET', 'test'); define('TARGET', 'test');
// LOGIN DB SCHEMA // LOGIN DB SCHEMA
// define('LOGIN_DB_SCHEMA', '');
// SHOULD SET // SHOULD SET
// DEFAULT_ACL_LEVEL (d80) // DEFAULT_ACL_LEVEL (d80)

View File

@@ -926,48 +926,114 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
public function daysIntervalProvider(): array public function daysIntervalProvider(): array
{ {
return [ return [
'valid interval /, not named array' => [ // normal and format tests
'2020/1/1', 'valid interval / not named array' => [
'2020/1/30', 'input_a' => '2020/1/1',
false, 'input_b' => '2020/1/30',
[29, 22, 8], 'return_named' => false, // return_named
'include_end_date' => true, // include_end_date
'exclude_start_date' => false, // exclude_start_date
'expected' => [30, 22, 8, false],
], ],
'valid interval /, named array' => [ 'valid interval / named array' => [
'2020/1/1', 'input_a' => '2020/1/1',
'2020/1/30', 'input_b' => '2020/1/30',
true, 'return_named' => true,
['overall' => 29, 'weekday' => 22, 'weekend' => 8], 'include_end_date' => true,
'exclude_start_date' => false,
'expected' => ['overall' => 30, 'weekday' => 22, 'weekend' => 8, 'reverse' => false],
], ],
'valid interval -' => [ 'valid interval with "-"' => [
'2020-1-1', 'input_a' => '2020-1-1',
'2020-1-30', 'input_b' => '2020-1-30',
false, 'return_named' => false,
[29, 22, 8], 'include_end_date' => true,
], 'exclude_start_date' => false,
'valid interval switched' => [ 'expected' => [30, 22, 8, false],
'2020/1/30',
'2020/1/1',
false,
[28, 0, 0],
], ],
'valid interval with time' => [ 'valid interval with time' => [
'2020/1/1 12:12:12', 'input_a' => '2020/1/1 12:12:12',
'2020/1/30 13:13:13', 'input_b' => '2020/1/30 13:13:13',
false, 'return_named' => false,
[28, 21, 8], 'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
], ],
// invalid
'invalid dates' => [ 'invalid dates' => [
'abc', 'input_a' => 'abc',
'xyz', 'input_b' => 'xyz',
false, 'return_named' => false,
[0, 0, 0] 'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [0, 0, 0, false]
], ],
// this test will take a long imte // this test will take a long time
'out of bound dates' => [ 'out of bound dates' => [
'1900-1-1', 'input_a' => '1900-1-1',
'9999-12-31', 'input_b' => '9999-12-31',
false, 'return_named' => false,
[2958463,2113189,845274], 'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [2958463, 2113189, 845274, false],
],
// tests for include/exclude
'exclude end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, false],
],
'exclude start date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, false],
],
'exclude start and end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, false],
],
// reverse
'reverse: valid interval' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, true],
],
'reverse: exclude end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start and end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, true],
], ],
]; ];
} }
@@ -982,20 +1048,52 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
* *
* @param string $input_a * @param string $input_a
* @param string $input_b * @param string $input_b
* @param bool $flag * @param bool $return_named
* @param array $expected * @param array $expected
* @return void * @return void
*/ */
public function testCalcDaysInterval( public function testCalcDaysInterval(
string $input_a, string $input_a,
string $input_b, string $input_b,
bool $flag, bool $return_named,
bool $include_end_date,
bool $exclude_start_date,
$expected $expected
): void { ): void {
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag) \CoreLibs\Combined\DateTime::calcDaysInterval(
$input_a,
$input_b,
return_named:$return_named,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysInterval'
); );
if ($return_named) {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNamedIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNumIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
}
} }
/** /**
@@ -1187,7 +1285,38 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
'2023-07-03', '2023-07-03',
'2023-07-27', '2023-07-27',
true true
] ],
// reverse
'reverse: no weekend' => [
'2023-07-04',
'2023-07-03',
false
],
'reverse: start weekend sat' => [
'2023-07-04',
'2023-07-01',
true
],
'reverse: start weekend sun' => [
'2023-07-04',
'2023-07-02',
true
],
'reverse: end weekend sat' => [
'2023-07-08',
'2023-07-03',
true
],
'reverse: end weekend sun' => [
'2023-07-09',
'2023-07-03',
true
],
'reverse: long period > 6 days' => [
'2023-07-27',
'2023-07-03',
true
],
]; ];
} }

View File

@@ -40,7 +40,7 @@ final class CoreLibsConvertByteTest extends TestCase
4 => '1.00 KB', 4 => '1.00 KB',
5 => '1.02KiB', 5 => '1.02KiB',
], ],
'invalud string number' => [ 'invalid string number' => [
0 => '1024 MB', 0 => '1024 MB',
1 => '1024 MB', 1 => '1024 MB',
2 => '1024 MB', 2 => '1024 MB',

View File

@@ -3692,7 +3692,7 @@ final class CoreLibsDBIOTest extends TestCase
* *
* @return array * @return array
*/ */
public function preparedProviderValue(): array public function providerDbGetPrepareCursorValue(): array
{ {
// 1: query (can be empty for do not set) // 1: query (can be empty for do not set)
// 2: stm name // 2: stm name
@@ -3736,7 +3736,7 @@ final class CoreLibsDBIOTest extends TestCase
* test return prepare cursor errors * test return prepare cursor errors
* *
* @covers ::dbGetPrepareCursorValue * @covers ::dbGetPrepareCursorValue
* @dataProvider preparedProviderValue * @dataProvider providerDbGetPrepareCursorValue
* @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName] * @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName]
* *
* @param string $query * @param string $query
@@ -3769,6 +3769,94 @@ final class CoreLibsDBIOTest extends TestCase
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function providerDbPreparedCursorStatus(): array
{
return [
'empty statement pararm' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_a',
'check_stm_name' => '',
'check_query' => '',
'expected' => false
],
'different stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_b',
'check_stm_name' => 'other_name',
'check_query' => '',
'expected' => 0
],
'same stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_c',
'check_stm_name' => 'test_stm_c',
'check_query' => '',
'expected' => 1
],
'same stm_name and query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_d',
'check_stm_name' => 'test_stm_d',
'check_query' => 'SELECT row_int, uid FROM table_with_primary_key',
'expected' => 2
],
'same stm_name and different query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_e',
'check_stm_name' => 'test_stm_e',
'check_query' => 'SELECT row_int, uid, row_int FROM table_with_primary_key',
'expected' => 1
],
'insert query test' => [
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'stm_name' => 'test_stm_f',
'check_stm_name' => 'test_stm_f',
'check_query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'expected' => 2
]
];
}
/**
* test cursor status for prepared statement
*
* @covers ::dbPreparedCursorStatus
* @dataProvider providerDbPreparedCursorStatus
* @testdox Check prepared $stm_name ($check_stm_name) status is $expected [$_dataName]
*
* @param string $query
* @param string $stm_name
* @param string $check_stm_name
* @param string $check_query
* @param bool|int $expected
* @return void
*/
public function testDbPreparedCursorStatus(
string $query,
string $stm_name,
string $check_stm_name,
string $check_query,
bool|int $expected
): void {
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
$db->dbPrepare($stm_name, $query);
// $db->dbExecute($stm_name);
$this->assertEquals(
$expected,
$db->dbPreparedCursorStatus($check_stm_name, $check_query),
'check prepared stement cursor status'
);
unset($db);
}
// - schema set/get tests // - schema set/get tests
// dbGetSchema, dbSetSchema // dbGetSchema, dbSetSchema

View File

@@ -969,44 +969,76 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
"query" => ["foo-get" => "bar"] "query" => ["foo-get" => "bar"]
]); ]);
$this->assertEquals("200", $response["code"], "multi call: get response code not matching"); $this->assertEquals("200", $response["code"], "multi call: get response code not matching");
$this->assertEquals( if (PHP_VERSION_ID >= 80400) {
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' $this->assertEquals(
. '"HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",' '{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_HOST":"soba.egplusww.jp"},' . '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1","HTTP_FIRST_CALL":"get",'
. '"REQUEST_TYPE":"GET",' . '"HTTP_ACCEPT":"*\/*"},"REQUEST_TYPE":"GET","PARAMS":{"foo-get":"bar"},"BODY":null}',
. '"PARAMS":{"foo-get":"bar"},"BODY":null}', $response['content'],
$response['content'], 'multi call: get content not matching'
'multi call: get content not matching' );
); } else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"GET",'
. '"PARAMS":{"foo-get":"bar"},"BODY":null}',
$response['content'],
'multi call: get content not matching'
);
}
// post // post
$response = $curl->post($this->url_basic, [ $response = $curl->post($this->url_basic, [
"headers" => ["second-call" => "post"], "headers" => ["second-call" => "post"],
"body" => ["foo-post" => "baz"] "body" => ["foo-post" => "baz"]
]); ]);
$this->assertEquals("200", $response["code"], "multi call: post response code not matching"); $this->assertEquals("200", $response["code"], "multi call: post response code not matching");
$this->assertEquals( if (PHP_VERSION_ID >= 80400) {
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' $this->assertEquals(
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*",' '{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_HOST":"soba.egplusww.jp"},' . '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"REQUEST_TYPE":"POST",' . '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*"},'
. '"PARAMS":[],"BODY":{"foo-post":"baz"}}', . '"REQUEST_TYPE":"POST","PARAMS":[],"BODY":{"foo-post":"baz"}}',
$response['content'], $response['content'],
'multi call: post content not matching' 'multi call: post content not matching'
); );
} else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"POST",'
. '"PARAMS":[],"BODY":{"foo-post":"baz"}}',
$response['content'],
'multi call: post content not matching'
);
}
// delete // delete
$response = $curl->delete($this->url_basic, [ $response = $curl->delete($this->url_basic, [
"headers" => ["third-call" => "delete"], "headers" => ["third-call" => "delete"],
]); ]);
$this->assertEquals("200", $response["code"], "multi call: delete response code not matching"); $this->assertEquals("200", $response["code"], "multi call: delete response code not matching");
$this->assertEquals( if (PHP_VERSION_ID >= 80400) {
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' $this->assertEquals(
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*",' '{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_HOST":"soba.egplusww.jp"},' . '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"REQUEST_TYPE":"DELETE",' . '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*"},'
. '"PARAMS":[],"BODY":[]}', . '"REQUEST_TYPE":"DELETE","PARAMS":[],"BODY":[]}',
$response['content'], $response['content'],
'multi call: delete content not matching' 'multi call: delete content not matching'
); );
} else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"DELETE",'
. '"PARAMS":[],"BODY":[]}',
$response['content'],
'multi call: delete content not matching'
);
}
} }
// MARK: auth header set via config // MARK: auth header set via config