Compare commits

...

3 Commits

8 changed files with 183 additions and 2 deletions

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 museum-digital Copyright (c) 2023-2025 museum-digital
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

0
phpstan-baseline.neon Normal file
View File

12
phpstan.neon Normal file
View File

@ -0,0 +1,12 @@
parameters:
level: 8
bootstrapFiles:
- ./tests/bootstrap.php
paths:
- src
- tests
dynamicConstantNames:
- DATABASENAME
- DATABASENAME_NODA
includes:
- phpstan-baseline.neon

View File

@ -986,4 +986,43 @@ final class MD_STD {
} . $year . '-' . $month . '-' . $day; } . $year . '-' . $month . '-' . $day;
} }
/**
* Finds the next occurence of any of a given set of substrings.
*
* @param string $haystack The string to search in.
* @param non-empty-array<non-empty-string> $needles The strings to search for.
* @param integer $offset If specified, search will
* start this number of
* characters counted from
* the beginning of the string.
* If the offset is negative,
* the search will start this
* number of characters
* counted from the end of
* the string.
*
* @return array{position: integer, needle: string}|array{}
*/
public static function strpos_multi(string $haystack, array $needles, int $offset = 0):array {
$lowest_option = [];
foreach ($needles as $needle) {
if (($pos = strpos($haystack, $needle, $offset)) !== false) {
if (empty($lowest_option)) {
$lowest_option = ['position' => $pos, 'needle' => $needle];
}
else if ($pos < $lowest_option['position']) {
$lowest_option = ['position' => $pos, 'needle' => $needle];
}
}
}
return $lowest_option;
}
} }

39
src/MD_STD_STRINGS.php Normal file
View File

@ -0,0 +1,39 @@
<?PHP
/**
* Gathers wrappers for handling strings.
*/
declare(strict_types = 1);
/**
* Encapsulates functions for handling strings.
*/
final class MD_STD_STRINGS {
/**
* Duplicates words ending in a given set of strings (e.g. dots) that serve as bind chars
* to allow indexing to then allow searching for them in either form.
*
* @param string $input Input string.
*
* @return string
*/
public static function duplicate_words_with_dots_for_indexing(string $input):string {
$charsToDuplicateOn = ',.!-';
$wordsToAdd = [];
$words = explode(' ', $input);
foreach ($words as $word) {
$trimmed = trim($word, $charsToDuplicateOn);
if ($trimmed !== $word) {
$wordsToAdd[] = $trimmed;
}
}
if (empty($wordsToAdd)) {
return $input;
}
return $input . ' ' . implode(' ', $wordsToAdd);
}
}

View File

@ -62,7 +62,7 @@ final class MD_STD_TEST_PROVIDERS {
/** /**
* Data provider for working mail addresses. * Data provider for working mail addresses.
* *
* @return array<array{0: string, 1: string}> * @return array<array{0: string}>
*/ */
public static function invalid_email_provider():array { public static function invalid_email_provider():array {

View File

@ -0,0 +1,53 @@
<?PHP
/**
* Tests for MD_STD_IN.
*
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
*/
declare(strict_types = 1);
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Small;
use PHPUnit\Framework\Attributes\CoversClass;
/**
* Tests for MD_STD_STRINGS.
*/
#[small]
#[CoversClass(\MD_STD_STRINGS::class)]
final class MD_STD_STRINGS_Test extends TestCase {
/**
* Data provider for strings to duplicate words with dots in.
*
* @return array<array{0: string, 1: string}>
*/
public static function duplicated_words_with_dots_provider():array {
$values = [
["hallo test. hallo", "hallo test. hallo test"],
];
$output = [];
foreach ($values as $value) {
$output[$value[0] . ' > ' . $value[1]] = $value;
}
return $output;
}
/**
* Function for testing duplicate_words_with_dots_for_indexing().
*
* @param string $input Input.
* @param string $expected Expected output.
*
* @return void
*/
#[DataProvider('duplicated_words_with_dots_provider')]
public function test_duplicate_words_with_dots_for_indexing(string $input, string $expected):void {
self::assertEquals($expected, MD_STD_STRINGS::duplicate_words_with_dots_for_indexing($input));
}
}

View File

@ -706,4 +706,42 @@ final class MD_STD_Test extends TestCase {
self::assertEquals("en", MD_STD::get_user_lang_no_cookie(["de", "en"], "en")); self::assertEquals("en", MD_STD::get_user_lang_no_cookie(["de", "en"], "en"));
} }
/**
* Data provider for returning a tmp file.
*
* @return array<string, array{0: non-empty-string, 1: non-empty-array<non-empty-string>, 2: int}>
*/
public static function strpos_multi_provider():array {
return [
"Search quotation markes on when='" => ["when='", ['"', '\''], 5],
"Search quotation markes on when=\"" => ["when=\"", ['"', '\''], 5],
"Search quotation markes on when=\"'" => ["when=\"'", ['"', '\''], 5],
"Search quotation markes on when= (non-existent)" => ["when=", ['"', '\''], -1],
];
}
/**
* Checks unlink_if_exists works.
*
* @param non-empty-string $haystack Haystack.
* @param non-empty-array<non-empty-string> $needles Needles.
* @param integer $expected Expected position.
*
* @return void
*/
#[DataProvider('strpos_multi_provider')]
public function test_strpos_multi(string $haystack, array $needles, int $expected):void {
if ($expected === -1) {
self::assertEmpty(MD_STD::strpos_multi($haystack, $needles));
}
else {
self::assertNotEmpty(MD_STD::strpos_multi($haystack, $needles));
self::assertEquals($expected, MD_STD::strpos_multi($haystack, $needles)['position']);
}
}
} }