| Current Path : /home/seto/indexator.pm/src/Import/ |
| Current File : /home/seto/indexator.pm/src/Import/ImportService.php.bak-20260722-183427 |
<?php
namespace App\Import;
use App\Core\Database;
use App\Core\Request;
use App\Urls\UrlNormalizer;
use App\Urls\UrlRepository;
use App\Urls\UrlValidator;
class ImportService
{
private UrlValidator $validator;
private UrlNormalizer $normalizer;
private UrlRepository $urlRepo;
public function __construct(private Database $db)
{
$this->validator = new UrlValidator();
$this->normalizer = new UrlNormalizer();
$this->urlRepo = new UrlRepository($db);
}
/**
* Import URLs into a project from the given source.
*
* @return array{imported: int, duplicates: int, invalid: int}
* @throws \RuntimeException on sitemap fetch / file read failure
*/
public function import(int $projectId, string $sourceType, Request $request): array
{
$rawUrls = $this->extractRaw($sourceType, $request);
$sourceType = in_array($sourceType, ['manual', 'file', 'sitemap'], true)
? $sourceType : 'manual';
return $this->processAndInsert($projectId, $rawUrls, $sourceType);
}
// ── Private ──────────────────────────────────────────────────────────────
private function extractRaw(string $sourceType, Request $request): array
{
return match($sourceType) {
'file' => $this->fromFile($request),
'sitemap' => $this->fromSitemap($request),
default => $this->fromManual($request),
};
}
private function fromManual(Request $request): array
{
$text = (string) $request->post('urls_manual', '');
return (new ManualImporter())->parse($text);
}
private function fromFile(Request $request): array
{
$file = $request->file('urls_file');
if (!$file) {
return [];
}
return (new FileImporter())->parse($file);
}
private function fromSitemap(Request $request): array
{
$sitemapUrl = trim((string) $request->post('sitemap_url', ''));
if ($sitemapUrl === '') {
return [];
}
$config = $GLOBALS['config'];
$importer = new SitemapImporter($config);
return $importer->fetch($sitemapUrl);
}
private function processAndInsert(int $projectId, array $rawUrls, string $sourceType): array
{
$report = ['imported' => 0, 'duplicates' => 0, 'invalid' => 0];
if (empty($rawUrls)) {
return $report;
}
// Deduplicate raw input first
$seen = [];
$toInsert = [];
foreach ($rawUrls as $raw) {
$raw = trim($raw);
if (!$this->validator->isValid($raw)) {
$report['invalid']++;
continue;
}
$normalized = $this->normalizer->normalize($raw);
if (isset($seen[$normalized])) {
$report['duplicates']++;
continue;
}
$seen[$normalized] = true;
$toInsert[] = ['url' => $raw, 'normalized_url' => $normalized];
}
// Count how many already exist in DB (will be ignored by INSERT OR IGNORE)
$beforeCount = $this->urlRepo->countByProject($projectId);
$this->urlRepo->bulkInsert($projectId, $toInsert, $sourceType);
$afterCount = $this->urlRepo->countByProject($projectId);
$inserted = $afterCount - $beforeCount;
$dbDuplicates = count($toInsert) - $inserted;
$report['imported'] = $inserted;
$report['duplicates'] += $dbDuplicates;
return $report;
}
}