Compare commits

..

12 Commits

Author SHA1 Message Date
Clemens Schwaighofer
94edb7f556 Add unique page name check for edit pages, bug fixes in Form Template Generate and DB Array IO classes 2024-03-21 12:45:39 +09:00
Clemens Schwaighofer
3f5b3f02ad Update Readme to reflect that current version is v9 2024-03-08 14:41:07 +09:00
Clemens Schwaighofer
a270922b4b Published: v9.12.0 2024-03-07 15:04:18 +09:00
Clemens Schwaighofer
8c607ae610 tools update, bug fix Strings to return path if null, Fix form list loader, fix paths 2024-03-07 15:01:19 +09:00
Clemens Schwaighofer
d3d4cf512f add php code sniffer xml 2023-12-05 17:38:01 +09:00
Clemens Schwaighofer
efae352c35 Published: v9.11.1 2023-11-29 10:51:19 +09:00
Clemens Schwaighofer
a1614bace2 Bug Fix in DB IO with parameter detection with <> 2023-11-29 10:50:25 +09:00
Clemens Schwaighofer
62ce863f2c Release: v9.11.0 2023-11-02 14:08:23 +09:00
Clemens Schwaighofer
b6ef3b29f6 ArrayHandler add next/prev key search 2023-11-02 14:06:31 +09:00
Clemens Schwaighofer
1f178628a2 Release: v9.10.1 2023-10-31 10:24:18 +09:00
Clemens Schwaighofer
67b725cb65 DB\IO fixes for logging 2023-10-31 10:21:52 +09:00
Clemens Schwaighofer
648d2c3eb5 Release: v9.10.0 2023-10-23 17:14:47 +09:00
26 changed files with 374 additions and 52 deletions

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="^9.6" installed="9.6.13" location="./tools/phpunit" copy="false"/>
<phar name="phpcs" version="^3.7.2" installed="3.7.2" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.7.2" location="./tools/phpcbf" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.15.0" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="^1.10.37" installed="1.10.37" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.2" installed="5.4.2" location="./tools/phan" copy="false"/>
<phar name="phpunit" version="^9.6" installed="9.6.17" location="./tools/phpunit" copy="false"/>
<phar name="phpcs" version="^3.7.2" installed="3.9.0" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.9.0" location="./tools/phpcbf" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.23.1" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="^1.10.37" installed="1.10.63" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.2" installed="5.4.3" location="./tools/phan" copy="false"/>
</phive>

View File

@@ -22,7 +22,7 @@ Alternative setup composer local zip file repot:
## Install package
`composer require egrajp/corelibs-composer-all:^8.0`
`composer require egrajp/corelibs-composer-all:^9.0`
## Tests

18
phpcs.xml Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<ruleset name="MyStandard">
<description>PSR12 override rules (strict, standard). Switch spaces indent to tab.</description>
<arg name="tab-width" value="4"/>
<rule ref="PSR1"/>
<rule ref="PSR12">
<!-- turn off white space check for tab -->
<exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
</rule>
<!-- no space indent, must be tab, 4 is tab iwdth -->
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
<rule ref="Generic.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="4"/>
<property name="tabIndent" value="true"/>
</properties>
</rule>
</ruleset>

View File

@@ -1 +1 @@
9.9.1
9.12.0

View File

@@ -51,6 +51,23 @@ class File
// return lines in file
return $lines;
}
/**
* get the mime type of a file via finfo
* if file not found, throws exception
* else returns '' for any other finfo read problem
*
* @param string $read_file File to read, relative or absolute path
* @return string
*/
public static function getMimeType(string $read_file): string
{
$finfo = new \finfo(FILEINFO_MIME_TYPE);
if (!is_file($read_file)) {
throw new \UnexpectedValueException('[getMimeType] File not found: ' . $read_file);
}
return $finfo->file($read_file) ?: '';
}
}
// __END__

View File

