CoreLibs update

This commit is contained in:
Clemens Schwaighofer
2023-09-11 13:40:26 +09:00
parent c0db3be770
commit 74c8b8d71e
14 changed files with 757 additions and 24 deletions

View File

@@ -0,0 +1,53 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-error_msg';
ob_end_flush();
use CoreLibs\Logging\Logger\MessageLevel as ml;
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: ERROR MSG';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title><head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$em = new \CoreLibs\Logging\ErrorMessage($log);
print "FN: " . ml::fromName('Affe')->name . "<br>";
print "NU: " . ml::fromValue(100)->name . "<br>";
print "NU: " . ml::fromValue(1000)->name . "<br>";
$em->setErrorMsg('123', 'error', 'msg this is bad, not logged');
$em->setErrorMsg('123', 'error', 'msg this is bad, logged', log_error:true);
$em->setErrorMsg('1000', 'info', 'This is good');
$em->setErrorMsg('9999', 'abort', 'BAD: This is critical (abort)');
$em->setErrorMsg('10-1000', 'wrong', 'Wrong level: This is emergency');
print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>";
print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>";
print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>";
print "</body></html>";
// __END__

View File

@@ -15,7 +15,7 @@ define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-datetime';
$LOG_FILE_ID = 'classTest-file';
ob_end_flush();
use CoreLibs\Check\File;

View File

@@ -115,6 +115,7 @@ $test_files = [
'class_test.config.link.php' => 'Class Test: CONFIG LINK',
'class_test.config.direct.php' => 'Class Test: CONFIG DIRECT',
'class_test.class-calls.php' => 'Class Test: CLASS CALLS',
'class_test.error_msg.php' => 'Class Test: ERROR MSG',
'subfolder/class_test.config.direct.php' => 'Class Test: CONFIG DIRECT SUB',
];

4
www/composer.lock generated
View File

