Compare commits

...

21 Commits

Author SHA1 Message Date
Clemens Schwaighofer
39de680b66 Extend Error Message collector print warning log 2024-09-24 15:15:23 +09:00
Clemens Schwaighofer
2e81a4da82 Release: v9.16.0 2024-09-20 13:43:20 +09:00
Clemens Schwaighofer
61782be11c Various updates as follows
* commit 5cec54d508fd4a34de509b3ac28d6277b6abc090 (HEAD -> master, all/master, all/development, all/NewFeatures)
| log size 644
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-09-20 13:33:19 +0900
|
|     Add "Success" to message logging levels, fixes for PHP 8.4, other preg_match fixes
|
|     The Logger/MessageLevel gets "success" as level 110 to something a bit
|     heigher than "ok" which is the general "OK" for anything ending without
|     an error. The "success" is currently only used in file uploads with the
|     java script ajax file uploader
|
|     Fix any "type $var = null" with correctly "?type $var = null" for PHP 8.4 (phphan)
|
|     Fix preg match no return catches for DB IO compare version and for language
|     look up.
|
|  4dev/tests/Logging/CoreLibsLoggingErrorMessagesTest.php |  5 +++++
|  www/admin/class_test.html.php                           |  1 +
|  www/admin/class_test.php                                |  2 +-
|  www/admin/layout/javascript/edit.jq.js                  |  2 +-
|  www/lib/CoreLibs/Admin/Backend.php                      |  6 +++---
|  www/lib/CoreLibs/Basic.php                              |  2 +-
|  www/lib/CoreLibs/Convert/Extends/SetVarTypeMain.php     |  6 +++---
|  www/lib/CoreLibs/Convert/SetVarTypeNull.php             |  6 +++---
|  www/lib/CoreLibs/DB/IO.php                              | 24 ++++++++++++++++++------
|  www/lib/CoreLibs/Language/GetLocale.php                 |  4 ++--
|  www/lib/CoreLibs/Logging/Logger/MessageLevel.php        |  2 ++
|  www/lib/CoreLibs/Output/Form/Elements.php               | 12 ++++++------
|  www/lib/CoreLibs/Template/HtmlBuilder/Element.php       |  4 ++--
|  13 files changed, 48 insertions(+), 28 deletions(-)
|
* commit 8e60c992f109993b40d9e5ec9354ffb7d7db9f79
| log size 123
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-09-03 12:06:01 +0900
|
|     Fixes phan/phpstan
|
|  phpstan.neon                                    | 6 +++---
|  www/lib/CoreLibs/Get/System.php                 | 2 +-
|  www/lib/CoreLibs/Template/HtmlBuilder/Block.php | 4 ----
|  3 files changed, 4 insertions(+), 8 deletions(-)
|
* commit 1b5437b675f6ceda4318f19522d47a08f28f95a8
| log size 147
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-09-03 11:58:36 +0900
|
|     Add testing for new added bom utf8 replace
|
|  4dev/tests/Convert/CoreLibsConvertStringsTest.php | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
|  4dev/tests/Convert/data/UTF8.csv                  |  1 +
|  4dev/tests/Convert/data/UTF8BOM.csv               |  1 +
|  4dev/tests/Get/CoreLibsGetSystemTest.php          | 23 +++++++++++++++++++++++
|  www/admin/class_test.system.php                   |  4 +++-
|  5 files changed, 76 insertions(+), 1 deletion(-)
|
* commit ef80cba5610b8acae8fc11d3f0a441c1f5a03735
| log size 659
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-09-03 09:49:01 +0900
|
|     Add new functions: get IPs, strip UTF8 BOM from text, text updates
|
|     Add the following new static methods
|
|     Convert\Strings::stripUTF8BomBytes: removes the UTF8 BOM bytes from the beginning of a line
|     Used for CSV files created in Excel for the first header entry (line 0/row 0)
|
|     Get\Systen::getIpAddresses: gets all IP addresses for the the current access user
|     and returns an array
|
|     Moved the frontend folder detection from the first load config to the config.path.php
|
|     Cleaned up the translations JS scripts
|
|  4dev/bin/create_mo.sh                           |  9 +++++----
|  4dev/bin/mo_to_js.sh                            | 63 +++++++++++++++++++++++++++++++++++----------------------------
|  www/configs/config.path.php                     | 16 +++++++++++++++-
|  www/configs/config.php                          | 15 +--------------
|  www/lib/CoreLibs/Convert/Strings.php            | 12 ++++++++++++
|  www/lib/CoreLibs/DB/IO.php                      |  2 +-
|  www/lib/CoreLibs/Get/System.php                 | 23 +++++++++++++++++++++++
|  www/lib/CoreLibs/Template/HtmlBuilder/Block.php | 37 ++++++++++++++++++++++++++-----------
|  8 files changed, 118 insertions(+), 59 deletions(-)
|
* commit 2d71e760e8fb7b4b0a5552a2f62bedffad928f4f
| log size 120
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-08-21 11:45:17 +0900
|
|     Composer update
|
|  www/composer.lock                          | 12 ++++++------
|  www/lib/CoreLibs/Template/SmartyExtend.php |  3 ++-
|  www/vendor/composer/installed.json         | 14 +++++++-------
|  www/vendor/composer/installed.php          |  6 +++---
|  www/vendor/gullevek/dotenv/Readme.md       | 23 +++++++++++++++++++++++
|  www/vendor/gullevek/dotenv/src/DotEnv.php  | 13 ++++++++++---
|  6 files changed, 51 insertions(+), 20 deletions(-)
|
* commit a8d07634ffaf961a37557437aac1f202ae18fa6e
| log size 182
| Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com>
| Date:   2024-08-07 13:41:09 +0900
|
|     Add soba.egplusww.jp as local development host, jshint esversion update to 11
|
|  www/admin/layout/javascript/edit.jq.js |  2 +-
|  www/configs/config.host.php            | 28 +++++++++++-----------------
|  2 files changed, 12 insertions(+), 18 deletions(-)
|
2024-09-20 13:40:20 +09:00
Clemens Schwaighofer
e7fe4655d1 Release: v9.15.0 2024-09-03 12:15:49 +09:00
Clemens Schwaighofer
561be4bce6 Update with get address method and utf8 bom replacer 2024-09-03 12:12:11 +09:00
Clemens Schwaighofer
51fef30364 Release: v9.14.0 2024-08-05 13:34:05 +09:00
Clemens Schwaighofer
89a4b4cf3e HTML::htmlent and HTML::checked method updates 2024-08-05 13:28:11 +09:00
Clemens Schwaighofer
3eb1229590 Release: v9.13.2 2024-07-29 16:34:07 +09:00
Clemens Schwaighofer
f174e9ec34 DB-IO fix for JSON/JSONB operators when checking for placeholders 2024-07-29 16:32:45 +09:00
Clemens Schwaighofer
928369cff7 Release: v9.13.1 2024-07-29 16:14:37 +09:00
Clemens Schwaighofer
29f4800e1a DB IO Placeholder regex fix for JSON/JSONB placeholders 2024-07-29 16:13:08 +09:00
Clemens Schwaighofer
e706a67427 Shellcheck updates for publish.sh script 2024-07-19 18:39:30 +09:00
Clemens Schwaighofer
672de694ee Readme file update 2024-06-18 10:00:11 +09:00
Clemens Schwaighofer
c69eac3258 Move temp folder for phpstan to local, update github actions
Note: Github actions are not used right now
2024-05-22 18:53:16 +09:00
Clemens Schwaighofer
eca62e53c9 Disabled workflow
For this to work we have to move the smarty-extended package to an official
composer package
2024-05-22 14:21:00 +09:00
Clemens Schwaighofer
62cd3badfe GitHub action update 2024-05-22 14:18:21 +09:00
Clemens Schwaighofer
4bd2568d94 composer.json file update 2024-05-22 14:15:59 +09:00
Clemens Schwaighofer
b3c7947c67 Github actions wrong folder name 2024-05-22 14:13:46 +09:00
Clemens Schwaighofer
6710f44646 GitHub action for PHPstan CI 2024-05-22 14:11:05 +09:00
Clemens Schwaighofer
f89be6bd19 Update composer publish script
check for GITEA_PUBLISH and GITLAB_PUBLISH to trigger actual publish run
2024-05-22 11:11:18 +09:00
Clemens Schwaighofer
9696336abc Release: v9.13.0 2024-05-22 11:10:30 +09:00
30 changed files with 438 additions and 105 deletions

