diff --git a/CHANGELOG.md b/CHANGELOG.md index 857cc5ab..81d229f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,30 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.ht --- +## [2.42.2] — 2026-09-17 + +Der Batch-Import trennte Schlagworte an Kommas — das Formular tut das ausdrücklich nicht. + +### 🐛 Fixed +- **Import und Formular widersprachen sich bei Schlagworten mit Komma.** Das Formular warnt + seit jeher: „Trennen Sie die Schlagwörter nicht mit Komma" — ein Komma darf Teil eines + Schlagworts sein (z. B. „Berlin, Stadt"). Der Batch-Import spaltete dieselbe Eingabe aber an + Komma **und** Zeilenumbruch. Dieselben Rohdaten ergaben je nach Weg ein anderes Ergebnis, und + ein per Komma geschriebenes Schlagwort landete beim Veröffentlichen unbemerkt als mehrere + `dcat:keyword`-Werte statt einem. Aufgefallen an den eigenen Beispieldateien: `"Demografie, + Statistik"` wurde beim Import zu zwei Schlagworten, im Formular wäre es eines geblieben. Der + Import trennt jetzt wie das Formular ausschließlich an Zeilenumbrüchen; mehrere Zeilen passen + in eine CSV-Zelle, wenn sie in Anführungszeichen steht (Excel/LibreOffice schreiben das beim + Export automatisch so). +- **`samples/import-example.csv` und `.json` gingen mit schlechtem Beispiel voran** — beide + nutzten kommagetrennte Schlagworte. Auf Zeilentrennung umgestellt. + +Tests: ein bestehender Test verlangte die alte, falsche Form (Komma spaltet) und ist jetzt auf +das richtige Verhalten umgestellt; ein neuer Test hält fest, dass ein Komma innerhalb eines +Schlagworts erhalten bleibt. + +--- + ## [2.42.1] — 2026-09-17 Der empfohlene Harvest-Endpunkt lieferte Turtle, das **kein RDF-Parser lesen konnte** — und diff --git a/CLAUDE.md b/CLAUDE.md index 2054e6d5..12b7af7c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -765,7 +765,7 @@ Update **both** locations: - MINOR: New features (backward-compatible) - PATCH: Bug fixes only -Current: **v2.42.1** +Current: **v2.42.2** --- diff --git a/README.md b/README.md index 80445a26..93b8157d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
-
+
@@ -149,7 +149,7 @@ Importiere mehrere Datensätze auf einmal aus CSV oder JSON Dateien. Der Import-
- `language` — Sprache (z.B. de, en)
- `format` — Dateiformat (z.B. CSV, JSON, PDF)
- `issued` — Veröffentlichungsdatum
-- `keywords` — Schlagworte (komma-getrennt)
+- `keywords` — Schlagworte (eine pro Zeile, wie im Formular — kein Komma als Trenner: In eine CSV-Zelle passen mehrere Zeilen, wenn sie in Anführungszeichen steht)
- `byte_size` — Dateigröße in Bytes (nur ganze Zahl; abweichende Werte werden als Fehler markiert)
- `attribution` — Namensnennungstext
diff --git a/includes/class-batch-import.php b/includes/class-batch-import.php
index f4302da4..48a7fe89 100644
--- a/includes/class-batch-import.php
+++ b/includes/class-batch-import.php
@@ -489,9 +489,18 @@ private static function create_dataset_from_record( array $record, int $row_inde
if ( 'byte_size' === $field ) {
$value = (string) absint( $value );
} elseif ( 'keywords' === $field ) {
- // Schlagworte werden intern zeilengetrennt gespeichert. Import
- // erlaubt Komma- ODER Zeilentrennung — beides zu Zeilen normalisieren.
- $split = preg_split( '/[\r\n,]+/', self::neutralize_formula( $value ) );
+ // Schlagworte werden intern zeilengetrennt gespeichert — genau wie
+ // im Formular, das ausdrücklich vor Kommas warnt (ein Komma im
+ // Schlagwort ist zulässig, z. B. „Berlin, Stadt"). Bis v2.42.1
+ // spaltete der Import zusätzlich an Kommas: Dieselbe Eingabe ergab
+ // im Formular ein Schlagwort, im Import zwei — und ein via Komma
+ // geschriebenes Schlagwort landete im veröffentlichten JSON-LD als
+ // mehrere `dcat:keyword`-Werte, ohne dass jemand das so eingegeben
+ // hätte. Nur noch Zeilenumbrüche trennen; ein Komma bleibt Teil des
+ // Schlagworts. Mehrere Zeilen in einer CSV-Zelle: Feld in
+ // Anführungszeichen setzen, Zeilenumbrüche darin bleiben erhalten
+ // (Excel/LibreOffice tun das beim Export automatisch).
+ $split = preg_split( '/[\r\n]+/', self::neutralize_formula( $value ) );
$parts = array_values(
array_filter(
array_map( 'trim', is_array( $split ) ? $split : array() ),
diff --git a/open-data-wizard.php b/open-data-wizard.php
index 58d971e5..daa86f7d 100644
--- a/open-data-wizard.php
+++ b/open-data-wizard.php
@@ -3,7 +3,7 @@
* Plugin Name: Open Data Wizard
* Plugin URI: https://github.com/daimpad/OpenDataWizard
* Description: DCAT-AP 3.0 konforme Open Data Metadatenverwaltung für WordPress. Bereitstellung als maschinenlesbarer JSON-LD-Endpoint für offene Daten.
- * Version: 2.42.1
+ * Version: 2.42.2
* Requires at least: 6.4
* Requires PHP: 8.1
* Author: nozilla
@@ -26,7 +26,7 @@
exit;
}
-define( 'ODW_VERSION', '2.42.1' );
+define( 'ODW_VERSION', '2.42.2' );
define( 'ODW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'ODW_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'ODW_PLUGIN_FILE', __FILE__ );
diff --git a/package.json b/package.json
index 0976c398..eb90a12d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "open-data-wizard",
- "version": "2.42.1",
+ "version": "2.42.2",
"description": "WordPress plugin for publishing open data as DCAT-AP 3.0 compliant metadata",
"author": "Open Data Wizard Team",
"license": "GPL-2.0-or-later",
diff --git a/samples/import-example.csv b/samples/import-example.csv
index 663368d9..54691951 100644
--- a/samples/import-example.csv
+++ b/samples/import-example.csv
@@ -1,6 +1,13 @@
title,publisher,description,access_url,license,theme,language,format,issued,keywords
-"Bevölkerungszahlen 2024","Statistisches Amt","Bevölkerungszahlen nach Stadt und Jahr für 2024","https://example.com/data/population-2024.csv","cc-by","SOCI","de","CSV","2024-01-15","Demografie, Statistik"
-"Arbeitslosenquoten 2024","Arbeitsamt","Monatliche Arbeitslosenquoten nach Bundesland","https://example.com/data/unemployment.xlsx","cc0","ECON","de","XLSX","2024-02-01","Beschäftigung, Wirtschaft"
-"Schulstandorte","Bildungsministerium","Verzeichnis aller öffentlichen Schulen mit Adressen","https://example.com/data/schools.geojson","cc-by-sa","EDUC","de","GeoJSON","2024-01-01","Schulen, Bildung, Geolocation"
-"Breitbandverfügbarkeit","Telekommunikationsbehörde","Verfügbarkeit von Breitbandanbindung nach Postleitzahl","https://example.com/data/broadband.csv","cc0","TECH","de","CSV","2024-03-01","Internet, Infrastruktur"
-"Energieverbrauch nach Sektor 2023","Energieamt","Jährlicher Energieverbrauch nach Wirtschaftssektor","https://example.com/data/energy.json","cc-by","ENVI","de","JSON","2023-12-31","Energie, Umwelt, Statistik"
+"Bevölkerungszahlen 2024","Statistisches Amt","Bevölkerungszahlen nach Stadt und Jahr für 2024","https://example.com/data/population-2024.csv","cc-by","SOCI","de","CSV","2024-01-15","Demografie
+Statistik"
+"Arbeitslosenquoten 2024","Arbeitsamt","Monatliche Arbeitslosenquoten nach Bundesland","https://example.com/data/unemployment.xlsx","cc0","ECON","de","XLSX","2024-02-01","Beschäftigung
+Wirtschaft"
+"Schulstandorte","Bildungsministerium","Verzeichnis aller öffentlichen Schulen mit Adressen","https://example.com/data/schools.geojson","cc-by-sa","EDUC","de","GeoJSON","2024-01-01","Schulen
+Bildung
+Geolocation"
+"Breitbandverfügbarkeit","Telekommunikationsbehörde","Verfügbarkeit von Breitbandanbindung nach Postleitzahl","https://example.com/data/broadband.csv","cc0","TECH","de","CSV","2024-03-01","Internet
+Infrastruktur"
+"Energieverbrauch nach Sektor 2023","Energieamt","Jährlicher Energieverbrauch nach Wirtschaftssektor","https://example.com/data/energy.json","cc-by","ENVI","de","JSON","2023-12-31","Energie
+Umwelt
+Statistik"
diff --git a/samples/import-example.json b/samples/import-example.json
index 180c7cb7..20c91b3a 100644
--- a/samples/import-example.json
+++ b/samples/import-example.json
@@ -9,7 +9,7 @@
"language": "de",
"format": "CSV",
"issued": "2024-01-15",
- "keywords": "Demografie, Statistik"
+ "keywords": "Demografie\nStatistik"
},
{
"title": "Arbeitslosenquoten 2024",
@@ -21,7 +21,7 @@
"language": "de",
"format": "XLSX",
"issued": "2024-02-01",
- "keywords": "Beschäftigung, Wirtschaft"
+ "keywords": "Beschäftigung\nWirtschaft"
},
{
"title": "Schulstandorte",
@@ -33,7 +33,7 @@
"language": "de",
"format": "GeoJSON",
"issued": "2024-01-01",
- "keywords": "Schulen, Bildung, Geolocation"
+ "keywords": "Schulen\nBildung\nGeolocation"
},
{
"title": "Breitbandverfügbarkeit",
@@ -45,7 +45,7 @@
"language": "de",
"format": "CSV",
"issued": "2024-03-01",
- "keywords": "Internet, Infrastruktur"
+ "keywords": "Internet\nInfrastruktur"
},
{
"title": "Energieverbrauch nach Sektor 2023",
@@ -57,6 +57,6 @@
"language": "de",
"format": "JSON",
"issued": "2023-12-31",
- "keywords": "Energie, Umwelt, Statistik"
+ "keywords": "Energie\nUmwelt\nStatistik"
}
]
diff --git a/tests/test-batch-import.php b/tests/test-batch-import.php
index 18dad755..4e397786 100644
--- a/tests/test-batch-import.php
+++ b/tests/test-batch-import.php
@@ -509,21 +509,40 @@ public function test_import_maps_license_short_code_to_https_uri(): void {
}
/**
- * Keywords may arrive comma- or newline-separated; internally they are
- * stored one per line.
+ * Keywords are stored one per line — only newlines separate them, exactly
+ * like the form field. Blank lines in between are dropped.
*/
public function test_import_normalises_keywords_to_one_per_line(): void {
$meta = array();
$this->mock_import_environment( $meta );
$record = $this->valid_record( 'Mit Schlagworten' );
- $record['keywords'] = 'Bäume, Umwelt ,, Klima';
+ $record['keywords'] = "Bäume\n\nUmwelt\n \nKlima";
ODW_Batch_Import::import_records( array( $record ) );
$this->assertSame( "Bäume\nUmwelt\nKlima", $meta['_odw_keywords'] );
}
+ /**
+ * A comma inside a keyword must survive the import — it is not a
+ * separator here. Until v2.42.1 the import split on commas too, so the
+ * same value produced one keyword via the form but several via import,
+ * and a genuinely comma-containing keyword (e.g. „Berlin, Stadt") was
+ * silently split into two `dcat:keyword` values on publish.
+ */
+ public function test_import_keeps_comma_within_a_single_keyword(): void {
+ $meta = array();
+ $this->mock_import_environment( $meta );
+
+ $record = $this->valid_record( 'Komma im Schlagwort' );
+ $record['keywords'] = 'Demografie, Statistik';
+
+ ODW_Batch_Import::import_records( array( $record ) );
+
+ $this->assertSame( 'Demografie, Statistik', $meta['_odw_keywords'] );
+ }
+
/**
* A failing wp_insert_post() is counted and reported with its row number
* instead of aborting the whole import.