@@ -236,6 +236,54 @@ class ArrayHandler
return $hit_list;
}
/**
* main wrapper function for next/prev key
*
* @param array<mixed> $array array to search in
* @param int|string $key key for next/prev
* @param bool $next [=true] if to search next or prev
* @return int|string|null Next/prev key or null for end/first
*/
private static function arrayGetKey(array $array, int|string $key, bool $next = true): int|string|null
{
$keys = array_keys($array);
if (($position = array_search($key, $keys, true)) === false) {
return null;
}
$next_position = $next ? $position + 1 : $position - 1;
if (!isset($keys[$next_position])) {
return null;
}
return $keys[$next_position];
}
/**
* Get previous array key from an array
* null on not found
*
* @param array<mixed> $array
* @param int|string $key
* @return int|string|null Next key, or null for not found
*/
public static function arrayGetPrevKey(array $array, int|string $key): int|string|null
{
return self::arrayGetKey($array, $key, false);
}
/**
* Get next array key from an array
* null on not found
*
* @param array<mixed> $array
* @param int|string $key
* @return int|string|null Next key, or null for not found
*/
public static function arrayGetNextKey(array $array, int|string $key): int|string|null
{
return self::arrayGetKey($array, $key, true);
}
/**
* correctly recursive merges as an array as array_merge_recursive
* just glues things together

View File

@@ -385,7 +385,7 @@ class DateTime
} else {
$str = implode(', ', array_slice($formatted, 0, -1));
if (!empty($formatted[count($formatted) - 1])) {
$str .= ' and ' . $formatted[count($formatted) - 1];
$str .= ' and ' . (string)array_pop($formatted);
}
return $negative . $str;
}
@@ -675,9 +675,9 @@ class DateTime
foreach ($period as $dt) {
$curr = $dt->format('D');
if ($curr == 'Sat' || $curr == 'Sun') {
$days[2] ++;
$days[2]++;
} else {
$days[1] ++;
$days[1]++;
}
}
if ($return_named === true) {

View File

@@ -118,6 +118,22 @@ class Strings
return $value;
}
}
/**
* Strip any duplicated slahes from a path
* eg: //foo///bar/foo.inc -> /foo/bar/foo.inc
*
* @param string $path Path to strip slashes from
* @return string Clean path, on error returns original path
*/
public static function stripMultiplePathSlashes(string $path): string
{
return preg_replace(
'#/+#',
'/',
$path
) ?? $path;
}
}
// __END__

View File