33
.github/workflows-disabled/ci.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: CI
run-name: ${{ github.actor}} runs CI
on: [push]
jobs:
phpstan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# - uses: php-actions/composer@v6
# env:
# COMPOSER_ROOT_VERSION: dev-master
- name: "Restore result cache"
uses: actions/cache/restore@v4
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
restore-keys: |
result-cache-v1-${{ matrix.php-version }}-
- name: PHPStan Static Analysis
uses: php-actions/phpstan@v3
with:
path: src/
- name: "Save result cache"
uses: actions/cache/save@v4
if: always()
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
# - name: PHPunit Tests
# run: |
# vendor/bin/phpunit

2
.shellcheckrc Normal file
View File

@@ -0,0 +1,2 @@
shell=bash
external-sources=true

View File

@@ -9,16 +9,41 @@ For local install only
- Template\SmartyExtended
- Admin\EditBase
## Setup from central composer
## Publish to gitea or gitlab server
Setup from gitea internal servers
Currently there are only gitea and gitlab supported, github does not have support for composer packages
```sh
composer config repositories.git.egplusww.jp.Composer composer https://git.egplusww.jp/api/packages/Composer/composer
`publish\publish.sh go` will run the publish script
All the configuration is done in the `publish\.env.deploy` file
```ini
# downlaod file name is "Repository name" "-" "version" where
# version is "vN.N.N"
GITEA_PUBLISH=1
GITEA_UPLOAD_FILENAME="Upload-File-Name";
GITEA_USER=gitea-user
GITEA_TOKEN=gitea-tokek
GITEA_URL_DL=https://[gitea.hostname]/[to/package/folder]/archive
GITEA_URL_PUSH=https://[gitea.hostname]/api/packages/[organization]/composer
GITLAB_PUBLISH=1
GITLAB_URL=gitlab URl to repository
GITLAB_DEPLOY_TOKEN=gitlab-token
```
Alternative setup composer local zip file repot:
`composer config repositories.composer.egplusww.jp composer http://composer.egplusww.jp`
At the moment there is only one gitea or gitlab target setable
## Setup from central composer
Setup from gitea servers
[hostname] is the hostname for your gitea server (or wherever this is published)
[OrgName] is the organization name where the composer packages are hosted
```sh
composer config repositories.[hostname].Composer composer https://[hostname]/api/packages/[OrgName]/composer
```
## Install package