@@ -8,11 +8,11 @@
"packages": [
{
"name": "egrajp/corelibs-composer-all",
"version": "dev-development",
"version": "dev-master",
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "e1466432a88803eb54ee761f3a4a076760876531"
"reference": "67fd7b172aabff319e5612a78946de4124573bdd"
},
"require": {
"php": ">=8.2",

View File

@@ -2,12 +2,12 @@
"packages": [
{
"name": "egrajp/corelibs-composer-all",
"version": "dev-development",
"version_normalized": "dev-development",
"version": "dev-master",
"version_normalized": "dev-master",
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "e1466432a88803eb54ee761f3a4a076760876531"
"reference": "67fd7b172aabff319e5612a78946de4124573bdd"
},
"require": {
"php": ">=8.2",

View File

@@ -11,9 +11,9 @@
),
'versions' => array(
'egrajp/corelibs-composer-all' => array(
'pretty_version' => 'dev-development',
'version' => 'dev-development',
'reference' => 'e1466432a88803eb54ee761f3a4a076760876531',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '67fd7b172aabff319e5612a78946de4124573bdd',
'type' => 'library',
'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all',
'aliases' => array(),

View File

@@ -1 +1 @@
9.6.0
9.7.3

View File

@@ -26,8 +26,12 @@ class SetVarTypeMain
?string $default = null,
bool $to_null = false
): ?string {
if (is_string($val)) {
return $val;
if (
$val === null ||
is_scalar($val) ||
$val instanceof \Stringable
) {
return (string)$val;
}
if ($to_null === false) {
return (string)$default;
@@ -39,6 +43,7 @@ class SetVarTypeMain
* Will convert input data to string if possible.
* Runs for string/int/float/bool/null
* Will skip array/object/resource/callable/etc and use default for that
* Note: this is pretty much the same as setStrMain because string is easy
*
* @param mixed $val Input variable
* @param string|null $default Default value
@@ -71,6 +76,7 @@ class SetVarTypeMain
/**
* If input variable is int, return it, else return default value. If to_null
* is true then null as return is allowed, else only int is returned
* Note, if float is sent in, int is returned
*
* @param mixed $val Input variable
* @param int|null $default Default value
@@ -82,8 +88,8 @@ class SetVarTypeMain
?int $default = null,
bool $to_null = false
): ?int {
if (is_int($val)) {
return $val;
if (is_numeric($val)) {
return (int)$val;
}
if ($to_null === false) {
return (int)$default;
@@ -129,6 +135,7 @@ class SetVarTypeMain
/**
* If input is float return it, else set to default value. If to_null is set
* to true, allow null return
* Note if an int is sent in, float is returned
*
* @param mixed $val Input variable
* @param float|null $default Default value
@@ -140,8 +147,8 @@ class SetVarTypeMain
?float $default = null,
bool $to_null = false
): ?float {
if (is_float($val)) {
return $val;
if (is_numeric($val)) {
return (float)$val;
}
if ($to_null === false) {
return (float)$default;

View File

@@ -0,0 +1,220 @@
<?php
/**
* AUTOR: Clemens Schwaighofer
* CREATED: 2023/9/7
* DESCRIPTION:
* General error collection class for output to frontend or to log
*/
declare(strict_types=1);
namespace CoreLibs\Logging;
use CoreLibs\Logging\Logger\MessageLevel;
class ErrorMessage
{
/** @var array<int,array{id:string,level:string,str:string,target:string,highlight:string[]}> */
private array $error_str = [];
/** @var \CoreLibs\Logging\Logging $log */
public \CoreLibs\Logging\Logging $log;
/** @var bool $log_error global flag to log error level message */
private bool $log_error = false;
/**
* init ErrorMessage
*
* @param \CoreLibs\Logging\Logging $log
* @param bool $log_error [=false]
*/
public function __construct(
\CoreLibs\Logging\Logging $log,
bool $log_error = false
) {
$this->log = $log;
$this->log_error = $log_error;
}
/**
* pushes new error message into the error_str array
* error_id: internal Error ID (should be unique)
* level: error level, can only be ok, info, warn, error, abort, crash
* ok and info are positive response: success
* warn: success, but there might be some things that are not 100% ok
* error: input error or error in executing request
* abort: an internal error happened as mandatory information that normally is
* there is missing, or the ACL level that should normally match does not
* will be logged to "critical"
* crash: system failure or critical system problems (db connection failure)
* will be logged as "alert"
* not set: unkown, will be logged as "emergency"
* target/highlight: id target name for frontend where to attach this message
* highlight is a list of other target points to highlight
*
* @param string $error_id Any internal error ID for this error
* @param string $level Error level in ok/info/warn/error
* @param string $str Error message (out)
* @param string $target alternate attachment point for this error message
* @param array<string> $highlight Any additional error data as error OR
* highlight points for field highlights
* @param string|null $message If abort/crash, non localized $str
* @param array<mixed> $context Additionl info for abort/crash messages
* @param bool|null $log_error [=null] log level 'error' to error, if null use global,
* else set for this call only
*/
public function setErrorMsg(
string $error_id,
string $level,
string $str,
string $target = '',
array $highlight = [],
?string $message = null,
array $context = [],
?bool $log_error = null,
): void {
if ($log_error === null) {
$log_error = $this->log_error;
}
$original_level = $level;
$level = MessageLevel::fromName($level)->name;
// if not string set, write message string if set, else level/error id
if (empty($str)) {
$str = $message ?? 'L:' . $level . '|E:' . $error_id;
}
$this->error_str[] = [
'id' => $error_id,
'level' => $level,
'str' => $str,
'target' => $target,
'highlight' => $highlight,
];
// write to log for abort/crash
switch ($level) {
case 'error':
if ($log_error) {
$this->log->error($message ?? $str, array_merge([
'id' => $error_id,
'level' => $original_level,
], $context));
}
break;
case 'abort':
$this->log->critical($message ?? $str, array_merge([
'id' => $error_id,
'level' => $original_level,
], $context));
break;
case 'crash':
$this->log->alert($message ?? $str, array_merge([
'id' => $error_id,
'level' => $original_level,
], $context));
break;
case 'unknown':
$this->log->emergency($message ?? $str, array_merge([
'id' => $error_id,
'level' => $original_level,
], $context));
break;
}
}
/**
* pushes new error message into the error_str array
* Note, the parameter order is different and does not need an error id
* This is for backend alerts
*
* @param string $level error level (ok/warn/info/error)
* @param string $str error string
* @param string|null $error_id optional error id for precise error lookup
* @param string $target Alternate id name for output target on frontend
* @param array<string> $highlight Any additional error data as error OR
* highlight points for field highlights
* @param string|null $message If abort/crash, non localized $str
* @param array<mixed> $context Additionl info for abort/crash messages
* @param bool|null $log_error [=null] log level 'error' to error, if null use global,
* else set for this call only
*/
public function setMessage(
string $level,
string $str,
?string $error_id = null,
string $target = '',
array $highlight = [],
?string $message = null,
array $context = [],
?bool $log_error = null,
): void {
$this->setErrorMsg($error_id ?? '', $level, $str, $target, $highlight, $message, $context, $log_error);
}
// *********************************************************************
// GETTERS
// *********************************************************************
/**
* Returns the current set error content from setErrorMsg method
*
* @return array<int,array{id:string,level:string,str:string,target:string,highlight:string[]}> Error messages array
*/
public function getErrorMsg(): array
{
return $this->error_str;
}
/**
* Current set error ids
*
* @return array<string>
*/
public function getErrorIds(): array
{
return array_column($this->error_str, 'id');
}
/**
* Gets the LAST entry in the array list.
* If nothing found returns empty array set
*
* @return array{id:string,level:string,str:string,target:string,highlight:string[]} Error block
*/
public function getLastErrorMsg(): array
{
return $this->error_str[array_key_last($this->error_str)] ?? [
'level' => '',
'str' => '',
'id' => '',
'target' => '',
'highlight' => [],
];
}
// *********************************************************************
// FLAG SETTERS
// *********************************************************************
/**
* Set the log error flag
*
* @param bool $flag True to log level error too, False for do not (Default)
* @return void
*/
public function setFlagLogError(bool $flag): void
{
$this->log_error = $flag;
}
/**
* Get the current log error flag
*
* @return bool
*/
public function getFlagLogError(): bool
{
return $this->log_error;
}
}
// __END__

View File

@@ -113,17 +113,32 @@ enum Level: int
/**
* Returns true if the passed $level is higher or equal to $this
*
* @param Level $level
* @return bool
*/
public function includes(Level $level): bool
{
return $this->value <= $level->value;
}
/**
* If level is higher than set one
*
* @param Level $level
* @return bool
*/
public function isHigherThan(Level $level): bool
{
return $this->value > $level->value;
}
/**
* if level is lower than set one
*
* @param Level $level
* @return bool
*/
public function isLowerThan(Level $level): bool
{
return $this->value < $level->value;

View File

@@ -0,0 +1,84 @@
<?php // phpcs:disable Generic.Files.LineLength
/**
* AUTOR: Clemens Schwaighofer
* CREATED: 2023-09-08
* DESCRIPTION:
* Error message return levels
*/
declare(strict_types=1);
namespace CoreLibs\Logging\Logger;
enum MessageLevel: int
{
case ok = 100;
case info = 200;
case warn = 300;
case error = 400;
case abort = 500;
case crash = 550;
case unknown = 600;
/**
* @param string $name any string name, if not matching use unkown
* @return static
*/
public static function fromName(string $name): self
{
return match (strtolower($name)) {
'ok' => self::ok,
'info' => self::info,
'warn', 'warning' => self::warn,
'error' => self::error,
'abort' => self::abort,
'crash' => self::crash,
default => self::unknown,
};
}
/**
* @param int $value
* @return static
*/
public static function fromValue(int $value): self
{
return self::tryFrom($value) ?? self::unknown;
}
/**
* Returns true if the passed $level is higher or equal to $this
*
* @param MessageLevel $level
* @return bool
*/
public function includes(MessageLevel $level): bool
{
return $this->value <= $level->value;
}
/**
* If level is higher than set one
*
* @param MessageLevel $level
* @return bool
*/
public function isHigherThan(MessageLevel $level): bool
{
return $this->value > $level->value;
}
/**
* if level is lower than set one
*
* @param MessageLevel $level
* @return bool
*/
public function isLowerThan(MessageLevel $level): bool
{
return $this->value < $level->value;
}
}
// __END__

View File

@@ -43,12 +43,17 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
'int, no override' => [
1,
null,
null
'1'
],
'int, override set' => [
1,
'not int',
'not int'
'1'
],
'array, override set' => [
[1, 2],
null,
null
]
];
}
@@ -201,7 +206,7 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
'float' => [
1.5,
null,
null
1
]
];
}
@@ -349,7 +354,7 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
'int' => [
1,
null,
null
1.0
]
];
}

View File

@@ -43,11 +43,16 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
'int, no override' => [
1,
null,
''
'1'
],
'int, override set' => [
1,
'not int',
'1'
],
'array, override set' => [
[1, 2],
'not int',
'not int'
]
];
@@ -189,7 +194,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
'float' => [
1.5,
null,
0
1
]
];
}
@@ -330,7 +335,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
'int' => [
1,
null,
0.0
1.0
]
];
}
@@ -341,7 +346,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
* @dataProvider varSetTypeFloatProvider
* @testdox setFloat $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param mixed $input
* @param float|null $default
* @param float $expected
* @return void

