Use dedicated territory service to get territory data from nominatim

This commit is contained in:
2025-01-26 14:23:04 +01:00
parent 6d7b210d13
commit 99a044ee95
2 changed files with 82 additions and 0 deletions
+21
View File
@@ -5,11 +5,13 @@ namespace App\Library\Benzina\Pump;
use App\Entity\Accounting\Accounting;
use App\Entity\Project\Project;
use App\Entity\Project\ProjectStatus;
use App\Entity\Project\ProjectTerritory;
use App\Entity\User\User;
use App\Library\Benzina\Pump\Trait\ArrayPumpTrait;
use App\Library\Benzina\Pump\Trait\DoctrinePumpTrait;
use App\Repository\User\UserRepository;
use App\Service\LocalizationService;
use App\Service\Project\TerritoryService;
use Doctrine\ORM\EntityManagerInterface;
class ProjectsPump extends AbstractPump implements PumpInterface
@@ -22,6 +24,7 @@ class ProjectsPump extends AbstractPump implements PumpInterface
private UserRepository $userRepository,
private EntityManagerInterface $entityManager,
private LocalizationService $localizationService,
private TerritoryService $territoryService,
) {}
public function supports(mixed $batch): bool
@@ -52,6 +55,7 @@ class ProjectsPump extends AbstractPump implements PumpInterface
$project->setTranslatableLocale($this->getProjectLang($record['lang']));
$project->setTitle($record['name']);
$project->setSubtitle($record['subtitle']);
$project->setTerritory($this->getProjectTerritory($record));
$project->setDescription($record['description']);
$project->setOwner($owners[$record['owner']]);
$project->setStatus($this->getProjectStatus($record['status']));
@@ -107,6 +111,23 @@ class ProjectsPump extends AbstractPump implements PumpInterface
return $this->localizationService->getLanguage($lang);
}
private function getProjectTerritory(array $record): ProjectTerritory
{
if (empty($record['country'])) {
return ProjectTerritory::unknown();
}
if (!empty($record['project_location'])) {
$cleanLocation = self::cleanProjectLocation($record['project_location']);
if ($cleanLocation !== '') {
return $this->territoryService->search($cleanLocation);
}
}
return $this->territoryService->search($record['country']);
}
private function getProjectStatus(int $status): ProjectStatus
{
switch ($status) {
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace App\Service\Project;
use App\Entity\Project\ProjectTerritory;
use App\Service\Nominatim\NominatimService;
class TerritoryService
{
public function __construct(
private NominatimService $nominatimService,
) {}
public function search(string $query): ProjectTerritory
{
$search = $this->nominatimService->search($query);
if (empty($search)) {
return ProjectTerritory::unknown();
}
$result = $search[0];
if (!\array_key_exists('address', $result)) {
throw new \Exception("Key 'address' not found in Nominatim result. Did you forget to pass `addressDetails = true`?");
}
$address = $result['address'];
if (!\array_key_exists('country_code', $address)) {
return ProjectTerritory::unknown();
}
return $this->processResultAddress($address);
}
private function processResultAddress(array $address): ProjectTerritory
{
$country = \strtoupper($address['country_code']);
$subLvl1 = null;
$subLvl2 = null;
foreach ($address as $addrKey => $addrVal) {
if (!\str_starts_with($addrKey, 'ISO3166-2')) {
continue;
}
$level = \array_reverse(\explode('-', $addrKey))[0];
$level = \intval(\str_replace('lvl', '', $level));
if ($level < 5) {
$subLvl1 = $addrVal;
} else {
$subLvl2 = $addrVal;
}
}
return new ProjectTerritory($country, $subLvl1, $subLvl2);
}
}