Files
myep-team/src/MyEp/Api/ResponseMapper.php
T

142 lines
3.9 KiB
PHP

<?php
namespace App\MyEp\Api;
use App\BusProNet\Model\Country;
use App\BusProNet\Model\Hotel;
use App\BusProNet\Model\Pickup;
use Psr\Log\LoggerInterface;
/**
* Turns MyE&P list responses into the BusProNet models the application already works
* with, keyed the way the data providers expose them.
*
* The id MyE&P reports for hotels and pickups is the BusProNet idbuspro, so it fills
* both the id and the busProId of the models.
*/
class ResponseMapper
{
public function __construct(private readonly LoggerInterface $logger)
{
}
/**
* @return array<int, Hotel> keyed by busProId
*/
public function mapHotels(array $rows): array
{
$hotels = [];
foreach ($rows as $row) {
if (null === $busProId = $this->readBusProId($row, 'hotel')) {
continue;
}
$hotel = new Hotel();
$hotel
->setBusProId($busProId)
->setCode($this->readString($row, 'code'))
->setName($this->readString($row, 'name'))
->setCountry($this->readString($row, 'country'))
->setCountryCode($this->readCountryCode($row))
->setCostUnit($this->readString($row, 'costUnit'))
;
$hotels[$busProId] = $hotel;
}
return $hotels;
}
/**
* @return array<int, Pickup> keyed by busProId
*/
public function mapPickups(array $rows): array
{
$pickups = [];
foreach ($rows as $row) {
if (null === $busProId = $this->readBusProId($row, 'pickup')) {
continue;
}
$pickup = new Pickup();
$pickup
->setId($busProId)
->setBusProId($busProId)
->setCode($this->readString($row, 'code'))
->setCity($this->readString($row, 'city'))
->setStreet($this->readString($row, 'street'))
;
// the time is a property of a boarding stop on a date, never of the stop itself
$pickups[$busProId] = $pickup;
}
return $pickups;
}
/**
* @return array<string, Country> keyed by token
*/
public function mapCountries(array $rows): array
{
$countries = [];
foreach ($rows as $row) {
$token = is_array($row) ? $this->readString($row, 'token') : null;
if (null === $token || '' === $token) {
$this->logger->warning('Skipped a MyE&P country without a token', ['row' => $row]);
continue;
}
$country = new Country();
$country
->setName($this->readString($row, 'name'))
->setToken($token)
->setNationality($this->readString($row, 'nationality'))
;
$countries[$token] = $country;
}
return $countries;
}
private function readCountryCode(array $row): ?string
{
$countryCode = CountryCode::normalize($row['countryCode'] ?? null);
if (null === $countryCode && null !== ($row['country'] ?? null)) {
$this->logger->warning('MyE&P reported a hotel country it could not map to ISO', [
'id' => $row['id'] ?? null,
'country' => $row['country'],
'countryCode' => $row['countryCode'] ?? null,
]);
}
return $countryCode;
}
private function readBusProId(mixed $row, string $type): ?int
{
$busProId = is_array($row) ? (int) ($row['id'] ?? 0) : 0;
if (0 === $busProId) {
$this->logger->warning(sprintf('Skipped a MyE&P %s without an id', $type), ['row' => $row]);
return null;
}
return $busProId;
}
private function readString(array $row, string $key): ?string
{
$value = $row[$key] ?? null;
return null === $value ? null : (string) $value;
}
}