View File

@@ -0,0 +1,343 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Logging\Logger\Level;
/**
* Test class for Logging
* @coversDefaultClass \CoreLibs\Logging\ErrorMessages
* @testdox \CoreLibs\Logging\ErrorMEssages method tests
*/
final class CoreLibsLoggingErrorMessagesTest extends TestCase
{
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
/**
* tear down and remove log data
*
* @return void
*/
public static function tearDownAfterClass(): void
{
array_map('unlink', glob(self::LOG_FOLDER . '*.log'));
}
/**
* for checking level only
*
* @return array
*/
public function providerErrorMessageLevel(): array
{
return [
'ok' => [
'level' => 'ok',
'str' => 'OK',
'expected' => 'ok',
],
'info' => [
'level' => 'info',
'str' => 'INFO',
'expected' => 'info',
],
'warn' => [
'level' => 'warn',
'str' => 'WARN',
'expected' => 'warn'
],
'warning' => [
'level' => 'warning',
'str' => 'WARN',
'expected' => 'warn'
],
'error' => [
'level' => 'error',
'str' => 'ERROR',
'expected' => 'error'
],
'abort' => [
'level' => 'abort',
'str' => 'ABORT',
'expected' => 'abort'
],
'crash' => [
'level' => 'crash',
'str' => 'CRASH',
'expected' => 'crash'
],
'wrong level' => [
'level' => 'wrong',
'str' => 'WRONG',
'expected' => 'unknown'
]
];
}
/**
* Undocumented function
*
* @dataProvider providerErrorMessageLevel
* @testdox error message level: $level will be $expected [$_dataName]
*
* @param string $level
* @param string $str
* @param string $expected
* @return void
*/
public function testErrorMessageLevelOk(string $level, string $str, string $expected): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testErrorMessages',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Debug,
]);
$em = new \CoreLibs\Logging\ErrorMessage($log);
$em->setMessage(
$level,
$str
);
$this->assertEquals(
[
'level' => $expected,
'str' => $str,
'id' => '',
'target' => '',
'highlight' => [],
],
$em->getLastErrorMsg()
);
}
/**
* Undocumented function
*
* @testdox Test of all methods for n messages [$_dataName]
*
* @return void
*/
public function testErrorMessageOk(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testErrorMessages',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Debug
]);
$em = new \CoreLibs\Logging\ErrorMessage($log);
$em->setErrorMsg(
'100',
'info',
'INFO MESSAGE'
);
$this->assertEquals(
[
'id' => '100',
'level' => 'info',
'str' => 'INFO MESSAGE',
'target' => '',
'highlight' => [],
],
$em->getLastErrorMsg()
);
$this->assertEquals(
['100'],
$em->getErrorIds()
);
$this->assertEquals(
[
[
'id' => '100',
'level' => 'info',
'str' => 'INFO MESSAGE',
'target' => '',
'highlight' => [],
]
],
$em->getErrorMsg()
);
$em->setErrorMsg(
'200',
'error',
'ERROR MESSAGE'
);
$this->assertEquals(
[
'id' => '200',
'level' => 'error',
'str' => 'ERROR MESSAGE',
'target' => '',
'highlight' => [],
],
$em->getLastErrorMsg()
);
$this->assertEquals(
['100', '200'],
$em->getErrorIds()
);
$this->assertEquals(
[
[
'id' => '100',
'level' => 'info',
'str' => 'INFO MESSAGE',
'target' => '',
'highlight' => [],
],
[
'id' => '200',
'level' => 'error',
'str' => 'ERROR MESSAGE',
'target' => '',
'highlight' => [],
]
],
$em->getErrorMsg()
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerErrorMessageLog(): array
{
return [
'error, not logged' => [
'id' => '200',
'level' => 'error',
'str' => 'ERROR MESSAGE',
'message' => null,
'log_error' => null,
'expected' => '<ERROR> ERROR MESSAGE',
],
'error, logged' => [
'id' => '200',
'level' => 'error',
'str' => 'ERROR MESSAGE',
'message' => null,
'log_error' => true,
'expected' => '<ERROR> ERROR MESSAGE',
],
'error, logged, message' => [
'id' => '200',
'level' => 'error',
'str' => 'ERROR MESSAGE',
'message' => 'OTHER ERROR MESSAGE',
'log_error' => true,
'expected' => '<ERROR> OTHER ERROR MESSAGE',
],
'crash' => [
'id' => '300',
'level' => 'crash',
'str' => 'CRASH MESSAGE',
'message' => null,
'log_error' => null,
'expected' => '<ALERT> CRASH MESSAGE',
],
'crash, message' => [
'id' => '300',
'level' => 'crash',
'str' => 'CRASH MESSAGE',
'message' => 'OTHER CRASH MESSAGE',
'log_error' => null,
'expected' => '<ALERT> OTHER CRASH MESSAGE',
],
'abort' => [
'id' => '200',
'level' => 'abort',
'str' => 'ABORT MESSAGE',
'message' => null,
'log_error' => null,
'expected' => '<CRITICAL> ABORT MESSAGE',
],
'abort, message' => [
'id' => '200',
'level' => 'abort',
'str' => 'ABORT MESSAGE',
'message' => 'OTHER ABORT MESSAGE',
'log_error' => null,
'expected' => '<CRITICAL> OTHER ABORT MESSAGE',
],
'unknown' => [
'id' => '400',
'level' => 'wrong level',
'str' => 'WRONG LEVEL MESSAGE',
'message' => null,
'log_error' => null,
'expected' => '<EMERGENCY> WRONG LEVEL MESSAGE',
],
'unknown, message' => [
'id' => '400',
'level' => 'wrong level',
'str' => 'WRONG LEVEL MESSAGE',
'message' => 'OTHER WRONG LEVEL MESSAGE',
'log_error' => null,
'expected' => '<EMERGENCY> OTHER WRONG LEVEL MESSAGE',
],
];
}
/**
* Undocumented function
*
* @dataProvider providerErrorMessageLog
* @testdox Test Log writing [$_dataName]
*
* @param string $id
* @param string $level
* @param string $str
* @param string|null $message
* @param bool|null $log_error
* @param string $expected
* @return void
*/
public function testErrorMessageLog(
string $id,
string $level,
string $str,
?string $message,
?bool $log_error,
string $expected
): void {
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testErrorMessages',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Debug,
'log_per_run' => true
]);
$em = new \CoreLibs\Logging\ErrorMessage($log);
$em->setErrorMsg(
$id,
$level,
$str,
message: $message,
log_error: $log_error
);
$file_content = '';
if (is_file($log->getLogFolder() . $log->getLogFile())) {
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
}
// if n
if ($level == 'error' && ($log_error === null || $log_error === false)) {
$this->assertStringNotContainsString(
$expected,
$file_content
);
} else {
$this->assertStringContainsString(
$expected,
$file_content
);
}
}
}
// __END__