composer test update

This commit is contained in:
Clemens Schwaighofer
2023-05-31 16:43:30 +09:00
parent 3d6b461b20
commit f5a9757ae3
72 changed files with 5256 additions and 1853 deletions

View File

@@ -1,44 +0,0 @@
<?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 '../configs/config.php';
// define log file id
$LOG_FILE_ID = 'classTest-config-direct';
ob_end_flush();
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: CONFIG DIRECT';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title><head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "DIR: " . DIR . "<br>";
print "BASE: " . BASE . "<br>";
print "ROOT: " . ROOT . "<br>";
print "BASE NAME: " . BASE_NAME . "<br>";
echo "Config path prefix: " . ($CONFIG_PATH_PREFIX ?? '') . "<br>";
print "DB Name: " . DB_CONFIG_NAME . "<br>";
print "DB Config: " . \CoreLibs\Debug\Support::printAr(DB_CONFIG) . "<br>";
print "</body></html>";
// __END__

View File

@@ -6,11 +6,6 @@
declare(strict_types=1);
$DEBUG_ALL_OVERRIDE = false; // set to 1 to debug on live/remote server locations
$DEBUG_ALL = true;
$PRINT_ALL = true;
$DB_DEBUG = true;
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
@@ -23,17 +18,16 @@ require 'config.php';
$LOG_FILE_ID = 'classTest';
$SET_SESSION_NAME = EDIT_SESSION_NAME;
use CoreLibs\Logging;
use CoreLibs\Debug\Support;
// init login & backend class
$session = new CoreLibs\Create\Session($SET_SESSION_NAME);
$log = new CoreLibs\Debug\Logging([
$log = new Logging\Logging([
'log_folder' => BASE . LOG,
'file_id' => $LOG_FILE_ID,
'log_file_id' => $LOG_FILE_ID,
// add file date
'print_file_date' => true,
// set debug and print flags
'debug_all' => $DEBUG_ALL,
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL,
'log_per_date' => true,
]);
$db = new CoreLibs\DB\IO(DB_CONFIG, $log);
$login = new CoreLibs\ACL\Login(
@@ -72,52 +66,64 @@ print "<!DOCTYPE html>";
print "<html><head><title>TEST CLASS</title><head>";
print "<body>";
print '<div><a href="class_test.db.php">Class Test: DB</a></div>';
print '<div><a href="class_test.db.dbReturn.php">Class Test: DB dbReturn</a></div>';
print '<div><a href="class_test.convert.colors.php">Class Test: CONVERT COLORS</a></div>';
print '<div><a href="class_test.check.colors.php">Class Test: CHECK COLORS</a></div>';
print '<div><a href="class_test.mime.php">Class Test: MIME</a></div>';
print '<div><a href="class_test.json.php">Class Test: JSON</a></div>';
print '<div><a href="class_test.token.php">Class Test: FORM TOKEN</a></div>';
print '<div><a href="class_test.password.php">Class Test: PASSWORD</a></div>';
print '<div><a href="class_test.math.php">Class Test: MATH</a></div>';
print '<div><a href="class_test.html.php">Class Test: HTML/ELEMENTS</a></div>';
print '<div><a href="class_test.email.php">Class Test: EMAIL</a></div>';
print '<div><a href="class_test.create_email.php">Class Test: CREATE EMAIL</a></div>';
print '<div><a href="class_test.uids.php">Class Test: UIDS</a></div>';
print '<div><a href="class_test.phpv.php">Class Test: PHP VERSION</a></div>';
print '<div><a href="class_test.hash.php">Class Test: HASH</a></div>';
print '<div><a href="class_test.encoding.php">Class Test: ENCODING (CHECK/CONVERT/MIME)</a></div>';
print '<div><a href="class_test.image.php">Class Test: IMAGE</a></div>';
print '<div><a href="class_test.byte.php">Class Test: BYTE CONVERT</a></div>';
print '<div><a href="class_test.strings.php">Class Test: STRING CONVERT</a></div>';
print '<div><a href="class_test.datetime.php">Class Test: DATE/TIME</a></div>';
print '<div><a href="class_test.array.php">Class Test: ARRAY HANDLER</a></div>';
print '<div><a href="class_test.file.php">Class Test: FILE</a></div>';
print '<div><a href="class_test.randomkey.php">Class Test: RANDOM KEY</a></div>';
print '<div><a href="class_test.system.php">Class Test: SYSTEM</a></div>';
print '<div><a href="class_test.readenvfile.php">Class Test: READ ENV FILE</a></div>';
print '<div><a href="class_test.runningtime.php">Class Test: RUNNING TIME</a></div>';
print '<div><a href="class_test.memoryusage.php">Class Test: MEMORY USAGE</a></div>';
print '<div><a href="class_test.debug.php">Class Test: DEBUG</a></div>';
print '<div><a href="class_test.output.form.php">Class Test: OUTPUT FORM</a></div>';
print '<div><a href="class_test.admin.backend.php">Class Test: BACKEND ADMIN CLASS</a></div>';
print '<div><a href="class_test.lang.php">Class Test: LANG/L10n</a></div>';
print '<div><a href="class_test.varistype.php">Class Test: SET VAR TYPE</a></div>';
print '<div><a href="class_test.session.php">Class Test: SESSION</a></div>';
print '<div><a href="class_test.session.read.php">Class Test: SESSION: READ</a></div>';
print '<div><a href="class_test.smarty.php">Class Test: SMARTY</a></div>';
print '<div><a href="class_test.login.php">Class Test: LOGIN</a></div>';
print '<div><a href="class_test.autoloader.php">Class Test: AUTOLOADER</a></div>';
print '<div><a href="class_test.config.link.php">Class Test: CONFIG LINK</a></div>';
print '<div><a href="class_test.config.direct.php">Class Test: CONFIG DIRECT</a></div>';
print '<div><a href="subfolder/class_test.config.direct.php">Class Test: CONFIG DIRECT SUB</a></div>';
// key: file name, value; name
$test_files = [
'class_test.db.php' => 'Class Test: DB',
'class_test.db.single.php' => 'Class Test: DB SINGLE',
'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn',
'class_test.convert.colors.php' => 'Class Test: CONVERT COLORS',
'class_test.check.colors.php' => 'Class Test: CHECK COLORS',
'class_test.mime.php' => 'Class Test: MIME',
'class_test.json.php' => 'Class Test: JSON',
'class_test.token.php' => 'Class Test: FORM TOKEN',
'class_test.password.php' => 'Class Test: PASSWORD',
'class_test.encryption.php' => 'Class Test: ENCRYPTION',
'class_test.math.php' => 'Class Test: MATH',
'class_test.html.php' => 'Class Test: HTML/ELEMENTS',
'class_test.email.php' => 'Class Test: EMAIL',
'class_test.create_email.php' => 'Class Test: CREATE EMAIL',
'class_test.uids.php' => 'Class Test: UIDS',
'class_test.phpv.php' => 'Class Test: PHP VERSION',
'class_test.hash.php' => 'Class Test: HASH',
'class_test.encoding.php' => 'Class Test: ENCODING (CHECK/CONVERT/MIME)',
'class_test.image.php' => 'Class Test: IMAGE',
'class_test.byte.php' => 'Class Test: BYTE CONVERT',
'class_test.strings.php' => 'Class Test: STRING CONVERT',
'class_test.datetime.php' => 'Class Test: DATE/TIME',
'class_test.array.php' => 'Class Test: ARRAY HANDLER',
'class_test.file.php' => 'Class Test: FILE',
'class_test.randomkey.php' => 'Class Test: RANDOM KEY',
'class_test.system.php' => 'Class Test: SYSTEM',
'class_test.readenvfile.php' => 'Class Test: READ ENV FILE',
'class_test.runningtime.php' => 'Class Test: RUNNING TIME',
'class_test.memoryusage.php' => 'Class Test: MEMORY USAGE',
'class_test.debug.php' => 'Class Test: DEBUG',
'class_test.logging.php' => 'Class Test: LOGGING',
'class_test.output.form.php' => 'Class Test: OUTPUT FORM',
'class_test.admin.backend.php' => 'Class Test: BACKEND ADMIN CLASS',
'class_test.lang.php' => 'Class Test: LANG/L10n',
'class_test.varistype.php' => 'Class Test: SET VAR TYPE',
'class_test.session.php' => 'Class Test: SESSION',
'class_test.session.read.php' => 'Class Test: SESSION: READ',
'class_test.smarty.php' => 'Class Test: SMARTY',
'class_test.login.php' => 'Class Test: LOGIN',
'class_test.autoloader.php' => 'Class Test: AUTOLOADER',
'class_test.config.link.php' => 'Class Test: CONFIG LINK',
'class_test.config.direct.php' => 'Class Test: CONFIG DIRECT',
'subfolder/class_test.config.direct.php' => 'Class Test: CONFIG DIRECT SUB',
];
asort($test_files);
foreach ($test_files as $file => $name) {
print '<div><a href="' . $file . '">' . $name . '</a></div>';
}
print "<hr>";
print "L: " . CoreLibs\Debug\Support::printAr($locale) . "<br>";
print "L: " . Support::dumpVar($locale) . "<br>";
// print all _ENV vars set
print "<div>READ _ENV ARRAY:</div>";
print CoreLibs\Debug\Support::printAr(array_map('htmlentities', $_ENV));
print Support::dumpVar(array_map('htmlentities', $_ENV));
// set + check edit access id
$edit_access_id = 3;
if (is_object($login) && isset($login->loginGetAcl()['unit'])) {
@@ -132,7 +138,7 @@ if (is_object($login) && isset($login->loginGetAcl()['unit'])) {
print "Something went wrong with the login<br>";
}
// $backend->log->debug('SESSION', \CoreLibs\Debug\Support::printAr($_SESSION));
// $backend->log->debug('SESSION', \CoreLibs\Debug\Support::dumpVar($_SESSION));
print '<form method="post" name="loginlogout">';
print '<a href="javascript:document.loginlogout.login_logout.value=\'Logou\';'
@@ -140,18 +146,23 @@ print '<a href="javascript:document.loginlogout.login_logout.value=\'Logou\';'
print '<input type="hidden" name="login_logout" value="">';
print '</form>';
// print the debug core vars
foreach (['on', 'off'] as $flag) {
foreach (['debug', 'echo', 'print'] as $type) {
$prefix = $flag == 'off' ? 'NOT ' : '';
print $prefix . strtoupper($type) . ' OUT: '
. \CoreLibs\Debug\Support::printAr(\CoreLibs\Convert\SetVarType::setArray(
$backend->log->getLogLevel($type, $flag)
)) . '<br>';
}
}
foreach (['debug', 'echo', 'print'] as $type) {
print strtoupper($type) . ' OUT ALL: ' . $backend->log->getLogLevelAll($type) . '<br>';
print "Log Level: " . $backend->log->getLoggingLevel()->getName() . "<br>";
print "Log ID: " . $backend->log->getLogFileId() . "<br>";
print "Log Date: " . $backend->log->getLogDate() . "<br>";
print "Log Max File Size: " . $backend->log->getLogMaxFileSize() . " bytes<br>";
print "Log Flags: " . $backend->log->getLogFlags() . "<br>";
foreach (
[
Logging\Logger\Flag::per_run,
Logging\Logger\Flag::per_date,
Logging\Logger\Flag::per_group,
Logging\Logger\Flag::per_page,
Logging\Logger\Flag::per_class,
Logging\Logger\Flag::per_level
] as $flag
) {
print "Log Flag: " . $flag->name . ": "
. CoreLibs\Debug\Support::printBool($backend->log->getLogFlag($flag)) . "<br>";
}
$log->debug('SOME MARK', 'Some error output');
@@ -160,7 +171,7 @@ $log->debug('SOME MARK', 'Some error output');
print "EDIT ACCESS ID: " . $backend->edit_access_id . "<br>";
if (is_object($login)) {
// print "ACL: <br>".$backend->print_ar($login->loginGetAcl())."<br>";
$log->debug('ACL', "ACL: " . \CoreLibs\Debug\Support::printAr($login->loginGetAcl()));
$log->debug('ACL', "ACL: " . \CoreLibs\Debug\Support::dumpVar($login->loginGetAcl()));
// print "DEFAULT ACL: <br>".$backend->print_ar($login->default_acl_list)."<br>";
// print "DEFAULT ACL: <br>".$backend->print_ar($login->default_acl_list)."<br>";
// $result = array_flip(
@@ -182,15 +193,11 @@ print "THIS HOST: " . HOST_NAME . ", with PROTOCOL: " . HOST_PROTOCOL . " is run
print "DIR: " . DIR . "<br>";
print "BASE: " . BASE . "<br>";
print "ROOT: " . ROOT . "<br>";
print "HOST: " . HOST_NAME . " => DB HOST: " . DB_CONFIG_NAME . " => " . print_r(DB_CONFIG, true) . "<br>";
print "HOST: " . HOST_NAME . " => DB HOST: " . DB_CONFIG_NAME . " => " . Support::dumpVar(DB_CONFIG) . "<br>";
print "DS is: " . DIRECTORY_SEPARATOR . "<br>";
print "SERVER HOST: " . $_SERVER['HTTP_HOST'] . "<br>";
// print error messages
// print $login->log->printErrorMsg();
print $log->printErrorMsg();
print "</body></html>";
# __END__

View File

@@ -6,11 +6,6 @@
declare(strict_types=1);
$DEBUG_ALL_OVERRIDE = 0; // set to 1 to debug on live/remote server locations
$DEBUG_ALL = 1;
$PRINT_ALL = 1;
$DB_DEBUG = 1;
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
@@ -23,15 +18,10 @@ require '../../configs/config.php';
$LOG_FILE_ID = 'classTest-config-direct';
ob_end_flush();
$log = new CoreLibs\Debug\Logging([
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'file_id' => $LOG_FILE_ID,
// add file date
'print_file_date' => true,
// set debug and print flags
'debug_all' => $DEBUG_ALL,
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: CONFIG DIRECT SUB';
@@ -49,9 +39,6 @@ echo "Config path prefix: " . ($CONFIG_PATH_PREFIX ?? '') . "<br>";
print "DB Name: " . DB_CONFIG_NAME . "<br>";
print "DB Config: " . \CoreLibs\Debug\Support::printAr(DB_CONFIG) . "<br>";
// error message
print $log->printErrorMsg();
print "</body></html>";
// __END__

View File

@@ -12,7 +12,8 @@
"require": {
"egrajp/smarty-extended": "^4.3",
"egrajp/corelibs-composer-all": "@dev",
"gullevek/dotenv": "^2.0"
"gullevek/dotenv": "^2.0",
"psr/log": "^2.0 || ^3.0"
},
"autoload": {
"classmap": [

57
www/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9699de1d948a72e73dc2663bf7a951e5",
"content-hash": "4cde2c3b3397cacb92afaa89e66985db",
"packages": [
{
"name": "egrajp/corelibs-composer-all",
@@ -12,10 +12,11 @@
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "f66f8f282e15a15ecd25e21a2767359b5ec875d4"
"reference": "24f7a903efb9bfd8b99c7aae9e1e77013c753cd9"
},
"require": {
"php": ">=8.1"
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"require-dev": {
"egrajp/smarty-extended": "^4.3",
@@ -128,6 +129,56 @@
"source": "https://github.com/gullevek/dotEnv/tree/v2.0.8"
},
"time": "2023-03-03T00:32:02+00:00"
},
{
"name": "psr/log",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.0"
},
"time": "2021-07-14T16:46:02+00:00"
}
],
"packages-dev": [],

View File

@@ -8,5 +8,6 @@ $baseDir = dirname($vendorDir);
return array(
'gullevek\\dotenv\\' => array($vendorDir . '/gullevek/dotenv/src'),
'gullevek\\dotEnv\\' => array($vendorDir . '/gullevek/dotenv/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
'CoreLibs\\' => array($vendorDir . '/egrajp/corelibs-composer-all/src'),
);

View File

@@ -12,6 +12,10 @@ class ComposerStaticInit1b7cd5bacf2590b458d7a94400b505d4
'gullevek\\dotenv\\' => 16,
'gullevek\\dotEnv\\' => 16,
),
'P' =>
array (
'Psr\\Log\\' => 8,
),
'C' =>
array (
'CoreLibs\\' => 9,
@@ -27,6 +31,10 @@ class ComposerStaticInit1b7cd5bacf2590b458d7a94400b505d4
array (
0 => __DIR__ . '/..' . '/gullevek/dotenv/src',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/src',
),
'CoreLibs\\' =>
array (
0 => __DIR__ . '/..' . '/egrajp/corelibs-composer-all/src',

View File

@@ -7,10 +7,11 @@
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "f66f8f282e15a15ecd25e21a2767359b5ec875d4"
"reference": "24f7a903efb9bfd8b99c7aae9e1e77013c753cd9"
},
"require": {
"php": ">=8.1"
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"require-dev": {
"egrajp/smarty-extended": "^4.3",
@@ -129,6 +130,59 @@
"source": "https://github.com/gullevek/dotEnv/tree/v2.0.8"
},
"install-path": "../gullevek/dotenv"
},
{
"name": "psr/log",
"version": "3.0.0",
"version_normalized": "3.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"time": "2021-07-14T16:46:02+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.0"
},
"install-path": "../psr/log"
}
],
"dev": true,

View File

@@ -13,7 +13,7 @@
'egrajp/corelibs-composer-all' => array(
'pretty_version' => 'dev-development',
'version' => 'dev-development',
'reference' => 'f66f8f282e15a15ecd25e21a2767359b5ec875d4',
'reference' => '24f7a903efb9bfd8b99c7aae9e1e77013c753cd9',
'type' => 'library',
'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all',
'aliases' => array(),
@@ -46,5 +46,14 @@
'aliases' => array(),
'dev_requirement' => false,
),
'psr/log' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@@ -16,7 +16,8 @@
],
"minimum-stability": "dev",
"require": {
"php": ">=8.1"
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"require-dev": {
"phpstan/phpstan": "^1.10",

View File

@@ -73,65 +73,65 @@ use CoreLibs\Convert\Json;
class Login
{
/** @var string the user id var*/
private $euid;
/** @var ?int the user id var*/
private ?int $euid;
/** @var string _GET/_POST loginUserId parameter for non password login */
private $login_user_id = '';
private string $login_user_id = '';
/** @var string source, either _GET or _POST or empty */
private $login_user_id_source = '';
private string $login_user_id_source = '';
/** @var bool set to true if illegal characters where found in the login user id string */
private $login_user_id_unclear = false;
private bool $login_user_id_unclear = false;
// is set to one if login okay, or EUID is set and user is okay to access this page
/** @var bool */
private $permission_okay = false;
private bool $permission_okay = false;
/** @var string pressed login */
private $login = '';
private string $login = '';
/** @var string master action command */
private $action;
private string $action;
/** @var string login name */
private $username;
private string $username;
/** @var string login password */
private $password;
private string $password;
/** @var string logout button */
private $logout;
private string $logout;
/** @var bool if this is set to true, the user can change passwords */
private $password_change = false;
private bool $password_change = false;
/** @var bool password change was successful */
private $password_change_ok = false;
private bool $password_change_ok = false;
// can we reset password and mail to user with new password set screen
/** @var bool */
private $password_forgot = false;
private bool $password_forgot = false;
/** @var bool password forgot mail send ok */
// private $password_forgot_ok = false;
/** @var string */
private $change_password;
private string $change_password;
/** @var string */
private $pw_username;
private string $pw_username;
/** @var string */
private $pw_old_password;
private string $pw_old_password;
/** @var string */
private $pw_new_password;
private string $pw_new_password;
/** @var string */
private $pw_new_password_confirm;
private string $pw_new_password_confirm;
/** @var array<string> array of users for which the password change is forbidden */
private $pw_change_deny_users = [];
private array $pw_change_deny_users = [];
/** @var string */
private $logout_target = '';
private string $logout_target = '';
/** @var int */
private $max_login_error_count = -1;
private int $max_login_error_count = -1;
/** @var array<string> */
private $lock_deny_users = [];
private array $lock_deny_users = [];
/** @var string */
private $page_name = '';
private string $page_name = '';
/** @var int if we have password change we need to define some rules */
private $password_min_length = 9;
private int $password_min_length = 9;
/** @var int an true maxium min, can never be set below this */
private $password_min_length_max = 9;
private int $password_min_length_max = 9;
// max length is fixed as 255 (for input type max), if set highter
// it will be set back to 255
/** @var int */
private $password_max_length = 255;
private int $password_max_length = 255;
/** @var int minum password length */
public const PASSWORD_MIN_LENGTH = 9;
@@ -158,7 +158,7 @@ class Login
. "$/";
/** @var array<string> can have several regexes, if nothing set, all is ok */
private $password_valid_chars = [
private array $password_valid_chars = [
// '^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z!@#$%]{8,}$',
// '^(?.*(\pL)u)(?=.*(\pN)u)(?=.*([^\pL\pN])u).{8,}',
];
@@ -166,13 +166,13 @@ class Login
// login error code, can be matched to the array login_error_msg,
// which holds the string
/** @var int */
private $login_error = 0;
private int $login_error = 0;
/** @var array<mixed> all possible login error conditions */
private $login_error_msg = [];
private array $login_error_msg = [];
// this is an array holding all strings & templates passed
// rom the outside (translation)
/** @var array<mixed> */
private $login_template = [
private array $login_template = [
'strings' => [],
'password_change' => '',
'template' => ''
@@ -180,59 +180,59 @@ class Login
// acl vars
/** @var array<mixed> */
private $acl = [];
private array $acl = [];
/** @var array<mixed> */
private $default_acl_list = [];
private array $default_acl_list = [];
/** @var array<string,int> Reverse list to lookup level from type */
private $default_acl_list_type = [];
private array $default_acl_list_type = [];
/** @var int default ACL level to be based on if nothing set */
private $default_acl_level = 0;
private int $default_acl_level = 0;
// login html, if we are on an ajax page
/** @var string|null */
private $login_html = '';
private ?string $login_html = '';
/** @var bool */
private $login_is_ajax_page = false;
private bool $login_is_ajax_page = false;
// settings
/** @var array<string,mixed> options */
private $options = [];
private array $options = [];
/** @var array<string,string> locale options: locale, domain, encoding (opt), path */
private $locale = [
private array $locale = [
'locale' => '',
'domain' => '',
'encoding' => '',
'path' => '',
];
/** @var \CoreLibs\Debug\Logging logger */
public $log;
/** @var \CoreLibs\Logging\Logging logger */
public \CoreLibs\Logging\Logging $log;
/** @var \CoreLibs\DB\IO database */
public $db;
public \CoreLibs\DB\IO $db;
/** @var \CoreLibs\Language\L10n language */
public $l;
public \CoreLibs\Language\L10n $l;
/** @var \CoreLibs\Create\Session session class */
public $session;
public \CoreLibs\Create\Session $session;
/**
* constructor, does ALL, opens db, works through connection checks,
* finishes itself
*
* @param \CoreLibs\DB\IO $db Database connection class
* @param \CoreLibs\Debug\Logging $log Logging class
* @param \CoreLibs\Logging\Logging $log Logging class
* @param \CoreLibs\Create\Session $session Session interface class
* @param array<string,mixed> $options Login ACL settings
* $auto_login [default true] DEPRECATED, moved into options
*/
public function __construct(
\CoreLibs\DB\IO $db,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
\CoreLibs\Create\Session $session,
array $options = []
) {
// attach db class
$this->db = $db;
// log login data for this class only
$log->setLogPer('class', true);
$log->setLogFlag(\CoreLibs\Logging\Logger\Flag::per_class);
// attach logger
$this->log = $log;
// attach session class
@@ -883,7 +883,7 @@ class Login
}
// normal user processing
// set class var and session var
$_SESSION['EUID'] = $this->euid = $res['edit_user_id'];
$_SESSION['EUID'] = $this->euid = (int)$res['edit_user_id'];
// check if user is okay
$this->loginCheckPermissions();
if ($this->login_error == 0) {
@@ -1048,7 +1048,7 @@ class Login
}
// build master unit array
$unit_access[$res['edit_access_id']] = [
'id' => $res['edit_access_id'],
'id' => (int)$res['edit_access_id'],
'acl_level' => $res['level'],
'acl_type' => $res['type'],
'name' => $res['name'],
@@ -1179,6 +1179,12 @@ class Login
$this->acl['page'] = $_SESSION['PAGES_ACL_LEVEL'][$this->page_name];
}
$this->acl['unit_id'] = null;
$this->acl['unit_name'] = null;
$this->acl['unit_uid'] = null;
$this->acl['unit'] = [];
$this->acl['unit_detail'] = [];
// PER ACCOUNT (UNIT/edit access)->
foreach ($_SESSION['UNIT'] as $ea_id => $unit) {
// if admin flag is set, all units are set to 100
@@ -1849,13 +1855,13 @@ HTML;
if ($login_user_id_changed > 0) {
$this->login_user_id_unclear = true;
// error for invalid user id?
$this->log->debug('LOGIN USER ID', 'Invalid characters: '
$this->log->error('LOGIN USER ID: Invalid characters: '
. $login_user_id_changed . ' in loginUserId: '
. $this->login_user_id . ' (' . $this->login_user_id_source . ')');
}
}
// if there is none, there is none, saves me POST/GET check
$this->euid = array_key_exists('EUID', $_SESSION) ? $_SESSION['EUID'] : 0;
$this->euid = array_key_exists('EUID', $_SESSION) ? (int)$_SESSION['EUID'] : 0;
// get login vars, are so, can't be changed
// prepare
// pass on vars to Object vars
@@ -1911,21 +1917,6 @@ HTML;
// echo $this->login_html;
$this->loginPrintLogin();
}
// do not go anywhere, quit processing here
// do something with possible debug data?
if (
in_array($this->options['target'], ['live', 'remove'])
) {
// login
$this->log->setLogLevelAll('debug', $this->options['debug']);
$this->log->setLogLevelAll('echo', false);
$this->log->setLogLevelAll('print', $this->options['debug']);
}
$status_msg = $this->log->printErrorMsg();
// if ($this->echo_output_all) {
if ($this->log->getLogLevelAll('echo')) {
echo $status_msg;
}
// exit so we don't process anything further, at all
$this->loginTerminate(3000);
} else {
@@ -2119,7 +2110,7 @@ HTML;
// unset session vars set/used in this login
$this->session->sessionDestroy();
// unset euid
$this->euid = '';
$this->euid = null;
// then prints the login screen again
$this->permission_okay = false;
}
@@ -2507,7 +2498,7 @@ HTML;
*/
public function loginGetEuid(): string
{
return $this->euid;
return (string)$this->euid;
}
}

View File

@@ -35,97 +35,97 @@ class Backend
{
// page name
/** @var array<mixed> */
public $menu = [];
public array $menu = [];
/** @var int|string */
public $menu_show_flag = 0; // top menu flag (mostly string)
public int|string $menu_show_flag = 0; // top menu flag (mostly string)
// action ids
/** @var array<string> */
public $action_list = [
public array $action_list = [
'action', 'action_id', 'action_sub_id', 'action_yes', 'action_flag',
'action_menu', 'action_value', 'action_error', 'action_loaded'
];
/** @var string */
public $action;
public string $action;
/** @var string|int */
public $action_id;
public string|int $action_id;
/** @var string|int */
public $action_sub_id;
public string|int $action_sub_id;
/** @var string|int|bool */
public $action_yes;
public string|int|bool $action_yes;
/** @var string */
public $action_flag;
public string $action_flag;
/** @var string */
public $action_menu;
public string $action_menu;
/** @var string */
public $action_loaded;
public string $action_loaded;
/** @var string */
public $action_value;
public string $action_value;
/** @var string */
public $action_error;
public string $action_error;
// ACL array variable if we want to set acl data from outisde
/** @var array<mixed> */
public $acl = [];
public array $acl = [];
/** @var int */
public $default_acl;
public int $default_acl;
// queue key
/** @var string */
public $queue_key;
public string $queue_key;
// the current active edit access id
/** @var int */
public $edit_access_id;
/** @var int|null */
public int|null $edit_access_id;
/** @var string */
public $page_name;
public string $page_name;
// error/warning/info messages
/** @var array<mixed> */
public $messages = [];
public array $messages = [];
/** @var bool */
public $error = false;
public bool $error = false;
/** @var bool */
public $warning = false;
public bool $warning = false;
/** @var bool */
public $info = false;
public bool $info = false;
// internal lang & encoding vars
/** @var string */
public $lang_dir = '';
public string $lang_dir = '';
/** @var string */
public $lang;
public string $lang;
/** @var string */
public $lang_short;
public string $lang_short;
/** @var string */
public $domain;
public string $domain;
/** @var string */
public $encoding;
/** @var \CoreLibs\Debug\Logging logger */
public $log;
public string $encoding;
/** @var \CoreLibs\Logging\Logging logger */
public \CoreLibs\Logging\Logging $log;
/** @var \CoreLibs\DB\IO database */
public $db;
public \CoreLibs\DB\IO $db;
/** @var \CoreLibs\Language\L10n language */
public $l;
public \CoreLibs\Language\L10n $l;
/** @var \CoreLibs\Create\Session session class */
public $session;
public \CoreLibs\Create\Session $session;
// smarty publics [end processing in smarty class]
/** @var array<mixed> */
public $DATA;
public array $DATA = [];
/** @var array<mixed> */
public $HEADER;
public array $HEADER = [];
/** @var array<mixed> */
public $DEBUG_DATA;
public array $DEBUG_DATA = [];
/** @var array<mixed> */
public $CONTENT_DATA;
public array $CONTENT_DATA = [];
// CONSTRUCTOR / DECONSTRUCTOR |====================================>
/**
* main class constructor
*
* @param \CoreLibs\DB\IO $db Database connection class
* @param \CoreLibs\Debug\Logging $log Logging class
* @param \CoreLibs\Logging\Logging $log Logging class
* @param \CoreLibs\Create\Session $session Session interface class
* @param \CoreLibs\Language\L10n $l10n l10n language class
* @param int|null $set_default_acl_level Default ACL level
*/
public function __construct(
\CoreLibs\DB\IO $db,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
\CoreLibs\Create\Session $session,
\CoreLibs\Language\L10n $l10n,
?int $set_default_acl_level = null
@@ -133,7 +133,7 @@ class Backend
// attach db class
$this->db = $db;
// set to log not per class
$log->setLogPer('class', false);
$log->unsetLogFlag(\CoreLibs\Logging\Logger\Flag::per_class);
// attach logger
$this->log = $log;
// attach session class

View File

@@ -20,36 +20,36 @@ use SmartyException;
class EditBase
{
/** @var array<mixed> */
private $HEADER = [];
private array $HEADER = [];
/** @var array<mixed> */
private $DATA = [];
private array $DATA = [];
/** @var array<mixed> */
private $DEBUG_DATA = [];
private array $DEBUG_DATA = [];
/** @var string the template name */
private $EDIT_TEMPLATE = '';
private string $EDIT_TEMPLATE = '';
/** @var \CoreLibs\Template\SmartyExtend smarty system */
private $smarty;
private \CoreLibs\Template\SmartyExtend $smarty;
/** @var \CoreLibs\Output\Form\Generate form generate system */
private $form;
/** @var \CoreLibs\Debug\Logging */
public $log;
private \CoreLibs\Output\Form\Generate $form;
/** @var \CoreLibs\Logging\Logging */
public \CoreLibs\Logging\Logging $log;
/** @var \CoreLibs\ACL\Login */
public $login;
public \CoreLibs\ACL\Login $login;
/**
* construct form generator
*
* @param array<mixed> $db_config db config array, mandatory
* @param \CoreLibs\Debug\Logging $log Logging class, null auto set
* @param \CoreLibs\Logging\Logging $log Logging class, null auto set
* @param \CoreLibs\Language\L10n $l10n l10n language class, null auto set
* @param \CoreLibs\ACL\Login $login login class for ACL settings
* @param array<string,mixed> $options Various settings options
*/
public function __construct(
array $db_config,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
\CoreLibs\Language\L10n $l10n,
\CoreLibs\ACL\Login $login,
array $options
@@ -63,7 +63,7 @@ class EditBase
$options['compile_id'] ?? '',
);
// turn off set log per class
$log->setLogPer('class', false);
$log->unsetLogFlag(\CoreLibs\Logging\Logger\Flag::per_class);
// create form class
$this->form = new \CoreLibs\Output\Form\Generate(

View File

@@ -58,39 +58,39 @@ class Basic
{
// page and host name
/** @var string */
public $page_name;
public string $page_name;
/** @var string */
public $host_name;
public string $host_name;
/** @var int */
public $host_port;
public int $host_port;
// logging interface, Debug\Logging class
/** @var \CoreLibs\Debug\Logging */
public $log;
/** @var \CoreLibs\Logging\Logging */
public \CoreLibs\Logging\Logging $log;
/** @var \CoreLibs\Create\Session */
public $session;
public \CoreLibs\Create\Session $session;
// email valid checks
/** @var array<mixed> */
public $email_regex_check = [];
public array $email_regex_check = [];
/** @var string */
public $email_regex; // regex var for email check
public string $email_regex; // regex var for email check
// data path for files
/** @var array<mixed> */
public $data_path = [];
public array $data_path = [];
// ajax flag
/** @var bool */
protected $ajax_page_flag = false;
protected bool $ajax_page_flag = false;
/**
* main Basic constructor to init and check base settings
* @param \CoreLibs\Debug\Logging|null $log Logging class
* @param \CoreLibs\Logging\Logging|null $log Logging class
* @param string|null $session_name Set session name
* @deprecated DO NOT USE Class\Basic anymore. Use dedicated logger and sub classes
*/
public function __construct(
\CoreLibs\Debug\Logging $log = null,
\CoreLibs\Logging\Logging $log = null,
?string $session_name = null
) {
trigger_error('Class \CoreLibs\Basic is deprected', E_USER_DEPRECATED);
@@ -120,7 +120,10 @@ class Basic
}
// logging interface moved here (->debug is now ->log->debug)
$this->log = $log ?? new \CoreLibs\Debug\Logging();
$this->log = $log ?? new \CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => 'ClassBasic-DEPRECATED',
]);
// set ajax page flag based on the AJAX_PAGE varaibles
// convert to true/false so if AJAX_PAGE is 0 or false it is
@@ -176,8 +179,9 @@ class Basic
*/
public function basicSetLogId(string $string): string
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use $basic->log->basicSetLogId() or use \CoreLibs\Debug\Logging() class', E_USER_DEPRECATED);
return $this->log->setLogId($string);
trigger_error('Method ' . __METHOD__ . ' is deprecated, use log->setLogId() or use \CoreLibs\Logging\Logging() class', E_USER_DEPRECATED);
$this->log->setLogFileId($string);
return $this->log->getLogFileId();
}
// ****** DEBUG/ERROR FUNCTIONS ******
@@ -252,7 +256,7 @@ class Basic
}
// ****** DEBUG LOGGING FUNCTIONS ******
// Moved to \CoreLibs\Debug\Logging
// Moved to \CoreLibs\Logging\Logging
/**
* passes list of level names, to turn on debug
@@ -265,68 +269,9 @@ class Basic
*/
public function debugFor(string $type, string $flag): void
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use $basic->log->debugFor() or use \CoreLibs\Debug\Logging() class', E_USER_DEPRECATED);
/** @phan-suppress-next-line PhanTypeMismatchArgumentReal, PhanParamTooFew @phpstan-ignore-next-line */
$this->log->setLogLevel(...[func_get_args()]);
trigger_error('Method ' . __METHOD__ . ' functionaility is fully deprecated', E_USER_DEPRECATED);
}
/**
* checks if we have a need to work on certain debug output
* Needs debug/echo/print ad target for which of the debug flag groups we check
* also needs level string to check in the per level output flag check.
* In case we have invalid target it will return false
* @param string $target target group to check debug/echo/print
* @param string $level level to check in detailed level flag
* @return bool true on access allowed or false on no access
*/
/* private function doDebugTrigger(string $target, string $level): bool
{
$access = false;
// check if we do debug, echo or print
switch ($target) {
case 'debug':
if ((
(isset($this->debug_output[$level]) && $this->debug_output[$level]) ||
$this->debug_output_all
) &&
(!isset($this->debug_output_not[$level]) ||
(isset($this->debug_output_not[$level]) && !$this->debug_output_not[$level])
)
) {
$access = true;
}
break;
case 'echo':
if ((
(isset($this->echo_output[$level]) && $this->echo_output[$level]) ||
$this->echo_output_all
) &&
(!isset($this->echo_output_not[$level]) ||
(isset($this->echo_output_not[$level]) && !$this->echo_output_not[$level])
)
) {
$access = true;
}
break;
case 'print':
if ((
(isset($this->print_output[$level]) && $this->print_output[$level]) ||
$this->print_output_all
) &&
(!isset($this->print_output_not[$level]) ||
(isset($this->print_output_not[$level]) && !$this->print_output_not[$level])
)
) {
$access = true;
}
break;
default:
// fall through with access false
break;
}
return $access;
} */
/**
* write debug data to error_msg array
* @param string $level id for error message, groups messages together
@@ -335,11 +280,12 @@ class Basic
* all html tags will be stripped and <br> changed to \n
* this is only used for debug output
* @return void has no return
* @deprecated Use $basic->log->debug() instead
* @deprecated Use Logger\Logger->debug() instead
*/
public function debug(string $level, string $string, bool $strip = false): void
{
$this->log->debug($level, $string, $strip);
trigger_error('Method ' . __METHOD__ . ' has moved to Logger\Logger->debug()', E_USER_DEPRECATED);
$this->log->debug($level, $string);
}
/**
@@ -351,8 +297,7 @@ class Basic
*/
public function mergeErrors(array $error_msg = []): void
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use $basic->log->mergeErrors() or use \CoreLibs\Debug\Logging() class', E_USER_DEPRECATED);
$this->log->mergeErrors($error_msg);
trigger_error('Method ' . __METHOD__ . ' is fully deprecated', E_USER_DEPRECATED);
}
/**
@@ -363,7 +308,8 @@ class Basic
*/
public function printErrorMsg(string $string = ''): string
{
return $this->log->printErrorMsg($string);
trigger_error('Method ' . __METHOD__ . ' is fully deprecated', E_USER_DEPRECATED);
return '';
}
/**
@@ -376,8 +322,7 @@ class Basic
*/
public function resetErrorMsg(string $level = ''): void
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use $basic->log->resetErrorMsg() or use \CoreLibs\Debug\Logging() class', E_USER_DEPRECATED);
$this->log->resetErrorMsg($level);
trigger_error('Method ' . __METHOD__ . ' is fully deprecated', E_USER_DEPRECATED);
}
// ****** DEBUG SUPPORT FUNCTIONS ******
@@ -388,11 +333,11 @@ class Basic
* prints a html formatted (pre) array
* @param array<mixed> $array any array
* @return string formatted array for output with <pre> tag added
* @deprecated Use $this->log->prAr() instead
* @deprecated Use \CoreLibs\Debug\Support::prAr() instead
*/
public function printAr(array $array): string
{
return $this->log->prAr($array);
return \CoreLibs\Debug\Support::prAr($array);
}
/**

View File

@@ -8,7 +8,7 @@ class Email
{
// this is for error check parts in where the email regex failed
/** @var array<int,string> */
private static $email_regex_check = [
private static array $email_regex_check = [
0 => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$", // MASTER
1 => "@(.*)@(.*)", // double @
@@ -21,7 +21,7 @@ class Email
];
// for above position, description string below
/** @var array<int,string> */
private static $email_regex_check_message = [
private static array $email_regex_check_message = [
0 => 'Invalid email address',
1 => 'Double @ mark in email address',
2 => 'Invalid email part before @ sign',
@@ -33,7 +33,7 @@ class Email
];
// the array with the mobile types that are valid
/** @var array<string,string> */
private static $mobile_email_type = [
private static array $mobile_email_type = [
'.*@docomo\.ne\.jp$' => 'keitai_docomo',
// correct are a[2-4], b2, c[1-9], e[2-9], h[2-4], t[1-9]
'.*@([a-z0-9]{2}\.)?ezweb\.ne\.jp$' => 'keitai_kddi_ezweb',
@@ -72,7 +72,7 @@ class Email
];
// short list for mobile email types
/** @var array<string,string> */
private static $mobile_email_type_short = [
private static array $mobile_email_type_short = [
'keitai_docomo' => 'docomo',
'keitai_kddi_ezweb' => 'kddi',
'keitai_kddi' => 'kddi',

View File

@@ -11,7 +11,7 @@ namespace CoreLibs\Check;
class Encoding
{
/** @var int<min, -1>|int<1, max>|string */
private static $mb_error_char = '';
private static int|string $mb_error_char = '';
/**
* set error char

View File

@@ -12,7 +12,7 @@ namespace CoreLibs\Convert;
class MimeAppName
{
/** @var array<string,string> */
private static $mime_apps = [];
private static array $mime_apps = [];
/**
* constructor: init mime list

View File

@@ -14,7 +14,7 @@ namespace CoreLibs\Create;
class Email
{
/** @var array<string> allowed list for encodings that can do KV folding */
private static $encoding_kv_allowed = [
private static array $encoding_kv_allowed = [
'UTF-8',
'EUC-JP',
'SJIS',
@@ -25,7 +25,7 @@ class Email
'JIS-ms',
];
/** @var string normaly this does not need to be changed */
private static $mb_convert_kana_mode = 'KV';
private static string $mb_convert_kana_mode = 'KV';
/**
* create mime encoded email part for to/from emails.
@@ -137,7 +137,7 @@ class Email
* @param bool $kv_folding If set to true and a valid encoding,
* do KV folding
* @param bool $test test flag, default off
* @param \CoreLibs\Debug\Logging|null $log Logging class,
* @param \CoreLibs\Logging\Logging|null $log Logging class,
* only used if test flag is true
* @return int 2 test only, no sent
* 1 for ok,
@@ -156,7 +156,7 @@ class Email
string $encoding = 'UTF-8',
bool $kv_folding = false,
bool $test = false,
?\CoreLibs\Debug\Logging $log = null
?\CoreLibs\Logging\Logging $log = null
): int {
/** @var array<string> */
$to_emails = [];
@@ -259,11 +259,11 @@ class Email
$mail_delivery_status = 2;
}
// log if an log instance exists
if ($log instanceof \CoreLibs\Debug\Logging) {
if ($log instanceof \CoreLibs\Logging\Logging) {
// build debug strings: convert to UTF-8 if not utf-8
$log->debug('SEND EMAIL', 'HEADERS: ' . $log->prAr($headers) . ', '
$log->debug('SEND EMAIL', 'HEADERS: ' . \CoreLibs\Debug\Support::prAr($headers) . ', '
. 'ENCODING: ' . $encoding . ', '
. 'KV FOLDING: ' . $log->prBl($kv_folding) . ', '
. 'KV FOLDING: ' . \CoreLibs\Debug\Support::prBl($kv_folding) . ', '
. 'TO: ' . $to_email . ', '
. 'SUBJECT: ' . $out_subject . ', '
. 'BODY: ' . ($encoding == 'UTF-8' ?

View File

@@ -10,6 +10,7 @@ namespace CoreLibs\Create;
class Hash
{
public const DEFAULT_HASH = 'adler32';
public const STANDARD_HASH_LONG = 'ripemd160';
public const STANDARD_HASH_SHORT = 'adler32';
@@ -58,7 +59,7 @@ class Hash
/**
* replacemend for __crc32b call (alternate)
* defaults to adler 32
* allowed crc32b, adler32, fnv132, fnv1a32, joaat
* allowed: any in hash algos list, default to adler 32
* all that create 8 char long hashes
*
* @param string $string string to hash
@@ -67,15 +68,15 @@ class Hash
*/
public static function __hash(
string $string,
string $hash_type = self::STANDARD_HASH_SHORT
string $hash_type = self::DEFAULT_HASH
): string {
// if not empty, check if in valid list
if (
!in_array(
$hash_type,
['crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat']
)
empty($hash_type) ||
!in_array($hash_type, hash_algos())
) {
$hash_type = 'adler32';
// fallback to default hash type if none set or invalid
$hash_type = self::DEFAULT_HASH;
}
return hash($hash_type, $string);
}

View File

@@ -12,13 +12,13 @@ class RandomKey
{
// key generation
/** @var string */
private static $key_range = '';
private static string $key_range = '';
/** @var int */
private static $one_key_length;
private static int $one_key_length;
/** @var int */
private static $key_length = 4; // default key length
private static int $key_length = 4; // default key length
/** @var int */
private static $max_key_length = 256; // max allowed length
private static int $max_key_length = 256; // max allowed length
/**
* if launched as class, init random key data first
@@ -100,7 +100,9 @@ class RandomKey
public static function randomKeyGen(int $key_length = -1): string
{
// init random key strings if not set
if (!is_numeric(self::$one_key_length)) {
if (
!isset(self::$one_key_length)
) {
self::initRandomKeyData();
}
$use_key_length = 0;

View File

@@ -16,7 +16,7 @@ namespace CoreLibs\Create;
class Session
{
/** @var string list for errors */
private $session_intern_error_str = '';
private string $session_intern_error_str = '';
/**
* init a session, if array is empty or array does not have session_name set

View File

@@ -1,5 +1,12 @@
<?php
/**
* Create uniqIds
*
* If convert ID to hash:
* https://github.com/vinkla/hashids
*/
declare(strict_types=1);
namespace CoreLibs\Create;
@@ -7,10 +14,39 @@ namespace CoreLibs\Create;
class Uids
{
// what to use as a default hash if non ise set and no DEFAULT_HASH is defined
public const DEFAULT_HASH = 'sha256';
/** @var int */
public const DEFAULT_UNNIQ_ID_LENGTH = 64;
/** @var string */
public const STANDARD_HASH_LONG = 'ripemd160';
/** @var string */
public const STANDARD_HASH_SHORT = 'adler32';
/**
* Create unique id, lower length is for
*
* @param int $length Length for uniq id, min is 4 characters
* Uneven lengths will return lower bound (9 -> 8)
* @param bool $force_length [default=false] if set to true and we have
* uneven length, then we shorten to this length
* @return string Uniq id
*/
private static function uniqIdL(int $length = 64, bool $force_length = false): string
{
$uniqid_length = ($length < 4) ? 4 : $length;
if ($force_length) {
$uniqid_length++;
}
/** @var int<1,max> make sure that internal this is correct */
$random_bytes_length = ($uniqid_length - ($uniqid_length % 2)) / 2;
$uniqid = bin2hex(random_bytes($random_bytes_length));
// if not forced shorten return next lower length
if (!$force_length) {
return $uniqid;
}
return substr($uniqid, 0, $length);
}
/**
* creates psuedo random uuid v4
* Code take from class here:
@@ -20,7 +56,7 @@ class Uids
*/
public static function uuidv4(): string
{
return sprintf(
/* return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff),
@@ -38,49 +74,62 @@ class Uids
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
); */
$data = random_bytes(16);
assert(strlen($data) == 16);
// 0-1: 32 bits for "time_low"
// 2: 16 bits for "time_mid"
// 3: 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
// 4: 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
// 5-7: 48 bits for "node"
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
/**
* TODO: make this a proper uniq ID creation
* add uuidv4 subcall to the uuid function too
* creates a uniq id
* creates a uniq id based on lengths
*
* @param string $type uniq id type, currently md5 or sha256 allowed
* if not set will use DEFAULT_HASH if set
* @return string uniq id
* @param int|string $length Either length in int, or fallback type for length
* for string type md5 (32), sha256 (64)
* STANDARD_HASH_LONG: ripemd160 (40)
* STANDARD_HASH_SHORT: adler32 (8)
* It is recommended to use the integer
* @param bool $force_length [default=false] if set to true and we have
* uneven length, then we shorten to this length
* @return string Uniq id
*/
public static function uniqId(string $type = ''): string
{
$uniq_id = '';
switch ($type) {
public static function uniqId(
int|string $length = self::DEFAULT_UNNIQ_ID_LENGTH,
bool $force_length = false
): string {
if (is_int($length)) {
return self::uniqIdL($length, $force_length);
}
switch ($length) {
case 'md5':
$uniq_id = md5(uniqid((string)rand(), true));
$length = 32;
break;
case self::DEFAULT_HASH:
$uniq_id = hash(self::DEFAULT_HASH, uniqid((string)rand(), true));
case 'sha256':
$length = 64;
break;
case self::STANDARD_HASH_LONG:
$uniq_id = hash(self::STANDARD_HASH_LONG, uniqid((string)rand(), true));
$length = 40;
break;
case self::STANDARD_HASH_SHORT:
$uniq_id = hash(self::STANDARD_HASH_SHORT, uniqid((string)rand(), true));
$length = 8;
break;
default:
// if not empty, check if in valid list
if (
!empty($type) &&
in_array($type, hash_algos())
) {
$hash = $type;
} else {
// fallback to default hash type if none set or invalid
$hash = self::DEFAULT_HASH;
}
$uniq_id = hash($hash, uniqid((string)rand(), true));
$length = 64;
break;
}
return $uniq_id;
return self::uniqIdL($length);
}
/**

View File

@@ -39,16 +39,16 @@ class ArrayIO extends \CoreLibs\DB\IO
{
// main calss variables
/** @var array<mixed> */
public $table_array; // the array from the table to work on
public array $table_array; // the array from the table to work on
/** @var string */
public $table_name; // the table_name
public string $table_name; // the table_name
/** @var string */
public $pk_name = ''; // the primary key from this table
public string $pk_name = ''; // the primary key from this table
/** @var int|string|null */
public $pk_id; // the PK id
public int|string|null $pk_id; // the PK id
// security values
/** @var int base acl for current page */
private $base_acl_level = 0;
private int $base_acl_level = 0;
/**
* constructor for the array io class, set the
@@ -57,7 +57,7 @@ class ArrayIO extends \CoreLibs\DB\IO
* @param array<mixed> $db_config db connection config
* @param array<mixed> $table_array table array config
* @param string $table_name table name string
* @param \CoreLibs\Debug\Logging $log Logging class
* @param \CoreLibs\Logging\Logging $log Logging class
* @param int $base_acl_level Set base acl level, if needed
* @param int $acl_admin Flag if this is an admin ACL access level
*/
@@ -65,7 +65,7 @@ class ArrayIO extends \CoreLibs\DB\IO
array $db_config,
array $table_array,
string $table_name,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
int $base_acl_level = 0,
int $acl_admin = 0
) {
@@ -243,7 +243,7 @@ class ArrayIO extends \CoreLibs\DB\IO
return $this->table_array;
}
if ($acl_limit === true && $this->base_acl_level < 100) {
$this->log->debug('DB DELETE ERROR', 'ACL Limit on, Delete, '
$this->log->error('DB DELETE ERROR: ACL Limit on, Delete, '
. 'but base ACL level of 100 not met: ' . $this->base_acl_level);
return $this->table_array;
}
@@ -406,7 +406,7 @@ class ArrayIO extends \CoreLibs\DB\IO
}
// early abort for new write with not enough ACL level
if ($insert && $acl_limit === true && $this->base_acl_level < 100) {
$this->log->debug('DB WRITE ERROR', 'ACL Limit on, Insert, '
$this->log->error('DB WRITE ERROR: ACL Limit on, Insert, '
. 'but base ACL level of 100 not met: ' . $this->base_acl_level);
return $this->table_array;
}
@@ -579,7 +579,7 @@ class ArrayIO extends \CoreLibs\DB\IO
} // while ...
if (empty($q_data)) {
$this->log->debug('DB WRITE ERROR', 'No data to write, possible through ACL');
$this->log->error('DB WRITE ERROR: No data to write, possible through ACL');
return $this->table_array;
}

View File

@@ -298,111 +298,108 @@ class IO
// can bet set from outside
// encoding to
/** @var string */
private $to_encoding = '';
/** @var string */
private $query; // the query string at the moment
/** @var array<mixed> */
private $params; // current params for query
private string $to_encoding = '';
/** @var string the query string at the moment */
private string $query;
/** @var array<mixed> current params for query */
private array $params;
// only inside
// basic vars
/** @var \PgSql\Connection|false|null */ // replace object with PgSql\Connection|
private $dbh; // the dbh handler, if disconnected by command is null, bool:false on error,
/** @var bool */
private $db_debug = false; // DB_DEBUG ... (if set prints out debug msgs)
/** @var string */
private $db_name; // the DB connected to
/** @var string */
private $db_user; // the username used
/** @var string */
private $db_pwd; // the password used
/** @var string */
private $db_host; // the hostname
/** @var int */
private $db_port; // default db port
/** @var string */
private $db_schema; // optional DB schema, if not set uses public
/** @var string */
private $db_encoding; // optional auto encoding convert, not used if not set
/** @var string */
private $db_type; // type of db (mysql,postgres,...)
/** @var string */
private $db_ssl; // ssl flag (for postgres only), disable, allow, prefer, require
// the dbh handler, if disconnected by command is null, bool:false on error,
/** @var \PgSql\Connection|false|null */
private \PgSql\Connection|false|null $dbh;
/** @var bool DB_DEBUG ... (if set prints out debug msgs) */
private bool $db_debug = false;
/** @var string the DB connected to */
private string $db_name;
/** @var string the username used */
private string $db_user;
/** @var string the password used*/
private string $db_pwd;
/** @var string the hostname */
private string $db_host;
/** @var int default db port */
private int $db_port;
/** @var string optional DB schema, if not set uses public*/
private string $db_schema;
/** @var string optional auto encoding convert, not used if not set */
private string $db_encoding;
/** @var string type of db (mysql,postgres,...) */
private string $db_type;
/** @var string ssl flag (for postgres only), disable, allow, prefer, require */
private string $db_ssl;
// FOR BELOW: (This should be private and only readable through some method)
// cursor array for cached readings
/** @var array<mixed,mixed> */
private $cursor_ext; // hash of hashes
/** @var array<string,mixed> extended cursoers string index with content */
private array $cursor_ext;
// per query vars
/** @var \PgSql\Result|false */ // replace object with PgSql\Result
private $cursor; // actual cursor (DBH)
/** @var int */
private $num_rows; // how many rows have been found
/** @var int */
private $num_fields; // how many fields has the query
/** @var \PgSql\Result|false actual cursor (DBH) */
private \PgSql\Result|false $cursor;
/** @var int how many rows have been found */
private int $num_rows;
/** @var int how many fields has the query */
private int $num_fields;
/** @var array<string> array with the field names of the current query */
private $field_names = [];
private array $field_names = [];
/** @var array<string> field type names */
private $field_types = [];
/** @var array<mixed> */
private $insert_id_arr = []; // always return as array, even if only one
/** @var string */
private $insert_id_pk_name; // primary key name for insert recovery from insert_id_arr
private array $field_types = [];
/** @var array<mixed> always return as array, even if only one */
private array $insert_id_arr = [];
/** @var string primary key name for insert recovery from insert_id_arr */
private string $insert_id_pk_name;
// other vars
/** @var string */
private $nbsp = ''; // used by print_array recursion function
/** @var string used by print_array recursion function */
private string $nbsp = '';
// error & warning id
/** @var string */
private $error_id;
private string $error_id;
/** @var string */
private $warning_id;
private string $warning_id;
/** @var string */
private $error_history_id;
private string $error_history_id;
/** @var array<mixed> Stores warning and errors combinded with detail info */
private $error_history_long = [];
// error thrown on class init if we cannot connect to db
/** @var bool */
protected $db_connection_closed = false;
private array $error_history_long = [];
/** @var bool error thrown on class init if we cannot connect to db */
protected bool $db_connection_closed = false;
// sub include with the database functions
/** @var \CoreLibs\DB\SQL\PgSQL if we have other DB types we need to add them here */
private $db_functions;
private \CoreLibs\DB\SQL\PgSQL $db_functions;
// endless loop protection
/** @var int */
private $MAX_QUERY_CALL;
/** @var int */
public const DEFAULT_MAX_QUERY_CALL = 20; // default
private int $MAX_QUERY_CALL;
/** @var int maxium query calls allowed in a dbReturnRow loop before we error out */
public const DEFAULT_MAX_QUERY_CALL = 20;
/** @var array<mixed> */
private $query_called = [];
private array $query_called = [];
// error string
/** @var array<mixed> */
protected $error_string = [];
protected array $error_string = [];
// prepared list
/** @var array<mixed> */
private $prepare_cursor = [];
private array $prepare_cursor = [];
// primary key per table list
// format is 'table' => 'pk_name'
/** @var array<mixed> */
private $pk_name_table = [];
// internal primary key name, for cross calls in async
/** @var string */
private $pk_name;
// if we use RETURNING in the INSERT call
/** @var bool */
private $returning_id = false;
// if a sync is running holds the hash key of the query
/** @var string */
private $async_running;
private array $pk_name_table = [];
/** @var string internal primary key name, for cross calls in async */
private string $pk_name;
/** @var bool if we use RETURNING in the INSERT call */
private bool $returning_id = false;
/** @var string if a sync is running holds the hash key of the query */
private string $async_running;
// logging class, must be public so settings can be changed
/** @var \CoreLibs\Debug\Logging */
public $log;
/** @var \CoreLibs\Logging\Logging */
public \CoreLibs\Logging\Logging $log;
/**
* main DB concstructor with auto connection to DB and failure set on failed connection
* @param array<mixed> $db_config DB configuration array
* @param \CoreLibs\Debug\Logging $log Logging class
* @param \CoreLibs\Logging\Logging $log Logging class
* @param bool|null $db_debug_override Overrides debug settings in db_config
*/
public function __construct(
array $db_config,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
?bool $db_debug_override = null
) {
// attach logger
@@ -703,10 +700,20 @@ class IO
}
if ($error_data !== []) {
$error_string .= '<br>['
. $this->log->prAr($error_data)
. \CoreLibs\Debug\Support::prAr($error_data)
. ']';
}
$this->log->debug($debug_id, $error_string, true, $prefix);
switch ($id) {
case 'DB_ERROR':
$this->log->error($debug_id . ' :' . $prefix . $error_string);
break;
case 'DB_WARNING':
$this->log->warning($debug_id . ' :' . $prefix . $error_string);
break;
default:
$this->log->debug($debug_id, $error_string, $prefix);
break;
}
}
/**
@@ -1366,7 +1373,10 @@ class IO
*/
public function dbClose(): void
{
if ($this->dbh) {
if (
!empty($this->dbh) &&
$this->dbh instanceof \PgSql\Connection
) {
// reset any client encodings set
$this->dbResetEncoding();
// calls db close
@@ -2735,9 +2745,9 @@ class IO
}
$result = $this->db_functions->__dbExecute($stm_name, $data);
if ($result === false) {
$this->log->debug('ExecuteData', 'ERROR in STM[' . $stm_name . '|'
$this->log->error('ExecuteData: ERROR in STM[' . $stm_name . '|'
. $this->prepare_cursor[$stm_name]['result'] . ']: '
. $this->log->prAr($data));
. \CoreLibs\Debug\Support::prAr($data));
$this->__dbError(
22,
$this->prepare_cursor[$stm_name]['result'],
@@ -3398,6 +3408,9 @@ class IO
*/
public function dbGetInsertPKName(): string
{
if (!isset($this->insert_id_pk_name)) {
return '';
}
return (string)$this->insert_id_pk_name;
}
@@ -3506,6 +3519,9 @@ class IO
*/
public function dbGetNumFields(): ?int
{
if (!isset($this->num_fields)) {
return null;
}
return $this->num_fields;
}

View File

@@ -59,9 +59,9 @@ namespace CoreLibs\DB\SQL;
class PgSQL implements Interface\SqlFunctions
{
/** @var string */
private $last_error_query;
private string $last_error_query;
/** @var \PgSql\Connection|false */
private $dbh = false;
private \PgSql\Connection|false $dbh = false;
/**
* queries last error query and returns true or false if error was set

View File

@@ -12,9 +12,9 @@ namespace CoreLibs\Debug;
class FileWriter
{
/** @var string */
private static $debug_filename = 'debug_file.log'; // where to write output
private static string $debug_filename = 'debug_file.log'; // where to write output
/** @var string */
private static $debug_folder;
private static string $debug_folder;
/**
* Set a debug log folder, if not set BASE+LOG folders are set
@@ -77,7 +77,7 @@ class FileWriter
) {
/** @deprecated Do not use this anymore, define path with fsetFolder */
trigger_error(
'fsetFolder must be set first. Setting via LOG_FILE_ID and LOg constants is deprecated',
'fsetFolder must be set first. Setting via LOG_FILE_ID and LOG constants is deprecated',
E_USER_DEPRECATED
);
self::$debug_folder = BASE . LOG;

View File

@@ -1,895 +1,26 @@
<?php
/*
* Debug support functions
*
* These are if there is any debug to print out at all at the end
 * debug_output_all - general yes no
 * It's recommended to use the method "debug_for" to turn on of the array vars
 * debug_output - turn on for one level (Array)
 * debug_output_not - turn off for one level (array)
 *
 * Print out the debug at thend of the html
 * echo_output_all
 * echo_output
 * echo_output_not
 *
 * Write debug to file
 * print_output_all
 * print_output
 * print_output_not
* This is a wrapper placeholder for
* \CoreLibs\Logging\Logger
*/
declare(strict_types=1);
namespace CoreLibs\Debug;
use CoreLibs\Debug\Support;
use CoreLibs\Create\Uids;
use CoreLibs\Get\System;
use CoreLibs\Convert\Html;
class Logging
/**
* @deprecated Use \CoreLibs\Logger\Logging
*/
class Logging extends \CoreLibs\Logging\Logging
{
// options
/** @var array<mixed> */
private $options = [];
// page and host name
/** @var string */
private $page_name;
/** @var string */
private $host_name;
/** @var int */
private $host_port;
// internal error reporting vars
/** @var array<mixed> */
private $error_msg = []; // the "connection" to the outside errors
// debug output prefix
/** @var string */
private $error_msg_prefix = ''; // prefix to the error string (the class name)
// debug flags
/** @var array<mixed> */
private $debug_output = []; // if this is true, show debug on desconstructor
/** @var array<mixed> */
private $debug_output_not = [];
/** @var bool */
private $debug_output_all = false;
/** @var array<mixed> */
private $echo_output = []; // errors: echo out, default is 1
/** @var array<mixed> */
private $echo_output_not = [];
/** @var bool */
private $echo_output_all = false;
/** @var array<mixed> */
private $print_output = []; // errors: print to file, default is 0
/** @var array<mixed> */
private $print_output_not = [];
/** @var bool */
private $print_output_all = false;
// debug flags/settings
/** @var string */
private $running_uid = ''; // unique ID set on class init and used in logging as prefix
// log file name
/** @var string */
private $log_folder = '';
/** @var string */
private $log_file_name_ext = 'log'; // use this for date rotate
/** @var string */
private $log_file_name = '';
/** @var int */
private $log_max_filesize = 0; // set in kilobytes
/** @var string */
private $log_print_file = 'error_msg##LOGID####LEVEL####CLASS####PAGENAME####DATE##';
/** @var string */
private $log_file_unique_id; // a unique ID set only once for call derived from this class
/** @var string */
private $log_file_date = ''; // Y-m-d file in file name
/** @var bool */
private $log_print_file_date = true; // if set add Y-m-d and do automatic daily rotation
/** @var string */
private $log_file_id = ''; // a alphanumeric name that has to be set as global definition
/** @var bool */
private $log_per_level = false; // set, it will split per level (first parameter in debug call)
/** @var bool */
private $log_per_class = false; // set, will split log per class
/** @var bool */
private $log_per_page = false; // set, will split log per called file
/** @var bool */
private $log_per_run = false; // create a new log file per run (time stamp + unique ID)
// script running time
/** @var float */
private $script_starttime;
/**
* Init logger
*
* global vars that can be used
* - BASE
* - LOG
* - LOG_FILE_ID
* options array layout
* - log_folder:
* - print_file_date:
* - file_id:
* - unique_id:
* - log_per_level:
* - log_per_class:
* - log_per_page:
* - log_per_run:
* - debug_all:
* - echo_all:
* - print_all:
* - debug (array):
* - echo (array):
* - print (array):
* - debug_not (array):
* - echo_not (array):
* - print_not (array):
*
* @param array<mixed> $options Array with settings options
*/
public function __construct(array $options = [])
{
// copy the options over
$this->options = $options;
// set log folder from options
$this->log_folder = $this->options['log_folder'] ?? '';
// legacy flow, check must set constants
if (empty($this->log_folder) && defined('BASE') && defined('LOG')) {
/** @deprecated Do not use this anymore, define path on class load */
trigger_error(
'options: log_folder must be set. Setting via BASE and LOG constants is deprecated',
E_USER_DEPRECATED
);
// make sure this is writeable, else skip
$this->log_folder = BASE . LOG;
}
// fallback + notice
if (empty($this->log_folder)) {
/* trigger_error(
'options or constant not set or folder not writable. fallback to: ' . getcwd(),
E_USER_NOTICE
); */
$this->log_folder = getcwd() . DIRECTORY_SEPARATOR;
}
// if folder is not writeable, abort
if (!is_writeable($this->log_folder)) {
trigger_error(
'Folder: ' . $this->log_folder . ' is not writeable for logging',
E_USER_ERROR
);
}
// check if log_folder has a trailing /
if (substr($this->log_folder, -1, 1) != DIRECTORY_SEPARATOR) {
$this->log_folder .= DIRECTORY_SEPARATOR;
}
// running time start for script
$this->script_starttime = microtime(true);
// set per run UID for logging
$this->running_uid = Uids::uniqIdShort();
// set the page name
$this->page_name = System::getPageName();
// set host name
list($this->host_name , $this->host_port) = System::getHostName();
// add port to host name if not port 80
if ($this->host_port != 80) {
$this->host_name .= ':' . $this->host_port;
}
// can be overridden with basicSetLogFileId later
if (!empty($this->options['file_id'])) {
$this->setLogId($this->options['file_id']);
} elseif (!empty($GLOBALS['LOG_FILE_ID'])) {
/** @deprecated Do not use this anymore, define file_id on class load */
trigger_error(
'options: file_id must be set. Setting via LOG_FILE_ID global variable is deprecated',
E_USER_DEPRECATED
);
// legacy flow, should be removed and only set via options
$this->setLogId($GLOBALS['LOG_FILE_ID']);
// TODO trigger deprecation error
// trigger_error(
// 'Debug\Logging: Do not use globals LOG_FILE_ID to set log id for Logging',
// E_USER_DEPRECATED
// );
} elseif (defined('LOG_FILE_ID')) {
/** @deprecated Do not use this anymore, define file_id on class load */
trigger_error(
'options: file_id must be set. Setting via LOG_FILE_ID constant is deprecated',
E_USER_DEPRECATED
);
// legacy flow, should be removed and only set via options
$this->setLogId(LOG_FILE_ID);
// trigger deprecation error
// trigger_error(
// 'Debug\Logging: Do not use constant LOG_FILE_ID to set log id for Logging',
// E_USER_DEPRECATED
// );
}
// init the log levels
$this->initLogLevels();
}
// *** PRIVATE ***
/**
* init the basic log levels based on global set variables
*
* @return void
*/
private function initLogLevels(): void
{
// if given via parameters, only for all
// globals overrule given settings, for one (array), eg $ECHO['db'] = 1;
foreach (['debug', 'echo', 'print'] as $type) {
// include or exclude (off) from output
foreach (['on', 'off'] as $flag) {
$in_type = $type;
if ($flag == 'off') {
$in_type .= '_not';
}
$up_type = strtoupper($in_type);
if (
isset($this->options[$in_type]) &&
is_array($this->options[$in_type])
) {
$this->setLogLevel($type, $flag, $this->options[$in_type]);
} elseif (
isset($GLOBALS[$up_type]) &&
is_array($GLOBALS[$up_type])
) {
// TODO trigger deprecation error
$this->setLogLevel($type, $flag, $GLOBALS[$up_type]);
}
}
}
// TODO remove all $GLOBALS call and only use options
// all overrule
$this->setLogLevelAll(
'debug',
$this->options['debug_all'] ??
// for user login, should be handled outside like globals
$_SESSION['DEBUG_ALL'] ?? // DEPRECATED
$GLOBALS['DEBUG_ALL'] ?? // DEPRECATED
false
);
$this->setLogLevelAll(
'print',
$this->options['print_all'] ??
// for user login, should be handled outside like globals
$_SESSION['DEBUG_ALL'] ?? // DEPRECATED
$GLOBALS['PRINT_ALL'] ?? // DEPRECATED
false
);
$this->setLogLevelAll(
'echo',
$this->options['echo_all'] ??
$GLOBALS['ECHO_ALL'] ?? // DEPRECATED
false
);
// GLOBAL rules for log writing
// add file date is default on
$this->setGetLogPrintFileDate(
$this->options['print_file_date'] ??
$GLOBALS['LOG_PRINT_FILE_DATE'] ?? // DEPRECATED
true
);
// all other logging file name flags are off
$this->setLogPer(
'level',
$this->options['per_level'] ??
$GLOBALS['LOG_PER_LEVEL'] ?? // DEPRECATED
false
);
$this->setLogPer(
'class',
$this->options['per_class'] ??
$GLOBALS['LOG_PER_CLASS'] ?? // DEPRECATED
false
);
$this->setLogPer(
'page',
$this->options['per_page'] ??
$GLOBALS['LOG_PER_PAGE'] ?? // DEPRECATED
false
);
$this->setLogPer(
'run',
$this->options['per_run'] ??
$GLOBALS['LOG_PER_RUN'] ?? // DEPRECATED
false
);
// set log per date
if ($this->setGetLogPrintFileDate()) {
$this->log_file_date = date('Y-m-d');
}
// set per run ID
if ($this->log_per_run) {
$this->setLogUniqueId();
}
}
/**
* checks if we have a need to work on certain debug output
* Needs debug/echo/print ad target for which of the debug flag groups we check
* also needs level string to check in the per level output flag check.
* In case we have invalid target it will return false
*
* @param string $target target group to check debug/echo/print
* @param string $level level to check in detailed level flag
* @return bool true on access allowed or false on no access
*/
private function doDebugTrigger(string $target, string $level): bool
{
$access = false;
// check if we do debug, echo or print
if (
(
$this->getLogLevel($target, 'on', $level) ||
$this->getLogLevelAll($target)
) &&
!$this->getLogLevel($target, 'off', $level)
) {
$access = true;
}
return $access;
}
/**
* writes error msg data to file for current level
*
* @param string $level the level to write
* @param string $error_string error string to write
* @return bool True if message written, FAlse if not
*/
private function writeErrorMsg(string $level, string $error_string): bool
{
// only write if write is requested
if (
!($this->doDebugTrigger('debug', $level) &&
$this->doDebugTrigger('print', $level))
) {
return false;
}
// init base file path
$fn = $this->log_folder . $this->log_print_file . '.' . $this->log_file_name_ext;
// log ID prefix settings, if not valid, replace with empty
if (!empty($this->log_file_id)) {
$rpl_string = '_' . $this->log_file_id;
} else {
$rpl_string = '';
}
$fn = str_replace('##LOGID##', $rpl_string, $fn); // log id (like a log file prefix)
if ($this->log_per_run) {
$rpl_string = '_' . $this->log_file_unique_id; // add 8 char unique string
} elseif ($this->setGetLogPrintFileDate()) {
$rpl_string = '_' . $this->log_file_date; // add date to file
} else {
$rpl_string = '';
}
$fn = str_replace('##DATE##', $rpl_string, $fn); // create output filename
// write per level
$rpl_string = !$this->log_per_level ? '' :
// normalize level, replace all non alphanumeric characters with -
'_' . (
// if return is only - then set error string
preg_match(
"/^-+$/",
$level_string = preg_replace("/[^A-Za-z0-9-_]/", '-', $level) ?? ''
) ?
'INVALID-LEVEL-STRING' :
$level_string
);
$fn = str_replace('##LEVEL##', $rpl_string, $fn); // create output filename
// set per class, but don't use get_class as we will only get self
$rpl_string = !$this->log_per_class ? '' : '_'
// set sub class settings
. str_replace('\\', '-', Support::getCallerClass());
$fn = str_replace('##CLASS##', $rpl_string, $fn); // create output filename
// if request to write to one file
$rpl_string = !$this->log_per_page ?
'' :
'_' . System::getPageName(System::NO_EXTENSION);
$fn = str_replace('##PAGENAME##', $rpl_string, $fn); // create output filename
// write to file
// first check if max file size is is set and file is bigger
if (
$this->log_max_filesize > 0 &&
((filesize($fn) / 1024) > $this->log_max_filesize)
) {
// for easy purpose, rename file only to attach timestamp, nur sequence numbering
rename($fn, $fn . '.' . date("YmdHis"));
}
$this->log_file_name = $fn;
$fp = fopen($this->log_file_name, 'a');
if ($fp !== false) {
fwrite($fp, $error_string);
fclose($fp);
return true;
} else {
echo "<!-- could not open file: " . $this->log_file_name . " //-->";
return false;
}
}
// *** PUBLIC ***
/**
* Temporary method to read all class variables for testing purpose
*
* @param string $name what variable to return
* @return mixed can be anything, bool, string, int, array
*/
public function getSetting(string $name): mixed
{
// for debug purpose only
return $this->{$name};
}
/**
* sets the internal log file prefix id
* string must be a alphanumeric string
* if non valid string is given it returns the previous set one only
*
* @param string $string log file id string value
* @return string returns the set log file id string
* @deprecated Use $log->setLogId()
*/
public function basicSetLogId(string $string): string
{
return $this->setLogId($string);
}
/**
* sets the internal log file prefix id
* string must be a alphanumeric string
* if non valid string is given it returns the previous set one only
*
* @param string $string log file id string value
* @return string returns the set log file id string
*/
public function setLogId(string $string): string
{
if (preg_match("/^[\w\-]+$/", $string)) {
$this->log_file_id = $string;
}
return $this->log_file_id;
}
/**
* return current set log file id
* @return string
*/
public function getLogId(): string
{
return $this->log_file_id;
}
/**
* old name for setLogLevel
*
* @param string $type debug, echo, print
* @param string $flag on/off
* array $array of levels to turn on/off debug
* @return bool Return false if type or flag is invalid
* @deprecated Use setLogLevel
*/
public function debugFor(string $type, string $flag): bool
{
/** @phan-suppress-next-line PhanTypeMismatchArgumentReal, PhanParamTooFew @phpstan-ignore-next-line */
return $this->setLogLevel(...[func_get_args()]);
}
/**
* set log level settings for All types
* if invalid type, skip
*
* @param string $type Type to get: debug, echo, print
* @param bool $set True or False
* @return bool Return false if type invalid
*/
public function setLogLevelAll(string $type, bool $set): bool
{
// skip set if not valid
if (!in_array($type, ['debug', 'echo', 'print'])) {
return false;
}
$this->{$type . '_output_all'} = $set;
return true;
}
/**
* get the current log level setting for All level blocks
*
* @param string $type Type to get: debug, echo, print
* @return bool False on failure, or the boolean flag from the all var
*/
public function getLogLevelAll(string $type): bool
{
// type check for debug/echo/print
if (!in_array($type, ['debug', 'echo', 'print'])) {
return false;
}
return $this->{$type . '_output_all'};
}
/**
* passes list of level names, to turn on debug
* eg $foo->debugFor('print', 'on', ['LOG', 'DEBUG', 'INFO']);
*
* @param string $type debug, echo, print
* @param string $flag on/off
* @param array<mixed> $debug_on Array of levels to turn on/off debug
* To turn off a level set 'Level' => false,
* If not set, switches to on
* @return bool Return false if type or flag invalid
* also false if debug array is empty
*/
public function setLogLevel(string $type, string $flag, array $debug_on): bool
{
// abort if not valid type
if (!in_array($type, ['debug', 'echo', 'print'])) {
return false;
}
// invalid flag type
if (!in_array($flag, ['on', 'off'])) {
return false;
}
if (count($debug_on) >= 1) {
foreach ($debug_on as $level => $set) {
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
if (!is_bool($set)) {
$level = $set;
$set = true;
}
$this->{$switch}[$level] = $set;
}
} else {
return false;
}
return true;
}
/**
* return the log level for the array type normal and not (disable)
*
* @param string $type debug, echo, print
* @param string $flag on/off
* @param string|null $level if not null then check if this array entry is set
* else return false
* @return array<mixed>|bool if $level is null, return array, else boolean true/false
*/
public function getLogLevel(string $type, string $flag, ?string $level = null): array|bool
{
// abort if not valid type
if (!in_array($type, ['debug', 'echo', 'print'])) {
return false;
}
// invalid flag type
if (!in_array($flag, ['on', 'off'])) {
return false;
}
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
// log level direct check must be not null or not empty string
if (!empty($level)) {
return $this->{$switch}[$level] ?? false;
}
// array
return $this->{$switch};
}
/**
* set flags for per log level type
* - level: set per sub group level
* - class: split by class
* - page: split per page called
* - run: for each run
*
* @param string $type Type to get: level, class, page, run
* @param bool $set True or False
* @return bool Return false if type invalid
*/
public function setLogPer(string $type, bool $set): bool
{
if (!in_array($type, ['level', 'class', 'page', 'run'])) {
return false;
}
$this->{'log_per_' . $type} = $set;
// if per run set unique id
if ($type == 'run' && $set == true) {
$this->setLogUniqueId();
}
return true;
}
/**
* return current set log per flag in bool
*
* @param string $type Type to get: level, class, page, run
* @return bool True of false for turned on or off
*/
public function getLogPer(string $type): bool
{
if (!in_array($type, ['level', 'class', 'page', 'run'])) {
return false;
}
return $this->{'log_per_' . $type};
}
/**
* Sets a unique id based on current date (y/m/d, h:i:s) and a unique id (8 chars)
* if override is set to true it will be newly set, else if already set nothing changes
*
* @param bool $override True to force new set
* @return void
*/
public function setLogUniqueId(bool $override = false): void
{
if (!$this->log_file_unique_id || $override == true) {
$this->log_file_unique_id =
date('Y-m-d_His') . '_U_'
. substr(hash('sha1', uniqid((string)mt_rand(), true)), 0, 8);
}
}
/**
* Return current set log file unique id,
* empty string for not set
*
* @return string
*/
public function getLogUniqueId(): string
{
return $this->log_file_unique_id;
}
/**
* Set or get the log file date extension flag
* if null or empty parameter gets current flag
*
* @param boolean|null $set Set the date suffix for log files
* If set to null return current set
* @return boolean Current set flag
*/
public function setGetLogPrintFileDate(?bool $set = null): bool
{
if ($set !== null) {
$this->log_print_file_date = $set;
}
return $this->log_print_file_date;
}
/**
* Return current set log file name
*
* @return string Filename set set after the last time debug was called
*/
public function getLogFileName(): string
{
return $this->log_file_name;
}
/**
* A replacement for the \CoreLibs\Debug\Support::printAr
* But this does not wrap it in <pre></pre>
* It uses some special code sets so we can convert that to pre flags
* for echo output {##HTMLPRE##} ... {##/HTMLPRE##}
* Do not use this without using it in a string in debug function
*
* @param array<mixed> $a Array to format
* @return string print_r formated
*/
public function prAr(array $a): string
{
return '##HTMLPRE##' . print_r($a, true) . '##/HTMLPRE##';
}
/**
* Convert bool value to string value
*
* @param bool $bool Bool value to be transformed
* @param string $true Override default string 'true'
* @param string $false Override default string 'false'
* @return string $true or $false string for true/false bool
*/
public function prBl(
bool $bool,
string $true = 'true',
string $false = 'false'
): string {
return $bool ? $true : $false;
}
/**
* write debug data to error_msg array
*
* @param string $level id for error message, groups messages together
* @param string $string the actual error message
* @param bool $strip default on false, if set to true,
* all html tags will be stripped and <br> changed to \n
* this is only used for debug output
* @param string $prefix Attach some block before $string.
* Will not be stripped even
* when strip is true
* if strip is false, recommended to add that to $string
* @return bool True if logged, false if not logged
*/
public function debug(
string $level,
string $string,
bool $strip = false,
string $prefix = ''
): bool {
$status = false;
// must be debug on and either echo or print on
if (
!$this->doDebugTrigger('debug', $level) ||
(
// if debug is on, either print or echo must be set to on
!$this->doDebugTrigger('print', $level) &&
!$this->doDebugTrigger('echo', $level)
)
) {
return $status;
}
// get the last class entry and wrie that
$class = Support::getCallerClass();
// get timestamp
$timestamp = Support::printTime();
// same string put for print (no html data inside)
// write to file if set
$status = $this->writeErrorMsg(
$level,
'[' . $timestamp . '] '
. '[' . $this->host_name . '] '
. '[' . System::getPageName(System::FULL_PATH) . '] '
. '[' . $this->running_uid . '] '
. '{' . $class . '} '
. '<' . $level . '> - '
// strip the htmlpre special tags if exist
. str_replace(
['##HTMLPRE##', '##/HTMLPRE##'],
'',
// if stripping all html, etc is requested, only for write error msg
($strip ?
// find any <br> and replace them with \n
// strip rest of html elements (base only)
preg_replace(
"/(<\/?)(\w+)([^>]*>)/",
'',
str_replace('<br>', "\n", $prefix . $string)
) :
$prefix . $string
) ?: ''
)
. "\n"
);
// write to error level msg array if there is an echo request
if ($this->doDebugTrigger('echo', $level)) {
// init if not set
if (!isset($this->error_msg[$level])) {
$this->error_msg[$level] = [];
}
// HTML string
$this->error_msg[$level][] = '<div>'
. '[<span style="font-weight: bold; color: #5e8600;">' . $timestamp . '</span>] '
. '[<span style="font-weight: bold; color: #c56c00;">' . $level . '</span>] '
. '[<span style="color: #b000ab;">' . $this->host_name . '</span>] '
. '[<span style="color: #08b369;">' . $this->page_name . '</span>] '
. '[<span style="color: #0062A2;">' . $this->running_uid . '</span>] '
. '{<span style="font-style: italic; color: #928100;">' . $class . '</span>} - '
// as is prefix, allow HTML
. $prefix
// we replace special HTMLPRE with <pre> entries
. str_replace(
['##HTMLPRE##', '##/HTMLPRE##'],
['<pre>', '</pre>'],
Html::htmlent($string)
)
. "</div><!--#BR#-->";
$status = true;
}
return $status;
}
/**
* for ECHO ON only
* returns error data as string so it can be echoed out
*
* @param string $header_prefix prefix string for header
* @return string error msg for all levels
*/
public function printErrorMsg(string $header_prefix = ''): string
{
$string_output = '';
// if not debug && echo on, do not return anything
if (
!$this->getLogLevelAll('debug') ||
!$this->getLogLevelAll('echo')
) {
return $string_output;
}
if ($this->error_msg_prefix) {
$header_prefix = $this->error_msg_prefix;
}
$script_end = microtime(true) - $this->script_starttime;
foreach ($this->error_msg as $level => $temp_debug_output) {
if ($this->doDebugTrigger('debug', $level)) {
if ($this->doDebugTrigger('echo', $level)) {
$string_output .= '<div style="font-size: 12px;">'
. '[<span style="font-style: italic; color: #c56c00;">' . $level . '</span>] '
. ($header_prefix ? "<b>**** " . Html::htmlent($header_prefix) . " ****</br>\n" : '')
. '</div>'
. join('', $temp_debug_output);
} // echo it out
} // do printout
} // for each level
// create the output wrapper around
// so we have a nice formated output per class
if ($string_output) {
$string_prefix = '<div style="text-align: left; padding: 5px; font-size: 10px; '
. 'font-family: sans-serif; border-top: 1px solid black; '
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
. 'background-color: white; color: black;">'
. '<div style="font-size: 12px;">{<span style="font-style: italic; color: #928100;">'
. Support::getCallerClass() . '</span>}</div>';
$string_output = $string_prefix . $string_output
. '<div><span style="font-style: italic; color: #108db3;">Script Run Time:</span> '
. $script_end . '</div>'
. '</div>';
}
// }
return $string_output;
}
/**
* for ECHO ON only
* unsests the error message array
* can be used if writing is primary to file
* if no level given resets all
*
* @param string $level optional level
* @return void has no return
*/
public function resetErrorMsg(string $level = ''): void
{
if (!$level) {
$this->error_msg = [];
} elseif (isset($this->error_msg[$level])) {
unset($this->error_msg[$level]);
}
}
/**
* for ECHO ON only
* Get current error message array
*
* @return array<mixed> error messages collected
*/
public function getErrorMsg(): array
{
return $this->error_msg;
}
/**
* for ECHO ON only
* merges the given error array with the one from this class
* only merges visible ones
*
* @param array<mixed> $error_msg error array
* @return void has no return
*/
public function mergeErrors(array $error_msg = []): void
{
array_push($this->error_msg, ...$error_msg);
parent::__construct($options);
}
}

View File

@@ -0,0 +1,911 @@
<?php
/**
* THIS IS LEGACY LOGGING AND WILL BE FULLY REMOVED IN FUTURE VERSION.
* use \CoreLibs\Logger\Logging instead
* for the need to reference old:
* use CoreLibs\Debug\LoggingLegacy as Logging;
*/
/*
* Debug support functions
*
* These are if there is any debug to print out at all at the end
 * debug_output_all - general yes no
 * It's recommended to use the method "debug_for" to turn on of the array vars
 * debug_output - turn on for one level (Array)
 * debug_output_not - turn off for one level (array)
 *
 * Print out the debug at thend of the html
 * echo_output_all
 * echo_output
 * echo_output_not
 *
 * Write debug to file
 * print_output_all
 * print_output
 * print_output_not
*/
declare(strict_types=1);
namespace CoreLibs\Debug;
use CoreLibs\Debug\Support;
use CoreLibs\Create\Uids;
use CoreLibs\Get\System;
use CoreLibs\Convert\Html;
class LoggingLegacy
{
// options
/** @var array<mixed> */
private $options = [];
// page and host name
/** @var string */
private $page_name;
/** @var string */
private $host_name;
/** @var int */
private $host_port;
// internal error reporting vars
/** @var array<mixed> */
private $error_msg = []; // the "connection" to the outside errors
// debug output prefix
/** @var string */
private $error_msg_prefix = ''; // prefix to the error string (the class name)
// debug flags/settings
/** @var string */
private $running_uid = ''; // unique ID set on class init and used in logging as prefix
// log file name
/** @var string */
private $log_folder = '';
/** @var string */
private $log_file_name_ext = 'log'; // use this for date rotate
/** @var string */
private $log_file_name = '';
/** @var int */
private $log_max_filesize = 0; // set in kilobytes
/** @var string */
private $log_print_file = 'error_msg{LOGID}{LEVEL}{CLASS}{PAGENAME}{DATE_RUNID}';
/** @var string */
private $log_file_unique_id; // a unique ID set only once for call derived from this class
/** @var string */
private $log_file_date = ''; // Y-m-d file in file name
/** @var bool */
private $log_print_file_date = true; // if set add Y-m-d and do automatic daily rotation
/** @var string */
private $log_file_id = ''; // a alphanumeric name that has to be set as global definition
/** @var bool */
private $log_per_level = false; // set, it will split per level (first parameter in debug call)
/** @var bool */
private $log_per_class = false; // set, will split log per class
/** @var bool */
private $log_per_page = false; // set, will split log per called file
/** @var bool */
private $log_per_run = false; // create a new log file per run (time stamp + unique ID)
// script running time
/** @var float */
private $script_starttime;
/** @var string[] current log levels */
private $log_levels = ['debug', 'echo', 'print'];
/** @var string[] log group per what for writing to file */
private $log_grouping = ['level', 'class', 'page', 'run'];
// debug flags [they must exist or we get a warning]
/** @var array<mixed> */
private $debug_output = []; // if this is true, show debug on desconstructor
/** @var array<mixed> */
private $debug_output_not = [];
/** @var bool */
private $debug_output_all = false;
/** @var array<mixed> */
private $echo_output = []; // errors: echo out, default is 1
/** @var array<mixed> */
private $echo_output_not = [];
/** @var bool */
private $echo_output_all = false;
/** @var array<mixed> */
private $print_output = []; // errors: print to file, default is 0
/** @var array<mixed> */
private $print_output_not = [];
/** @var bool */
private $print_output_all = false;
/**
* Init logger
*
* global vars that can be used
* - BASE
* - LOG
* - LOG_FILE_ID
* options array layout
* - log_folder:
* - file_id:
* - unique_id:
* - print_file_date:
* - log_per_level:
* - log_per_class:
* - log_per_page:
* - log_per_run:
* - debug_all:
* - echo_all:
* - print_all:
* - debug (array):
* - echo (array):
* - print (array):
* - debug_not (array):
* - echo_not (array):
* - print_not (array):
*
* @param array<mixed> $options Array with settings options
*/
public function __construct(array $options = [])
{
// copy the options over
$this->options = $options;
// set log folder from options
$this->log_folder = $this->options['log_folder'] ?? '';
// legacy flow, check must set constants
if (empty($this->log_folder) && defined('BASE') && defined('LOG')) {
/** @deprecated Do not use this anymore, define path on class load */
trigger_error(
'options: log_folder must be set. Setting via BASE and LOG constants is deprecated',
E_USER_DEPRECATED
);
// make sure this is writeable, else skip
$this->log_folder = BASE . LOG;
}
// fallback + notice
if (empty($this->log_folder)) {
/* trigger_error(
'options or constant not set or folder not writable. fallback to: ' . getcwd(),
E_USER_NOTICE
); */
$this->log_folder = getcwd() . DIRECTORY_SEPARATOR;
}
// if folder is not writeable, abort
if (!is_writeable($this->log_folder)) {
trigger_error(
'Folder: ' . $this->log_folder . ' is not writeable for logging',
E_USER_ERROR
);
}
// check if log_folder has a trailing /
if (substr($this->log_folder, -1, 1) != DIRECTORY_SEPARATOR) {
$this->log_folder .= DIRECTORY_SEPARATOR;
}
// running time start for script
$this->script_starttime = microtime(true);
// set per run UID for logging
$this->running_uid = Uids::uniqIdShort();
// set the page name
$this->page_name = System::getPageName();
// set host name
list($this->host_name , $this->host_port) = System::getHostName();
// add port to host name if not port 80
if ($this->host_port != 80) {
$this->host_name .= ':' . $this->host_port;
}
// can be overridden with basicSetLogFileId later
if (!empty($this->options['file_id'])) {
$this->setLogId($this->options['file_id']);
} elseif (!empty($GLOBALS['LOG_FILE_ID'])) {
/** @deprecated Do not use this anymore, define file_id on class load */
trigger_error(
'options: file_id must be set. Setting via LOG_FILE_ID global variable is deprecated',
E_USER_DEPRECATED
);
// legacy flow, should be removed and only set via options
$this->setLogId($GLOBALS['LOG_FILE_ID']);
// TODO trigger deprecation error
// trigger_error(
// 'Debug\Logging: Do not use globals LOG_FILE_ID to set log id for Logging',
// E_USER_DEPRECATED
// );
} elseif (defined('LOG_FILE_ID')) {
/** @deprecated Do not use this anymore, define file_id on class load */
trigger_error(
'options: file_id must be set. Setting via LOG_FILE_ID constant is deprecated',
E_USER_DEPRECATED
);
// legacy flow, should be removed and only set via options
$this->setLogId((string)LOG_FILE_ID);
// trigger deprecation error
// trigger_error(
// 'Debug\Logging: Do not use constant LOG_FILE_ID to set log id for Logging',
// E_USER_DEPRECATED
// );
}
// init the log levels
$this->initLogLevels();
}
// *** PRIVATE ***
/**
* init the basic log levels based on global set variables
*
* @return void
*/
private function initLogLevels(): void
{
// if given via parameters, only for all
// globals overrule given settings, for one (array), eg $ECHO['db'] = 1;
foreach ($this->log_levels as $type) {
// include or exclude (off) from output
foreach (['on', 'off'] as $flag) {
$in_type = $type;
if ($flag == 'off') {
$in_type .= '_not';
}
$up_type = strtoupper($in_type);
if (
isset($this->options[$in_type]) &&
is_array($this->options[$in_type])
) {
$this->setLogLevel($type, $flag, $this->options[$in_type]);
} elseif (
isset($GLOBALS[$up_type]) &&
is_array($GLOBALS[$up_type])
) {
// TODO trigger deprecation error
$this->setLogLevel($type, $flag, $GLOBALS[$up_type]);
}
}
}
// TODO remove all $GLOBALS call and only use options
// all overrule
$this->setLogLevelAll(
'debug',
$this->options['debug_all'] ??
// for user login, should be handled outside like globals
$_SESSION['DEBUG_ALL'] ?? // DEPRECATED
$GLOBALS['DEBUG_ALL'] ?? // DEPRECATED
false
);
$this->setLogLevelAll(
'print',
$this->options['print_all'] ??
// for user login, should be handled outside like globals
$_SESSION['DEBUG_ALL'] ?? // DEPRECATED
$GLOBALS['PRINT_ALL'] ?? // DEPRECATED
false
);
$this->setLogLevelAll(
'echo',
$this->options['echo_all'] ??
$GLOBALS['ECHO_ALL'] ?? // DEPRECATED
false
);
// GLOBAL rules for log writing
// add file date is default on
$this->setGetLogPrintFileDate(
$this->options['print_file_date'] ??
$GLOBALS['LOG_PRINT_FILE_DATE'] ?? // DEPRECATED
true
);
// all other logging file name flags are off
$this->setLogPer(
'level',
$this->options['per_level'] ??
$GLOBALS['LOG_PER_LEVEL'] ?? // DEPRECATED
false
);
$this->setLogPer(
'class',
$this->options['per_class'] ??
$GLOBALS['LOG_PER_CLASS'] ?? // DEPRECATED
false
);
$this->setLogPer(
'page',
$this->options['per_page'] ??
$GLOBALS['LOG_PER_PAGE'] ?? // DEPRECATED
false
);
$this->setLogPer(
'run',
$this->options['per_run'] ??
$GLOBALS['LOG_PER_RUN'] ?? // DEPRECATED
false
);
// set log per date
if ($this->setGetLogPrintFileDate()) {
$this->log_file_date = date('Y-m-d');
}
// set per run ID
if ($this->log_per_run) {
$this->setLogUniqueId();
}
}
/**
* checks if we have a need to work on certain debug output
* Needs debug/echo/print ad target for which of the debug flag groups we check
* also needs level string to check in the per level output flag check.
* In case we have invalid target it will return false
*
* @param string $target target group to check debug/echo/print
* @param string $level level to check in detailed level flag
* @return bool true on access allowed or false on no access
*/
private function doDebugTrigger(string $target, string $level): bool
{
$access = false;
// check if we do debug, echo or print
if (
(
$this->getLogLevel($target, 'on', $level) ||
$this->getLogLevelAll($target)
) &&
!$this->getLogLevel($target, 'off', $level)
) {
$access = true;
}
return $access;
}
/**
* writes error msg data to file for current level
*
* @param string $level the level to write
* @param string $error_string error string to write
* @return bool True if message written, False if not
*/
private function writeErrorMsg(string $level, string $error_string): bool
{
// only write if write is requested
if (
!($this->doDebugTrigger('debug', $level) &&
$this->doDebugTrigger('print', $level))
) {
return false;
}
// init base file path
$fn = $this->log_folder . $this->log_print_file . '.' . $this->log_file_name_ext;
// log ID prefix settings, if not valid, replace with empty
if (!empty($this->log_file_id)) {
$rpl_string = '_' . $this->log_file_id;
} else {
$rpl_string = '';
}
$fn = str_replace('{LOGID}', $rpl_string, $fn); // log id (like a log file prefix)
// if run id, we auto add ymd, so we ignore the log file date
if ($this->log_per_run) {
$rpl_string = '_' . $this->log_file_unique_id; // add 8 char unique string
} elseif ($this->setGetLogPrintFileDate()) {
$rpl_string = '_' . $this->log_file_date; // add date to file
} else {
$rpl_string = '';
}
$fn = str_replace('{DATE_RUNID}', $rpl_string, $fn); // create output filename
// write per level
$rpl_string = !$this->log_per_level ? '' :
// normalize level, replace all non alphanumeric characters with -
'_' . (
// if return is only - then set error string
preg_match(
"/^-+$/",
$level_string = preg_replace("/[^A-Za-z0-9-_]/", '-', $level) ?? ''
) ?
'INVALID-LEVEL-STRING' :
$level_string
);
$fn = str_replace('{LEVEL}', $rpl_string, $fn); // create output filename
// set per class, but don't use get_class as we will only get self
$rpl_string = !$this->log_per_class ? '' : '_'
// set sub class settings
. str_replace('\\', '-', Support::getCallerClass());
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
// if request to write to one file
$rpl_string = !$this->log_per_page ?
'' :
'_' . System::getPageName(System::NO_EXTENSION);
$fn = str_replace('{PAGENAME}', $rpl_string, $fn); // create output filename
// write to file
// first check if max file size is is set and file is bigger
if (
$this->log_max_filesize > 0 &&
((filesize($fn) / 1024) > $this->log_max_filesize)
) {
// for easy purpose, rename file only to attach timestamp, nur sequence numbering
rename($fn, $fn . '.' . date("YmdHis"));
}
$this->log_file_name = $fn;
$fp = fopen($this->log_file_name, 'a');
if ($fp !== false) {
fwrite($fp, $error_string);
fclose($fp);
return true;
} else {
echo "<!-- could not open file: " . $this->log_file_name . " //-->";
return false;
}
}
// *** PUBLIC ***
/**
* Temporary method to read all class variables for testing purpose
*
* @param string $name what variable to return
* @return mixed can be anything, bool, string, int, array
*/
public function getSetting(string $name): mixed
{
// for debug purpose only
return $this->{$name};
}
/**
* sets the internal log file prefix id
* string must be a alphanumeric string
* if non valid string is given it returns the previous set one only
*
* @param string $string log file id string value
* @return string returns the set log file id string
* @deprecated Use $log->setLogId()
*/
public function basicSetLogId(string $string): string
{
return $this->setLogId($string);
}
/**
* sets the internal log file prefix id
* string must be a alphanumeric string
* if non valid string is given it returns the previous set one only
*
* @param string $string log file id string value
* @return string returns the set log file id string
*/
public function setLogId(string $string): string
{
if (preg_match("/^[\w\-]+$/", $string)) {
$this->log_file_id = $string;
}
return $this->log_file_id;
}
/**
* return current set log file id
* @return string
*/
public function getLogId(): string
{
return $this->log_file_id;
}
/**
* old name for setLogLevel
*
* @param string $type debug, echo, print
* @param string $flag on/off
* array $array of levels to turn on/off debug
* @return bool Return false if type or flag is invalid
* @deprecated Use setLogLevel
*/
public function debugFor(string $type, string $flag): bool
{
/** @phan-suppress-next-line PhanTypeMismatchArgumentReal, PhanParamTooFew @phpstan-ignore-next-line */
return $this->setLogLevel(...[func_get_args()]);
}
/**
* set log level settings for All types
* if invalid type, skip
*
* @param string $type Type to get: debug, echo, print
* @param bool $set True or False
* @return bool Return false if type invalid
*/
public function setLogLevelAll(string $type, bool $set): bool
{
// skip set if not valid
if (!in_array($type, $this->log_levels)) {
return false;
}
$this->{$type . '_output_all'} = $set;
return true;
}
/**
* get the current log level setting for All level blocks
*
* @param string $type Type to get: debug, echo, print
* @return bool False on failure, or the boolean flag from the all var
*/
public function getLogLevelAll(string $type): bool
{
// type check for debug/echo/print
if (!in_array($type, $this->log_levels)) {
return false;
}
return $this->{$type . '_output_all'};
}
/**
* passes list of level names, to turn on debug
* eg $foo->debugFor('print', 'on', ['LOG', 'DEBUG', 'INFO']);
*
* @param string $type debug, echo, print
* @param string $flag on/off
* @param array<mixed> $debug_on Array of levels to turn on/off debug
* To turn off a level set 'Level' => false,
* If not set, switches to on
* @return bool Return false if type or flag invalid
* also false if debug array is empty
*/
public function setLogLevel(string $type, string $flag, array $debug_on): bool
{
// abort if not valid type
if (!in_array($type, $this->log_levels)) {
return false;
}
// invalid flag type
if (!in_array($flag, ['on', 'off'])) {
return false;
}
if (count($debug_on) >= 1) {
foreach ($debug_on as $level => $set) {
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
if (!is_bool($set)) {
$level = $set;
$set = true;
}
$this->{$switch}[$level] = $set;
}
} else {
return false;
}
return true;
}
/**
* return the log level for the array type normal and not (disable)
*
* @param string $type debug, echo, print
* @param string $flag on/off
* @param string|null $level if not null then check if this array entry is set
* else return false
* @return array<mixed>|bool if $level is null, return array, else boolean true/false
*/
public function getLogLevel(string $type, string $flag, ?string $level = null): array|bool
{
// abort if not valid type
if (!in_array($type, $this->log_levels)) {
return false;
}
// invalid flag type
if (!in_array($flag, ['on', 'off'])) {
return false;
}
$switch = $type . '_output' . ($flag == 'off' ? '_not' : '');
// log level direct check must be not null or not empty string
if (!empty($level)) {
return $this->{$switch}[$level] ?? false;
}
// array
return $this->{$switch};
}
/**
* set flags for per log level type
* - level: set per sub group level
* - class: split by class
* - page: split per page called
* - run: for each run
*
* @param string $type Type to get: level, class, page, run
* @param bool $set True or False
* @return bool Return false if type invalid
*/
public function setLogPer(string $type, bool $set): bool
{
if (!in_array($type, $this->log_grouping)) {
return false;
}
$this->{'log_per_' . $type} = $set;
// if per run set unique id
if ($type == 'run' && $set == true) {
$this->setLogUniqueId();
}
return true;
}
/**
* return current set log per flag in bool
*
* @param string $type Type to get: level, class, page, run
* @return bool True of false for turned on or off
*/
public function getLogPer(string $type): bool
{
if (!in_array($type, $this->log_grouping)) {
return false;
}
return $this->{'log_per_' . $type};
}
/**
* Sets a unique id based on current date (y/m/d, h:i:s) and a unique id (8 chars)
* if override is set to true it will be newly set, else if already set nothing changes
*
* @param bool $override True to force new set
* @return void
*/
public function setLogUniqueId(bool $override = false): void
{
if (!$this->log_file_unique_id || $override == true) {
$this->log_file_unique_id =
date('Y-m-d_His') . '_U_'
. substr(hash('sha1', uniqid((string)mt_rand(), true)), 0, 8);
}
}
/**
* Return current set log file unique id,
* empty string for not set
*
* @return string
*/
public function getLogUniqueId(): string
{
return $this->log_file_unique_id;
}
/**
* Set or get the log file date extension flag
* if null or empty parameter gets current flag
*
* @param boolean|null $set Set the date suffix for log files
* If set to null return current set
* @return boolean Current set flag
*/
public function setGetLogPrintFileDate(?bool $set = null): bool
{
if ($set !== null) {
$this->log_print_file_date = $set;
}
return $this->log_print_file_date;
}
/**
* Return current set log file name
*
* @return string Filename set set after the last time debug was called
*/
public function getLogFileName(): string
{
return $this->log_file_name;
}
/**
* A replacement for the \CoreLibs\Debug\Support::printAr
* But this does not wrap it in <pre></pre>
* It uses some special code sets so we can convert that to pre flags
* for echo output {##HTMLPRE##} ... {##/HTMLPRE##}
* Do not use this without using it in a string in debug function
*
* @param array<mixed> $a Array to format
* @return string print_r formated
*/
public function prAr(array $a): string
{
return '##HTMLPRE##' . print_r($a, true) . '##/HTMLPRE##';
}
/**
* Convert bool value to string value
*
* @param bool $bool Bool value to be transformed
* @param string $true Override default string 'true'
* @param string $false Override default string 'false'
* @return string $true or $false string for true/false bool
*/
public function prBl(
bool $bool,
string $true = 'true',
string $false = 'false'
): string {
return $bool ? $true : $false;
}
/**
* write debug data to error_msg array
*
* @param string $level id for error message, groups messages together
* @param string $string the actual error message
* @param bool $strip default on false, if set to true,
* all html tags will be stripped and <br> changed to \n
* this is only used for debug output
* @param string $prefix Attach some block before $string.
* Will not be stripped even
* when strip is true
* if strip is false, recommended to add that to $string
* @return bool True if logged, false if not logged
*/
public function debug(
string $level,
string $string,
bool $strip = false,
string $prefix = ''
): bool {
$status = false;
// must be debug on and either echo or print on
if (
!$this->doDebugTrigger('debug', $level) ||
(
// if debug is on, either print or echo must be set to on
!$this->doDebugTrigger('print', $level) &&
!$this->doDebugTrigger('echo', $level)
)
) {
return $status;
}
// get the last class entry and wrie that
$class = Support::getCallerClass();
// get timestamp
$timestamp = Support::printTime();
// same string put for print (no html data inside)
// write to file if set
$status = $this->writeErrorMsg(
$level,
'[' . $timestamp . '] '
. '[' . $this->host_name . '] '
. '[' . System::getPageName(System::FULL_PATH) . '] '
. '[' . $this->running_uid . '] '
. '{' . $class . '} '
. '<' . $level . '> - '
// strip the htmlpre special tags if exist
. str_replace(
['##HTMLPRE##', '##/HTMLPRE##'],
'',
// if stripping all html, etc is requested, only for write error msg
($strip ?
// find any <br> and replace them with \n
// strip rest of html elements (base only)
preg_replace(
"/(<\/?)(\w+)([^>]*>)/",
'',
str_replace('<br>', "\n", $prefix . $string)
) :
$prefix . $string
) ?: ''
)
. "\n"
);
// write to error level msg array if there is an echo request
if ($this->doDebugTrigger('echo', $level)) {
// init if not set
if (!isset($this->error_msg[$level])) {
$this->error_msg[$level] = [];
}
// HTML string
$this->error_msg[$level][] = '<div>'
. '[<span style="font-weight: bold; color: #5e8600;">' . $timestamp . '</span>] '
. '[<span style="font-weight: bold; color: #c56c00;">' . $level . '</span>] '
. '[<span style="color: #b000ab;">' . $this->host_name . '</span>] '
. '[<span style="color: #08b369;">' . $this->page_name . '</span>] '
. '[<span style="color: #0062A2;">' . $this->running_uid . '</span>] '
. '{<span style="font-style: italic; color: #928100;">' . $class . '</span>} - '
// as is prefix, allow HTML
. $prefix
// we replace special HTMLPRE with <pre> entries
. str_replace(
['##HTMLPRE##', '##/HTMLPRE##'],
['<pre>', '</pre>'],
Html::htmlent($string)
)
. "</div><!--#BR#-->";
$status = true;
}
return $status;
}
/**
* for ECHO ON only
* returns error data as string so it can be echoed out
*
* @param string $header_prefix prefix string for header
* @return string error msg for all levels
*/
public function printErrorMsg(string $header_prefix = ''): string
{
$string_output = '';
// if not debug && echo on, do not return anything
if (
!$this->getLogLevelAll('debug') ||
!$this->getLogLevelAll('echo')
) {
return $string_output;
}
if ($this->error_msg_prefix) {
$header_prefix = $this->error_msg_prefix;
}
$script_end = microtime(true) - $this->script_starttime;
foreach ($this->error_msg as $level => $temp_debug_output) {
if ($this->doDebugTrigger('debug', $level)) {
if ($this->doDebugTrigger('echo', $level)) {
$string_output .= '<div style="font-size: 12px;">'
. '[<span style="font-style: italic; color: #c56c00;">' . $level . '</span>] '
. ($header_prefix ? "<b>**** " . Html::htmlent($header_prefix) . " ****</br>\n" : '')
. '</div>'
. join('', $temp_debug_output);
} // echo it out
} // do printout
} // for each level
// create the output wrapper around
// so we have a nice formated output per class
if ($string_output) {
$string_prefix = '<div style="text-align: left; padding: 5px; font-size: 10px; '
. 'font-family: sans-serif; border-top: 1px solid black; '
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
. 'background-color: white; color: black;">'
. '<div style="font-size: 12px;">{<span style="font-style: italic; color: #928100;">'
. Support::getCallerClass() . '</span>}</div>';
$string_output = $string_prefix . $string_output
. '<div><span style="font-style: italic; color: #108db3;">Script Run Time:</span> '
. $script_end . '</div>'
. '</div>';
}
// }
return $string_output;
}
/**
* for ECHO ON only
* unsests the error message array
* can be used if writing is primary to file
* if no level given resets all
*
* @param string $level optional level
* @return void has no return
*/
public function resetErrorMsg(string $level = ''): void
{
if (!$level) {
$this->error_msg = [];
} elseif (isset($this->error_msg[$level])) {
unset($this->error_msg[$level]);
}
}
/**
* for ECHO ON only
* Get current error message array
*
* @return array<mixed> error messages collected
*/
public function getErrorMsg(): array
{
return $this->error_msg;
}
/**
* for ECHO ON only
* merges the given error array with the one from this class
* only merges visible ones
*
* @param array<mixed> $error_msg error array
* @return void has no return
*/
public function mergeErrors(array $error_msg = []): void
{
array_push($this->error_msg, ...$error_msg);
}
}
// __END__

View File

@@ -13,13 +13,13 @@ use CoreLibs\Convert\Byte;
class MemoryUsage
{
/** @var int */
private static $start_memory = 0;
private static int $start_memory = 0;
/** @var int */
private static $set_memory = 0;
private static int $set_memory = 0;
/** @var int */
private static $previous_memory = 0;
private static int $previous_memory = 0;
/** @var bool */
private static $debug_memory = false;
private static bool $debug_memory = false;
/**
* set memory flag, or return set memory flag

View File

@@ -12,18 +12,18 @@ class RunningTime
{
// hr
/** @var float */
private static $hr_start_time;
private static float $hr_start_time;
/** @var float */
private static $hr_end_time;
private static float $hr_end_time;
/** @var float */
private static $hr_last_time;
private static float $hr_last_time;
// normal
/** @var float */
private static $start_time;
private static float $start_time;
/** @var float */
private static $end_time;
private static float $end_time;
/** @var string */
private static $running_time_string;
private static string $running_time_string;
/**
* sub calculation for running time based on out time.
@@ -79,7 +79,7 @@ class RunningTime
public static function hrRunningTime(string $out_time = 'ms'): float
{
// if start time not set, set start time
if (!self::$hr_start_time) {
if (empty(self::$hr_start_time)) {
self::$hr_start_time = hrtime(true);
self::$hr_last_time = self::$hr_start_time;
$run_time = 0;
@@ -137,7 +137,7 @@ class RunningTime
list($micro, $timestamp) = explode(' ', microtime());
$running_time = 0;
// set start & end time
if (!self::$start_time) {
if (empty(self::$start_time)) {
// always reset running time string on first call
self::$running_time_string = '';
self::$start_time = ((float)$micro + (float)$timestamp);
@@ -149,7 +149,7 @@ class RunningTime
self::$running_time_string .= date('Y-m-d H:i:s', (int)$timestamp);
self::$running_time_string .= ' ' . $micro . ($simple ? ', ' : '<br>');
// if both are set
if (self::$start_time && self::$end_time) {
if (!empty(self::$start_time) && !empty(self::$end_time)) {
$running_time = self::$end_time - self::$start_time;
self::$running_time_string .= ($simple ? 'Run: ' : "<b>Script running time</b>: ") . $running_time . " s";
// reset start & end time after run

View File

@@ -21,7 +21,7 @@ class Support
*/
public static function printTime(int $set_microtime = -1): string
{
list($microtime, $timestamp) = explode(' ', microtime());
[$microtime, $timestamp] = explode(' ', microtime());
$string = date("Y-m-d H:i:s", (int)$timestamp);
// if microtime flag is -1 no round, if 0, no microtime, if >= 1, round that size
if ($set_microtime == -1) {
@@ -37,23 +37,21 @@ class Support
* prints a html formatted (pre) array
*
* @param array<mixed> $array any array
* @param bool $no_html set to true to use ##HTMLPRE##
* @param bool $no_html default add <pre>
* @return string formatted array for output with <pre> tag added
*/
public static function printAr(array $array, bool $no_html = false): string
{
if ($no_html === false) {
return "<pre>" . print_r($array, true) . "</pre>";
} else {
return '##HTMLPRE##' . print_r($array, true) . '##/HTMLPRE##';
}
return $no_html ?
print_r($array, true) :
'<pre>' . print_r($array, true) . '</pre>';
}
/**
* alternate name for printAr function
*
* @param array<mixed> $array any array
* @param bool $no_html set to true to use ##HTMLPRE##
* @param bool $no_html default add <pre>
* @return string formatted array for output with <pre> tag added
*/
public static function printArray(array $array, bool $no_html = false): string
@@ -61,26 +59,61 @@ class Support
return self::printAr($array, $no_html);
}
/**
* A replacement for the \CoreLibs\Debug\Support::printAr
* But this does not wrap it in <pre></pre>
* Do not use this without using it in a string in debug function
* Note: for full data debug dumps use Support::dumpVar()
*
* @param array<mixed> $a Array to format
* @return string print_r formated
*/
public static function prAr(array $a): string
{
return self::printAr($a, true);
}
/**
* convert bool value to string
* if $name is set prefix with nae
* default true: true, false: false
*
* @param bool $bool Variable to convert
* @param string $name [default: ''] Prefix name
* @param string $true [default: true] True string
* @param string $false [default: false] False string
* @return string String with converted bool text for debug
* @param bool $bool Variable to convert
* @param string $name [default: ''] Prefix name
* @param string $true [default: 'true'] True string
* @param string $false [default: 'false'] False string
* @param bool $no_html [default: false] if true do not print html
* @return string String with converted bool text for debug
*/
public static function printBool(
bool $bool,
string $name = '',
string $true = 'true',
string $false = 'false',
bool $no_html = false,
): string {
return
(!empty($name) ?
($no_html ?
$name : '<b>' . $name . '</b>') . ': '
: '')
. ($bool ? $true : $false);
}
/**
* Convert bool value to string value. Short name alias for printBool
*
* @param bool $bool Bool value to be transformed
* @param string $true [default: 'true'] Override default string 'true'
* @param string $false [default: 'false'] Override default string 'false'
* @return string $true or $false string for true/false bool
*/
public static function prBl(
bool $bool,
string $true = 'true',
string $false = 'false'
): string {
$string = (!empty($name) ? '<b>' . $name . '</b>: ' : '')
. ($bool ? $true : $false);
return $string;
return self::printBool($bool, '', $true, $false, true);
}
/**
@@ -89,9 +122,10 @@ class Support
* if object return get_class
* for array use printAr function, can be controlled with no_html for
* Debug\Logging compatible output
* Recommended to use Support::dumpVar()
*
* @param mixed $mixed
* @param bool $no_html set to true to use ##HTMLPRE##or html escape
* @param bool $no_html set to true to strip <pre> tags
* @return string
*/
public static function printToString(mixed $mixed, bool $no_html = false): string
@@ -119,12 +153,93 @@ class Support
}
}
/**
* Dumps var data and returns it as string
* var_dump based
* Recommended debug output
*
* @param mixed $data Anything
* @param bool $no_html [default=false] If true strip all html tags
* (for text print)
* @return string A text string
*/
public static function dumpVar(
mixed $data,
bool $no_html = false,
): string {
// dump data
ob_start();
var_dump($data);
$debug_dump = ob_get_clean() ?: '[FAILED TO GET var_dump() data]';
// check if the original caller is dV, if yes, up the caller level for
// the file line get by 1, so we get file + pos from the dV call and
// not this call
$caller_level = 1;
$caller_list = self::getCallerMethodList();
if ($caller_list[0] == 'dV') {
echo "Raise caller level<br>: " . $caller_list[0] . "<br>";
$caller_level = 2;
}
// we need to strip the string in <small></small that is
// "path ... CoreLibs/Debug/Support.php:<number>:
// and replace it with the caller methods and location
$caller_file_number = self::getCallerFileLine($caller_level);
$debug_dump = preg_replace(
'|<small>(/.*:\d+:)</small>|',
'<small>' . $caller_file_number . ':</small>',
$debug_dump
) ?? $debug_dump; // in case of failure keep original
// if strip is ture, remove all HTML tags and convert any html entities back
return $no_html ?
str_replace(
// things to replace in the string if set
['&gt;', '&lt;', '&#13;', '&#10;'],
['>', '<', "\r", "\n"],
strip_tags($debug_dump)
) :
$debug_dump;
}
/**
* exports (dumps) var, in more printable design, but without detail info
*
* @param mixed $data Anything
* @param bool $no_html If true true do not add <pre> tags
* @return string A text string
*/
public static function exportVar(mixed $data, bool $no_html = false): string
{
return $no_html ?
var_export($data, true) :
'<pre>' . var_export($data, true) . '</pre>';
}
/**
* Return file name and line number where this was called
* One level up
*
* @param int $level trace level, default 1
* @return string|null null or file name:line number
*/
public static function getCallerFileLine(int $level = 1): ?string
{
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// print \CoreLibs\Debug\Support::printAr($traces);
// We should check from top down if unset?
// sets the start point here, and in level two (the sub call) we find this
if (isset($traces[$level])) {
return ($traces[$level]['file'] ?? $traces[$level]['function'])
. ':' . ($traces[$level]['line'] ?? '-');
}
return null;
}
/**
* if there is a need to find out which parent method called a child method,
* eg for debugging, this function does this
*
* call this method in the child method and you get the parent function that called
* @param int $level debug level, default 1
* @param int $level trace level, default 1
* @return ?string null or the function that called the function
* where this method is called
*/

View File

@@ -54,14 +54,15 @@ class System
/**
* get the host name without the port as given by the SELF var
* if no host name found will set to NOHOST:0
*
* @return array<mixed> host name/port name
* @return array{string,int} host name/port number
*/
public static function getHostName(): array
{
$host = $_SERVER['HTTP_HOST'] ?? 'NOHOST:NOPORT';
list($host_name, $port) = array_pad(explode(':', $host), 2, self::DEFAULT_PORT);
return [$host_name, $port];
$host = $_SERVER['HTTP_HOST'] ?? 'NOHOST:0';
[$host_name, $port] = array_pad(explode(':', $host), 2, self::DEFAULT_PORT);
return [$host_name, (int)$port];
}
/**

View File

@@ -29,9 +29,9 @@ namespace CoreLibs\Language\Core;
class CachedFileReader extends \CoreLibs\Language\Core\StringReader
{
/** @var int */
public $error = 0;
public int $error = 0;
/** @var string */
public $fd_str = '';
public string $fd_str = '';
/**
* Undocumented function

View File

@@ -27,13 +27,13 @@ namespace CoreLibs\Language\Core;
class FileReader
{
/** @var int */
public $fr_pos;
public int $fr_pos;
/** @var resource|bool */
public $fr_fd;
public mixed $fr_fd; // no resource type yet
/** @var int */
public $fr_length;
public int $fr_length;
/** @var int */
public $error = 0;
public int $error = 0;
/**
* file read constructor

View File

@@ -41,31 +41,31 @@ class GetTextReader
{
// public:
/** @var int */
public $error = 0; // public variable that holds error code (0 if no error)
public int $error = 0; // public variable that holds error code (0 if no error)
// private:
/** @var int */
private $BYTEORDER = 0; // 0: low endian, 1: big endian
private int $BYTEORDER = 0; // 0: low endian, 1: big endian
/** @var FileReader */
private $STREAM;
private FileReader $STREAM;
/** @var bool */
private $short_circuit = false;
private bool $short_circuit = false;
/** @var bool */
private $enable_cache = false;
private bool $enable_cache = false;
/** @var int */
private $originals = 0; // offset of original table
private int $originals = 0; // offset of original table
/** @var int */
private $translations = 0; // offset of translation table
private int $translations = 0; // offset of translation table
/** @var string */
private $pluralheader = ''; // cache header field for plural forms
private string $pluralheader = ''; // cache header field for plural forms
/** @var int */
private $total = 0; // total string count
private int $total = 0; // total string count
/** @var array<mixed>|null */
private $table_originals = null; // table for original strings (offsets)
private array|null $table_originals = null; // table for original strings (offsets)
/** @var array<mixed>|null */
private $table_translations = null; // table for translated strings (offsets)
private array|null $table_translations = null; // table for translated strings (offsets)
/** @var array<mixed> */
private $cache_translations = []; // original -> translation mapping
private array $cache_translations = []; // original -> translation mapping
/* Methods */

View File

@@ -27,9 +27,9 @@ namespace CoreLibs\Language\Core;
class StringReader
{
/** @var int */
public $sr_pos;
public int $sr_pos;
/** @var string */
public $sr_str;
public string $sr_str;
/**
* constructor for string reader

View File

@@ -35,42 +35,42 @@ class L10n
/** @var string the default fallback encoding if nothing is set */
public const DEFAULT_CHARSET = 'UTF-8';
/** @var string the current locale */
private $locale = '';
private string $locale = '';
/** @var string the SET locale as WHERE the domain file is */
private $locale_set = '';
private string $locale_set = '';
/** @var string the default selected/active domain */
private $domain = '';
private string $domain = '';
/** @var string encoding, as from locale or set from outside */
private $override_encoding = self::DEFAULT_CHARSET;
private string $override_encoding = self::DEFAULT_CHARSET;
/** @var string encoding set during the parse Locale */
private $encoding = '';
private string $encoding = '';
/** @var array<string,array<string,GetTextReader>> locale > domain = translator */
private $domains = [];
private array $domains = [];
/** @var array<string,string> bound paths for domains */
private $paths = ['' => './'];
private array $paths = ['' => './'];
// files
/** @var string the full path to the mo file to loaded */
private $mofile = '';
private string $mofile = '';
/** @var string base path to search level */
private $base_locale_path = '';
private string $base_locale_path = '';
/** @var string dynamic set path to where the mo file is actually */
private $base_content_path = '';
private string $base_content_path = '';
// errors
/** @var bool if load of mo file was unsuccessful */
private $load_failure = false;
private bool $load_failure = false;
// object holders
/** @var FileReader|bool reader class for file reading, false for short circuit */
private $input = false;
private FileReader|bool $input = false;
/** @var GetTextReader reader class for MO data */
private $l10n;
private GetTextReader|null $l10n = null;
/**
* @static
* @var L10n self class
*/
private static $instance;
private static L10n $instance;
/**
* class constructor call for language getstring
@@ -124,7 +124,6 @@ class L10n
*/
public static function getInstance(): L10n
{
/** @phpstan-ignore-next-line */
if (empty(self::$instance)) {
self::$instance = new self();
}
@@ -253,6 +252,13 @@ class L10n
// dummy
$this->l10n = new GetTextReader($this->input);
}
// if this is still null here, we abort
if ($this->l10n === null) {
throw new \Exception(
"Could not create CoreLibs\Language\Core\GetTextReader object",
E_USER_ERROR
);
}
return $this->l10n;
}
@@ -673,6 +679,7 @@ class L10n
// fallback passthrough
if ($this->l10n === null) {
echo $text;
return;
}
echo $this->l10n->translate($text);
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* AUTOR: Clemens Schwaighofer
* CREATED: 2023/5/29
* DESCRIPTION:
* Logging options flags for output file name building
*
* per_run: and timestamp + uid will be added
* per_date: ymd will be added (per_run > per_date, cannot be used at the same time)
* per_group: for debug level, group per group id (old level)
* per_page: per file name logging
* per_class: log per class
* per_level: per logging level file split
*/
declare(strict_types=1);
namespace CoreLibs\Logging\Logger;
enum Flag: int
{
/** all off flag */
case all_off = 0;
/** write per run */
case per_run = 1;
/** write per date */
case per_date = 2;
/** was PER_LEVEL, write per group id (debug) */
case per_group = 4;
/** write per page (filename) */
case per_page = 8;
/** write per class */
case per_class = 16;
/** write per log level name */
case per_level = 32;
/**
* get internal name from string value
*
* @param non-empty-string $name
* @return self
*/
public static function fromName(string $name): self
{
return match ($name) {
'Run', 'run', 'per_run', 'PER_RUN' => self::per_run,
'Date', 'date', 'per_date', 'PER_DATE' => self::per_date,
'Group', 'group', 'per_group', 'PER_GROUP' => self::per_group,
'Page', 'page', 'per_page', 'PER_PAGE' => self::per_page,
'Class', 'class', 'per_class', 'PER_CLASS' => self::per_class,
'Level', 'level', 'per_level', 'PER_LEVEL' => self::per_level,
default => self::all_off,
};
}
/**
* Get internal name from int value
*
* @param int $value
* @return self
*/
public static function fromValue(int $value): self
{
return self::from($value);
}
/**
* convert current set level to name (upper case)
*
* @return string
*/
public function getName(): string
{
return strtoupper($this->name);
}
/** @var int[] */
public const VALUES = [
0,
1,
2,
4,
8,
16,
32,
];
/** @var string[] */
public const NAMES = [
'ALL_OFF',
'PER_RUN',
'PER_DATE',
'PER_GROUP',
'PER_PAGE',
'PER_CLASS',
'PER_LEVEL',
];
}
// __END__

View File

@@ -0,0 +1,216 @@
<?php // phpcs:disable Generic.Files.LineLength
/**
* AUTOR: Clemens Schwaighofer
* CREATED: 2023-05-25
* DESCRIPTION:
* Debug levels
*
* They are based on the Mono log ones
* FC 5424 {@see https://datatracker.ietf.org/doc/html/rfc5424}
*/
declare(strict_types=1);
namespace CoreLibs\Logging\Logger;
use Psr\Log\LogLevel;
/**
* Represents the log levels
*
* Monolog supports the logging levels described by RFC 5424 {@see https://datatracker.ietf.org/doc/html/rfc5424}
* but due to BC the severity values used internally are not 0-7.
*
* To get the level name/value out of a Level there are several options:
*
* - Use ->getName() to get the standard Monolog name which is full uppercased (e.g. "DEBUG")
* - Use ->toPsrLogLevel() to get the standard PSR-3 name which is full lowercased (e.g. "debug")
* - Use ->toRFC5424Level() to get the standard RFC 5424 value (e.g. 7 for debug, 0 for emergency)
* - Use ->name to get the enum case's name which is capitalized (e.g. "Debug")
*
* To get the internal value for filtering, if the includes/isLowerThan/isHigherThan methods are
* not enough, you can use ->value to get the enum case's integer value.
*/
enum Level: int
{
/**
* Detailed debug information
*/
case Debug = 100;
/**
* Interesting events
*
* Examples: User logs in, SQL logs.
*/
case Info = 200;
/**
* Uncommon events
*/
case Notice = 250;
/**
* Exceptional occurrences that are not errors
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*/
case Warning = 300;
/**
* Runtime errors
*/
case Error = 400;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception.
*/
case Critical = 500;
/**
* Action must be taken immediately
*
* Example: Entire website down, database unavailable, etc.
* This should trigger the SMS alerts and wake you up.
*/
case Alert = 550;
/**
* Urgent alert.
*/
case Emergency = 600;
/**
* @param value-of<self::NAMES>|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name
* @return static
*/
public static function fromName(string $name): self
{
return match ($name) {
'debug', 'Debug', 'DEBUG' => self::Debug,
'info', 'Info', 'INFO' => self::Info,
'notice', 'Notice', 'NOTICE' => self::Notice,
'warning', 'Warning', 'WARNING' => self::Warning,
'error', 'Error', 'ERROR' => self::Error,
'critical', 'Critical', 'CRITICAL' => self::Critical,
'alert', 'Alert', 'ALERT' => self::Alert,
'emergency', 'Emergency', 'EMERGENCY' => self::Emergency,
};
}
/**
* @param value-of<self::VALUES> $value
* @return static
*/
public static function fromValue(int $value): self
{
return self::from($value);
}
/**
* Returns true if the passed $level is higher or equal to $this
*/
public function includes(Level $level): bool
{
return $this->value <= $level->value;
}
public function isHigherThan(Level $level): bool
{
return $this->value > $level->value;
}
public function isLowerThan(Level $level): bool
{
return $this->value < $level->value;
}
/**
* Returns the monolog standardized all-capitals name of the level
*
* Use this instead of $level->name which returns the enum case name (e.g. Debug vs DEBUG if you use getName())
*
* @phan-suppress-next-line PhanTypeMismatchDeclaredReturn
* @return value-of<self::NAMES>
*/
public function getName(): string
{
return match ($this) {
self::Debug => 'DEBUG',
self::Info => 'INFO',
self::Notice => 'NOTICE',
self::Warning => 'WARNING',
self::Error => 'ERROR',
self::Critical => 'CRITICAL',
self::Alert => 'ALERT',
self::Emergency => 'EMERGENCY',
};
}
/**
* Returns the PSR-3 level matching this instance
*
* @phpstan-return \Psr\Log\LogLevel::*
*/
public function toPsrLogLevel(): string
{
return match ($this) {
self::Debug => LogLevel::DEBUG,
self::Info => LogLevel::INFO,
self::Notice => LogLevel::NOTICE,
self::Warning => LogLevel::WARNING,
self::Error => LogLevel::ERROR,
self::Critical => LogLevel::CRITICAL,
self::Alert => LogLevel::ALERT,
self::Emergency => LogLevel::EMERGENCY,
};
}
/**
* Returns the RFC 5424 level matching this instance
*
* @phpstan-return int<0, 7>
*/
public function toRFC5424Level(): int
{
return match ($this) {
self::Debug => 7,
self::Info => 6,
self::Notice => 5,
self::Warning => 4,
self::Error => 3,
self::Critical => 2,
self::Alert => 1,
self::Emergency => 0,
};
}
public const VALUES = [
100,
200,
250,
300,
400,
500,
550,
600,
];
public const NAMES = [
'DEBUG',
'INFO',
'NOTICE',
'WARNING',
'ERROR',
'CRITICAL',
'ALERT',
'EMERGENCY',
];
}
// __END__

File diff suppressed because it is too large Load Diff

View File

@@ -219,96 +219,97 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form;
use CoreLibs\Get\System;
use CoreLibs\Debug\Support;
class Generate extends \CoreLibs\DB\Extended\ArrayIO
{
// for the load statetment describes which elements from
// the load query should be shown and i which format
/** @var array<mixed> */
public $field_array = [];
public array $field_array = [];
/** @var string */
public $load_query; // the query needed for loading a data set (one row in the table)
public string $load_query; // the query needed for loading a data set (one row in the table)
/** @var string */
public $col_name; // the name of the columen (before _<type>) [used for order button]
public string $col_name; // the name of the columen (before _<type>) [used for order button]
/** @var int */
public $yes; // the yes flag that triggers the template to show ALL and not only new/load
public int $yes; // the yes flag that triggers the template to show ALL and not only new/load
/** @var string */
public $msg; // the error msg
public string $msg; // the error msg
/** @var int */
public $error; // the error flag set for printing red error msg
public int $error; // the error flag set for printing red error msg
/** @var int */
public $warning; // warning flag, for information (saved, loaded, etc)
public int $warning; // warning flag, for information (saved, loaded, etc)
/** @var string */
public $archive_pk_name; // the pk name for the load select form
public string $archive_pk_name; // the pk name for the load select form
/** @var string */
private $int_pk_name; // primary key, only internal usage
private string $int_pk_name; // primary key, only internal usage
/** @var array<mixed> */
public $reference_array = []; // reference arrays -> stored in $this->reference_array[$table_name] => [];
public array $reference_array = []; // reference arrays -> stored in $this->reference_array[$table_name] => [];
// NOTE: should be changed to this @var mixed[]
/** @var array<mixed> */
public $element_list; // element list for elements next to each other as a special sub group
public array $element_list; // element list for elements next to each other as a special sub group
/** @var array<mixed> */
public $table_array = [];
public array $table_array = [];
/** @var string */
public $my_page_name; // the name of the page without .php extension
public string $my_page_name; // the name of the page without .php extension
/** @var bool */
public $mobile_phone = false;
public bool $mobile_phone = false;
/** @var string */
public $email_regex;
public string $email_regex;
// buttons and checkboxes
/** @var string */
public $archive;
public string $archive;
/** @var string */
public $new;
public string $new;
/** @var string */
public $really_new;
public string $really_new;
/** @var string */
public $delete;
public string $delete;
/** @var string */
public $really_delete;
public string $really_delete;
/** @var string */
public $save;
public string $save;
/** @var string */
public $remove_button;
public string $remove_button;
// security values
/** @var int base acl for current page */
private $base_acl_level = 0;
private int $base_acl_level = 0;
/** @var int admin master flag (1/0) */
private $acl_admin = 0;
private int $acl_admin = 0;
/** @var array<mixed> */
public $security_level;
public array $security_level;
/** @var array<string,mixed> Login ACL */
public $login_acl = [];
public array $login_acl = [];
// layout publics
/** @var int */
public $table_width;
public int $table_width;
// internal lang & encoding vars
/** @var string */
public $lang_dir = '';
public string $lang_dir = '';
/** @var string */
public $lang;
public string $lang;
/** @var string */
public $lang_short;
public string $lang_short;
/** @var string */
public $domain;
public string $domain;
/** @var string */
public $encoding;
public string $encoding;
// language
/** @var \CoreLibs\Language\L10n */
public $l;
public \CoreLibs\Language\L10n $l;
// log
/** @var \CoreLibs\Debug\Logging */
public $log;
/** @var \CoreLibs\Logging\Logging */
public \CoreLibs\Logging\Logging $log;
// now some default error msgs (english)
/** @var array<mixed> */
public $language_array = [];
public array $language_array = [];
/**
* construct form generator
*
* @param array<mixed> $db_config db config array, mandatory
* @param \CoreLibs\Debug\Logging $log Logging class
* @param \CoreLibs\Logging\Logging $log Logging class
* @param \CoreLibs\Language\L10n $l10n l10n language class
* @param array<string,mixed> $login_acl Login ACL array,
* at least base/admin should be set
@@ -319,7 +320,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
*/
public function __construct(
array $db_config,
\CoreLibs\Debug\Logging $log,
\CoreLibs\Logging\Logging $log,
\CoreLibs\Language\L10n $l10n,
array $login_acl,
?array $table_arrays = null,
@@ -327,7 +328,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
// init logger if not set
$this->log = $log;
// don't log per class
$this->log->setLogPer('class', false);
$this->log->unsetLogFlag(\CoreLibs\Logging\Logger\Flag::per_class);
// init the language class
$this->l = $l10n;
// parse and read, legacy stuff
@@ -388,7 +389,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$this->load_query = $config_array['load_query'];
}
if (empty($this->load_query)) {
$this->log->debug('INIT ERROR', 'Missing Load Query for: ' . $this->my_page_name);
$this->log->error('Missing Load Query for: ' . $this->my_page_name);
}
$this->archive_pk_name = 'a_' . $this->pk_name;
$this->col_name = str_replace('_id', '', $this->pk_name);
@@ -485,7 +486,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
/** @var TableArrays\Interface\TableArraysInterface|false $class */
$class = new $class_string($this);
} catch (\Throwable $t) {
$this->log->debug('CLASS LOAD', 'Failed loading: ' . $class_string . ' => ' . $t->getMessage());
$this->log->critical('CLASS LOADING: Failed loading: ' . $class_string . ' => ' . $t->getMessage());
return false;
}
if (is_object($class)) {
@@ -827,7 +828,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
return $return_array;
}
if (empty($this->load_query)) {
$this->log->debug('LOAD LIST ERROR', 'Missing load list query');
$this->log->error('Missing load list query');
return $return_array;
}
@@ -2617,8 +2618,8 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
}
}
// add lost error ones
$this->log->debug('ERROR', 'P: ' . $data['prefix'] . ', '
. $this->log->prAr($_POST['ERROR'][$data['prefix']] ?? []));
$this->log->error('P: ' . $data['prefix'] . ', '
. Support::prAr($_POST['ERROR'][$data['prefix']] ?? []));
if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) {
$prfx = $data['prefix']; // short
$_post_data = [];

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditAccess implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditGroups implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditLanguages implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditMenuGroup implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditPages implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditSchemas implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditUsers implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -7,7 +7,7 @@ namespace CoreLibs\Output\Form\TableArrays;
class EditVisibleGroup implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
private \CoreLibs\Output\Form\Generate $form;
/**
* constructor

View File

@@ -23,13 +23,13 @@ class ProgressBar
// private vars
/** @var string */
public $code; // unique code
public string $code; // unique code
/** @var string */
public $status = 'new'; // current status (new,show,hide)
public string $status = 'new'; // current status (new,show,hide)
/** @var float|int */
public $step = 0; // current step
public float|int $step = 0; // current step
/** @var array<string,null|int|float> */
public $position = [ // current bar position
public array $position = [ // current bar position
'left' => null,
'top' => null,
'width' => null,
@@ -37,43 +37,43 @@ class ProgressBar
];
/** @var int */
public $clear_buffer_size = 1; // we need to send this before the lfush to get browser output
public int $clear_buffer_size = 1; // we need to send this before the lfush to get browser output
/** @var int */
public $clear_buffer_size_init = 1024 * 1024; // if I don't send that junk, it won't send anything
public int $clear_buffer_size_init = 1024 * 1024; // if I don't send that junk, it won't send anything
// public vars
/** @var int */
public $min = 0; // minimal steps
public int $min = 0; // minimal steps
/** @var int */
public $max = 100; // maximal steps
public int $max = 100; // maximal steps
/** @var int */
public $left = 5; // bar position from left
public int $left = 5; // bar position from left
/** @var int */
public $top = 5; // bar position from top
public int $top = 5; // bar position from top
/** @var int */
public $width = 300; // bar width
public int $width = 300; // bar width
/** @var int */
public $height = 25; // bar height
public int $height = 25; // bar height
/** @var int */
public $pedding = 0; // bar pedding
public int $pedding = 0; // bar pedding
/** @var string */
public $color = '#0033ff'; // bar color
public string $color = '#0033ff'; // bar color
/** @var string */
public $bgr_color = '#c0c0c0'; // bar background color
public string $bgr_color = '#c0c0c0'; // bar background color
/** @var string */
public $bgr_color_master = '#ffffff'; // master div background color
public string $bgr_color_master = '#ffffff'; // master div background color
/** @var int */
public $border = 1; // bar border width
public int $border = 1; // bar border width
/** @var string */
public $brd_color = '#000000'; // bar border color
public string $brd_color = '#000000'; // bar border color
/** @var string */
public $direction = 'right'; // direction of motion (right,left,up,down)
public string $direction = 'right'; // direction of motion (right,left,up,down)
/** @var array<string,string|bool|int> */
public $frame = ['show' => false]; // ProgressBar Frame
public array $frame = ['show' => false]; // ProgressBar Frame
/* 'show' => false, # frame show (true/false)
'left' => 200, # frame position from left
'top' => 100, # frame position from top
@@ -86,7 +86,7 @@ class ProgressBar
/** @#var array{string}{string: string|int} */
/** @var mixed[][] */
public $label = []; // ProgressBar Labels
public array $label = []; // ProgressBar Labels
/* 'name' => [ # label name
'type' => 'text', # label type (text,button,step,percent,crossbar)
'value' => 'Please wait ...', # label value
@@ -105,7 +105,7 @@ class ProgressBar
/** @var string */
// output strings
public $prefix_message = '';
public string $prefix_message = '';
/**
* progress bar constructor

View File

@@ -2,7 +2,9 @@
/**
* very simple symmetric encryption
* Better use: https://paragonie.com/project/halite
* Better use:
* https://paragonie.com/project/halite
* https://github.com/paragonie/halite
*
* current code is just to encrypt and decrypt
*

View File

@@ -24,134 +24,132 @@ class SmartyExtend extends \Smarty
{
// internal translation engine
/** @var \CoreLibs\Language\L10n */
public $l10n;
public \CoreLibs\Language\L10n $l10n;
// lang & encoding
/** @var string */
public $lang_dir = '';
public string $lang_dir = '';
/** @var string */
public $lang;
public string $lang;
/** @var string */
public $locale_set;
public string $lang_short;
/** @var string */
public $lang_short;
public string $domain;
/** @var string */
public $domain;
/** @var string */
public $encoding;
public string $encoding;
// page name
/** @var string */
public $page_name;
public string $page_name;
// array for data parsing
/** @var array<mixed> */
public $HEADER = [];
public array $HEADER = [];
/** @var array<mixed> */
public $DATA = [];
public array $DATA = [];
/** @var array<mixed> */
public $DEBUG_DATA = [];
public array $DEBUG_DATA = [];
/** @var array<mixed> */
private $CONTENT_DATA = [];
private array $CONTENT_DATA = [];
// control vars
/** @var bool */
public $USE_PROTOTYPE = USE_PROTOTYPE;
public bool $USE_PROTOTYPE = USE_PROTOTYPE;
/** @var bool */
public $USE_JQUERY = USE_JQUERY;
public bool $USE_JQUERY = USE_JQUERY;
/** @var bool */
public $USE_SCRIPTACULOUS = USE_SCRIPTACULOUS;
public bool $USE_SCRIPTACULOUS = USE_SCRIPTACULOUS;
// sub content input vars
/** @var bool */
public $USE_TINY_MCE = false;
public bool $USE_TINY_MCE = false;
/** @var bool */
public $JS_DATEPICKR = false;
public bool $JS_DATEPICKR = false;
/** @var bool */
public $JS_FLATPICKR = false;
public bool $JS_FLATPICKR = false;
/** @var bool */
public $JS_FILE_UPLOADER = false;
public bool $JS_FILE_UPLOADER = false;
/** @var bool */
public $DEBUG_TMPL = false;
public bool $DEBUG_TMPL = false;
/** @var bool */
public $USE_INCLUDE_TEMPLATE = false;
public bool $USE_INCLUDE_TEMPLATE = false;
// cache & compile
/** @var string */
public $CACHE_ID = '';
public string $CACHE_ID = '';
/** @var string */
public $COMPILE_ID = '';
public string $COMPILE_ID = '';
// template vars
/** @var string */
public $MASTER_TEMPLATE_NAME;
public string $MASTER_TEMPLATE_NAME;
/** @var string */
public $PAGE_FILE_NAME;
public string $PAGE_FILE_NAME;
/** @var string */
public $CONTENT_INCLUDE;
public string $CONTENT_INCLUDE;
/** @var string */
public $FORM_NAME;
public string $FORM_NAME;
/** @var string */
public $FORM_ACTION;
public string $FORM_ACTION;
/** @var string */
public $L_TITLE;
public string $L_TITLE;
/** @var string|int */
public $PAGE_WIDTH;
public string|int $PAGE_WIDTH;
// smarty include/set var
/** @var string */
public $TEMPLATE_PATH;
public string $TEMPLATE_PATH;
/** @var string */
public $TEMPLATE_NAME;
public string $TEMPLATE_NAME;
/** @var string */
public $INC_TEMPLATE_NAME;
public string $INC_TEMPLATE_NAME;
/** @var string */
public $JS_TEMPLATE_NAME;
public string $JS_TEMPLATE_NAME;
/** @var string */
public $CSS_TEMPLATE_NAME;
public string $CSS_TEMPLATE_NAME;
/** @var string|null */
public $TEMPLATE_TRANSLATE;
public string|null $TEMPLATE_TRANSLATE;
/** @var string|null */
public $JS_TRANSLATE;
public string|null $JS_TRANSLATE;
// core group
/** @var string */
public $JS_CORE_TEMPLATE_NAME;
public string $JS_CORE_TEMPLATE_NAME;
/** @var string */
public $CSS_CORE_TEMPLATE_NAME;
public string $CSS_CORE_TEMPLATE_NAME;
/** @var string */
public $JS_CORE_INCLUDE;
public string $JS_CORE_INCLUDE;
/** @var string */
public $CSS_CORE_INCLUDE;
public string $CSS_CORE_INCLUDE;
// local names
/** @var string */
public $JS_SPECIAL_TEMPLATE_NAME = '';
public string $JS_SPECIAL_TEMPLATE_NAME = '';
/** @var string */
public $CSS_SPECIAL_TEMPLATE_NAME = '';
public string $CSS_SPECIAL_TEMPLATE_NAME = '';
/** @var string */
public $JS_INCLUDE;
public string $JS_INCLUDE;
/** @var string */
public $CSS_INCLUDE;
public string $CSS_INCLUDE;
/** @var string */
public $JS_SPECIAL_INCLUDE;
public string $JS_SPECIAL_INCLUDE;
/** @var string */
public $CSS_SPECIAL_INCLUDE;
public string $CSS_SPECIAL_INCLUDE;
/** @var string */
public $ADMIN_JAVASCRIPT;
public string $ADMIN_JAVASCRIPT;
/** @var string */
public $ADMIN_STYLESHEET;
public string $ADMIN_STYLESHEET;
/** @var string */
public $FRONTEND_JAVASCRIPT;
public string $FRONTEND_JAVASCRIPT;
/** @var string */
public $FRONTEND_STYLESHEET;
public string $FRONTEND_STYLESHEET;
// other smarty folder vars
/** @var string */
public $INCLUDES;
public string $INCLUDES;
/** @var string */
public $JAVASCRIPT;
public string $JAVASCRIPT;
/** @var string */
public $CSS;
public string $CSS;
/** @var string */
public $FONT;
public string $FONT;
/** @var string */
public $PICTURES;
public string $PICTURES;
/** @var string */
public $CACHE_PICTURES;
public string $CACHE_PICTURES;
/** @var string */
public $CACHE_PICTURES_ROOT;
public string $CACHE_PICTURES_ROOT;
// constructor class, just sets the language stuff
/**
@@ -222,6 +220,7 @@ class SmartyExtend extends \Smarty
// core CS
$this->CSS_CORE_INCLUDE = '';
if (
!empty($this->CSS_CORE_TEMPLATE_NAME) &&
file_exists($this->CSS . $this->CSS_CORE_TEMPLATE_NAME) &&
is_file($this->CSS . $this->CSS_CORE_TEMPLATE_NAME)
) {
@@ -230,6 +229,7 @@ class SmartyExtend extends \Smarty
// core JS
$this->JS_CORE_INCLUDE = '';
if (
!empty($this->JS_CORE_TEMPLATE_NAME) &&
file_exists($this->JAVASCRIPT . $this->JS_CORE_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT . $this->JS_CORE_TEMPLATE_NAME)
) {
@@ -398,7 +398,7 @@ class SmartyExtend extends \Smarty
// javascript translate data as template for auto translate
if (empty($this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = 'jsTranslate-'
. $this->locale_set . '.' . $this->encoding
. $this->l10n->getLocaleSet() . '.' . $this->encoding
. '.tpl';
} else {
// we assume we have some fixed set
@@ -408,12 +408,12 @@ class SmartyExtend extends \Smarty
if (strpos($this->TEMPLATE_TRANSLATE, '.tpl')) {
$this->TEMPLATE_TRANSLATE = str_replace(
'.tpl',
'-' . $this->locale_set . '.' . $this->encoding . '.tpl',
'-' . $this->l10n->getLocaleSet() . '.' . $this->encoding . '.tpl',
$this->TEMPLATE_TRANSLATE
);
} else {
$this->TEMPLATE_TRANSLATE .= '-'
. $this->locale_set . '.' . $this->encoding
. $this->l10n->getLocaleSet() . '.' . $this->encoding
. '.tpl';
}
}
@@ -423,7 +423,7 @@ class SmartyExtend extends \Smarty
}
if (empty($this->JS_TRANSLATE)) {
$this->JS_TRANSLATE = 'translate-'
. $this->locale_set . '.' . $this->encoding . '.js';
. $this->l10n->getLocaleSet() . '.' . $this->encoding . '.js';
} else {
// we assume we have some fixed set
// we must add _<locale>.<encoding>
@@ -432,12 +432,12 @@ class SmartyExtend extends \Smarty
if (strpos($this->JS_TRANSLATE, '.js')) {
$this->JS_TRANSLATE = str_replace(
'.js',
'-' . $this->locale_set . '.' . $this->encoding . '.js',
'-' . $this->l10n->getLocaleSet() . '.' . $this->encoding . '.js',
$this->JS_TRANSLATE
);
} else {
$this->JS_TRANSLATE .= '-'
. $this->locale_set . '.' . $this->encoding
. $this->l10n->getLocaleSet() . '.' . $this->encoding
. '.js';
}
}
@@ -675,10 +675,12 @@ class SmartyExtend extends \Smarty
$this->HEADER['DEFAULT_ENCODING'] = $set_default_encoding;
// form name
$this->DATA['FORM_NAME'] = !$this->FORM_NAME ?
$this->DATA['FORM_NAME'] = empty($this->FORM_NAME) ?
str_replace('.php', '', $this->page_name) :
$this->FORM_NAME;
$this->DATA['FORM_ACTION'] = $this->FORM_ACTION;
$this->DATA['FORM_ACTION'] = empty($this->FORM_ACTION) ?
'' :
$this->FORM_ACTION;
// special for admin
if ($admin_call === true) {
// depreacte call globals cms on null 4mcs
@@ -735,7 +737,7 @@ class SmartyExtend extends \Smarty
}
// html title
// set local page title
$this->HEADER['HTML_TITLE'] = !$this->L_TITLE ?
$this->HEADER['HTML_TITLE'] = empty($this->L_TITLE) ?
ucfirst(str_replace('_', ' ', \CoreLibs\Get\System::getPageName(1)))
. (!empty($set_g_title) ? '-' . $this->l10n->__($set_g_title) : '') :
$this->l10n->__($this->L_TITLE);

View File

@@ -68,13 +68,10 @@ final class CoreLibsACLLoginTest extends TestCase
// logger is always needed
// define basic connection set valid and one invalid
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-ACL-Login-Test',
'debug_all' => true,
'echo_all' => false,
'print_all' => true,
'log_file_id' => 'CoreLibs-ACL-Login-Test',
]);
// test database we need to connect do, if not possible this test is skipped
self::$db = new \CoreLibs\DB\IO(

View File

@@ -22,12 +22,9 @@ final class CoreLibsCreateEmailTest extends TestCase
*/
public static function setUpBeforeClass(): void
{
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-Create-Email-Test',
'debug_all' => true,
'echo_all' => false,
'print_all' => true,
'log_file_id' => 'CoreLibs-Create-Email-Test',
]);
}
@@ -624,7 +621,7 @@ final class CoreLibsCreateEmailTest extends TestCase
// force new set for each run
self::$log->setLogUniqueId(true);
// set on of unique log id
self::$log->setLogPer('run', true);
self::$log->setLogFlag(\CoreLibs\Logging\Logger\Flag::per_run);
// init logger
$status = \CoreLibs\Create\Email::sendEmail(
$subject,
@@ -646,7 +643,9 @@ final class CoreLibsCreateEmailTest extends TestCase
// assert content: must load JSON from log file
if ($status == 2) {
// open file, get last entry with 'SEND EMAIL JSON' key
$file = file_get_contents(self::$log->getLogFileName());
$file = file_get_contents(
self::$log->getLogFolder() . self::$log->getLogFile()
);
if ($file !== false) {
// extract SEND EMAIL JSON line
$found = preg_match_all("/^.* <SEND EMAIL JSON> - (.*)$/m", $file, $matches);

View File

@@ -21,45 +21,83 @@ final class CoreLibsCreateUidsTest extends TestCase
public function uniqIdProvider(): array
{
return [
// number length
'too short' => [
0 => 1,
1 => 4,
2 => null
],
'valid length: 10' => [
0 => 10,
1 => 10,
2 => null
],
'valid length: 9, auto length' => [
0 => 9,
1 => 8,
2 => null
],
'valid length: 9, force length' => [
0 => 9,
1 => 9,
2 => true,
],
'very long: 512' => [
0 => 512,
1 => 512,
2 => null
],
// below is all legacy
'md5 hash' => [
0 => 'md5',
1 => 32,
2 => null
],
'sha256 hash' => [
0 => 'sha256',
1 => 64
1 => 64,
2 => null
],
'ripemd160 hash' => [
0 => 'ripemd160',
1 => 40
1 => 40,
2 => null
],
'adler32 hash' => [
0 => 'adler32',
1 => 8
1 => 8,
2 => null
],
'not in list hash but valid' => [
'not in list, set default length' => [
0 => 'sha3-512',
1 => strlen(hash('sha3-512', 'A'))
1 => 64,
2 => null
],
'default hash not set' => [
0 => null,
1 => 64,
2 => null
],
'invalid name' => [
0 => 'iamnotavalidhash',
1 => 64,
2 => null
],
'auto: ' . \CoreLibs\Create\Uids::DEFAULT_HASH => [
0 => \CoreLibs\Create\Uids::DEFAULT_HASH,
1 => strlen(hash(\CoreLibs\Create\Uids::DEFAULT_HASH, 'A'))
// auto calls
'auto: ' . \CoreLibs\Create\Uids::DEFAULT_UNNIQ_ID_LENGTH => [
0 => \CoreLibs\Create\Uids::DEFAULT_UNNIQ_ID_LENGTH,
1 => 64,
2 => null
],
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_LONG => [
0 => \CoreLibs\Create\Uids::STANDARD_HASH_LONG,
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A'))
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A')),
2 => null
],
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_SHORT => [
0 => \CoreLibs\Create\Uids::STANDARD_HASH_SHORT,
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_SHORT, 'A'))
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_SHORT, 'A')),
2 => null
],
];
}
@@ -105,25 +143,26 @@ final class CoreLibsCreateUidsTest extends TestCase
*
* @covers ::uniqId
* @dataProvider uniqIdProvider
* @testdox uniqId $input will be length $expected [$_dataName]
* @testdox uniqId $input will be length $expected (Force $flag) [$_dataName]
*
* @param string|null $input
* @param int|string|null $input
* @param string $expected
* @param bool|null $flag
* @return void
*/
public function testUniqId(?string $input, int $expected): void
public function testUniqId(int|string|null $input, int $expected, ?bool $flag): void
{
if ($input === null) {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqId())
);
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId());
} elseif ($flag === null) {
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId($input));
} else {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqId($input))
);
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId($input, $flag));
}
$this->assertEquals(
$expected,
$uniq_id_length
);
}
/**

View File

@@ -132,13 +132,10 @@ final class CoreLibsDBIOTest extends TestCase
);
}
// define basic connection set valid and one invalid
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-DB-IO-Test',
'debug_all' => false,
'echo_all' => false,
'print_all' => false,
'log_file_id' => 'CoreLibs-DB-IO-Test',
]);
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],

View File

@@ -10,12 +10,13 @@ use PHPUnit\Framework\TestCase;
/**
* Test class for Debug\Logging
* @coversDefaultClass \CoreLibs\Debug\Logging
* @testdox \CoreLibs\Debug\Logging method tests
* @coversDefaultClass \CoreLibs\Debug\LoggingLegacy
* @testdox \CoreLibs\Debug\LoggingLegacy method tests
*/
final class CoreLibsDebugLoggingTest extends TestCase
final class CoreLibsDebugLoggingLegacyTest extends TestCase
{
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
/**
* test set for options BASIC
*
@@ -24,7 +25,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
* 1: expected
* 2: override
* override:
* - constant for COSNTANTS
* - constant for CONSTANTS
* - global for _GLOBALS
*
* @return array
@@ -138,7 +139,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// reset error handler
restore_error_handler();
// check that settings match
@@ -308,7 +309,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// reset error handler
restore_error_handler();
// check current
@@ -385,7 +386,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogLevelAll',
'log_folder' => self::LOG_FOLDER
]);
@@ -510,7 +511,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
$expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogLevel',
'log_folder' => self::LOG_FOLDER
]);
@@ -592,7 +593,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogPer',
'log_folder' => self::LOG_FOLDER
]);
@@ -624,7 +625,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
public function testSetGetLogPrintFileDate(bool $input, bool $expected_set, bool $expected_get): void
{
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogPrintFileDate',
'log_folder' => self::LOG_FOLDER
]);
@@ -693,7 +694,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
*/
public function testPrAr(array $input, string $expected): void
{
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testPrAr',
'log_folder' => self::LOG_FOLDER
]);
@@ -757,7 +758,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
*/
public function testPrBl(bool $input, ?string $true, ?string $false, string $expected): void
{
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testPrBl',
'log_folder' => self::LOG_FOLDER
]);
@@ -932,7 +933,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// remove any files named /tmp/error_log_TestDebug*.log
array_map('unlink', glob($options['log_folder'] . 'error_msg_' . $options['file_id'] . '*.log'));
// init logger
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// * debug (A/B)
// NULL check for strip/prefix
$this->assertEquals(
@@ -1046,13 +1047,13 @@ final class CoreLibsDebugLoggingTest extends TestCase
public function testLogUniqueId(bool $option, bool $override): void
{
if ($option === true) {
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER,
'per_run' => $option
]);
} else {
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER
]);

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Debug\Support;
/**
* Test class for Debug\Support
@@ -40,6 +41,32 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printTime
* @dataProvider printTimeProvider
* @testdox printTime test with $microtime and match to regex [$_dataName]
*
* @param int|null $mircrotime
* @param string $expected
* @return void
*/
public function testPrintTime(?int $microtime, string $regex): void
{
if ($microtime === null) {
$this->assertMatchesRegularExpression(
$regex,
Support::printTime()
);
} else {
$this->assertMatchesRegularExpression(
$regex,
Support::printTime($microtime)
);
}
}
/**
* Undocumented function
*
@@ -50,18 +77,55 @@ final class CoreLibsDebugSupportTest extends TestCase
return [
'empty array' => [
0 => [],
1 => "<pre>Array\n(\n)\n</pre>"
1 => "<pre>Array\n(\n)\n</pre>",
2 => "Array\n(\n)\n",
],
'simple array' => [
0 => ['a', 'b'],
1 => "<pre>Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n</pre>"
. ")\n</pre>",
2 => "Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n",
],
];
}
/**
* Undocumented function
*
* @cover ::printAr
* @cover ::printArray
* @dataProvider printArrayProvider
* @testdox printAr/printArray $input will be $expected [$_dataName]
*
* @param array $input
* @param string $expected
* @param string $expected_strip
* @return void
*/
public function testPrintAr(array $input, string $expected, string $expected_strip): void
{
$this->assertEquals(
$expected,
Support::printAr($input),
'assert printAr'
);
$this->assertEquals(
$expected,
Support::printArray($input),
'assert printArray'
);
$this->assertEquals(
$expected_strip,
Support::prAr($input),
'assert prAr'
);
}
/**
* Undocumented function
*
@@ -73,27 +137,31 @@ final class CoreLibsDebugSupportTest extends TestCase
'true input default' => [
0 => true,
1 => [],
2 => 'true'
2 => 'true',
3 => 'true',
],
'false input default' => [
0 => false,
1 => [],
2 => 'false'
2 => 'false',
3 => 'false'
],
'false input param name' => [
0 => false,
1 => [
'name' => 'param test'
],
2 => '<b>param test</b>: false'
2 => '<b>param test</b>: false',
3 => 'false'
],
'true input param name, true override' => [
0 => true,
1 => [
'name' => 'param test',
'true' => 'ok'
'true' => 'ok',
],
2 => '<b>param test</b>: ok'
2 => '<b>param test</b>: ok',
3 => 'ok',
],
'false input param name, true override, false override' => [
0 => false,
@@ -102,11 +170,77 @@ final class CoreLibsDebugSupportTest extends TestCase
'true' => 'ok',
'false' => 'not',
],
2 => '<b>param test</b>: not'
2 => '<b>param test</b>: not',
3 => 'not'
],
];
}
/**
* Undocumented function
*
* @cover ::printBool
* @dataProvider printBoolProvider
* @testdox printBool $input will be $expected [$_dataName]
*
* @param bool $input
* @param array $params
* @param string $expected
* @param string $expected_strip
* @return void
*/
public function testPrintBool(bool $input, array $params, string $expected, string $expected_strip): void
{
if (
isset($params['name']) &&
isset($params['true']) &&
isset($params['false'])
) {
$string = Support::printBool(
$input,
$params['name'],
$params['true'],
$params['false']
);
$string_strip = Support::prBl(
$input,
$params['true'],
$params['false']
);
} elseif (isset($params['name']) && isset($params['true'])) {
$string = Support::printBool(
$input,
$params['name'],
$params['true']
);
$string_strip = Support::prBl(
$input,
$params['true'],
);
} elseif (isset($params['name'])) {
$string = Support::printBool(
$input,
$params['name']
);
$string_strip = Support::prBl(
$input
);
} else {
$string = Support::printBool($input);
$string_strip = Support::prBl($input);
}
$this->assertEquals(
$expected,
$string,
'assert printBool'
);
$this->assertEquals(
$expected_strip,
$string_strip,
'assert prBl'
);
}
/**
* Undocumented function
*
@@ -169,12 +303,10 @@ final class CoreLibsDebugSupportTest extends TestCase
'an array, no html' => [
['a', 'b'],
true,
"##HTMLPRE##"
. "Array\n(\n"
"Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n"
. "##/HTMLPRE##",
. ")\n",
],
// resource
'a resource' => [
@@ -191,6 +323,253 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printToString
* @dataProvider printToStringProvider
* @testdox printToString $input with $flag will be $expected [$_dataName]
*
* @param mixed $input anything
* @param boolean|null $flag html flag, only for string and array
* @param string $expected always string
* @return void
*/
public function testPrintToString(mixed $input, ?bool $flag, string $expected): void
{
if ($flag === null) {
// if expected starts with / and ends with / then this is a regex compare
if (
substr($expected, 0, 1) == '/' &&
substr($expected, -1, 1) == '/'
) {
$this->assertMatchesRegularExpression(
$expected,
Support::printToString($input)
);
} else {
$this->assertEquals(
$expected,
Support::printToString($input)
);
}
} else {
$this->assertEquals(
$expected,
Support::printToString($input, $flag)
);
}
}
/**
* Undocumented function
*
* @return array
*/
public function providerDumpExportVar(): array
{
return [
'string' => [
'input' => 'string',
'flag' => null,
'expected_dump' => 'string(6) "string"' . "\n",
'expected_export' => "<pre>'string'</pre>",
],
'string, no html' => [
'input' => 'string',
'flag' => true,
'expected_dump' => 'string(6) "string"' . "\n",
'expected_export' => "'string'",
],
// int
'int' => [
'input' => 6,
'flag' => null,
'expected_dump' => 'int(6)' . "\n",
'expected_export' => "<pre>6</pre>",
],
// float
'float' => [
'input' => 1.6,
'flag' => null,
'expected_dump' => 'float(1.6)' . "\n",
'expected_export' => "<pre>1.6</pre>",
],
// bool
'bool' => [
'input' => true,
'flag' => null,
'expected_dump' => 'bool(true)' . "\n",
'expected_export' => "<pre>true</pre>",
],
// array
'array' => [
'input' => ['string', true],
'flag' => null,
'expected_dump' => "array(2) {\n"
. " [0]=>\n"
. " string(6) \"string\"\n"
. " [1]=>\n"
. " bool(true)\n"
. "}\n",
'expected_export' => "<pre>array (\n"
. " 0 => 'string',\n"
. " 1 => true,\n"
. ")</pre>",
],
// more
];
}
/**
* Undocumented function
*
* @cover ::dumpVar
* @cover ::exportVar
* @dataProvider providerDumpExportVar
* @testdox dump/exportVar $input with $flag will be $expected_dump / $expected_export [$_dataName]
*
* @param mixed $input
* @param bool|null $flag
* @param string $expected_dump
* @param string $expected_export
* @return void
*/
public function testDumpExportVar(mixed $input, ?bool $flag, string $expected_dump, string $expected_export): void
{
if ($flag === null) {
$dump = Support::dumpVar($input);
$export = Support::exportVar($input);
} else {
$dump = Support::dumpVar($input, $flag);
$export = Support::exportVar($input, $flag);
}
$this->assertEquals(
$expected_dump,
$dump,
'assert dumpVar'
);
$this->assertEquals(
$expected_export,
$export,
'assert dumpVar'
);
}
/**
* Undocumented function
*
* @cover ::getCallerFileLine
* @testWith ["/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/www/vendor/phpunit/phpunit/src/Framework/TestCase.php:1608"]
* @testdox getCallerFileLine check if it returns $expected [$_dataName]
*
* @param string $expected
* @return void
*/
public function testGetCallerFileLine(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerFileLine()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethod
* @testWith ["testGetCallerMethod"]
* @testdox getCallerMethod check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerMethod(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerMethod()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethodList
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testdox getCallerMethodList check if it returns $expected [$_dataName]
*
* @param array $expected
* @return void
*/
public function testGetCallerMethodList(array $expected): void
{
$compare = Support::getCallerMethodList();
// 10: legact
// 11: direct
// 12: full call
switch (count($compare)) {
case 10:
// add nothing
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 10'
);
break;
case 11:
// add one "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 11'
);
break;
case 12:
// add two "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
array_splice(
$expected,
0,
0,
['include']
);
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 12'
);
break;
}
}
/**
* Undocumented function
*
* @cover ::getCallerClass
* @testWith ["PHPUnit\\TextUI\\Command"]
* @testdox getCallerClass check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerClass(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerClass()
);
}
/**
* Undocumented function
*
@@ -236,205 +615,6 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printTime
* @dataProvider printTimeProvider
* @testdox printTime test with $microtime and match to regex [$_dataName]
*
* @param int|null $mircrotime
* @param string $expected
* @return void
*/
public function testPrintTime(?int $microtime, string $regex): void
{
if ($microtime === null) {
$this->assertMatchesRegularExpression(
$regex,
\CoreLibs\Debug\Support::printTime()
);
} else {
$this->assertMatchesRegularExpression(
$regex,
\CoreLibs\Debug\Support::printTime($microtime)
);
}
}
/**
* Undocumented function
*
* @cover ::printAr
* @cover ::printArray
* @dataProvider printArrayProvider
* @testdox printAr/printArray $input will be $expected [$_dataName]
*
* @param array $input
* @param string $expected
* @return void
*/
public function testPrintAr(array $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printAr($input),
'assert printAr'
);
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printArray($input),
'assert printArray'
);
}
/**
* Undocumented function
*
* @cover ::printBool
* @dataProvider printBoolProvider
* @testdox printBool $input will be $expected [$_dataName]
*
* @param bool $input
* @param array $params
* @param string $expected
* @return void
*/
public function testPrintBool(bool $input, array $params, string $expected): void
{
if (
isset($params['name']) &&
isset($params['true']) &&
isset($params['false'])
) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name'],
$params['true'],
$params['false']
);
} elseif (isset($params['name']) && isset($params['true'])) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name'],
$params['true']
);
} elseif (isset($params['name'])) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name']
);
} else {
$string = \CoreLibs\Debug\Support::printBool($input);
}
$this->assertEquals(
$expected,
$string,
'assert printBool'
);
}
/**
* Undocumented function
*
* @cover ::printToString
* @dataProvider printToStringProvider
* @testdox printToString $input with $flag will be $expected [$_dataName]
*
* @param mixed $input anything
* @param boolean|null $flag html flag, only for string and array
* @param string $expected always string
* @return void
*/
public function testPrintToString(mixed $input, ?bool $flag, string $expected): void
{
if ($flag === null) {
// if expected starts with / and ends with / then this is a regex compare
if (
substr($expected, 0, 1) == '/' &&
substr($expected, -1, 1) == '/'
) {
$this->assertMatchesRegularExpression(
$expected,
\CoreLibs\Debug\Support::printToString($input)
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printToString($input)
);
}
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printToString($input, $flag)
);
}
}
/**
* Undocumented function
*
* @cover ::getCallerMethod
* @testWith ["testGetCallerMethod"]
* @testdox getCallerMethod check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerMethod(string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethod()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethodList
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"],["include", "main", "run", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testdox getCallerMethodList check if it returns $expected [$_dataName]
*
* @param array $expected
* @return void
*/
public function testGetCallerMethodList(array $expected, array $expected_group): void
{
$compare = \CoreLibs\Debug\Support::getCallerMethodList();
// if we direct call we have 10, if we call as folder we get 11
if (count($compare) == 10) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethodList(),
'assert expected 10'
);
} else {
$this->assertEquals(
$expected_group,
\CoreLibs\Debug\Support::getCallerMethodList(),
'assert expected group'
);
}
}
/**
* Undocumented function
*
* @cover ::getCallerClass
* @testWith ["PHPUnit\\TextUI\\Command"]
* @testdox getCallerClass check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerClass(string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerClass()
);
}
/**
* Undocumented function
*
@@ -453,19 +633,19 @@ final class CoreLibsDebugSupportTest extends TestCase
if ($replace === null && $flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input),
Support::debugString($input),
'assert all default'
);
} elseif ($flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace),
Support::debugString($input, $replace),
'assert flag default'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace, $flag),
Support::debugString($input, $replace, $flag),
'assert all set'
);
}

View File

@@ -67,17 +67,17 @@ final class CoreLibsGetSystemTest extends TestCase
'original set' => [
0 => null,
1 => 'NOHOST',
2 => 'NOPORT',
2 => 0,
],
'override set no port' => [
0 => 'foo.org',
1 => 'foo.org',
2 => '80'
2 => 80
],
'override set with port' => [
0 => 'foo.org:443',
1 => 'foo.org',
2 => '443'
2 => 443
]
];
}
@@ -138,10 +138,10 @@ final class CoreLibsGetSystemTest extends TestCase
*
* @param string|null $input
* @param string $expected_host
* @param string $expected_port
* @param int $expected_port
* @return void
*/
public function testGetHostNanme(?string $input, string $expected_host, string $expected_port): void
public function testGetHostNanme(?string $input, string $expected_host, int $expected_port): void
{
// print "HOSTNAME: " . $_SERVER['HTTP_HOST'] . "<br>";
// print "SERVER: " . print_r($_SERVER, true) . "\n";

View File

@@ -0,0 +1,797 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Logging\Logger\Level;
use CoreLibs\Logging\Logger\Flag;
// TODO: setLogPer test log file written matches pattern
/**
* Test class for Logging
* @coversDefaultClass \CoreLibs\Logging\Logging
* @testdox \CoreLibs\Logging\Logging method tests
*/
final class CoreLibsLoggingLoggingTest extends TestCase
{
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
private const REGEX_BASE = "\[[\d\-\s\.:]+\]\s{1}" // date
. "\[[\w\.]+(:\d+)?\]\s{1}" // host:port
. "\[[\w+\.\/]+:\d+\]\s{1}" // folder/file
. "\[\w+\]\s{1}" // run id
. "{[\w\\\\]+(::\w+)?}\s{1}"; // class
/**
* test set for options BASIC
*
* 0: options
* - null for NOT set
* 1: expected
* 2: override
* override:
* - constant for COSNTANTS
* - global for _GLOBALS
*
* @return array
*/
public function optionsProvider(): array
{
return [
'log folder set' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'log_file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// -> deprecation warning, log_folder must be set
'no log folder set' => [
'options' => [
'log_file_id' => 'testClassInit'
],
'expected' => [
'log_folder' => getcwd() . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => []
],
// -> upcoming deprecated
'file_id set but not log_file_id' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// both file_id and log_file_id set -> WARNING
'file_id and log_file_id set' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'file_id' => 'testClassInit',
'log_file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// no log file id set -> error,
'nothing set' => [
'options' => [],
'expected' => [
'log_folder' => getcwd() . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'NOHOST-0_PHPUnit-TextUI-Command',
],
'override' => []
]
];
}
/**
* init logging class
*
* @dataProvider optionsProvider
* @testdox init test [$_dataName]
*
* @param array $options
* @param array $expected
* @param array $override
* @return void
*/
public function testClassInit(array $options, array $expected, array $override): void
{
if (!empty($override['constant'])) {
foreach ($override['constant'] as $var => $value) {
if (!defined($var)) {
define($var, $value);
}
}
// for deprecated no log_folder set
// if base is defined and it does have AAASetupData set
// change the log_folder "Debug" to "AAASetupData"
if (
defined('BASE') &&
strpos(BASE, DIRECTORY_SEPARATOR . 'AAASetupData') !== false
) {
$expected['log_folder'] = str_replace(
DIRECTORY_SEPARATOR . 'Debug',
DIRECTORY_SEPARATOR . 'AAASetupData',
$expected['log_folder']
);
}
}
// if not log folder and constant set -> expect E_USER_DEPRECATION
if (!empty($override['constant']) && empty($options['log_folder'])) {
// the deprecation message
$deprecation_message = 'options: log_folder must be set. '
. 'Setting via BASE and LOG constants is deprecated';
// convert E_USER_DEPRECATED to a exception
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
// alert for log file id with globals
if (!empty($override['constant']) && empty($options['log_file_id'])) {
//
}
// alert for log file id and file id set
if (
!empty($options['log_file_id']) &&
!empty($options['file_id'])
) {
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \InvalidArgumentException($errstr, $errno);
},
E_USER_WARNING
);
$error_message = 'options: "file_id" is deprecated use: "log_file_id".';
$this->expectExceptionMessage($error_message);
$this->expectException(\InvalidArgumentException::class);
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
$this->expectException(\Exception::class);
// $error_message = 'options: both log_file_id and log_id are set at the same time, will use log_file_id';
// $this->expectExceptionMessage($error_message);
}
// empty log folder
if (empty($override['constant']) && empty($options['log_folder'])) {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Missing mandatory option: \"/");
} elseif (empty($options['log_file_id']) && !empty($options['file_id'])) {
// the deprecation message
$deprecation_message = 'options: "file_id" is deprecated use: "log_file_id".';
// convert E_USER_DEPRECATED to a exception
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Logging\Logging($options);
// reset error handler
restore_error_handler();
// check that settings match
$this->assertEquals(
$expected['log_folder'],
$log->getLogFolder(),
'log folder not matching'
);
$this->assertEquals(
$expected['log_file_id'],
$log->getLogFileId(),
'log file id not matching'
);
}
// test all setters/getters
// setLoggingLevel
// getLoggingLevel
// getJsDebug
/**
* Undocumented function
*
* @covers ::setLoggingLevel
* @covers ::getLoggingLevel
* @covers ::getJsDebug
* @testdox setLoggingLevel set/get checks
*
* @return void
*/
public function testSetLoggingLevel(): void
{
// valid that is not Debug
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Info
]);
$this->assertEquals(
Level::Info,
$log->getLoggingLevel()
);
$this->assertFalse(
$log->getJsDebug()
);
// not set, should be debug]
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
Level::Debug,
$log->getLoggingLevel()
);
$this->assertTrue(
$log->getJsDebug()
);
// invalid, should be debug, will throw excpetion too
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Option: "log_level" is not of instance \CoreLibs\Logging\Logger\Level');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => 'I'
]);
$this->assertEquals(
Level::Debug,
$log->getLoggingLevel()
);
$this->assertTrue(
$log->getJsDebug()
);
// set valid, then change
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Info
]);
$this->assertEquals(
Level::Info,
$log->getLoggingLevel()
);
$log->setLoggingLevel(Level::Notice);
$this->assertEquals(
Level::Notice,
$log->getLoggingLevel()
);
// illegal logging level
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Level \"NotGood\" is not defined, use one of: /");
$log->setLoggingLevel('NotGood');
}
// setLogFileId
// getLogFileId
/**
* Undocumented function
*
* @covers ::setLogFileId
* @covers ::getLogFileId
* @testdox setLogFileId set/get checks
*
* @return void
*/
public function testLogFileId(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogFileId',
'log_folder' => self::LOG_FOLDER
]);
// bad, keep same
$log->setLogFileId('$$##$%#$%&');
$this->assertEquals(
'testLogFileId',
$log->getLogFileId()
);
// good, change
$log->setLogFileId('validID');
$this->assertEquals(
'validID',
$log->getLogFileId()
);
// invalid on init
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessage('LogFileId: no log file id set');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => '$$$"#"#$"#$',
'log_folder' => self::LOG_FOLDER
]);
}
// setLogUniqueId
// getLogUniqueId
/**
* Undocumented function
*
* @return array
*/
public function logUniqueIdProvider(): array
{
return [
'option set' => [
'option' => true,
'override' => false,
],
'direct set' => [
'option' => false,
'override' => false,
],
'override set' => [
'option' => false,
'override' => true,
],
'option and override set' => [
'option' => false,
'override' => true,
],
];
}
/**
* Undocumented function
*
* @covers ::setLogUniqueId
* @covers ::getLogUniqueId
* @dataProvider logUniqueIdProvider
* @testdox per run log id set test: option: $option, override: $override [$_dataName]
*
* @param bool $option
* @param bool $override
* @return void
*/
public function testLogUniqueId(bool $option, bool $override): void
{
if ($option === true) {
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER,
'log_per_run' => $option
]);
} else {
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER
]);
$log->setLogUniqueId();
}
$per_run_id = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id,
'assert per log run id 1st'
);
if ($override === true) {
$log->setLogUniqueId(true);
$per_run_id_2nd = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id_2nd,
'assert per log run id 2nd'
);
$this->assertNotEquals(
$per_run_id,
$per_run_id_2nd,
'1st and 2nd don\'t match'
);
}
}
// setLogDate
// getLogDate
/**
* Undocumented function
*
* @covers ::setLogDate
* @covers ::getLogDate
* @testdox setLogDate set/get checks
*
* @return void
*/
public function testSetLogDate(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogFileId',
'log_folder' => self::LOG_FOLDER,
'log_per_date' => true,
]);
$this->assertEquals(
date('Y-m-d'),
$log->getLogDate()
);
}
// setLogFlag
// getLogFlag
// unsetLogFlag
// getLogFlags
// Logger\Flag
/**
* Undocumented function
*
* @covers Logger\Flag
* @testdox Logger\Flag enum test
*
* @return void
*/
public function testLoggerFlag(): void
{
// logger flags to check that they exist
$flags = [
'all_off' => 0,
'per_run' => 1,
'per_date' => 2,
'per_group' => 4,
'per_page' => 8,
'per_class' => 16,
'per_level' => 32,
];
// from int -> return value
foreach ($flags as $name => $value) {
$this->assertEquals(
Flag::fromName($name),
Flag::fromValue($value)
);
}
}
/**
* Undocumented function
*
* @covers ::setLogFlag
* @covers ::getLogFlag
* @covers ::unsetLogFlag
* @covers ::getLogFlags
* @testdox setLogDate set/get checks
*
* @return void
*/
public function testSetLogFlag(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFlag',
'log_folder' => self::LOG_FOLDER,
]);
// set valid log flag
$log->setLogFlag(Flag::per_run);
$this->assertTrue(
$log->getLogFlag(Flag::per_run)
);
// flags seum
$this->assertEquals(
Flag::per_run->value,
$log->getLogFlags(),
);
// unset valid log flag
$log->unsetLogFlag(Flag::per_run);
$this->assertFalse(
$log->getLogFlag(Flag::per_run)
);
// illegal Flags cannot be set, they will throw eerros onrun
// test multi set and sum is equals set
$log->setLogFlag(Flag::per_date);
$log->setLogFlag(Flag::per_group);
$this->assertEquals(
Flag::per_date->value + Flag::per_group->value,
$log->getLogFlags()
);
}
// setLogFolder
// getLogFolder
/**
* Undocumented function
*
* @covers ::setLogFolder
* @covers ::getLogFolder
* @testdox setLogFolder set/get checks, init check
*
* @return void
*/
public function testSetLogFolder(): void
{
// set to good folder
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFolder',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
self::LOG_FOLDER,
$log->getLogFolder()
);
// set to a good other folder
$log->setLogFolder(DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR);
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// good other folder with missing trailing slash
$log->setLogFolder(DIRECTORY_SEPARATOR . 'tmp');
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// a bad folder -> last good folder
$log->setLogFolder('I-am-not existing');
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// init with a bad folder
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessage('Folder: "I-am-bad" is not writeable for logging');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFolderInvalid',
'log_folder' => 'I-am-bad',
]);
}
// getLogFile (no set, only correct after log run)
// setLogMaxFileSize
// getLogMaxFileSize
/**
* Undocumented function
*
* @covers ::setLogMaxFileSize
* @covers ::getLogMaxFileSize
* @testdox setLogMaxFileSize set/get checks, init check
*
* @return void
*/
public function testSetLogMaxFileSize(): void
{
// init set to 0
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogMaxFileSize',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
0,
$log->getLogMaxFileSize()
);
// set to new, valid size
$file_size = 200 * 1024;
$valid = $log->setLogMaxFileSize($file_size);
$this->assertTrue($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
// invalid size, < 0, will be last and return false
$valid = $log->setLogMaxFileSize(-1);
$this->assertFalse($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
// too small (< MIN_LOG_MAX_FILESIZE)
$valid = $log->setLogMaxFileSize($log::MIN_LOG_MAX_FILESIZE - 1);
$this->assertFalse($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
}
// getOption (option params)
/**
* Undocumented function
*
* @covers ::getOption
* @testdox getOption checks
*
* @return void
*/
public function testGetOption(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testGetOption',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
self::LOG_FOLDER,
$log->getOption('log_folder')
);
// not found
$this->assertNull(
$log->getOption('I_do not exist')
);
}
// test all logger functions
// debug (special)
// info
// notice
// warning
// error
// critical
// alert
// emergency
/**
* Undocumented function
*
* @covers ::debug
* @testdox debug checks
*
* @return void
*/
public function testDebug(): void
{
// init logger
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testDebug',
'log_folder' => self::LOG_FOLDER,
]);
// clean all data in folder first
array_map('unlink', glob($log->getLogFolder() . $log->getLogFileId() . '*.log'));
$group_id = 'G';
$message = 'D';
$log_status = $log->debug($group_id, $message);
$this->assertTrue($log_status, 'debug write successful');
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
$log_level = $log->getLoggingLevel()->getName();
// [2023-05-30 15:51:39.36128800] [NOHOST:0]
// [www/vendor/bin/phpunit] [7b9d0747] {PHPUnit\TextUI\Command}
// <DEBUG:G> D
$this->assertMatchesRegularExpression(
"/" . self::REGEX_BASE
. "<$log_level:$group_id>\s{1}" // log level / group id
. "$message" // message
. "/",
$file_content
);
}
public function providerLoggingLevelWrite(): array
{
return [
'info' => [
'message' => 'I',
'file_id' => Level::Info->name,
'level' => Level::Info
],
'notice' => [
'message' => 'N',
'file_id' => Level::Notice->name,
'level' => Level::Notice
],
'warning' => [
'message' => 'W',
'file_id' => Level::Warning->name,
'level' => Level::Warning
],
'error' => [
'message' => 'E',
'file_id' => Level::Error->name,
'level' => Level::Error
],
'crticial' => [
'message' => 'C',
'file_id' => Level::Critical->name,
'level' => Level::Critical
],
'alert' => [
'message' => 'A',
'file_id' => Level::Alert->name,
'level' => Level::Alert
],
'emergency' => [
'message' => 'Em',
'file_id' => Level::Emergency->name,
'level' => Level::Emergency
],
];
}
/**
* Undocumented function
*
* @covers ::info
* @covers ::notice
* @covers ::warning
* @covers ::error
* @covers ::critical
* @covers ::alert
* @covers ::emergency
* @dataProvider providerLoggingLevelWrite
* @testdox logging level write checks for $level [$_dataName]
*
* @return void
*/
public function testLoggingLevelWrite(string $message, string $file_id, Level $level): void
{
// init logger
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'test' . $file_id,
'log_folder' => self::LOG_FOLDER,
'log_level' => $level,
]);
// clean all data in folder first
array_map('unlink', glob($log->getLogFolder() . $log->getLogFileId() . '*.log'));
switch ($level->value) {
case 200:
$log_status = $log->info($message);
break;
case 250:
$log_status = $log->notice($message);
break;
case 300:
$log_status = $log->warning($message);
break;
case 400:
$log_status = $log->error($message);
break;
case 500:
$log_status = $log->critical($message);
break;
case 550:
$log_status = $log->alert($message);
break;
case 600:
$log_status = $log->emergency($message);
break;
}
$this->assertTrue($log_status, 'log write successful');
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
$log_level = $log->getLoggingLevel()->getName();
$this->assertMatchesRegularExpression(
"/" . self::REGEX_BASE
. "<$log_level>\s{1}" // log level / group id
. "$message" // message
. "/",
$file_content,
'log message regex'
);
}
// deprecated calls check?
}
// __END__

