changes 0129092025 laptop

This commit is contained in:
2025-09-29 17:35:54 +02:00
parent 30eee6c5b0
commit 1fddf959f0
7 changed files with 277 additions and 4 deletions
+25 -1
View File
@@ -171,12 +171,27 @@ public function columns(Request $request, Import $import, CsvImportService $csv)
{
$validated = $request->validate([
'has_header' => 'nullable|boolean',
'delimiter' => 'nullable|string|max:4',
]);
$hasHeader = array_key_exists('has_header', $validated)
? (bool) $validated['has_header']
: (bool) ($import->meta['has_header'] ?? true);
// Resolve delimiter preference: explicit param > template meta > existing meta > auto-detect
$explicitDelimiter = null;
if (array_key_exists('delimiter', $validated) && $validated['delimiter'] !== null && $validated['delimiter'] !== '') {
$explicitDelimiter = (string) $validated['delimiter'];
} elseif ($import->import_template_id) {
// Try reading template meta for a default delimiter
$tplDelimiter = optional(ImportTemplate::find($import->import_template_id))->meta['delimiter'] ?? null;
if ($tplDelimiter) {
$explicitDelimiter = (string) $tplDelimiter;
}
} elseif (!empty($import->meta['forced_delimiter'] ?? null)) {
$explicitDelimiter = (string) $import->meta['forced_delimiter'];
}
// Only implement CSV/TSV detection for now; others can be added later
if (!in_array($import->source_type, ['csv','txt'])) {
return response()->json([
@@ -186,13 +201,21 @@ public function columns(Request $request, Import $import, CsvImportService $csv)
}
$fullPath = Storage::disk($import->disk)->path($import->path);
[$delimiter, $columns] = $csv->detectColumnsFromCsv($fullPath, $hasHeader);
if ($explicitDelimiter !== null && $explicitDelimiter !== '') {
$columns = $csv->parseColumnsFromCsv($fullPath, $explicitDelimiter, $hasHeader);
$delimiter = $explicitDelimiter;
} else {
[$delimiter, $columns] = $csv->detectColumnsFromCsv($fullPath, $hasHeader);
}
// Save meta
$meta = $import->meta ?? [];
$meta['has_header'] = $hasHeader;
$meta['detected_delimiter'] = $delimiter;
$meta['columns'] = $columns;
if ($explicitDelimiter) {
$meta['forced_delimiter'] = $explicitDelimiter;
}
$import->update([
'meta' => $meta,
'status' => $import->status === 'uploaded' ? 'parsed' : $import->status,
@@ -336,6 +359,7 @@ public function show(Import $import)
'import_templates.source_type',
'import_templates.default_record_type',
'import_templates.client_id',
'import_templates.meta',
'clients.uuid as client_uuid',
]);
@@ -227,8 +227,20 @@ public function update(Request $request, ImportTemplate $template)
'client_id' => 'nullable|integer|exists:clients,id',
'is_active' => 'boolean',
'sample_headers' => 'nullable|array',
'meta' => 'nullable|array',
'meta.delimiter' => 'nullable|string|max:4',
])->validate();
// Merge meta safely, preserving existing keys when not provided
$newMeta = $template->meta ?? [];
if (array_key_exists('meta', $data) && is_array($data['meta'])) {
$newMeta = array_merge($newMeta, $data['meta']);
// Drop empty delimiter to allow auto-detect
if (array_key_exists('delimiter', $newMeta) && (!is_string($newMeta['delimiter']) || trim((string) $newMeta['delimiter']) === '')) {
unset($newMeta['delimiter']);
}
}
$template->update([
'name' => $data['name'],
'description' => $data['description'] ?? null,
@@ -237,6 +249,7 @@ public function update(Request $request, ImportTemplate $template)
'client_id' => $data['client_id'] ?? null,
'is_active' => $data['is_active'] ?? $template->is_active,
'sample_headers' => $data['sample_headers'] ?? $template->sample_headers,
'meta' => $newMeta,
]);
return redirect()->route('importTemplates.edit', ['template' => $template->uuid])
+26
View File
@@ -62,4 +62,30 @@ public function detectColumnsFromCsv(string $path, bool $hasHeader): array
return [$bestDelim, $clean];
}
/**
* Parse columns from CSV using a specific delimiter. If $hasHeader is false,
* returns positional indices instead of header names.
*/
public function parseColumnsFromCsv(string $path, string $delimiter, bool $hasHeader): array
{
$firstLine = $this->readFirstLine($path);
if ($firstLine === null) {
return [];
}
$row = str_getcsv($firstLine, $delimiter);
$count = is_array($row) ? count($row) : 0;
if ($hasHeader) {
return array_map(function ($v) {
$v = trim((string) $v);
$v = preg_replace('/\s+/', ' ', $v);
return $v;
}, $row ?: []);
}
$cols = [];
for ($i = 0; $i < $count; $i++) {
$cols[] = (string) $i;
}
return $cols;
}
}
+5 -1
View File
@@ -58,7 +58,11 @@ public function process(Import $import, ?Authenticatable $user = null): array
->get(['source_column', 'target_field', 'transform', 'apply_mode', 'options']);
$header = $import->meta['columns'] ?? null;
$delimiter = $import->meta['detected_delimiter'] ?? ',';
// Prefer explicitly chosen delimiter, then template meta, else detected
$delimiter = $import->meta['forced_delimiter']
?? optional($import->template)->meta['delimiter']
?? $import->meta['detected_delimiter']
?? ',';
$hasHeader = (bool) ($import->meta['has_header'] ?? true);
$path = Storage::disk($import->disk)->path($import->path);