92 lines
2.6 KiB
PHP
92 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
class CsvImportService
|
|
{
|
|
/**
|
|
* Read the first line of a file; returns null on failure.
|
|
*/
|
|
public function readFirstLine(string $path): ?string
|
|
{
|
|
$fh = @fopen($path, 'r');
|
|
if (!$fh) return null;
|
|
$line = fgets($fh);
|
|
fclose($fh);
|
|
return $line === false ? null : $line;
|
|
}
|
|
|
|
/**
|
|
* Detect delimiter and return columns for first row.
|
|
* If $hasHeader is false, returns positional indices instead of header names.
|
|
* Returns [delimiter, columns].
|
|
*/
|
|
public function detectColumnsFromCsv(string $path, bool $hasHeader): array
|
|
{
|
|
// Use actual tab character for TSV; keep other common delimiters
|
|
$delims = [',',';','|',"\t"];
|
|
$bestDelim = ',';
|
|
$bestCols = [];
|
|
|
|
$firstLine = $this->readFirstLine($path);
|
|
if ($firstLine === null) {
|
|
return [$bestDelim, []];
|
|
}
|
|
|
|
$maxCount = 0;
|
|
foreach ($delims as $d) {
|
|
$row = str_getcsv($firstLine, $d);
|
|
$count = is_array($row) ? count($row) : 0;
|
|
if ($count > $maxCount) {
|
|
$maxCount = $count;
|
|
$bestDelim = $d;
|
|
$bestCols = $row;
|
|
}
|
|
}
|
|
|
|
if (!$hasHeader) {
|
|
// return positional indices 0..N-1
|
|
$cols = [];
|
|
for ($i = 0; $i < $maxCount; $i++) {
|
|
$cols[] = (string) $i;
|
|
}
|
|
return [$bestDelim, $cols];
|
|
}
|
|
|
|
// Clean header names
|
|
$clean = array_map(function ($v) {
|
|
$v = trim((string) $v);
|
|
$v = preg_replace('/\s+/', ' ', $v);
|
|
return $v;
|
|
}, $bestCols);
|
|
|
|
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;
|
|
}
|
|
}
|