View File

@@ -0,0 +1,3 @@
*log
*LOG
!.gitignore

19
www/vendor/psr/log/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2012 PHP Framework Interoperability Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

58
www/vendor/psr/log/README.md vendored Normal file
View File

@@ -0,0 +1,58 @@
PSR Log
=======
This repository holds all interfaces/classes/traits related to
[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
Note that this is not a logger of its own. It is merely an interface that
describes a logger. See the specification for more details.
Installation
------------
```bash
composer require psr/log
```
Usage
-----
If you need a logger, you can use the interface like this:
```php
<?php
use Psr\Log\LoggerInterface;
class Foo
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
try {
$this->doSomethingElse();
} catch (Exception $exception) {
$this->logger->error('Oh no!', array('exception' => $exception));
}
// do something useful
}
}
```
You can then pick one of the implementations of the interface to get a logger.
If you want to implement the interface, you can require this package and
implement `Psr\Log\LoggerInterface` in your code. Please read the
[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
for details.

26
www/vendor/psr/log/composer.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "psr/log",
"description": "Common interface for logging libraries",
"keywords": ["psr", "psr-3", "log"],
"homepage": "https://github.com/php-fig/log",
"license": "MIT",
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"require": {
"php": ">=8.0.0"
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Psr\Log;
/**
* This is a simple Logger implementation that other Loggers can inherit from.
*
* It simply delegates all log-level-specific methods to the `log` method to
* reduce boilerplate code that a simple Logger that does the same thing with
* messages regardless of the error level has to implement.
*/
abstract class AbstractLogger implements LoggerInterface
{
use LoggerTrait;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Psr\Log;
class InvalidArgumentException extends \InvalidArgumentException
{
}

18
www/vendor/psr/log/src/LogLevel.php vendored Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace Psr\Log;
/**
* Describes log levels.
*/
class LogLevel
{
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Psr\Log;
/**
* Describes a logger-aware instance.
*/
interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object.
*
* @param LoggerInterface $logger
*
* @return void
*/
public function setLogger(LoggerInterface $logger): void;
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Psr\Log;
/**
* Basic Implementation of LoggerAwareInterface.
*/
trait LoggerAwareTrait
{
/**
* The logger instance.
*
* @var LoggerInterface|null
*/
protected ?LoggerInterface $logger = null;
/**
* Sets a logger.
*
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace Psr\Log;
/**
* Describes a logger instance.
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: {foo} where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data. The only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* for the full interface specification.
*/
interface LoggerInterface
{
/**
* System is unusable.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function emergency(string|\Stringable $message, array $context = []): void;
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function alert(string|\Stringable $message, array $context = []): void;
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function critical(string|\Stringable $message, array $context = []): void;
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function error(string|\Stringable $message, array $context = []): void;
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function warning(string|\Stringable $message, array $context = []): void;
/**
* Normal but significant events.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function notice(string|\Stringable $message, array $context = []): void;
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function info(string|\Stringable $message, array $context = []): void;
/**
* Detailed debug information.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function debug(string|\Stringable $message, array $context = []): void;
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, string|\Stringable $message, array $context = []): void;
}

142
www/vendor/psr/log/src/LoggerTrait.php vendored Normal file
View File

@@ -0,0 +1,142 @@
<?php
namespace Psr\Log;
/**
* This is a simple Logger trait that classes unable to extend AbstractLogger
* (because they extend another class, etc) can include.
*
* It simply delegates all log-level-specific methods to the `log` method to
* reduce boilerplate code that a simple Logger that does the same thing with
* messages regardless of the error level has to implement.
*/
trait LoggerTrait
{
/**
* System is unusable.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function emergency(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function alert(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::ALERT, $message, $context);
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function critical(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::CRITICAL, $message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function error(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::ERROR, $message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function warning(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::WARNING, $message, $context);
}
/**
* Normal but significant events.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function notice(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::NOTICE, $message, $context);
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function info(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::INFO, $message, $context);
}
/**
* Detailed debug information.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function debug(string|\Stringable $message, array $context = []): void
{
$this->log(LogLevel::DEBUG, $message, $context);
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param array $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/
abstract public function log($level, string|\Stringable $message, array $context = []): void;
}

30
www/vendor/psr/log/src/NullLogger.php vendored Normal file
View File

@@ -0,0 +1,30 @@
<?php
namespace Psr\Log;
/**
* This Logger can be used to avoid conditional log calls.
*
* Logging should always be optional, and if no logger is provided to your
* library creating a NullLogger instance to have something to throw logs at
* is a good way to avoid littering your code with `if ($this->logger) { }`
* blocks.
*/
class NullLogger extends AbstractLogger
{
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param array $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, string|\Stringable $message, array $context = []): void
{
// noop
}
}