Collect unmapped entries in dry-run mode

See museum-digital/importer#235
This commit is contained in:
2025-11-13 00:28:24 +01:00
parent db3a659fa9
commit cb0684da05
25 changed files with 152 additions and 29 deletions

View File

@@ -9,21 +9,48 @@ final class MDImporterMissingConcordance extends Exception {
public string $target_type;
public string $value_to_map;
/** @var array<string, string> */
private static array $_missing_concordances = [];
/**
* Sets up an error.
*
* @param string $target_type Target type (e.g. "measurements").
* @param string $value_to_map Value to map.
*
* @return MDImporterMissingConcordance
* @return void
*/
public static function setup(string $target_type, string $value_to_map):MDImporterMissingConcordance {
public static function throw(string $target_type, string $value_to_map):void {
if (class_exists("MD_IMPORTER_CONF") && MD_IMPORTER_CONF::$dry_run === true) {
if (empty(self::$_missing_concordances)) {
// Register printing at the end
register_shutdown_function(function() {
echo PHP_EOL . PHP_EOL . "There are unmapped concordances. Please map them before proceeding." . PHP_EOL . "You may use https://concordance.museum-digital.org/ to do the mapping" . PHP_EOL . PHP_EOL;
foreach (self::$_missing_concordances as $key => $values) {
sort($values);
echo PHP_EOL . PHP_EOL . $key . PHP_EOL . PHP_EOL;
echo implode(PHP_EOL, array_unique($values));
}
});
}
if (!isset(self::$_missing_concordances[$target_type])) {
self::$_missing_concordances[$target_type] = [];
}
self::$_missing_concordances[$target_type][] = $value_to_map;
return;
}
$exception = new MDImporterMissingConcordance("Unmapped specific value of type " . $target_type . ": " . $value_to_map);
$exception->target_type = $target_type;
$exception->value_to_map = $value_to_map;
return $exception;
throw $exception;
}

View File

@@ -1278,7 +1278,8 @@ final class MDConcActor implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):int {
if (!isset(self::ACTOR_ROLES_TO_EVENT_TYPE[$input])) {
throw MDImporterMissingConcordance::setup("actor role", $input);
MDImporterMissingConcordance::throw("actor role", $input);
return 1; // Return default in dry-run mode
}
return self::ACTOR_ROLES_TO_EVENT_TYPE[$input];

View File

@@ -56,7 +56,8 @@ final class MDConcCertainty implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):bool {
if (!isset(self::MAPPING[$input])) {
throw MDImporterMissingConcordance::setup("certainty identifier", $input);
MDImporterMissingConcordance::throw("certainty identifier", $input);
return true; // Return default in dry-run mode
}
return self::MAPPING[$input];

View File

@@ -25,7 +25,8 @@ final class MDConcCheckTypes implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):MDObjectCheckType {
if (!isset(self::CHECK_TYPES[$input])) {
throw MDImporterMissingConcordance::setup("check", $input);
MDImporterMissingConcordance::throw("check", $input);
return MDObjectCheckType::completeness_check; // Return default in dry-run mode
}
return self::CHECK_TYPES[$input];

View File

@@ -45,7 +45,8 @@ final class MDConcCloserLocationTypes implements MDImporterConcordanceListInterf
public static function getConcordanceTarget(string $input):string {
if (!isset(self::LOCATION_TYPES_VERBOSE[$input])) {
throw MDImporterMissingConcordance::setup("location", $input);
MDImporterMissingConcordance::throw("location", $input);
return "3"; // Return default in dry-run mode
}
return self::LOCATION_TYPES_VERBOSE[$input];

View File

@@ -26,7 +26,8 @@ final class MDConcColors implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::COLORS_LIST[$input])) {
throw MDImporterMissingConcordance::setup("color", $input);
MDImporterMissingConcordance::throw("color", $input);
return "black"; // Return default in dry-run mode
}
return self::COLORS_LIST[$input];

View File

@@ -99,7 +99,8 @@ final class MDConcCurrencies implements MDImporterConcordanceListInterface {
if (in_array($input, MDCurrenciesSet::CURRENCIES, true)) {
return $input;
}
throw MDImporterMissingConcordance::setup("currency", $input);
MDImporterMissingConcordance::throw("currency", $input);
return "eu-EUR"; // Return default in dry-run mode
}
return self::CURRENCIES_LIST[$input];

View File

@@ -37,7 +37,8 @@ final class MDConcDamageTypes implements MDImporterConcordanceListInterface {
throw new MDImporterBlacklistedConcordanceTerm("Invalid damage type: " . $input);
}
throw MDImporterMissingConcordance::setup("damage", $input);
MDImporterMissingConcordance::throw("damage", $input);
return MDObjectDamageType::desiccation; // Return default in dry-run mode
}
return self::DAMAGE_TYPES[$input];