@@ -236,7 +236,7 @@ class ArrayIO extends \CoreLibs\DB\IO
*/
public function getPkId(): int|string|null
{
return $this->pk_id;
return $this->pk_id ?? null;
}
/**

View File

@@ -1186,7 +1186,7 @@ class IO
*/
private function __dbDebugPrepareContext(string $query, array $params = []): array
{
if ($this->params === []) {
if ($params === []) {
return [];
}
$error_data = [
@@ -1302,7 +1302,7 @@ class IO
}
}
}
$this->cursor_ext[$query_hash]['pos'] ++;
$this->cursor_ext[$query_hash]['pos']++;
return $return;
}
@@ -1318,14 +1318,14 @@ class IO
// regex for params: only stand alone $number allowed
// exclude all '' enclosed strings, ignore all numbers [note must start with digit]
// can have space/tab/new line
// must have = , ( [equal, comma, opening round bracket]
// must have <> = , ( [not equal, equal, comma, opening round bracket]
// can have space/tab/new line
// $ number with 1-9 for first and 0-9 for further digits
// /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
preg_match_all(
'/(?:\'.*?\')?\s*(?:\?\?|[(=,])\s*(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s',
'/(?:\'.*?\')?\s*(?:\?\?|<>|[(=,])\s*(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s',
$query,
$match
);
@@ -1519,7 +1519,7 @@ class IO
]);
return false;
}
$this->query_called[$query_hash] ++;
$this->query_called[$query_hash]++;
// return hash
return $query_hash;
}
@@ -2411,6 +2411,8 @@ class IO
// set the query
$this->cursor_ext[$query_hash]['query'] = $query;
// set the query parameters
$this->cursor_ext[$query_hash]['params'] = $params;
// before doing ANYTHING check if query is "SELECT ..." everything else does not work
if (!$this->dbCheckQueryForSelect($this->cursor_ext[$query_hash]['query'])) {
$this->__dbError(17, false, context: [
@@ -2420,8 +2422,6 @@ class IO
]);
return false;
}
// set the query parameters
$this->cursor_ext[$query_hash]['params'] = $params;
// QUERY PARAMS: run query params check and rewrite
if ($this->dbGetConvertPlaceholder() === true) {
try {
@@ -2469,7 +2469,7 @@ class IO
return false;
}
} else {
$this->cursor_ext[$query_hash]['log_pos'] ++;
$this->cursor_ext[$query_hash]['log_pos']++;
}
// reset log for each read
$this->cursor_ext[$query_hash]['log'] = [];
@@ -2668,8 +2668,8 @@ class IO
if ($return) {
$this->cursor_ext[$query_hash]['log'][] = 'Return Data';
// internal position counter
$this->cursor_ext[$query_hash]['pos'] ++;
$this->cursor_ext[$query_hash]['read_rows'] ++;
$this->cursor_ext[$query_hash]['pos']++;
$this->cursor_ext[$query_hash]['read_rows']++;
// read is finished
if (
$this->cursor_ext[$query_hash]['read_rows'] ==

View File

@@ -826,27 +826,28 @@ class Generate
$pk_selected = $res[$this->int_pk_name];
}
$t_string = '';
foreach ($this->field_array as $i => $field_array) {
foreach ($this->field_array as $field_array) {
if ($t_string) {
$t_string .= ', ';
}
if (isset($field_array['before_value'])) {
$t_string .= $field_array['before_value'];
if (!empty($field_array['before_value'])) {
$t_string .= $this->l->__($field_array['before_value']);
}
// must have res element set
if (
isset($field_array['name']) &&
!empty($field_array['name']) &&
isset($res[$field_array['name']])
) {
if (isset($field_array['binary'])) {
if (isset($field_array['binary'][0])) {
$t_string .= $field_array['binary'][0];
} elseif (isset($field_array['binary'][1])) {
$t_string .= $field_array['binary'][1];
}
$_t_value = '';
// if we have a binary set, where 0 = YES and 1 = NO
if (!empty($field_array['binary'])) {
$_t_value = !empty($res[$field_array['name']]) ?
($field_array['binary'][0] ?? 'Yes') :
($field_array['binary'][1] ?? 'No');
} else {
$t_string .= $res[$field_array['name']];
$_t_value = $res[$field_array['name']];
}
$t_string .= $this->l->__($_t_value);
}
}
$pk_names[] = $t_string;
@@ -1506,7 +1507,7 @@ class Generate
}
if (
!empty($this->reference_array[$key]['mandatory']) &&
!$this->reference_array[$key]['selected'][0]
empty($this->reference_array[$key]['selected'][0])
) {
$this->msg .= sprintf(
$this->l->__('Please select at least one Element from field <b>%s</b>!<br>'),

View File

@@ -53,6 +53,7 @@ class EditPages implements Interface\TableArraysInterface
'value' => $_POST['name'] ?? '',
'output_name' => 'Page name',
'mandatory' => 1,
'error_check' => 'unique',
'type' => 'text'
],
'order_number' => [

View File

@@ -204,11 +204,11 @@ class Image
E_USER_DEPRECATED
);
// NOTE: we need to depracte this
$cache_folder = BASE . LAYOUT . CONTENT_PATH . CACHE . IMAGES;
$cache_folder = BASE . CONTENT_PATH . LAYOUT . CACHE . IMAGES;
$web_folder = LAYOUT . CACHE . IMAGES;
if (!is_dir($cache_folder)) {
if (false === mkdir($cache_folder)) {
$cache_folder = BASE . LAYOUT . CONTENT_PATH . CACHE;
$cache_folder = BASE . CONTENT_PATH . LAYOUT . CACHE;
$web_folder = LAYOUT . CACHE;
}
}

View File

@@ -156,7 +156,7 @@ class ProgressBar
{
// avoid divison through 0
if ($this->max - $this->min == 0) {
$this->max ++;
$this->max++;
}
$percent = round(($step - $this->min) / ($this->max - $this->min) * 100);
if ($percent > 100) {
@@ -186,7 +186,7 @@ class ProgressBar
}
// avoid divison through 0
if ($this->max - $this->min == 0) {
$this->max ++;
$this->max++;
}
$pixel = round(($step - $this->min) * ($bar - ($this->pedding * 2)) / ($this->max - $this->min));
if ($step <= $this->min) {

View File

@@ -1,2 +1,2 @@
base="/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All/";
vendor/bin/phan --progress-bar -C --analyze-twice
tools/phan --progress-bar -C --analyze-twice

View File

@@ -1,2 +1,2 @@
base="/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All/";
vendor/bin/phpstan
tools/phpstan

View File

@@ -33,7 +33,7 @@ if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then
esac;
fi;
phpunit_call="${php_bin}${base}vendor/bin/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}test/phpunit/";
phpunit_call="${php_bin}${base}tools/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}test/phpunit/";
${phpunit_call};

View File

@@ -28,10 +28,10 @@ final class CoreLibsCheckFileTest extends TestCase
public function filesList(): array
{
return [
['filename.txt', 'txt', 5],
['filename.csv', 'csv', 15],
['filename.tsv', 'tsv', 0],
['file_does_not_exits', '', -1],
['filename.txt', 'txt', 5, 'text/plain'],
['filename.csv', 'csv', 15, 'text/csv'],
['filename.tsv', 'tsv', 0, 'text/plain'],
['file_does_not_exits', '', -1, ''],
];
}
@@ -63,6 +63,15 @@ final class CoreLibsCheckFileTest extends TestCase
return $list;
}
public function mimeTypeProvider(): array
{
$list = [];
foreach ($this->filesList() as $row) {
$list[$row[0] . ' must be mime type ' . $row[3]] = [$row[0], $row[3]];
}
return $list;
}
/**
* Tests if file extension matches
*
@@ -115,6 +124,51 @@ final class CoreLibsCheckFileTest extends TestCase
unlink($this->base_folder . $input);
}
}
/**
* Undocumented function
*
* @covers ::getMimeType
* @dataProvider mimeTypeProvider
* @testdox getMimeType $input must be mime type $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testGetMimeType(string $input, string $expected): void
{
if (!empty($expected)) {
$file = $this->base_folder . $input;
$fp = fopen($file, 'w');
switch ($expected) {
case 'text/csv':
for ($i = 1; $i <= 10; $i++) {
fwrite($fp, '"This is row","' . $expected . '",' . $i . PHP_EOL);
}
break;
case 'text/tsv':
for ($i = 1; $i <= 10; $i++) {
fwrite($fp, "\"This is row\"\t\"" . $expected . "\"\t\"" . $i . PHP_EOL);
}
break;
case 'text/plain':
fwrite($fp, 'This is mime type: ' . $expected . PHP_EOL);
break;
}
fclose($fp);
} else {
$this->expectException(\UnexpectedValueException::class);
}
$this->assertEquals(
$expected,
\CoreLibs\Check\File::getMimeType($this->base_folder . $input)
);
// unlink file
if (is_file($this->base_folder . $input)) {
unlink($this->base_folder . $input);
}
}
}
// __END__

View File

@@ -1098,16 +1098,109 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
* @testdox arrayFlatForKey array $input will be $expected [$_dataName]
*
* @param array $input
* @param string $search
* @param array $expected
* @return void
*/
public function testArrayFlatForKey(array $input, $search, array $expected): void
public function testArrayFlatForKey(array $input, string $search, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arrayFlatForKey($input, $search)
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerArrayGetNextPrevKey(): array
{
return [
'find, ok' => [
'input' => [
'a' => 'First',
'b' => 'Second',
'c' => 'Third',
],
'b',
'a',
'c'
],
'find, first' => [
'input' => [
'a' => 'First',
'b' => 'Second',
'c' => 'Third',
],
'a',
null,
'b'
],
'find, last' => [
'input' => [
'a' => 'First',
'b' => 'Second',
'c' => 'Third',
],
'c',
'b',
null
],
'find, not found' => [
'input' => [
'a' => 'First',
'b' => 'Second',
'c' => 'Third',
],
'z',
null,
null
],
'int, index' => [
'input' => [
'a',
'b',
'c'
],
1,
0,
2
]
];
}
/**
* Undocumented function
*
* @covers ::arrayGetPrevKey, ::arrayGetNextKey
* @dataProvider providerArrayGetNextPrevKey
* @testdox arrayGetNextPrevKey get next/prev key for $search wtih $expected_prev/$expected_next [$_dataName]
*
* @param array $input
* @param int|string $search
* @param int|string|null $expected_prev
* @param int|string|null $expected_next
* @return void
*/
public function testArrayGetNextPrevKey(
array $input,
int|string $search,
int|string|null $expected_prev,
int|string|null $expected_next
): void {
$this->assertEquals(
$expected_prev,
\CoreLibs\Combined\ArrayHandler::arrayGetPrevKey($input, $search),
'Find prev key in array'
);
$this->assertEquals(
$expected_next,
\CoreLibs\Combined\ArrayHandler::arrayGetNextKey($input, $search),
'Find next key in array'
);
}
}
// __END__

View File

@@ -256,6 +256,80 @@ final class CoreLibsConvertStringsTest extends TestCase
$output
);
}
/**
* provider for testStripMultiplePathSlashes
*
* @return array<mixed>
*/
public function stripMultiplePathSlashesProvider(): array
{
return [
'no slahses' => [
'input' => 'string_abc',
'expected' => 'string_abc',
],
'one slash' => [
'input' => 'some/foo',
'expected' => 'some/foo',
],
'two slashes' => [
'input' => 'some//foo',
'expected' => 'some/foo',
],
'three slashes' => [
'input' => 'some///foo',
'expected' => 'some/foo',
],
'slashes in front' => [
'input' => '/foo',
'expected' => '/foo',
],
'two slashes in front' => [
'input' => '//foo',
'expected' => '/foo',
],
'thee slashes in front' => [
'input' => '///foo',
'expected' => '/foo',
],
'slashes in back' => [
'input' => 'foo/',
'expected' => 'foo/',
],
'two slashes in back' => [
'input' => 'foo//',
'expected' => 'foo/',
],
'thee slashes in back' => [
'input' => 'foo///',
'expected' => 'foo/',
],
'multiple slashes' => [
'input' => '/foo//bar///string/end_times',
'expected' => '/foo/bar/string/end_times',
]
];
}
/**
* test multiple slashes clean up
*
* @covers ::stripMultiplePathSlashes
* @dataProvider stripMultiplePathSlashesProvider
* @testdox stripMultiplePathSlashes $input will be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testStripMultiplePathSlashes(string $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::stripMultiplePathSlashes($input)
);
}
}
// __END__

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/phan-5.4.2.phar
/home/clemens/.phive/phars/phan-5.4.3.phar

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/phpcbf-3.7.2.phar
/home/clemens/.phive/phars/phpcbf-3.9.0.phar

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/phpcs-3.7.2.phar
/home/clemens/.phive/phars/phpcs-3.9.0.phar

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/phpstan-1.10.37.phar
/home/clemens/.phive/phars/phpstan-1.10.63.phar

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/phpunit-9.6.13.phar
/home/clemens/.phive/phars/phpunit-9.6.17.phar

View File

@@ -1 +1 @@
/home/clemens/.phive/phars/psalm-5.15.0.phar
/home/clemens/.phive/phars/psalm-5.23.1.phar