czydojade/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php
2018-09-19 22:17:31 +02:00

195 lines
7.3 KiB
PHP

<?php
namespace App\Provider\ZtmGdansk;
use App\Entity\LineEntity;
use App\Entity\OperatorEntity;
use App\Entity\ProviderEntity;
use App\Entity\StopEntity;
use App\Entity\StopInTrack;
use App\Entity\TrackEntity;
use App\Model\Line as LineModel;
use App\Provider\ZtmGdansk\ZtmGdanskProvider;
use App\Service\DataUpdater;
use App\Service\IdUtils;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
{
const OPERATORS_URL = "http://91.244.248.19/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/8b3aa347-3bb7-4c58-9113-d47458ec1fc3/download/agency.json";
const LINES_URL = "http://91.244.248.19/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/4128329f-5adb-4082-b326-6e1aea7caddf/download/routes.json";
const STOPS_URL = "http://91.244.248.19/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/cd4c08b5-460e-40db-b920-ab9fc93c1a92/download/stops.json";
const TRACKS_URL = "http://91.244.248.19/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/33618472-342c-4a4a-ba88-a911ec0ad5a7/download/trips.json";
const STOPS_IN_TRACKS_URL = "http://91.244.248.19/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/0f2de200-e78b-4183-ae0d-071d7f07fc3f/download/stopsintrips.json";
private $em;
private $ids;
private $logger;
private $provider;
/**
* ZtmGdanskDataUpdateSubscriber constructor.
*
* @param $provider
* @param $em
*/
public function __construct(
EntityManagerInterface $em,
IdUtils $ids,
LoggerInterface $logger,
ZtmGdanskProvider $provider
) {
$this->em = $em;
$this->ids = $ids;
$this->logger = $logger;
$this->provider = $provider;
}
public function update()
{
$provider = ProviderEntity::createFromArray([
'name' => $this->provider->getName(),
'class' => ZtmGdanskProvider::class,
'id' => $this->provider->getIdentifier(),
]);
$this->em->persist($provider);
$save = [$this->em, 'persist'];
$this->getOperators($provider)->each($save);
$this->getLines($provider)->each($save);
$this->getStops($provider)->each($save);
$this->getTracks($provider)->each($save);
$this->em->flush();
}
private function getOperators(ProviderEntity $provider)
{
$this->logger->info('Obtaining operators from ZTM Gdańsk');
$operators = file_get_contents(self::OPERATORS_URL);
$operators = json_decode($operators, true)['agency'];
$this->logger->info(sprintf('Saving %s operators from ZTM Gdańsk', count($operators)));
return collect($operators)->map(function ($operator) use ($provider) {
return OperatorEntity::createFromArray([
'id' => $this->ids->generate($provider, $operator['agencyId']),
'name' => $operator['agencyName'],
'provider' => $provider,
]);
});
}
private function getLines(ProviderEntity $provider)
{
$this->logger->info('Obtaining lines from ZTM Gdańsk');
$lines = file_get_contents(self::LINES_URL);
$lines = json_decode($lines, true)[date('Y-m-d')]['routes'];
$this->logger->info(sprintf('Saving %s lines from ZTM Gdańsk', count($lines)));
return collect($lines)->map(function ($line) use ($provider) {
$symbol = $line['routeShortName'];
$operator = $this->em->getReference(
OperatorEntity::class,
$this->ids->generate($provider, $line['agencyId'])
);
$type = [
2 => LineModel::TYPE_TRAM,
5 => LineModel::TYPE_TROLLEYBUS,
];
return LineEntity::createFromArray([
'id' => $this->ids->generate($provider, $line['routeId']),
'symbol' => $symbol,
'description' => $line['routeLongName'],
'type' => $type[$line['agencyId']] ?? LineModel::TYPE_BUS,
'night' => preg_match('/^N\d{1,3}$/', $symbol),
'fast' => preg_match('/^[A-MO-Z]$/', $symbol),
'operator' => $operator,
'provider' => $provider,
]);
});
}
private function getStops(ProviderEntity $provider)
{
$this->logger->info('Obtaining stops from ZTM Gdańsk');
$stops = file_get_contents(self::STOPS_URL);
$stops = json_decode($stops, true)[date('Y-m-d')]['stops'];
$this->logger->info(sprintf('Saving %d stops from ZTM Gdańsk', count($stops)));
return collect($stops)->map(function ($stop) use ($provider) {
return StopEntity::createFromArray([
'id' => $this->ids->generate($provider, $stop['stopId']),
'name' => trim($stop['stopName'] ?? $stop['stopDesc']),
'variant' => trim($stop['zoneName'] == 'Gdańsk' ? $stop['stopCode'] : null),
'latitude' => $stop['stopLat'],
'longitude' => $stop['stopLon'],
'onDemand' => (bool)$stop['onDemand'],
'provider' => $provider,
]);
});
}
public function getTracks(ProviderEntity $provider)
{
$this->logger->info('Obtaining tracks from ZTM Gdańsk');
$tracks = file_get_contents(self::TRACKS_URL);
$tracks = json_decode($tracks, true)[date('Y-m-d')]['trips'];
$this->logger->info('Obtaining stops associations from ZTM Gdańsk');
$stops = file_get_contents(self::STOPS_IN_TRACKS_URL);
$stops = json_decode($stops, true)[date('Y-m-d')]['stopsInTrip'];
$stops = collect($stops)->groupBy(function ($stop) {
return sprintf("R%sT%s", $stop['routeId'], $stop['tripId']);
});
$this->logger->info(sprintf('Saving %d tracks from ZTM Gdańsk', count($stops)));
return collect($tracks)->map(function ($track) use ($provider, $stops) {
$entity = TrackEntity::createFromArray([
'id' => $this->ids->generate($provider, $track['id']),
'line' => $this->em->getReference(
LineEntity::class,
$this->ids->generate($provider, $track['routeId'])
),
'description' => preg_replace('/\(\d+\)/', '', $track['tripHeadsign']),
'provider' => $provider,
]);
$stops = $stops->get($track['id'])->map(function ($stop) use ($entity, $provider) {
return StopInTrack::createFromArray([
'stop' => $this->em->getReference(
StopEntity::class,
$this->ids->generate($provider, $stop['stopId'])
),
'track' => $entity,
'order' => $stop['stopSequence'] + (int)($stop['stopId'] > 30000), // HACK! Gdynia has 0 based sequence
]);
});
$entity->setStopsInTrack($stops->all());
return $entity;
});
}
public static function getSubscribedEvents()
{
return [
DataUpdater::UPDATE_EVENT => 'update',
];
}
}