View File

@@ -376,7 +376,8 @@ final class MDConcEntryTypes implements MDImporterConcordanceListInterface {
return self::ENTRY_TYPES_VERBOSE[$inputTrimmed];
}
throw MDImporterMissingConcordance::setup("entry (to museum)", $input);
MDImporterMissingConcordance::throw("entry (to museum)", $input);
return "99"; // Return default in dry-run mode
}
}

View File

@@ -397,7 +397,8 @@ vermuteter Herstellungsort' => 1,
public static function getConcordanceTarget(string $input):int {
if (!isset(self::EVENT_TYPE_NAMES_TO_ID[$input])) {
throw MDImporterMissingConcordance::setup("event", $input);
MDImporterMissingConcordance::throw("event", $input);
return 1; // Return default in dry-run mode
}
return self::EVENT_TYPE_NAMES_TO_ID[$input];

View File

@@ -28,7 +28,7 @@ enum MDConcFieldRelatedWorksType {
*/
public static function fromString(string $input):MDConcFieldRelatedWorksType {
return match($input) {
$output = match($input) {
"Dokumentiert in",
"dokumentiert in",
@@ -199,8 +199,15 @@ enum MDConcFieldRelatedWorksType {
"" => self::undefined,
default => throw new MDpageParameterNotFromListException("Unknown target field for related works type: " . $input),
default => null,
};
if ($output === null) {
MDImporterMissingConcordance::throw("related work type", $input);
return self::undefined; // Return default in dry-run mode
}
return $output;
}
}

View File

@@ -86,7 +86,8 @@ final class MDConcLanguages implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::LANGUAGES_LIST[$input])) {
throw MDImporterMissingConcordance::setup("language", $input);
MDImporterMissingConcordance::throw("language", $input);
return "de"; // Return default in dry-run mode
}
return self::LANGUAGES_LIST[$input];

View File

@@ -163,7 +163,8 @@ final class MDConcLicenses implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::LICENSES_LIST[$input])) {
throw MDImporterMissingConcordance::setup("licence", $input);
MDImporterMissingConcordance::throw("licence", $input);
return "RR-F"; // Return default in dry-run mode
}
return self::LICENSES_LIST[$input];

View File

@@ -31,7 +31,8 @@ final class MDConcLoanTypes implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::LOAN_TYPES[$input])) {
throw MDImporterMissingConcordance::setup("loan", $input);
MDImporterMissingConcordance::throw("loan", $input);
return "outgoing"; // Return default in dry-run mode
}
return self::LOAN_TYPES[$input];

View File

