chill-bundles/src/Bundle/ChillMainBundle/Service/Import/PostalCodeBEFromBestAddress.php

106 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\Import;
use League\Csv\Reader;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class PostalCodeBEFromBestAddress
{
private const RELEASE = 'https://gitea.champs-libres.be/api/v1/repos/Chill-project/belgian-bestaddresses-transform/releases/tags/v1.0.0';
private PostalCodeBaseImporter $baseImporter;
private HttpClientInterface $client;
private LoggerInterface $logger;
public function __construct(PostalCodeBaseImporter $baseImporter, HttpClientInterface $client, LoggerInterface $logger)
{
$this->baseImporter = $baseImporter;
$this->client = $client;
$this->logger = $logger;
}
public function import(string $lang = 'fr'): void
{
$fileDownloadUrl = $this->getFileDownloadUrl($lang);
$response = $this->client->request('GET', $fileDownloadUrl);
$tmpname = tempnam(sys_get_temp_dir(), 'postalcodes');
$tmpfile = fopen($tmpname, 'r+b');
if (false === $tmpfile) {
throw new RuntimeException('could not create temporary file');
}
foreach ($this->client->stream($response) as $chunk) {
fwrite($tmpfile, $chunk->getContent());
}
fclose($tmpfile);
$uncompressedStream = gzopen($tmpname, 'r');
$csv = Reader::createFromStream($uncompressedStream);
$csv->setDelimiter(',');
$csv->setHeaderOffset(0);
foreach ($csv as $offset => $record) {
$this->handleRecord($record);
}
gzclose($uncompressedStream);
unlink($tmpname);
$this->logger->info(__CLASS__ . ' list of postal code downloaded');
$this->baseImporter->finalize();
$this->logger->info(__CLASS__ . ' postal code fetched', ['offset' => $offset ?? 0]);
}
private function getFileDownloadUrl(string $lang): string
{
try {
$release = $this->client->request('GET', self::RELEASE)
->toArray();
} catch (TransportExceptionInterface $e) {
throw new RuntimeException('could not get the release definition', 0, $e);
}
$postals = array_filter($release['assets'], static function (array $item) use ($lang) {
return 'postals.' . $lang . '.csv.gz' === $item['name'];
});
return array_values($postals)[0]['browser_download_url'];
}
private function handleRecord(array $record): void
{
$this->baseImporter->importCode(
'BE',
trim($record['municipality_name']),
trim($record['postal_info_objectid']),
$record['municipality_objectid'],
'bestaddress',
$record['Y'],
$record['X'],
3812
);
}
}