Respect diacritics when looking up tag, actor, .. IDs

This commit is contained in:
Joshua Ramon Enslin 2024-10-10 09:51:28 +02:00
parent 06f13c1a71
commit a9c506497c
Signed by: jrenslin
GPG Key ID: 46016F84501B70AE
3 changed files with 628 additions and 142 deletions

View File

@ -10,6 +10,30 @@ declare(strict_types = 1);
* Contains static functions for getting IDs for noda entries by various means. * Contains static functions for getting IDs for noda entries by various means.
*/ */
final class NodaIDGetter { final class NodaIDGetter {
/**
* Comparison operation that allows for equality but also returns true
* if capitalization differs. If diacritics are available in one case
* and not in the other, there will be no match.
* This is needed to identify sufficiently exact matches despite a table
* collation of *_ci in MySQL.
*
* @param string $string_one First string in comparison.
* @param string $string_two Second string in comparison.
*
* @return boolean
*/
private static function _stri_matches(string $string_one, string $string_two):bool {
if ($string_one === $string_two) {
return true;
}
if (\strtolower($string_one) === \strtolower($string_two)) {
return true;
}
return false;
}
// //
// Actors // Actors
@ -80,21 +104,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$persinstRewriteResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_id` SELECT `persinst_id`, `input_name`
FROM `persinst_rewriting` FROM `persinst_rewriting`
WHERE `language` = ? WHERE `language` = ?
AND `input_name` = ? AND `input_name` = ?
LIMIT 1", "ss", $lang, $name); LIMIT 1", "ss", $lang, $name);
if ($persinstRewriteData = $persinstRewriteResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstRewriteData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstRewriteResult->close(); return 0;
return $output;
} }
@ -111,21 +136,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$persinstByTLNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_id` SELECT `persinst_id`, `trans_name`
FROM `persinst_translation` FROM `persinst_translation`
WHERE `trans_name` = ? WHERE `trans_name` = ?
AND `trans_language` = ? AND `trans_language` = ?
LIMIT 2", "ss", $name, $lang); LIMIT 2", "ss", $name, $lang);
if ($persinstByTlData = $persinstByTLNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstByTlData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstByTLNameResult->close(); return 0;
return $output;
} }
@ -145,8 +171,8 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$persinstByTLNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_translation`.`persinst_id` SELECT `persinst_translation`.`persinst_id`, `trans_name`
FROM `persinst_translation`, `persinst` FROM `persinst_translation`, `persinst`
WHERE `persinst_translation`.`persinst_id` = `persinst`.`persinst_id` WHERE `persinst_translation`.`persinst_id` = `persinst`.`persinst_id`
AND `trans_name` = ? AND `trans_name` = ?
@ -155,14 +181,15 @@ final class NodaIDGetter {
AND `persinst_sterbejahr` = ? AND `persinst_sterbejahr` = ?
LIMIT 2", "ssss", $name, $lang, $birth, $death); LIMIT 2", "ssss", $name, $lang, $birth, $death);
if ($persinstByTlData = $persinstByTLNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstByTlData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstByTLNameResult->close(); return 0;
return $output;
} }
@ -178,22 +205,23 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$persinstByBaseNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_id` SELECT `persinst_id`, `persinst_anzeigename`, `persinst_name`, CONCAT(`persinst_name`, ' (', `persinst_geburtsjahr`, '-', `persinst_sterbejahr`, ')')
FROM `persinst` FROM `persinst`
WHERE `persinst_anzeigename` = ? WHERE `persinst_anzeigename` = ?
OR `persinst_name` = ? OR `persinst_name` = ?
OR CONCAT(`persinst_name`, ' (', `persinst_geburtsjahr`, '-', `persinst_sterbejahr`, ')') = ? OR CONCAT(`persinst_name`, ' (', `persinst_geburtsjahr`, '-', `persinst_sterbejahr`, ')') = ?
LIMIT 2", "sss", $name, $name, $name); LIMIT 2", "sss", $name, $name, $name);
if ($persinstByBaseData = $persinstByBaseNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstByBaseData[0]; if (self::_stri_matches($cur[1], $name) || self::_stri_matches($cur[2], $name) || self::_stri_matches($cur[3], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstByBaseNameResult->close(); return 0;
return $output;
} }
@ -211,8 +239,8 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$persinstByBaseNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_id` SELECT `persinst_id`, `persinst_anzeigename`, `persinst_name`, CONCAT(`persinst_name`, ' (', `persinst_geburtsjahr`, '-', `persinst_sterbejahr`, ')')
FROM `persinst` FROM `persinst`
WHERE ( WHERE (
`persinst_anzeigename` = ? `persinst_anzeigename` = ?
@ -223,14 +251,15 @@ final class NodaIDGetter {
AND `persinst_sterbejahr` = ? AND `persinst_sterbejahr` = ?
LIMIT 2", "sssss", $name, $name, $name, $birth, $death); LIMIT 2", "sssss", $name, $name, $name, $birth, $death);
if ($persinstByBaseData = $persinstByBaseNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstByBaseData[0]; if (self::_stri_matches($cur[1], $name) || self::_stri_matches($cur[2], $name) || self::_stri_matches($cur[3], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstByBaseNameResult->close(); return 0;
return $output;
} }
@ -284,22 +313,23 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$lookUpName = $name . $birthYear . $deathYear; $lookUpName = $name . $birthYear . $deathYear;
$persinstByImportLogResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `persinst_id` SELECT `persinst_id`, `input_string`
FROM `persinst_logged_imports` FROM `persinst_logged_imports`
WHERE `instance` = ? WHERE `instance` = ?
AND `institution_id` = ? AND `institution_id` = ?
AND `input_string` = ? AND `input_string` = ?
LIMIT 2", "sis", $instance, $institution_id, $lookUpName); LIMIT 2", "sis", $instance, $institution_id, $lookUpName);
if ($persinstByImportLogData = $persinstByImportLogResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $persinstByImportLogData[0]; if (self::_stri_matches($cur[1], $lookUpName)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$persinstByImportLogResult->close(); return 0;
return $output;
} }
@ -345,21 +375,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$placeRewriteResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `ort_id` SELECT `ort_id`, `input_name`
FROM `ort_rewriting` FROM `ort_rewriting`
WHERE `language` = ? WHERE `language` = ?
AND `input_name` = ? AND `input_name` = ?
LIMIT 1", "ss", $lang, $name); LIMIT 1", "ss", $lang, $name);
if ($placeRewriteData = $placeRewriteResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $placeRewriteData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$placeRewriteResult->close(); return 0;
return $output;
} }
@ -375,20 +406,21 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$placeByBaseNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `ort_id` SELECT `ort_id`, `ort_name`
FROM `orte` FROM `orte`
WHERE `ort_name` = ? WHERE `ort_name` = ?
LIMIT 2", "s", $name); LIMIT 2", "s", $name);
if ($placeByBaseData = $placeByBaseNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $placeByBaseData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$placeByBaseNameResult->close(); return 0;
return $output;
} }
@ -405,21 +437,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$placeByTLNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `ort_id` SELECT `ort_id`, `trans_name`
FROM `ort_translation` FROM `ort_translation`
WHERE `trans_name` = ? WHERE `trans_name` = ?
AND `trans_language` = ? AND `trans_language` = ?
LIMIT 2", "ss", $name, $lang); LIMIT 2", "ss", $name, $lang);
if ($placeByTlData = $placeByTLNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $placeByTlData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$placeByTLNameResult->close(); return 0;
return $output;
} }
@ -470,22 +503,23 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$placeByImportLogResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `ort_id` SELECT `ort_id`, `input_string`
FROM `orte_logged_imports` FROM `orte_logged_imports`
WHERE `instance` = ? WHERE `instance` = ?
AND `institution_id` = ? AND `institution_id` = ?
AND `input_string` = ? AND `input_string` = ?
LIMIT 2", "sis", $instance, $institution_id, $name); LIMIT 2", "sis", $instance, $institution_id, $name);
if ($placeByImportLogData = $placeByImportLogResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $placeByImportLogData[0]; if (self::_stri_matches($cur[1], $name)) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$placeByImportLogResult->close(); return 0;
return $output;
} }
@ -533,17 +567,19 @@ final class NodaIDGetter {
$output = []; $output = [];
$tagRewriteResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `tag_id` SELECT `tag_id`, `input_name`
FROM `tag_rewriting` FROM `tag_rewriting`
WHERE `tag_language` = ? WHERE `tag_language` = ?
AND `input_name` = ?", "ss", $lang, $name); AND `input_name` = ?", "ss", $lang, $name);
while ($tagRewriteData = $tagRewriteResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output[] = $tagRewriteData[0]; if (self::_stri_matches($name, $cur[1])) {
$output[] = $cur[0];
}
} }
$tagRewriteResult->close(); $result->close();
return $output; return $output;
@ -561,20 +597,21 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$tagByBaseNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `tag_id` SELECT `tag_id`, `tag_name`
FROM `tag` FROM `tag`
WHERE `tag_name` = ? WHERE `tag_name` = ?
LIMIT 2", "s", $name); LIMIT 2", "s", $name);
if ($tagByBaseData = $tagByBaseNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $tagByBaseData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$tagByBaseNameResult->close(); return 0;
return $output;
} }
@ -591,21 +628,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$tagByTLNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `tag_id` SELECT `tag_id`, `trans_name`
FROM `tag_translation` FROM `tag_translation`
WHERE `trans_name` = ? WHERE `trans_name` = ?
AND `trans_language` = ? AND `trans_language` = ?
LIMIT 2", "ss", $name, $lang); LIMIT 2", "ss", $name, $lang);
if ($tagByTlData = $tagByTLNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $tagByTlData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$tagByTLNameResult->close(); return 0;
return $output;
} }
@ -656,22 +694,23 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$tagByImportLogResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `tag_id` SELECT `tag_id`, `input_string`
FROM `tag_logged_imports` FROM `tag_logged_imports`
WHERE `instance` = ? WHERE `instance` = ?
AND `institution_id` = ? AND `institution_id` = ?
AND `input_string` = ? AND `input_string` = ?
LIMIT 2", "sis", $instance, $institution_id, $name); LIMIT 2", "sis", $instance, $institution_id, $name);
if ($tagByImportLogData = $tagByImportLogResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $tagByImportLogData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$tagByImportLogResult->close(); return 0;
return $output;
} }
@ -719,20 +758,21 @@ final class NodaIDGetter {
$output = []; $output = [];
$timeRewriteResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `zeit_id` SELECT `zeit_id`, `input_name`
FROM `zeit_rewriting` FROM `zeit_rewriting`
WHERE `language` = ? WHERE `language` = ?
AND `input_name` = ?", "ss", $lang, $name); AND `input_name` = ?", "ss", $lang, $name);
if ($timeRewriteData = $timeRewriteResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = (int)$timeRewriteData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$timeRewriteResult->close(); return 0;
return $output;
} }
@ -748,20 +788,21 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$timeByBaseNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `zeit_id` SELECT `zeit_id`, `zeit_name`
FROM `zeiten` FROM `zeiten`
WHERE `zeit_name` = ? WHERE `zeit_name` = ?
LIMIT 2", "s", $name); LIMIT 2", "s", $name);
if ($timeByBaseData = $timeByBaseNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $timeByBaseData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$timeByBaseNameResult->close(); return 0;
return $output;
} }
@ -778,21 +819,22 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$timeByTLNameResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `zeit_id` SELECT `zeit_id`, `trans_name`
FROM `zeit_translation` FROM `zeit_translation`
WHERE `trans_name` = ? WHERE `trans_name` = ?
AND `trans_language` = ? AND `trans_language` = ?
LIMIT 2", "ss", $name, $lang); LIMIT 2", "ss", $name, $lang);
if ($timeByTlData = $timeByTLNameResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $timeByTlData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$timeByTLNameResult->close(); return 0;
return $output;
} }
@ -810,22 +852,23 @@ final class NodaIDGetter {
if (empty($name)) return 0; if (empty($name)) return 0;
$timeByImportLogResult = $mysqli_noda->query_by_stmt(" $result = $mysqli_noda->query_by_stmt("
SELECT `zeit_id` SELECT `zeit_id`, `input_string`
FROM `zeiten_logged_imports` FROM `zeiten_logged_imports`
WHERE `instance` = ? WHERE `instance` = ?
AND `institution_id` = ? AND `institution_id` = ?
AND `input_string` = ? AND `input_string` = ?
LIMIT 2", "sis", $instance, $institution_id, $name); LIMIT 2", "sis", $instance, $institution_id, $name);
if ($timeByImportLogData = $timeByImportLogResult->fetch_row()) { while ($cur = $result->fetch_row()) {
$output = $timeByImportLogData[0]; if (self::_stri_matches($name, $cur[1])) {
$result->close();
return (int)$cur[0];
} }
else $output = 0; }
$result->close();
$timeByImportLogResult->close(); return 0;
return $output;
} }

433
tests/NodaIDGetterTest.php Normal file
View File

@ -0,0 +1,433 @@
<?PHP
/**
* Test for functions for looking up entry IDs by their (exact) names.
*
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
*/
declare(strict_types = 1);
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Medium;
require_once __DIR__ . '/../../MDMysqli/test_connections.conf.php';
/**
* Test for functions for looking up entry IDs by their (exact) names.
*/
#[Medium]
#[CoversClass(\NodaIDGetter::class)]
final class NodaIDGetterTest extends TestCase {
private MDMysqli $_mysqli;
/**
* Quasi-constructor connects to DB.
*
* @return void
*/
protected function setUp():void {
$this->_mysqli = md_noda_mysqli_connect();
}
/**
* Gets string and integer value from a mysql query.
*
* @param MDMysqli $mysqli DB connection.
* @param string $query DB query.
*
* @return array{0: string, 1: integer}
*/
private static function _getNameAndIdFromDbQuery(MDMysqli $mysqli, string $query):array {
$result = $mysqli->do_read_query($query . "
LIMIT 1");
if (!($cur = $result->fetch_row())) {
throw new Exception("Failed to get result for query: " . $query);
}
$result->close();
return [
(string)$cur[0],
(int)$cur[1],
];
}
/**
* Replaces vowels in string with variants with diacritics for testing
* exact matching.
*
* @param string $input Input string.
*
* @return string
*/
public static function _replaceVowelsWithDiacriticVariants(string $input):string {
return strtr($input, [
'a' => 'ä',
'o' => 'ö',
'u' => 'ü',
'i' => 'ï',
'e' => 'è',
]);
}
/**
* Runs regular tests on the term:
* - Matching by exact same name works.
* - Matching by same name with different capitalization works.
* - Matching by same name with diacritics replacing non-diacritic vowels fails
* (counter to MySQL's _ci-type notations rules).
*
* @param string $function NodaIDGetter's callback function for identification.
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
private function runRegularComparisonTests(string $function, string $name, int $expected_id):void {
self::assertEquals($expected_id,
NodaIDGetter::$function($this->_mysqli, "de", $name),
"Entry " . $name . " is not matched in exact lookup. Expected ID: " . $expected_id);
// Ensure that different capitalization does not influence the results
self::assertEquals($expected_id,
NodaIDGetter::$function($this->_mysqli, "de", strtoupper($name)));
self::assertEquals($expected_id,
NodaIDGetter::$function($this->_mysqli, "de", strtolower($name)));
// Ensure that diacritics will stop the entry from matching
$nameReplaced = self::_replaceVowelsWithDiacriticVariants($name);
self::assertNotEquals($expected_id,
NodaIDGetter::$function($this->_mysqli, "de", $nameReplaced));
}
// PersinstIDByName
/**
* Returns a test actor name.
*
* @return array<array{0: string, 1: integer}>
*/
public static function persinstByNameProvider():array {
$mysqli = md_main_mysqli_connect();
$persinstByNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `persinst_name`, `persinst_id`
FROM `" . DATABASENAME_NODA . "`.`persinst`
WHERE INSTR(`persinst_name`, 'i')");
$persinstByDisplayNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `persinst_anzeigename`, `persinst_id`
FROM `" . DATABASENAME_NODA . "`.`persinst`
WHERE INSTR(`persinst_anzeigename`, 'i')
AND `persinst_sterbejahr` != ''");
$persinstByDisplayNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `trans_name`, `persinst_id`
FROM `" . DATABASENAME_NODA . "`.`persinst_translation`
WHERE INSTR(`trans_name`, 'i')
AND `trans_language` = 'de'");
$mysqli->close();
return [
'Persinst ID by name: ' . $persinstByNameSimple[0] => $persinstByNameSimple,
'Persinst ID by display name: ' . $persinstByDisplayNameSimple[0] => $persinstByDisplayNameSimple,
'Persinst ID by translated name: ' . $persinstByDisplayNameSimple[0] => $persinstByDisplayNameSimple,
];
}
/**
* Test getting persinst by name works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('persinstByNameProvider')]
public function testGetPersinstIdByNameWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getPersinstIDByName", $name, $expected_id);
}
// PersinstIDByRewrite
/**
* Returns a test actor name.
*
* @return array<array{0: string, 1: integer}>
*/
public static function persinstByRewriteProvider():array {
$mysqli = md_main_mysqli_connect();
$persinstByRewriteSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `input_name`, `persinst_id`
FROM `" . DATABASENAME_NODA . "`.`persinst_rewriting`
WHERE INSTR(`input_name`, 'i')");
$mysqli->close();
return [
'Persinst ID by rewrite: ' . $persinstByRewriteSimple[0] => $persinstByRewriteSimple,
];
}
/**
* Test getting persinst by rewrite works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('persinstByRewriteProvider')]
public function testGetPersinstIdByRewriteWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getPersinstIDByRewrite", $name, $expected_id);
}
// PlaceIDByName
/**
* Returns a test place name.
*
* @return array<array{0: string, 1: integer}>
*/
public static function placeByNameProvider():array {
$mysqli = md_main_mysqli_connect();
$placeByNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `ort_name`, `ort_id`
FROM `" . DATABASENAME_NODA . "`.`orte`
WHERE INSTR(`ort_name`, 'i')");
$placeByDisplayNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `trans_name`, `ort_id`
FROM `" . DATABASENAME_NODA . "`.`ort_translation`
WHERE INSTR(`trans_name`, 'i')
AND `trans_language` = 'de'");
$mysqli->close();
return [
'Place ID by name: ' . $placeByNameSimple[0] => $placeByNameSimple,
'Place ID by translated name: ' . $placeByDisplayNameSimple[0] => $placeByDisplayNameSimple,
];
}
/**
* Test getting persinst by name works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('placeByNameProvider')]
public function testGetPlaceIdByNameWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getPlaceIDByName", $name, $expected_id);
}
// PlaceIDByRewrite
/**
* Returns a test place name registered for rewriting.
*
* @return array<array{0: string, 1: integer}>
*/
public static function placeByRewriteProvider():array {
$mysqli = md_main_mysqli_connect();
$placeByRewriteSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `input_name`, `ort_id`
FROM `" . DATABASENAME_NODA . "`.`ort_rewriting`
WHERE INSTR(`input_name`, 'i')");
$mysqli->close();
return [
'Place ID by rewrite: ' . $placeByRewriteSimple[0] => $placeByRewriteSimple,
];
}
/**
* Test getting places by rewrite works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('placeByRewriteProvider')]
public function testGetPlaceIdByRewriteWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getPlaceIDByRewrite", $name, $expected_id);
}
// TagIDByName
/**
* Returns a test tag name.
*
* @return array<array{0: string, 1: integer}>
*/
public static function tagByNameProvider():array {
$mysqli = md_main_mysqli_connect();
$tagByNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `tag_name`, `tag_id`
FROM `" . DATABASENAME_NODA . "`.`tag`
WHERE INSTR(`tag_name`, 'i')");
$tagByDisplayNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `trans_name`, `tag_id`
FROM `" . DATABASENAME_NODA . "`.`tag_translation`
WHERE INSTR(`trans_name`, 'i')
AND `trans_language` = 'de'");
$mysqli->close();
return [
'Tag ID by name: ' . $tagByNameSimple[0] => $tagByNameSimple,
'Tag ID by translated name: ' . $tagByDisplayNameSimple[0] => $tagByDisplayNameSimple,
];
}
/**
* Test getting tags by name works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('tagByNameProvider')]
public function testGetTagIdByNameWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getTagIDByName", $name, $expected_id);
}
// TagIDByRewrite
/**
* Returns a test tag name registered for rewriting.
*
* @return array<array{0: string, 1: integer}>
*/
public static function tagByRewriteProvider():array {
$mysqli = md_main_mysqli_connect();
$tagByRewriteSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `input_name`, `tag_id`
FROM `" . DATABASENAME_NODA . "`.`tag_rewriting`
WHERE INSTR(`input_name`, 'i')");
$mysqli->close();
return [
'Tag ID by rewrite: ' . $tagByRewriteSimple[0] => $tagByRewriteSimple,
];
}
/**
* Test getting tags by rewrite works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('tagByRewriteProvider')]
public function testGetTagIdByRewriteWorks(string $name, int $expected_id):void {
self::assertContains($expected_id, NodaIDGetter::getTagIDByRewrite($this->_mysqli, "de", $name));
// Ensure that different capitalization does not influence the results
self::assertContains($expected_id, NodaIDGetter::getTagIDByRewrite($this->_mysqli, "de", strtoupper($name)));
self::assertContains($expected_id, NodaIDGetter::getTagIDByRewrite($this->_mysqli, "de", strtolower($name)));
// Ensure that diacritics will stop the entry from matching
$nameReplaced = self::_replaceVowelsWithDiacriticVariants($name);
self::assertFalse(in_array($expected_id, NodaIDGetter::getTagIDByRewrite($this->_mysqli, "de", $nameReplaced), true));
}
// TimeIDByName
/**
* Returns a test time name.
*
* @return array<array{0: string, 1: integer}>
*/
public static function timeByNameProvider():array {
$mysqli = md_main_mysqli_connect();
$timeByNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `zeit_name`, `zeit_id`
FROM `" . DATABASENAME_NODA . "`.`zeiten`
WHERE INSTR(`zeit_name`, 'i')");
$timeByDisplayNameSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `trans_name`, `zeit_id`
FROM `" . DATABASENAME_NODA . "`.`zeit_translation`
WHERE INSTR(`trans_name`, 'i')
AND `trans_language` = 'de'");
$mysqli->close();
return [
'Time ID by name: ' . $timeByNameSimple[0] => $timeByNameSimple,
'Time ID by translated name: ' . $timeByDisplayNameSimple[0] => $timeByDisplayNameSimple,
];
}
/**
* Test getting persinst by name works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('timeByNameProvider')]
public function testGetTimeIdByNameWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getTimeIDByName", $name, $expected_id);
}
// timeIDByRewrite
/**
* Returns a test time name registered for rewriting.
*
* @return array<array{0: string, 1: integer}>
*/
public static function timeByRewriteProvider():array {
$mysqli = md_main_mysqli_connect();
$timeByRewriteSimple = self::_getNameAndIdFromDbQuery($mysqli, "SELECT `input_name`, `zeit_id`
FROM `" . DATABASENAME_NODA . "`.`zeit_rewriting`
WHERE INSTR(`input_name`, 'i')");
$mysqli->close();
return [
'Time ID by rewrite: ' . $timeByRewriteSimple[0] => $timeByRewriteSimple,
];
}
/**
* Test getting times by rewrite works.
*
* @param string $name Name of the entry.
* @param integer $expected_id Expected target ID.
*
* @return void
*/
#[DataProvider('timeByRewriteProvider')]
public function testGetTimeIdByRewriteWorks(string $name, int $expected_id):void {
$this->runRegularComparisonTests("getTimeIDByRewrite", $name, $expected_id);
}
}

View File

@ -12,7 +12,17 @@ declare(strict_types = 1);
// Try using class map as defined through /scripts/buildClassMap.php // Try using class map as defined through /scripts/buildClassMap.php
foreach (array_merge([__DIR__ . '/../tests', __DIR__ . '/../src', __DIR__ . '/../src/enums', __DIR__ . '/../../MD_STD/src', __DIR__ . '/../../MDErrorReporter', __DIR__ . '/../../MDErrorReporter/exceptions', __DIR__ . '/../../MDErrorReporter/exceptions/generic', __DIR__ . '/../../MDErrorReporter/exceptions/updates']) as $classDir) { foreach (array_merge([__DIR__ . '/../tests',
__DIR__ . '/../src',
__DIR__ . '/../src/enums',
__DIR__ . '/../../MD_STD/src',
__DIR__ . '/../../MDErrorReporter',
__DIR__ . '/../../MDErrorReporter/exceptions',
__DIR__ . '/../../MDErrorReporter/exceptions/generic',
__DIR__ . '/../../MDErrorReporter/exceptions/updates',
__DIR__ . '/../../MDMysqli/src',
__DIR__ . '/../../MDMysqli/exceptions',
]) as $classDir) {
if (\file_exists("$classDir/$className.php")) { if (\file_exists("$classDir/$className.php")) {
include "$classDir/$className.php"; include "$classDir/$className.php";