@@ -23,6 +23,7 @@ final class MDConcMarkingPosition implements MDImporterConcordanceListInterface
"Mitte" => "center",
"vorn am Kasten, mittig, einseitig" => "center",
"an Gehäuse mittig" => "center",
'mitte' => 'center', // Center
// Left
"Links" => "left",
@@ -35,6 +36,7 @@ final class MDConcMarkingPosition implements MDImporterConcordanceListInterface
"Waagebalken links" => "left",
"Vorderseite links (Brusthöhe)" => "left",
"an Skala links und am Gehäuse Fronseite" => "left",
'mitte links' => 'left', // Left
// Right
"mittig rechts" => "right",
@@ -43,9 +45,13 @@ final class MDConcMarkingPosition implements MDImporterConcordanceListInterface
"rechts neben Bildnis" => "right",
"Rechter Bildrand" => "right",
"Balken rechts" => "right",
'Mitte rechts' => 'right', // Right
// Bottom
"unten" => "bottom",
'Mitte unten' => 'bottom', // Bottom
'unten links u. rechts' => 'bottom', // Bottom
'unten rechts/links' => 'bottom', // Bottom
"unter der Zeichnung" => "bottom",
"unter der Bild" => "bottom",
"unterer Bildrand" => "bottom",
@@ -166,6 +172,7 @@ final class MDConcMarkingPosition implements MDImporterConcordanceListInterface
"Rückseite Keilrahmen" => "rear_side",
"Rükseite" => "rear_side",
"Rückseite, unter Doublierung" => "rear_side",
'verso' => 'rear_side', // Rear side
// rear_bottom
"Rückseite unten" => "rear_bottom",
@@ -450,7 +457,8 @@ final class MDConcMarkingPosition implements MDImporterConcordanceListInterface
public static function getConcordanceTarget(string $input):string {
if (!isset(self::MARKING_POSITIONS_VERBOSE[$input])) {
throw MDImporterMissingConcordance::setup("marking position", $input);
MDImporterMissingConcordance::throw("marking position", $input);
return "other"; // Return default in dry-run mode
}
return self::MARKING_POSITIONS_VERBOSE[$input];

View File

@@ -16,6 +16,7 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
// Default: Handwritten
"-" => "handwritten",
"x" => "handwritten",
'Handschriftlich mit Bleistift - Signatur' => 'handwritten', // Handwritten
"schwarz" => "handwritten",
"braun" => "handwritten",
"Leinenarbeit" => "handwritten",
@@ -57,6 +58,25 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"aufgemalt/geschrieben" => "handwritten",
"Aufschrift" => "handwritten",
"Aufschrift (Bleistift)" => "handwritten",
'handschirftlich - Handschrift' => 'handwritten', // Handwritten
'handschirftlich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'handschriflich mit Bleistift - Handschrift' => 'handwritten', // Handwritten
'handschriflich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'handschrifltich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'handschriftich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'handschriftlich - Handschrift' => 'handwritten', // Handwritten
'handschriftlich mit Bleisift - Signatur' => 'handwritten', // Handwritten
'handschriftlich mit Bleistift - Beschriftung' => 'handwritten', // Handwritten
'handschriftlich mit Bleistift - Handschrift' => 'handwritten', // Handwritten
'handschriftlich mit Feder - Signatur' => 'handwritten', // Handwritten
'handschriftlich mit Kohle - Signatur' => 'handwritten', // Handwritten
'handschriftlich mit Kugelschreiber - Handschrift' => 'handwritten', // Handwritten
'handschriftlich mit schwarzer Kreide - Signatur' => 'handwritten', // Handwritten
'handschriftliche Dedikation - Handschrift' => 'handwritten', // Handwritten
'handschriftllich mit Bleistift - Handschrift' => 'handwritten', // Handwritten
'handschriftllich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'hanschriftlich mit Bleistift - Signatur' => 'handwritten', // Handwritten
'marking' => 'handwritten', // Handwritten
"Aufschrift mit Tinte" => "handwritten",
"Beischrift" => "handwritten",
"Benennung" => "handwritten",
@@ -230,6 +250,12 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"Druck, weiße Schrift" => "overprint",
"gedruckt und geprägt" => "overprint",
"gdruckt" => "overprint",
'gedruckt - Inschrift' => 'overprint', // Overprint
'gedruckt - Signatur' => 'overprint', // Overprint
'gedruckt - Stempel' => 'overprint', // Overprint
'gedruckt im Stein - Beschriftung' => 'overprint', // Overprint
'gedruckt im Stein - Inschrift' => 'overprint', // Overprint
'gedruckt im Stein - Signatur' => 'overprint', // Overprint
"gerduckt" => "overprint",
"goldener Druck mit Ornamenten und Zierrahmen" => "overprint",
"Golddruck" => "overprint",
@@ -299,11 +325,15 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"schwarz gestempelt" => "stamp",
"Signaturenstempel" => "stamp",
"stamped" => "stamp",
'gestemnpelt - Stempel' => 'stamp', // Stamped
'gestempelt - Signatur' => 'stamp', // Stamped
'gestempelt - Stempel' => 'stamp', // Stamped
"Stempel" => "stamp",
"Stempel (rund)" => "stamp",
"Stempel,Kugelschreiber" => "stamp",
"Stempel eingeprägt" => "stamp",
"Stempelaufdruck" => "stamp",
'Signatur gestempelt - Signatur' => 'stamp', // Stamped
"Beschriftung (gestempelt)" => "stamp",
"Beschriftung auf Montierung (gestempelt)" => "stamp",
@@ -399,6 +429,14 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"eingeritzt" => "scarified",
"handschliff" => "scarified",
"Schliff" => "scarified",
'Signatur geritzt - Signatur' => 'scarified', // Scarified
'Signatur geritzt in der Platte - Signatur' => 'scarified', // Scarified
'geritzt - Beschriftung' => 'scarified', // Scarified
'geritzt - Inschrift' => 'scarified', // Scarified
'geritzt - Marke' => 'scarified', // Scarified
'geritzt - Signatur' => 'scarified', // Scarified
'geritzt in der Platte - Beschriftung' => 'scarified', // Scarified
'geritzt in der Platte - Signatur' => 'scarified', // Scarified
# Hallmarked
"gepunzt" => "hallmarked",
@@ -416,7 +454,9 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"Signatur" => "signature",
"signiert" => "signature",
"farbig bemalt und glasiert" => "signature",
'geruckt - Signatur' => 'signature', // Signature
"gemalt und glasiert" => "signature",
'Signatur gedruckt im Stein - Signatur' => 'signature', // Signature
"Signatur (handschriftlich)" => "signature",
"Signatur (gedruckt)" => "signature",
"Signatur (gemalt)" => "signature",
@@ -432,14 +472,20 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
"Signatur mit Datum (gemalt)" => "signature",
"Signatur mit Datum (gestempelt)" => "signature",
"Signatur mit Datum (gezeichnet)" => "signature",
'signatur im Holzstock - Signatur' => 'signature', // Signature
'signatur im Stein - Signatur' => 'signature', // Signature
"Künstlersignatur" => "signature",
"Signatur (geritzt)" => "signature",
"Signatur mit Kugelschreiber" => "signature",
"handschriftlich mit Bleistift - Signatur" => "signature",
"im Stein - Signatur" => "signature",
'Signatur im Holzstock - Signatur' => "signature",
'Signatur im Stein - Signatur' => "signature",
'Signatur in der Platte - Signatur' => "signature",
# Watermark
"Wasserzeichen" => "watermark",
'Wasserzeichen - Wasserzeichen' => 'watermark', // Watermark
];
@@ -453,7 +499,8 @@ final class MDConcMarkingType implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::MARKING_TYPES_VERBOSE[$input])) {
throw MDImporterMissingConcordance::setup("marking", $input);
MDImporterMissingConcordance::throw("marking", $input);
return "marking"; // Return default in dry-run mode
}
return self::MARKING_TYPES_VERBOSE[$input];