View File

@@ -21,7 +21,8 @@
},
"require-dev": {
"egrajp/smarty-extended": "^4.3",
"gullevek/dotenv": "dev-master"
"gullevek/dotenv": "dev-master",
"phpunit/phpunit": "^9"
},
"repositories": {
"git.egplusww.jp.Composer": {

View File

@@ -2,7 +2,7 @@
includes:
- phpstan-conditional.php
parameters:
tmpDir: /tmp/phpstan-corelibs-composer
tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs-composer
level: 8 # max is now 9
checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false

View File

@@ -1 +1 @@
9.12.2
9.16.0

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
PACKAGE_DOWNLOAD="${BASE_FOLDER}package-download/";
if [ ! -d "${PACKAGE_DOWNLOAD}" ]; then
mkdir "${PACKAGE_DOWNLOAD}";
@@ -15,30 +15,35 @@ if [ -z "${VERSION}" ]; then
fi;
# compare version, if different or newer, deploy
if [ -f "${file_last_published}" ]; then
LAST_PUBLISHED_VERSION=$(cat ${file_last_published});
if $(dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"); then
LAST_PUBLISHED_VERSION=$(cat "${file_last_published}");
if dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"; then
echo "git tag version ${VERSION} is not newer than previous published version ${LAST_PUBLISHED_VERSION}";
exit;
fi;
fi;
# read in the .env.deploy file and we must have
# for gitea
# GITEA_PUBLISH: must be set with a value to trigger publish run
# GITEA_UPLOAD_FILENAME
# GITLAB_USER
# GITLAB_TOKEN
# GITLAB_URL
# GITEA_USER
# GITEA_DEPLOY_TOKEN
# GITEA_URL_DL
# GITEA_URL_PUSH
# for gitlab
# GITLAB_PUBLISH: must be set with a value to trigger publish run
# GITLAB_USER
# GITLAB_TOKEN
# GITLAB_URL
if [ ! -f "${BASE_FOLDER}.env.deploy" ]; then
echo "Deploy enviroment file .env.deploy is missing";
exit;
fi;
set -o allexport;
cd ${BASE_FOLDER};
cd "${BASE_FOLDER}" || exit;
# shellcheck source=.env.deploy
source .env.deploy;
cd -;
cd - || exit;
set +o allexport;
if [ "${go_flag}" != "go" ]; then
@@ -50,37 +55,42 @@ fi;
echo "[START]";
# gitea
if [ ! -z "${GITEA_UPLOAD_FILENAME}" ] &&
[ ! -z "${GITEA_URL_DL}" ] && [ ! -z "${GITEA_URL_PUSH}" ] &&
[ ! -z "${GITEA_USER}" ] && [ ! -z "${GITEA_TOKEN}" ]; then
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
curl -LJO \
--output-dir "${PACKAGE_DOWNLOAD}" \
${GITEA_URL_DL}/v${VERSION}.zip;
fi;
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
echo "Version file does not exist for ${VERSION}";
# skip iof
if [ -n "${GITEA_PUBLISH}" ]; then
if [ -n "${GITEA_UPLOAD_FILENAME}" ] &&
[ -n "${GITEA_URL_DL}" ] && [ -n "${GITEA_URL_PUSH}" ] &&
[ -n "${GITEA_USER}" ] && [ -n "${GITEA_TOKEN}" ]; then
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
curl -LJO \
--output-dir "${PACKAGE_DOWNLOAD}" \
"${GITEA_URL_DL}"/v"${VERSION}".zip;
fi;
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
echo "Version file does not exist for ${VERSION}";
else
curl --user "${GITEA_USER}":"${GITEA_TOKEN}" \
--upload-file "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" \
"${GITEA_URL_PUSH}"?version="${VERSION}";
echo "${VERSION}" > "${file_last_published}";
fi;
else
curl --user ${GITEA_USER}:${GITEA_TOKEN} \
--upload-file "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" \
${GITEA_URL_PUSH}?version=${VERSION};
echo "${VERSION}" > "${file_last_published}";
echo "Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
fi;
else
echo "Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
fi;
# gitlab
if [ ! -z "${GITLAB_URL}" ] && [ ! -z "${GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v${VERSION} \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing GITLAB_DEPLOY_TOKEN environment variable";
if [ -n "${GITLAB_PUBLISH}" ]; then
if [ -n "${GITLAB_URL}" ] && [ -n "${GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v"${VERSION}" \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing GITLAB_URL or GITLAB_DEPLOY_TOKEN environment variable";
fi;
fi;
echo "";
echo "[DONE]";

View File

@@ -504,9 +504,9 @@ class Backend
string $data,
string $key_name,
string $key_value,
string $associate = null,
string $file = null,
string $db_schema = null,
?string $associate = null,
?string $file = null,
?string $db_schema = null,
): void {
/** @var string $DB_SCHEMA check schema */
$DB_SCHEMA = 'public';

View File

@@ -90,7 +90,7 @@ class Basic
* @deprecated DO NOT USE Class\Basic anymore. Use dedicated logger and sub classes
*/
public function __construct(
\CoreLibs\Logging\Logging $log = null,
?\CoreLibs\Logging\Logging $log = null,
?string $session_name = null
) {
trigger_error('Class \CoreLibs\Basic is deprected', E_USER_DEPRECATED);

View File

@@ -52,7 +52,7 @@ class SetVarTypeMain
*/
protected static function makeStrMain(
mixed $val,
string $default = null,
?string $default = null,
bool $to_null = false
): ?string {
// int/float/string/bool/null, everything else is ignored
@@ -113,7 +113,7 @@ class SetVarTypeMain
*/
protected static function makeIntMain(
mixed $val,
int $default = null,
?int $default = null,
bool $to_null = false
): ?int {
// if we can filter it to a valid int, we can convert it
@@ -167,7 +167,7 @@ class SetVarTypeMain
*/
protected static function makeFloatMain(
mixed $val,
float $default = null,
?float $default = null,
bool $to_null = false
): ?float {
if (

View File

@@ -16,16 +16,22 @@ class Html
/**
* full wrapper for html entities
*
* uses default params as: ENT_QUOTES | ENT_HTML5
* switches from ENT_HTML401 to ENT_HTML5 as we assume all our pages have <!DOCTYPE html>
* removed: ENT_SUBSTITUTE -> wrong characters will be replaced with space
* encodes in UTF-8
* does not double encode
*
* @param mixed $string string to html encode
* @param int $flags [default: ENT_QUOTES | ENT_HTML5]
* @return mixed if string, encoded, else as is (eg null)
*/
public static function htmlent(mixed $string): mixed
public static function htmlent(mixed $string, int $flags = ENT_QUOTES | ENT_HTML5): mixed
{
if (is_string($string)) {
return htmlentities($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
} else {
return $string;
return htmlentities($string, $flags, 'UTF-8', false);
}
return $string;
}
/**
@@ -54,14 +60,10 @@ class Html
*/
public static function checked(array|string $haystack, string $needle, int $type = 0): ?string
{
if (is_array($haystack)) {
if (in_array($needle, $haystack)) {
return $type ? 'checked' : 'selected';
}
} else {
if ($haystack == $needle) {
return $type ? 'checked' : 'selected';
}
if (is_array($haystack) && in_array($needle, $haystack)) {
return $type ? 'checked' : 'selected';
} elseif (!is_array($haystack) && $haystack == $needle) {
return $type ? 'checked' : 'selected';
}
return null;
}

View File

@@ -35,7 +35,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param string|null $default Default override value
* @return string|null Input value as string or default as string/null
*/
public static function makeStr(mixed $val, string $default = null): ?string
public static function makeStr(mixed $val, ?string $default = null): ?string
{
return SetVarTypeMain::makeStrMain($val, $default, true);
}
@@ -60,7 +60,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param int|null $default Default override value
* @return int|null Input value as int or default as int/null
*/
public static function makeInt(mixed $val, int $default = null): ?int
public static function makeInt(mixed $val, ?int $default = null): ?int
{
return SetVarTypeMain::makeIntMain($val, $default, true);
}
@@ -84,7 +84,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param float|null $default Default override value
* @return float|null Input value as float or default as float/null
*/
public static function makeFloat(mixed $val, float $default = null): ?float
public static function makeFloat(mixed $val, ?float $default = null): ?float
{
return SetVarTypeMain::makeFloatMain($val, $default, true);
}

View File

@@ -134,6 +134,18 @@ class Strings
$path
) ?? $path;
}
/**
* Remove UTF8 BOM Byte string from line
* Note: this is often found in CSV files exported from Excel at the first row, first element
*
* @param string $text
* @return string
*/
public static function stripUTF8BomBytes(string $text): string
{
return trim($text, pack('H*', 'EFBBBF'));
}
}
// __END__

View File

@@ -1324,8 +1324,12 @@ class IO
// /s for matching new line in . list
// [disabled, we don't used ^ or $] /m for multi line match
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
preg_match_all(
'/(?:\'.*?\')?\s*(?:\?\?|<>|[(=,])\s*(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s',
'/'
. '(?:\'.*?\')?\s*(?:\?\?|<>|' . $query_split . ')\s*'
. '(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
. '/s',
$query,
$match
);
@@ -1892,7 +1896,12 @@ class IO
$matches = [];
// compare has =, >, < prefix, and gets stripped
// if the rest is not X.Y format then error
preg_match("/^([<>=]{1,})(\d{1,})\.(\d{1,})/", $compare, $matches);
if (!preg_match("/^([<>=]{1,})(\d{1,})\.(\d{1,})/", $compare, $matches)) {
$this->log->error('Could not regex match compare version string', [
"compare" => $compare
]);
return false;
}
$compare = $matches[1];
$to_master = $matches[2];
$to_minor = $matches[3];
@@ -1904,11 +1913,18 @@ class IO
}
// db_version can return X.Y.Z
// we only compare the first two
preg_match(
"/^(\d{1,})\.(\d{1,})\.?(\d{1,})?/",
$this->dbVersion(),
$matches
);
if (
!preg_match(
"/^(\d{1,})\.(\d{1,})\.?(\d{1,})?/",
$this->dbVersion(),
$matches
)
) {
$this->log->error('Could not regex match dbVersion string', [
"dbVersion" => $this->dbVersion()
]);
return false;
}
$master = $matches[1];
$minor = $matches[2];
$version = $master . ($minor < 10 ? '0' : '') . $minor;
@@ -2398,7 +2414,7 @@ class IO
// flag if we have cache data stored at the moment
'cached' => false,
// when fetch array or cache read returns false
// in loop read that means dbReturn retuns false without erro
// in loop read that means dbReturn retuns false without error
'finished' => false,
// read from cache/db (pos == rows)
'read_finished' => false,

View File

@@ -39,9 +39,11 @@ class ConvertPlaceholder
): array {
$convert_to = strtolower($convert_to);
$matches = [];
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
$pattern = '/'
// prefix string part, must match towards
. '(?:\'.*?\')?\s*(?:\?\?|[(=,])\s*'
// seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
. '(?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*'
// match for replace part
. '(?:'
// digit -> ignore
@@ -96,7 +98,10 @@ class ConvertPlaceholder
$type = 'named';
$matches_return = $named_matches;
// only check for :named
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(:\w+))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(:\w+))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set
@@ -134,7 +139,10 @@ class ConvertPlaceholder
// order and data stays the same
$params_new = $params;
// only check for ?
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set
@@ -163,7 +171,10 @@ class ConvertPlaceholder
$type = 'numbered';
$matches_return = $numbered_matches;
// only check for $n
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set

View File

@@ -116,6 +116,29 @@ class System
3
) === 'cli' ? true : false;
}
/**
* Collect all IP addresses
* REMOTE_ADDR, HTTP_X_FORWARD_FOR, CLIENT_IP
* and retuns them in an array with index of io source
* if address source has addresses with "," will add "-array" with these as array block
*
* @return array<string,string|array<string>>
*/
public static function getIpAddresses(): array
{
$ip_addr = [];
foreach (['REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'CLIENT_IP'] as $_ip_source) {
if (!empty($_SERVER[$_ip_source])) {
$ip_addr[$_ip_source] = $_SERVER[$_ip_source];
// same level as ARRAY IF there is a , inside
if (strstr($_SERVER[$_ip_source], ',') !== false) {
$ip_addr[$_ip_source . '-array'] = explode(',', $_SERVER[$_ip_source]);
}
}
}
return $ip_addr;
}
}
// __END__

View File

@@ -46,7 +46,7 @@ class CachedFileReader extends \CoreLibs\Language\Core\StringReader
if (!is_resource($fd)) {
$this->error = 3; // Cannot read file, probably permissions
} else {
$this->fd_str = fread($fd, filesize($filename) ?: 0) ?: '';
$this->fd_str = fread($fd, filesize($filename) ?: 1) ?: '';
fclose($fd);
}
} else {

View File

@@ -128,7 +128,7 @@ class GetLocale
$matches
)
) {
$lang = ($matches['lang'] ?? 'en')
$lang = $matches['lang']
// add country only if set
. (!empty($matches['country']) ? '_' . $matches['country'] : '');
} else {
@@ -235,7 +235,7 @@ class GetLocale
$matches
)
) {
$lang = ($matches['lang'] ?? 'en')
$lang = $matches['lang']
// add country only if set
. (!empty($matches['country']) ? '_' . $matches['country'] : '');
} else {

View File

@@ -24,16 +24,20 @@ class ErrorMessage
/** @var bool $log_error global flag to log error level message */
private bool $log_error = false;
/** @var bool $log_warning global flat to log warning level messages */
private bool $log_warning = false;
/**
* init ErrorMessage
*
* @param \CoreLibs\Logging\Logging $log
* @param null|bool $log_error [=null], defaults to false if log is not level debug
* @param null|bool $log_warning [=null], defaults to false if log is not level debug
*/
public function __construct(
\CoreLibs\Logging\Logging $log,
?bool $log_error = null
?bool $log_error = null,
?bool $log_warning = null
) {
$this->log = $log;
// if log default logging is debug then log_error is default set to true
@@ -43,6 +47,13 @@ class ErrorMessage
$log_error = $log_error ?? false;
}
$this->log_error = $log_error;
// if log default logging is debug then log_warning is default set to true
if ($this->log->loggingLevelIsDebug() && $log_warning === null) {
$log_warning = true;
} else {
$log_warning = $log_warning ?? false;
}
$this->log_warning = $log_warning;
}
/**
@@ -81,6 +92,8 @@ class ErrorMessage
* @param array<mixed> $context Additionl info for abort/crash messages
* @param bool|null $log_error [=null] log level 'error' to error, if null use global,
* else set for this call only
* @param bool|null $log_warning [=null] log level 'warning' to warning, if null use global,
* else set for this call only
*/
public function setErrorMsg(
string $error_id,
@@ -93,10 +106,14 @@ class ErrorMessage
?string $message = null,
array $context = [],
?bool $log_error = null,
?bool $log_warning = null,
): void {
if ($log_error === null) {
$log_error = $this->log_error;
}
if ($log_warning === null) {
$log_warning = $this->log_warning;
}
$original_level = $level;
$level = MessageLevel::fromName($level)->name;
// if not string set, write message string if set, else level/error id
@@ -121,6 +138,14 @@ class ErrorMessage
'level' => $original_level,
], $context));
break;
case 'warn':
if ($log_warning) {
$this->log->warning($message ?? $str, array_merge([
'id' => $error_id,
'level' => $original_level,
], $context));
}
break;
case 'error':
if ($log_error) {
$this->log->error($message ?? $str, array_merge([
@@ -169,6 +194,8 @@ class ErrorMessage
* @param array<mixed> $context Additionl info for abort/crash messages
* @param bool|null $log_error [=null] log level 'error' to error, if null use global,
* else set for this call only
* @param bool|null $log_warning [=null] log level 'warning' to warning, if null use global,
* else set for this call only
*/
public function setMessage(
string $level,
@@ -181,6 +208,7 @@ class ErrorMessage
?string $message = null,
array $context = [],
?bool $log_error = null,
?bool $log_warning = null,
): void {
$this->setErrorMsg(
$error_id ?? '',
@@ -192,7 +220,8 @@ class ErrorMessage
$jump_target,
$message,
$context,
$log_error
$log_error,
$log_warning
);
}
@@ -314,6 +343,27 @@ class ErrorMessage
{
return $this->log_error;
}
/**
* Set the log warning flag
*
* @param bool $flag True to log level warning too, False for do not (Default)
* @return void
*/
public function setFlagLogWarning(bool $flag): void
{
$this->log_warning = $flag;
}
/**
* Get the current log error flag
*
* @return bool
*/
public function getFlagLogWarning(): bool
{
return $this->log_warning;
}
}
// __END__

View File

@@ -14,6 +14,7 @@ namespace CoreLibs\Logging\Logger;
enum MessageLevel: int
{
case ok = 100;
case success = 150; // special for file uploads
case info = 200;
case notice = 250;
case warn = 300;
@@ -30,6 +31,7 @@ enum MessageLevel: int
{
return match (strtolower($name)) {
'ok' => self::ok,
'success' => self::success,
'info' => self::info,
'notice' => self::notice,
'warn', 'warning' => self::warn,

View File

@@ -194,13 +194,13 @@ class Elements
"/(mailto:)?(\>)?\b([\w\.-]+)@([\w\.\-]+)\.([a-zA-Z]{2,4})\b(\|([^\||^#]+)(#([^\|]+))?\|)?/",
function ($matches) {
return self::createEmail(
$matches[1] ?? '',
$matches[2] ?? '',
$matches[3] ?? '',
$matches[4] ?? '',
$matches[5] ?? '',
$matches[1],
$matches[2],
$matches[3],
$matches[4],
$matches[5],
$matches[7] ?? '',
$matches[9] ?? ''
$matches[9] ?? '',
);
},
$output

View File

@@ -19,7 +19,7 @@ use CoreLibs\Template\HtmlBuilder\General\HtmlBuilderExcpetion;
class Block
{
/**
* Undocumented function
* Create Element
*
* @param string $tag
* @param string $id
@@ -86,7 +86,7 @@ class Block
}
/**
* Undocumented function
* Add multiple elements to the base element
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $base
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} ...$attach
@@ -101,7 +101,7 @@ class Block
}
/**
* Undocumented function
* Add multiple sub elements to the base element
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $element
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $sub
@@ -117,7 +117,7 @@ class Block
}
/**
* Undocumented function
* Remove all sub element entries
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $element
* @return array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>}
@@ -131,7 +131,7 @@ class Block
// CSS Elements
/**
* Undocumented function
* Add css entry to the css entries
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $element
* @param string ...$css
@@ -144,7 +144,7 @@ class Block
}
/**
* Undocumented function
* Remove a css entry entry from the css array
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $element
* @param string ...$css
@@ -157,7 +157,7 @@ class Block
}
/**
* Undocumented function
* Switch CSS entries
* scssel (switch) is not supported
* use rcssel -> acssel
*
@@ -175,7 +175,7 @@ class Block
}
/**
* Undocumented function
* Build HTML from the content tree
* alias phfo
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $tree
@@ -231,7 +231,19 @@ class Block
}
/**
* Undocumented function
* Alias for phfo
*
* @param array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>} $tree
* @param bool $add_nl [default=false]
* @return string
*/
public static function phfo(array $tree, bool $add_nl = false): string
{
return self::buildHtml($tree, $add_nl);
}
/**
* Build HTML elements from an array of elements
* alias phfa
*
* @param array<array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>}> $list
@@ -248,8 +260,7 @@ class Block
}
/**
* Undocumented function
* wrapper for buildHtmlFromList
* alias for buildHtmlFromList
*
* @param array<array{tag:string,id:string,name:string,content:string,css:array<string>,options:array<string,string>,sub:array<mixed>}> $list array of Elements to build string from
* @param bool $add_nl [default=false] Optional output string line break

View File

@@ -401,7 +401,7 @@ class Element
* @param bool $add_nl [default=false] Optional output string line breaks
* @return string HTML as string
*/
public function buildHtml(Element $tree = null, bool $add_nl = false): string
public function buildHtml(?Element $tree = null, bool $add_nl = false): string
{
// print "D01: " . microtime(true) . "<br>";
if ($tree === null) {
@@ -533,7 +533,7 @@ class Element
* @return string build html as string
* @deprecated Do not use, use Element->buildHtml() instead
*/
public static function printHtmlFromObject(Element $tree = null, bool $add_nl = false): string
public static function printHtmlFromObject(?Element $tree = null, bool $add_nl = false): string
{
// nothing ->bad
if ($tree === null) {

View File

@@ -185,7 +185,7 @@ class SmartyExtend extends \Smarty
// call basic smarty
// or Smarty::__construct();
parent::__construct();
// iinit lang
// init lang
$this->l10n = $l10n;
// parse and read, legacy stuff
$locale = $this->l10n->getLocaleAsArray();
@@ -203,7 +203,8 @@ class SmartyExtend extends \Smarty
_bind_textdomain_codeset($this->domain, $this->encoding);
// register smarty variable
$this->registerPlugin('modifier', 'getvar', [&$this, 'getTemplateVars']);
// $this->registerPlugin(\Smarty\Smarty::PLUGIN_MODIFIER, 'getvar', [&$this, 'getTemplateVars']);
$this->registerPlugin(self::PLUGIN_MODIFIER, 'getvar', [&$this, 'getTemplateVars']);
$this->page_name = \CoreLibs\Get\System::getPageName();

View File

@@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase;
*/
final class CoreLibsConvertStringsTest extends TestCase
{
private const DATA_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR;
/**
* Undocumented function
*
@@ -330,6 +332,52 @@ final class CoreLibsConvertStringsTest extends TestCase
\CoreLibs\Convert\Strings::stripMultiplePathSlashes($input)
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerStripUTF8BomBytes(): array
{
return [
"utf8-bom" => [
"file" => "UTF8BOM.csv",
"expect" => "Asset Type,Epic,File Name\n",
],
"utf8" => [
"file" => "UTF8.csv",
"expect" => "Asset Type,Epic,File Name\n",
],
];
}
/**
* test utf8 bom remove
*
* @covers ::stripUTF8BomBytes
* @dataProvider providerStripUTF8BomBytes
* @testdox stripUTF8BomBytes $file will be $expected [$_dataName]
*
* @param string $file
* @param string $expected
* @return void
*/
public function testStripUTF8BomBytes(string $file, string $expected): void
{
// load sample file
if (!is_file(self::DATA_FOLDER . $file)) {
$this->markTestSkipped('File: ' . $file . ' could not be opened');
}
$file = file_get_contents(self::DATA_FOLDER . $file);
if ($file === false) {
$this->markTestSkipped('File: ' . $file . ' could not be read');
}
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::stripUTF8BomBytes($file)
);
}
}
// __END__

View File

@@ -0,0 +1 @@
Asset Type,Epic,File Name
1 Asset Type Epic File Name

View File

@@ -0,0 +1 @@
Asset Type,Epic,File Name
1 Asset Type Epic File Name

View File

@@ -216,6 +216,29 @@ final class CoreLibsGetSystemTest extends TestCase
);
}
}
/**
* Undocumented function
*
* @covers ::getIpAddresses
* @testdox getIpAddresses check
*
* @return void
*/
public function testGetIpAddresses()
{
// response must have "REMOTE_ADDR" entry, others are optional
// NOTE: we have no IP addresses on command line
$this->assertTrue(
true,
"We do not have REMOTE_ADDR on command line"
);
// $this->assertContains(
// 'REMOTE_ADDR',
// array_keys(\CoreLibs\Get\System::getIpAddresses()),
// 'failed REMOTE_ADDR assert'
// );
}
}
// __END__

View File

@@ -39,6 +39,11 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'OK',
'expected' => 'ok',
],
'success' => [
'level' => 'success',
'str' => 'SUCCESS',
'expected' => 'success',
],
'info' => [
'level' => 'info',
'str' => 'INFO',
@@ -225,6 +230,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'ERROR MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<ERROR> ERROR MESSAGE',
],
'error, logged' => [
@@ -233,6 +239,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'ERROR MESSAGE',
'message' => null,
'log_error' => true,
'log_warning' => null,
'expected' => '<ERROR> ERROR MESSAGE',
],
'error, logged, message' => [
@@ -241,14 +248,43 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'ERROR MESSAGE',
'message' => 'OTHER ERROR MESSAGE',
'log_error' => true,
'log_warning' => null,
'expected' => '<ERROR> OTHER ERROR MESSAGE',
],
'warn, not logged' => [
'id' => '300',
'level' => 'warn',
'str' => 'WARNING MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<WARNING> WARNING MESSAGE',
],
'warn, logged' => [
'id' => '300',
'level' => 'warn',
'str' => 'WARNING MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => true,
'expected' => '<WARNING> WARNING MESSAGE',
],
'warn, logged, message' => [
'id' => '300',
'level' => 'warn',
'str' => 'WARNING MESSAGE',
'message' => 'OTHER WARNING MESSAGE',
'log_error' => null,
'log_warning' => true,
'expected' => '<WARNING> OTHER WARNING MESSAGE',
],
'notice' => [
'id' => '100',
'level' => 'notice',
'str' => 'NOTICE MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<NOTICE> NOTICE MESSAGE',
],
'notice, message' => [
@@ -257,6 +293,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'NOTICE MESSAGE',
'message' => 'OTHER NOTICE MESSAGE',
'log_error' => null,
'log_warning' => null,
'expected' => '<NOTICE> OTHER NOTICE MESSAGE',
],
'crash' => [
@@ -265,6 +302,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'CRASH MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<ALERT> CRASH MESSAGE',
],
'crash, message' => [
@@ -273,6 +311,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'CRASH MESSAGE',
'message' => 'OTHER CRASH MESSAGE',
'log_error' => null,
'log_warning' => null,
'expected' => '<ALERT> OTHER CRASH MESSAGE',
],
'abort' => [
@@ -281,6 +320,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'ABORT MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<CRITICAL> ABORT MESSAGE',
],
'abort, message' => [
@@ -289,6 +329,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'ABORT MESSAGE',
'message' => 'OTHER ABORT MESSAGE',
'log_error' => null,
'log_warning' => null,
'expected' => '<CRITICAL> OTHER ABORT MESSAGE',
],
'unknown' => [
@@ -297,6 +338,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'WRONG LEVEL MESSAGE',
'message' => null,
'log_error' => null,
'log_warning' => null,
'expected' => '<EMERGENCY> WRONG LEVEL MESSAGE',
],
'unknown, message' => [
@@ -305,6 +347,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'str' => 'WRONG LEVEL MESSAGE',
'message' => 'OTHER WRONG LEVEL MESSAGE',
'log_error' => null,
'log_warning' => null,
'expected' => '<EMERGENCY> OTHER WRONG LEVEL MESSAGE',
],
];
@@ -321,6 +364,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
* @param string $str
* @param string|null $message
* @param bool|null $log_error
* @param bool|null $log_warning
* @param string $expected
* @return void
*/
@@ -330,6 +374,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
string $str,
?string $message,
?bool $log_error,
?bool $log_warning,
string $expected
): void {
$log = new \CoreLibs\Logging\Logging([
@@ -344,7 +389,8 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
$level,
$str,
message: $message,
log_error: $log_error
log_error: $log_error,
log_warning: $log_warning
);
$file_content = '';
if (is_file($log->getLogFolder() . $log->getLogFile())) {
@@ -358,6 +404,11 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
$expected,
$file_content
);
} elseif ($level == 'warn' && ($log_warning === null || $log_warning === false)) {
$this->assertStringNotContainsString(
$expected,
$file_content
);
} else {
$this->assertStringContainsString(
$expected,
@@ -377,6 +428,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
* @param string $str
* @param string|null $message
* @param bool|null $log_error
* @param bool|null $log_warning
* @param string $expected
* @return void
*/
@@ -386,6 +438,7 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
string $str,
?string $message,
?bool $log_error,
?bool $log_warning,
string $expected
): void {
$log = new \CoreLibs\Logging\Logging([
@@ -400,7 +453,8 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
$level,
$str,
message: $message,
log_error: $log_error
log_error: $log_error,
log_warning: $log_warning
);
$file_content = '';
if (is_file($log->getLogFolder() . $log->getLogFile())) {
@@ -414,6 +468,11 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
$expected,
$file_content
);
} elseif ($level == 'warn' && $log_warning === false) {
$this->assertStringNotContainsString(
$expected,
$file_content
);
} else {
$this->assertStringContainsString(
$expected,

2
tmp/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore