firefly-import-preprocessor/src/MetadataExtractor.php
Reindl David (IT-PTR-CEN2-SL10) 170b2d2016 release 1.0
2026-05-02 17:53:19 +02:00

127 lines
4.2 KiB
PHP

<?php
namespace UbsCsvTransformer;
/**
* Extrahiert Metadaten aus Header-Zeilen mit Regex
*
* Diese Klasse extrahiert konstante Werte aus den Metadatenzeilen
* (Header-Zeilen vor der eigentlichen CSV-Tabelle) mittels Regex-Regeln.
*/
class MetadataExtractor
{
private array $rules;
public function __construct(array $rules = [])
{
$this->rules = $rules;
}
/**
* Extrahiert Metadaten aus den übergebenen Zeilen
*
* @param array $lines Array von Zeilen aus dem CSV-Header
* @return array Extrahierte Metadaten
*/
public function extract(array $lines): array
{
$metadata = [];
foreach ($this->rules as $rule) {
// Validiere erforderliche Felder
if (empty($rule['name']) || empty($rule['regex'])) {
continue;
}
$ruleName = $rule['name'];
$lineNumber = $rule['lineNumber'] ?? 1;
$regex = $rule['regex'];
// ✅ KORRIGIERT: Off-by-One Fix
// config.json: "lineNumber": 1, 2, 3 (1-basiert, für Menschen lesbar)
// PHP Arrays: $lines[0], $lines[1], $lines[2] (0-basiert)
// Konvertierung: arrayIndex = lineNumber - 1
$arrayIndex = $lineNumber - 1;
// Prüfe ob Zeile existiert
if (!isset($lines[$arrayIndex])) {
// Zeile existiert nicht - Debug-Info für Support
DebugLogger::log('metadata_warning', "Extraction rule not found", [
'rule_name' => $ruleName,
'expected_lineNumber' => $lineNumber,
'array_index' => $arrayIndex,
'available_lines' => count($lines)
]);
continue;
}
$line = $lines[$arrayIndex];
// Regex mit '#' als Delimiter (erlaubt '/' in User-Patterns); '#' im Pattern escapen
$pattern = '#' . str_replace('#', '\#', $regex) . '#u';
$matchResult = @preg_match_all($pattern, $line, $matches);
if ($matchResult === false) {
DebugLogger::log('metadata_error', "Invalid regex pattern", [
'rule_name' => $ruleName,
'pattern' => $regex,
]);
continue;
}
if ($matchResult === 0) {
// Regex matched nicht auf dieser Zeile
DebugLogger::log('metadata_warning', "Regex did not match", [
'rule_name' => $ruleName,
'lineNumber' => $lineNumber,
'regex_pattern' => $regex,
'line_content' => substr($line, 0, 100)
]);
continue;
}
// ✅ KORRIGIERT: captureGroup benutzen
// captureGroup definiert welche Klammer-Gruppe extrahiert wird
// 0 = komplette Match
// 1 = erste Klammer-Gruppe (...)
// 2 = zweite Klammer-Gruppe, etc.
$captureGroup = isset($rule['captureGroup']) ? intval($rule['captureGroup']) : 1;
// Sicherstellen dass die Capture Group existiert
if (!isset($matches[$captureGroup]) || empty($matches[$captureGroup])) {
// Fallback: Nutze komplette Match wenn Gruppe nicht existiert
$metadata[$ruleName] = $matches[0][0] ?? '';
// echo "DEBUG: extraction_rule '{$ruleName}' - captureGroup {$captureGroup} not found, falling back to complete match\n";
} else {
// Nutze die spezifische Capture Group
$metadata[$ruleName] = $matches[$captureGroup][0] ?? '';
}
DebugLogger::log('metadata', "Extraction rule applied", [
'rule_name' => $ruleName,
'value' => $metadata[$ruleName] ?? null,
]);
}
return $metadata;
}
/**
* Gibt die Anzahl der definierten Extraction-Rules zurück
*
* @return int Anzahl Rules
*/
public function getRuleCount(): int
{
return count($this->rules);
}
/**
* Gibt alle definierten Extraction-Rules zurück
*
* @return array Die Rules
*/
public function getRules(): array
{
return $this->rules;
}
}