View File

@@ -19,7 +19,7 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
*/
public static function getConcordanceTarget(string $input):MDMeasurementType|false {
return match($input) {
$output = match($input) {
// Just list entries
"Allgemein",
@@ -390,6 +390,8 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
"Höhe (S 6962/8)",
"Höhe (S 7083/3)",
"Höhe (S 7135/1c)",
"Höhe (Höhe)",
"Höhe (Mappe)",
"Höhe (c)",
"Höhe (g mit h)",
"Reliefhöhe" => MDMeasurementType::height,
@@ -414,6 +416,8 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
"Länge (g)",
"Länge (8)",
"Länge (1c)",
"Länge (Mappe)",
"Tiefe (Mappe)",
"Länge (S 6514/3)",
"Länge (S 6519/3)",
"Länge (S 7139/3)",
@@ -556,6 +560,8 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
" (Breite)",
"Breite (ein Nagel)",
"width",
"Breite (Breite)",
"Breite (Mappe)",
"Breite (S 6576/1)",
"Breite (mit Griffen)",
"Breite (mit Handhabe)",
@@ -761,6 +767,7 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
"Höhe (Druckstock/Bild)",
"Höhe max (Darstellung)",
"Höhe (Chine collé)",
"Höhe (Batt)",
"Bildmass (Höhe)" => MDMeasurementType::height_image_size,
"Breite (Bild)",
@@ -893,9 +900,16 @@ final class MDConcMeasurementTypes implements MDImporterConcordanceListInterface
"Bodendurchmesser",
"Durchmesser (Boden)" => MDMeasurementType::diameter_of_base,
default => throw MDImporterMissingConcordance::setup("measurements", $input),
default => null,
};
if ($output === null) {
MDImporterMissingConcordance::throw("measurements", $input);
return MDMeasurementType::diameter_of_base; // Return default in dry-run mode
}
return $output;
}
}

View File

@@ -26,7 +26,8 @@ final class MDConcObjectForms implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::FORMS_LIST[$input])) {
throw MDImporterMissingConcordance::setup("form/shape", $input);
MDImporterMissingConcordance::throw("form/shape", $input);
return 'cube'; // Return default in dry-run mode
}
return self::FORMS_LIST[$input];

View File

@@ -106,7 +106,8 @@ final class MDConcObjectTagRelTypes implements MDImporterConcordanceListInterfac
throw new MDImporterTagRelationTypeIsEventType("Tag-object relationship type is signifies not tags, but an event component.");
}
throw MDImporterMissingConcordance::setup("object-tag relationship", $input);
MDImporterMissingConcordance::throw("object-tag relationship", $input);
return 'tag'; // Return default in dry-run mode
}
}

View File

@@ -65,7 +65,8 @@ final class MDConcOwnershipStatus implements MDImporterConcordanceListInterface
if (isset(self::OWNERSHIP_TYPES_VERBOSE[trim($input)])) {
return self::OWNERSHIP_TYPES_VERBOSE[trim($input)];
}
throw MDImporterMissingConcordance::setup("ownership", $input);
MDImporterMissingConcordance::throw("ownership", $input);
return 'deaccessed'; // Return default in dry-run mode
}
return self::OWNERSHIP_TYPES_VERBOSE[$input];

View File

@@ -108,7 +108,8 @@ final class MDConcPlace implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):int {
if (!isset(self::PLACE_ROLES_TO_EVENT_TYPE[$input])) {
throw MDImporterMissingConcordance::setup("place (in event)", $input);
MDImporterMissingConcordance::throw("place (in event)", $input);
return 1; // Return default in dry-run mode
}
return self::PLACE_ROLES_TO_EVENT_TYPE[$input];

View File

@@ -27,7 +27,8 @@ final class MDConcSex implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::SEXES_LIST[$input])) {
throw MDImporterMissingConcordance::setup("sex", $input);
MDImporterMissingConcordance::throw("sex", $input);
return 'other'; // Return default in dry-run mode
}
return self::SEXES_LIST[$input];

View File

@@ -68,7 +68,8 @@ final class MDConcSourceTypes implements MDImporterConcordanceListInterface {
return self::SOURCE_TYPES[strtolower($input)];
}
throw MDImporterMissingConcordance::setup("source", $input);
MDImporterMissingConcordance::throw("source", $input);
return 'proceedings'; // Return default in dry-run mode
}
}

View File

@@ -54,7 +54,8 @@ final class MDConcTime implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):int {
if (!isset(self::TIME_ROLES_TO_EVENT_TYPE[$input])) {
throw MDImporterMissingConcordance::setup("time (in event)", $input);
MDImporterMissingConcordance::throw("time (in event)", $input);
return 1; // Return default in dry-run mode
}
return self::TIME_ROLES_TO_EVENT_TYPE[$input];

View File

@@ -45,7 +45,8 @@ final class MDConcTitleTypes implements MDImporterConcordanceListInterface {
public static function getConcordanceTarget(string $input):string {
if (!isset(self::TITLE_TYPES[$input])) {
throw MDImporterMissingConcordance::setup("title", $input);
MDImporterMissingConcordance::throw("title", $input);
return "Dialect"; // Return default in dry-run mode
}
return self::TITLE_TYPES[$input];